- Go 97.4%
- Makefile 2.6%
| cmd | ||
| internal/models | ||
| man | ||
| pkg | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||
| Makefile | ||
| README.md | ||
| readme.md | ||
| stowbun | ||
Dotman
A modern dotfile management tool in Go that replaces GNU Stow. Features an interactive Bubble Tea TUI and Git integration.
Features
- Stow Replacement: Creates and manages symlinks without GNU Stow
- Interactive TUI: Bubble Tea-based user interface for management
- Git Integration: Uses the system Git installation
- Package Management: Organize dotfiles into logical packages
- Flexible Symlinks: Choose target and source directories freely
- Shell Completions: Auto-completion support for Bash, Zsh, Fish, and PowerShell
- Simple CLI: Intuitive commands for all operations
Installation
Requirements
- Go 1.21 or higher
- Git (system installation)
Build from Source
git clone https://quelloffen.ch/zenn/dotman
cd dotman
make build
sudo make install
Or manually:
git clone https://quelloffen.ch/zenn/dotman
cd dotman
go build -o dotman ./cmd/dotman
sudo mv dotman /usr/local/bin/
Or Install Directly
go install quelloffen.ch/zenn/dotman/cmd/dotman@latest
Install Manpages
make install-man
Install Shell Completions
Dotman supports shell completions for Bash, Zsh, Fish, and PowerShell using the built-in completion command.
Bash
Add to ~/.bashrc:
eval "$(dotman completion bash)"
Or install system-wide:
sudo dotman completion bash > /etc/bash_completion.d/dotman
Zsh
Add to ~/.zshrc:
eval "$(dotman completion zsh)"
Or install system-wide:
dotman completion zsh > "${fpath[1]}/_dotman"
Fish
dotman completion fish > ~/.config/fish/completions/dotman.fish
PowerShell
Add to your PowerShell profile:
dotman completion powershell | Out-String | Invoke-Expression
Makefile Commands
When building from source, you can use the following make commands:
make build # Compile the application
make install # Install to /usr/local/bin (requires sudo)
make install-user # Install to ~/.local/bin (no sudo required)
make install-man # Install manpages to /usr/local/share/man
make run # Run without building
make clean # Remove build artifacts
make test # Run tests
make fmt # Format code
make help # Show all available commands
Quick Start
# Initialize a new dotfiles repository
dotman init
# Or clone an existing one
dotman init git@github.com:username/dotfiles.git
# Add configuration files
dotman add ~/.config/nvim
dotman add ~/.bashrc home
# Start the interactive TUI
dotman tui
# Or use CLI commands
dotman apply # Activate all packages
dotman sync # Commit and push changes
Directory Structure
Dotman stores dotfiles in ~/.dotfiles/ (configurable):
~/.dotfiles/
├── .config/
│ ├── nvim/
│ │ └── init.lua
│ └── kitty/
│ └── kitty.conf
├── bash/
│ ├── .bashrc
│ └── .bash_profile
└── .git/
Each folder is a "package" and contains the files to be linked.
Commands
init [repository-url]
Initializes a new repository or clones an existing one.
dotman init
dotman init git@github.com:user/dotfiles.git
add <path> [package]
Adds a file or directory to the dotfiles.
dotman add ~/.config/nvim
dotman add ~/.bashrc home
dotman add ~/.zshrc zsh
remove <path>
Removes a file from dotfiles and restores it.
dotman remove ~/.config/nvim
list [package]
Lists all managed files.
dotman list
dotman list .config
apply [package]
Activates (creates symlinks for) all or a specific package.
dotman apply
dotman apply .config
unapply [package]
Deactivates (removes symlinks) all or a specific package.
dotman unapply
dotman unapply .config
sync [message]
Commits and pushes all changes.
dotman sync
dotman sync "Updated nvim config"
tui
Starts the interactive user interface.
dotman tui
Keyboard shortcuts in the TUI:
j/kor↓/↑: Navigate up/downh/l: Switch between panesSpace/Enter: Toggle package/directory expansiono: Expand all directoriesq: Quit
status
Shows the current status.
dotman status
completion [shell]
Generates shell completion scripts. Supported shells: bash, zsh, fish, powershell.
dotman completion bash
dotman completion zsh
dotman completion fish
dotman completion powershell
Configuration
The configuration is stored in ~/.dotman.json:
{
"dotfiles_dir": "/home/username/.dotfiles",
"target_dir": "/home/username",
"packages": [],
"updated_at": "2024-01-15T10:30:00Z"
}
How It Works
Adding a File
- File is moved to the dotfiles directory
- Original file is replaced by a symlink
- Change is added to Git
Before:
~/.config/nvim/init.lua
After dotman add ~/.config/nvim:
~/.dotfiles/.config/nvim/init.lua (actual file)
~/.config/nvim/ → ~/.dotfiles/.config/nvim (symlink)
Package Structure
Packages are simply folders in the dotfiles directory:
~/.dotfiles/.config/nvim/
~/.dotfiles/.config/kitty/
~/.dotfiles/bash/
When you run dotman apply, symlinks are created:
~/.config/nvim → ~/.dotfiles/.config/nvim
~/.config/kitty → ~/.dotfiles/.config/kitty
~/.bashrc → ~/.dotfiles/bash/.bashrc
Git Workflow
Dotman uses your system Git:
# Edit your dotfiles normally (they are linked)
vim ~/.config/nvim/init.lua
# Check changes
cd ~/.dotfiles && git status
# Sync with dotman
dotman sync "Updated nvim config"
# Or manually
git add .
git commit -m "Updated nvim config"
git push
Tips & Tricks
Different Packages for Different Machines
Create package-specific configurations:
# Laptop-specific
dotman add ~/.config/i3 laptop
# Server-specific
dotman add ~/.ssh/config server
Then activate only the needed packages:
dotman apply laptop
dotman apply .config
Ignoring Files
Create a .gitignore in ~/.dotfiles/:
*.log
.DS_Store
secrets/
Backup Before Changes
Before major changes:
dotman sync "Backup before reorganization"
Troubleshooting
"target already exists"
A file already exists at the target location:
# Backup and then apply
mv ~/.config/nvim ~/.config/nvim.backup
dotman apply .config
Symlink Not Working
Check if the file was really moved:
ls -la ~/.dotfiles/
ls -la ~/.config/
Git Errors
Make sure Git is configured:
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
Comparison with Stow
| Feature | GNU Stow | Dotman |
|---|---|---|
| Symlink Management | Yes | Yes |
| Interactive TUI | No | Yes |
| Integrated Git | No | Yes |
| Shell Completions | No | Yes |
| Simple CLI | Partial | Yes |
| Package Structure | Yes | Yes |
| Selectable Target Directory | Partial | Yes |
License
MIT License - See LICENSE file
Contributing
Contributions are welcome! Open an issue or pull request at quelloffen.ch/zenn/dotman.
Made with love in Go