Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/pablopunk/dot
Manage your apps, dotfiles, and their dependencies automagically
https://github.com/pablopunk/dot
automagically brew dependencies dotfiles homebrew install linux mac magic
Last synced: 17 days ago
JSON representation
Manage your apps, dotfiles, and their dependencies automagically
- Host: GitHub
- URL: https://github.com/pablopunk/dot
- Owner: pablopunk
- Created: 2024-10-09T12:57:07.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2024-12-06T14:43:50.000Z (18 days ago)
- Last Synced: 2024-12-06T16:45:05.195Z (18 days ago)
- Topics: automagically, brew, dependencies, dotfiles, homebrew, install, linux, mac, magic
- Language: Lua
- Homepage:
- Size: 131 KB
- Stars: 2
- Watchers: 1
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# `dot`
> Manage your dotfiles and their dependencies automagically
## Table of Contents
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Usage](#usage)
- [`init.lua`](#initlua)
- [Recursive](#recursive)
- [Profiles](#profiles)
- [Force Mode `-f`](#force-mode--f)
- [Unlinking Configs `--unlink`](#unlinking-configs---unlink)
- [Purging Modules `--purge`](#purging-modules---purge)
- [Hooks](#hooks)
- [Summary of Command-Line Options](#summary-of-command-line-options)
- [Examples](#examples)
- [To do](#to-do)## Installation
```bash
$ brew install pablopunk/brew/dot
```## Quick Start
```bash
$ cd /path/to/dotfiles
$ treeprofiles/
├── work.lua
├── personal.lua
├── linux-server.lua
modules/
├── neovim/
│ ├── init.lua
│ └── config/
├── zsh/
│ ├── init.lua
│ └── zshrc
└── apps/
├── work/
│ └── init.lua
└── personal/
└── init.lua$ dot # Link all dotfiles and install dependencies
$ dot neovim # Only process the 'neovim' module
$ dot work # Only process the 'work' profile
```## Usage
Each module under the `modules/` folder needs to have at least an `init.lua`. If not, it will be ignored.
### `init.lua`
Example for neovim:
```lua
-- modules/neovim/init.lua
return {
brew = {
{ name = "neovim", options = "--HEAD" },
"ripgrep"
},
config = {
source = "./config", -- Our config directory within the module
output = "~/.config/nvim", -- Where the config will be linked to
}
}
```The config will be linked to the home folder with a soft link. In this case:
```bash
~/.config/nvim → ~/dotfiles/modules/neovim/config
```You can also specify multiple configurations for a single module:
```lua
-- modules/multi-config/init.lua
return {
brew = { "cursor" },
config = {
{
source = "./config/settings.json",
output = "~/Library/Application Support/Cursor/User/settings.json",
},
{
source = "./config/keybindings.json",
output = "~/Library/Application Support/Cursor/User/keybindings.json",
}
}
}
```This will create two symlinks:
```bash
~/Library/Application Support/Cursor/User/settings.json → ~/dotfiles/modules/multi-config/config/settings.json
~/Library/Application Support/Cursor/User/keybindings.json → ~/dotfiles/modules/multi-config/config/keybindings.json
```As you can see, you can declare dependencies as [Homebrew](https://brew.sh) packages, which makes it possible to also use `dot` to install GUI apps (Homebrew casks). You can create a module without any config to use it as an installer for your apps:
```lua
-- modules/apps/init.lua
return {
brew = { "whatsapp", "spotify", "slack", "vscode" }
}
```### Recursive
In the example above, let's say we want to separate our apps into "work" and "personal". We could either create 2 modules on the root folder or create a nested folder for each:
```lua
-- modules/apps/work/init.lua
return {
brew = { "slack", "vscode" }
}
``````lua
-- modules/apps/personal/init.lua
return {
brew = { "whatsapp", "spotify" }
}
```### Profiles
If you have several machines, you might not want to install all tools on every computer. That's why `dot` allows **profiles**.
Let's create a new "personal" profile:
```lua
-- profiles/personal.lua
return {
modules = {
"*",
"!apps/work",
}
}
```In this example, running `dot personal` will:
- `*`: Install everything under `modules/`, including nested directories.
- `!apps/work`: Exclude the `apps/work` module and its submodules.You can use the following patterns in your profile:
- `"*"`: Include all modules recursively.
- `"!module_name"`: Exclude a specific module and its submodules.
- `"module_name"`: Include a specific module.For example, a work profile might look like this:
```lua
-- profiles/work.lua
return {
modules = {
"apps/work",
"slack",
"neovim",
"zsh"
}
}
```> [!NOTE]
> If your profile is named just like a module (e.g., `profiles/neovim` and `modules/neovim`), running `dot neovim` will default to the profile.### Force Mode `-f`
By default, `dot` won't touch your existing dotfiles if the destination already exists. If you still want to replace them, you can use the `-f` flag:
```bash
$ dot -f neovim
```> [!NOTE]
> It won't remove the existing config but will move it to a new path: `.before-dot`.### Unlinking Configs `--unlink`
If you want to remove the symlinks created by `dot` for a specific module but keep your configuration, you can use the `--unlink` option:
```bash
$ dot --unlink neovim
```This command will:
- Remove the symlink at the destination specified in `config.output`.
- Copy the config source from `config.source` to the output location.This is useful if you want to maintain your configuration files without `dot` managing them anymore.
### Purging Modules `--purge`
To completely remove a module, including uninstalling its dependencies and removing its configuration, use the `--purge` option:
```bash
$ dot --purge neovim
```This command will:
- Uninstall the Homebrew dependencies listed in the module's `init.lua`.
- Remove the symlink or config file/directory specified in `config.output`.
- Run any `post_purge` hooks if defined in the module.> [!WARNING]
> `--purge` will uninstall packages from your system and remove configuration files. Use with caution.### Hooks
You can define `post_install` and `post_purge` hooks in your module's `init.lua` to run arbitrary commands after the module has been installed or purged.
```lua
return {
brew = { "gh" },
post_install = "gh auth login"
}
```You can also define multi-line hooks:
```lua
return {
brew = { "gh" },
post_install = [[
gh auth status | grep 'Logged in to github.com account' > /dev/null || gh auth login --web -h github.com
gh extension list | grep gh-copilot > /dev/null || gh extension install github/gh-copilot
]],
}
```### Summary of Command-Line Options
- **Install Modules**: Install dependencies and link configurations.
```bash
$ dot # Install all modules
$ dot neovim # Install only the 'neovim' module
$ dot work # Install only the 'work' profile
```- **Force Mode**: Replace existing configurations, backing them up to `.before-dot`.
```bash
$ dot -f # Force install all modules
$ dot -f neovim # Force install the 'neovim' module
```- **Unlink Configs**: Remove symlinks but keep the config files in their destination.
```bash
$ dot --unlink neovim
```- **Purge Modules**: Uninstall dependencies and remove configurations.
```bash
$ dot --purge neovim
```### Wget Configuration
It now supports downloading files using `wget`. This can be useful for fetching binaries or other resources that are not available through Homebrew. You can specify a `wget` configuration in your module's `init.lua` file.
Example:
```lua
-- modules/apps/init.lua
return {
wget = {
{
url = "https://app1piece.com/1Piece-4.2.1.zip",
output = "/Applications/1Piece.app",
zip = true,
},
{
url = "https://fakedomain.com/fake.app",
output = "/Applications/Fake.app",
},
},
}
```This will:
- Download the file from the specified URL.
- Unzip it if `zip = true`.
- Install it to the specified output path.Just use it like any other module:
```bash
$ dot apps
```> [!NOTE]
> When using `zip = true`, make sure the output file name matches the unzipped file name. In the example above, the output is `/Applications/1Piece.app` because the zip file contains a file named `1Piece.app`.## Examples
- [pablopunk/dotfiles](https://github.com/pablopunk/dotfiles): my own dotfiles.
## To do
- [x] `dot` will install dependencies and link files.
- [x] Support Homebrew dependencies.
- [x] `dot -f` will remove the existing configs if they exist (moves config to `*.before-dot`).
- [x] Allow post-install hooks in bash.
- [x] Allow installing only one module with `dot neovim`.
- [x] Allow multiple setups in one repo. Similar to "hosts" in Nix, `dot work` reads `profiles/work.lua` which includes whatever it wants from `modules/`.
- [x] Package and distribute `dot` through Homebrew.
- [x] Add `--unlink` option to remove symlinks and copy configs to output.
- [x] Add `--purge` option to uninstall dependencies and remove configurations.
- [x] Allow array of config. For example I could like two separate folders that are not siblings
- [x] Improve profiles syntax. For example, `{ "*", "apps/work" }` should still be recursive except in "apps/". Or maybe accept negative patterns like `{ "!apps/personal" }` -> everything but apps/personal.
- [x] Add screenshots to the README.
- [ ] Support more ways of adding dependencies (e.g., wget binaries, git clone, apt...).
- [x] wget
- [ ] git clone
- [ ] apt
- [ ] Unlinking dotfiles without copying. An option like `dot --unlink --no-copy` could be added.
- [ ] `dot --purge-all` to purge all modules at once.
- [ ] Support Mac defaults, similar to `nix-darwin`.
- [ ] Support an `os` field. i.e `os = { "mac" }` will be ignored on Linux.
- [ ] After using a profile, like `dot profile1`, it should remember it and all calls to `dot` should be done with this profile unless another profile is explicitely invoked, like `dot profile2`, which will replace it for the next invokations.