dtow is a symlink manager script for GNU/Linux and Mac, written in bash, that was heavily inspired by GNU Stow, with more emphasis on dotfile (config file) managment. dtow was made after I ran into issues while using stow to symlink files to root directories, like /etc. dtow was designed to be as close to a drop-in replacement for stow, as it was possible, using the same CLI option naming and, most of the time, functionality.
THIS PROGRAM COMES WITH NO WARRANTY, USE AT YOUR OWN RISK
- Clone the git repo:
git clone https://github.com/JacksStuff0905/dtow.git - Enter the repo directory:
cd dtow - Run the install script:
./install.sh - Exit the repo directory:
cd .. - Remove the repo directory:
rm -r dtow
Uninstalling
- Clone the git repo (if you haven't already):
git clone https://github.com/JacksStuff0905/dtow.git - Enter the repo directory:
cd dtow - Run the uninstall script:
./uninstall.sh - Exit the repo directory:
cd .. - Remove the repo directory:
rm -r dtow
Syntax:
dtow [OPTION ...] [-D|-S|-R] PACKAGE ... [-D|-S|-R] PACKAGE ...
Use like GNU Stow with the difference being:
- everything inside
package/homewill be symlinked/copied to~/ - everything inside
package/rootwill be symlinked/copied to/ - everything inside
package/that is not either of the above will be symlinked/copied to the default target -~/ - if a file cannot be symlinked due to permission problems, dtow will try running the command as the super user, asking for credentials in the process.
- use
dtow --helpto print the help - WARNING: Some of the options listed have not been implemented yet, to check which ones go to the TODO section of this readme. - configure dtow with the
.dtowfile - configure ignores with the
.dtowignorefile - The project is very much in alpha development, there could and probably will be issues when using it. It has only been tested in the most basic of situations.
At the basic level dtow functions similarly to stow - it symlinks the config of a specified package (e.g. neovim), which is stored as a directory inside the main stow/dtow directory, to the target path as defined by the file structure inside the package directory. Where the two programs diverge, is the fact that dtow can support defining target directories.
For example, in the package directory (neovim/) there is a directory called home (neovim/home/). According to the default dtow configuration, the file structure inside the home directory (neovim/home/) will be copied over to the user home directory (~/ or $HOME/), so a if the package file structure looks like this:
neovim/
└── home/
└── .config/
└── nvim/
└── init.vim
Inside the home (~/ or $HOME/) directory of the user, a file structure like this will be created, where the init.vim file will be symlinked:
~/
└── .config/
└── nvim/
└── init.vim
By default there are two predefined target directories - home/, which points to ~/ (the user's home directory) and root/ which points to / (the root of the filesystem). All other target directories will be copied to the default target - ~/ (the user's home directory), so the directory tree could be refactored, with no change to the result, to look like this:
neovim/
└── .config/
└── nvim/
└── init.vim
Where .config/ will be assumed to be copied to ~/.config/
This is a change in comparison to the behaviour of GNU Stow, which by default targets the parent directory of the stow directory, aka ../
All the target directories, including the default, can be configured in the dtow configuration file (.dtow) placed inside the dtow/stow directory. More over, using the .dtowignore file, it is possible to define files and directories for dtow to ignore during any operation.
So a complete dtow file structure would look like this:
parent-directory/
├── some-package/
│ ├── home/
│ │ ├── home-file.txt
│ │ └── ignored-home-file
│ └── root/
│ └── root-file.txt
├── another-package/
│ └── another-home-file.txt
├── some-ignored-file
├── .dtow
└── .dtowignore
Adopt (or --adopt) is the option which is based on the GNU Stow option of the same name. However it may have different quirks and behave differently in some specific scenarios. Still, the core idea remains the same - (when enabled) if a file is found inside the target directory of a stowing operation (-S or --stow) dtow will move it inside the package directory to the file's respective spot. This will be followed with the usual symlinking of the file from the package directory to the target directory, so to an end user everything will work the same. Here's an example:
Let's say there's a configuration for neovim, and the package directory looks like this:
neovim/
└── .config/
└── nvim/
└── init.vim
And the user's home directory looks like this:
~/
└── .config/
└── nvim/
└── file-to-be-adopted
Running dtow --adopt neovim will perform these actions:
- Look any files inside the target directory (~/) that should be adopted. (file-to-be-adopted)
- Move them to the stow directory
- Perform the normal stow operation
And the resulting file structures will look like this:
Package directory:
neovim/
└── .config/
└── nvim/
├── init.vim
└── file-to-be-adopted
Target directory:
~/
└── .config/
└── nvim/
├── init.vim
└── file-to-be-adopted
Both of the configuration files (.dtow, .dtowignore) support comments starting with the character '#'.
.dtow
# This is the dtow configuration file
# You can define folder aliases with the equal(=) operator, like so:
root=/
# You can utilize environment variables:
home=$HOME
# You can define the default folder with the dot(.) symbol.
# It is the fallback in case there are no alias matches with the above:
.=$HOME
.dtowignore
# This is the ignore file, use it like the .gitignore file in git
some-ignored-file
some-ignored-folder/
some-package/another-ignored-file
some-package/another-ignored-folder/
This project was created out of necessity, so it may not be the fastest and most efficient.
There is a very high chance, that there could be issues while using dtow, as it is in very early development, however, as I plan to use it myself, I will probably be fixing most of the bugs I find.
The help menu of the script includes some options which have not been implemented yet. That includes:
--defer=REGEX
--override=REGEX
--dotfiles