stoww is a simple shell script that wraps GNU
Stow to provide additional features for
managing dotfiles or software packages. It handles pre/post-installation and
removal scripts, manages a .stowed
flag file, and ensures certain files are
not stowed.
- Pre/Post Scripts: Automatically runs
stow-preinst
,stow-postinst
,stow-prerm
, andstow-postrm
scripts (or their hidden counterparts.stow-preinst
,.stow-postinst
, etc.) if they exist and are executable. - Conflict Detection: Reports an error if both hidden and non-hidden versions of a script are present in the package directory.
- Flag File Management: Creates a
.stowed
file in the package directory when the package is stowed and deletes it when unstowed. - Ignore Patterns: Ensures that special scripts and any files matching
*.stow-*
orstow-*
are not stowed. - Full GNU Stow Compatibility: Supports all GNU Stow options by passing
them directly to the
stow
command.
-
Clone the Repository:
git clone https://github.com/jpasquier/stoww.git
-
Make the Script Executable:
cd stoww chmod +x stoww
-
Move the Script to a Directory in Your PATH:
sudo mv stoww /usr/local/bin/
-
(Optional) Create an Alias:
Since
stoww
is a complete wrapper for GNU Stow, you might find it convenient to alias it:alias stow=stoww
Add the above line to your shell's configuration file (e.g.,
.bashrc
,.zshrc
) to make it permanent.
Note: It is also possible to build a Debian package
stoww [OPTIONS] PACKAGE...
-S
,--stow
: Stow the package(s).-D
,--delete
: Unstow the package(s).-R
,--restow
: Restow the package(s).-h
,--help
: Display help information.
All other options are passed directly to GNU Stow.
-
Stow a Package:
stoww -S mypackage
-
Unstow a Package:
stoww -D mypackage
-
Restow a Package:
stoww -R mypackage
-
Specify Target Directory:
stoww -t /usr/local -S mypackage
-
Executable Scripts: Ensure that your
stow-*
or.stow-*
scripts are executable. You can make them executable with:chmod +x stow-preinst stow-postinst stow-prerm stow-postrm chmod +x .stow-preinst .stow-postinst .stow-prerm .stow-postrm
If these scripts are not executable,
stoww
will not be able to run them. -
Hidden vs. Non-Hidden Scripts:
- You can choose to use either hidden (
.stow-*
) or non-hidden (stow-*
) scripts. - Do Not Use Both: If both versions of a script are present in the
package directory,
stoww
will report an error and exit. Please ensure only one version is used per script type.
- You can choose to use either hidden (
-
Idempotence: Ensure that your
stow-*
(or.stow-*
) scripts are idempotent. This means they should be safe to run multiple times without causing unintended side effects or errors.- Repeated Execution: The
stoww
command may invoke these scripts every time it is run, especially during operations like restowing or updating packages. - Preventing Issues: Non-idempotent scripts could, for example, add duplicate entries to configuration files, create conflicting symbolic links, or modify system state in ways that lead to errors when the script is executed more than once.
- Check Before Action: Before performing an operation (like adding a line to a file), check if it has already been done.
- Use Conditional Logic: Employ
if
statements to ensure actions are only taken when necessary. - Clean Up Safely: When removing or modifying files, ensure that they exist and are in the expected state.
- Repeated Execution: The
-
Ignored Files: The script automatically ignores the following files to prevent them from being stowed:
.stowed
- Any files matching
*.stow-*
(e.g.,.stow-preinst
) - Any files matching
stow-*
(e.g.,stow-postinst
)
-
Stowing (
-S
,--stow
):- Runs
stow-preinst
or.stow-preinst
if it exists and is executable. - Reports an error if both versions exist.
- Creates the
.stowed
flag file in the package directory. - Executes
stow
with the specified options and ignore patterns. - Runs
stow-postinst
or.stow-postinst
if it exists and is executable. - Reports an error if both versions exist.
- Runs
-
Unstowing (
-D
,--delete
):- Runs
stow-prerm
or.stow-prerm
if it exists and is executable. - Reports an error if both versions exist.
- Removes the
.stowed
flag file from the package directory. - Executes
stow -D
with the specified options and ignore patterns. - Runs
stow-postrm
or.stow-postrm
if it exists and is executable. - Reports an error if both versions exist.
- Runs
-
Restowing (
-R
,--restow
):- Runs
stow-prerm
or.stow-prerm
if it exists and is executable. - Reports an error if both versions exist.
- Removes the
.stowed
flag file from the package directory. - Executes
stow -R
with the specified options and ignore patterns. - Runs
stow-postinst
or.stow-postinst
if it exists and is executable. - Reports an error if both versions exist.
- Recreates the
.stowed
flag file.
- Runs
You can build a Debian package for stoww
using the provided
build-stoww-deb
script.
Ensure the following tools are installed on your system:
git
fakeroot
dpkg-deb
-
Clone the Repository (if you haven't already):
git clone https://github.com/yourusername/stoww.git cd stoww
-
Make the Build Script Executable:
chmod +x build-stoww-deb
-
Build the Package from GitHub Repository:
This is the default behavior. The script will clone the latest code from GitHub and build the package.
./build-stoww-deb
-
Build the Package from Local Repository:
If you have made local changes and wish to build the package from your current working directory, use the
--local
option../build-stoww-deb --local
-
Find the Generated Package:
The
.deb
package will be located in your current directory.ls *.deb
For usage information:
./build-stoww-deb --help
-
Building from Local Repository:
- Ensure you are in the root directory of the
stoww
Git repository. - The script will use the current state of your local code, including any uncommitted changes.
- The version number in the package will reflect your local Git commit count and hash.
- Ensure you are in the root directory of the
-
Permissions:
- The script uses
fakeroot
to build the package without requiring root privileges.
- The script uses
-
Cleanup:
- Temporary build files are cleaned up automatically after the script finishes.
A completion function for stoww
, adapted from the completion script for
stow
, is included in the repository. To enable it, follow these steps:
-
Create a Custom Completion Directory:
mkdir -p ~/.zsh/completion
-
Add the Directory to Your
$fpath
:Add the following line to your
~/.zshrc
before callingcompinit
:fpath=(~/.zsh/completion $fpath)
-
Copy the
_stoww
Completion Function:cp zsh_completion ~/.zsh/completion/_stoww
-
Initialize the Completion System:
In your
~/.zshrc
, ensure you have:autoload -Uz compinit compinit
-
Reload Zsh Configuration:
rm -f ~/.zcompdump source ~/.zshrc
-
Test the Completion:
Type
stoww
followed by[Tab]
to see if completions are suggested.
-
Ensure
compinit
Is Called: The completion system must be initialized withcompinit
for completions to work. -
Avoid Caching Issues: If completions don't seem to update, try deleting the
.zcompdump
file:sh rm -f ~/.zcompdump compinit
-
No Need for Root Permissions: Placing the completion script in your home directory avoids the need for
sudo
or root access.
While stoww
provides additional features over GNU Stow, it remains a simple
wrapper script. For more complex package management needs, consider using
dedicated package managers or configuration management tools.
But hey, sometimes simple is better! This script aims to be a straightforward solution for straightforward needs.
Contributions are welcome! Feel free to open issues or submit pull requests.
This project is licensed under the MIT License.