Warning
This tool is a work in progress and is developed as my personal utility. I may or may not update it further and add new features. I'm also not giving any guarantees that your configs are safe with this tool, it's highly experimental and it's in the experiments phase. This tool is offered as-is and I will not be responding to feature requests that aren't aligned with my needs.
Note
Contributions are always welcome, but due to the experimental/wip nature of this project, I may be slow to react to issues / pull requests until further notice.
An opinionated and pretty basic dotfiles manager inspired by stow, yet with additional configuration options and a built-in git integration.
Currently the easies and best option is to use cargo install. If you don't have
the rust toolchain on your system, visit Install Rust.
cargo install --git https://github.com/daltongd/straw.gitYou can also clone this repo and compile it yourself.
straw expects your configs to be in a stow-like directory structure under your
~/.dotfiles directory. Directories within ~/.dotfiles with names that begin with
a dot (., e.g. -> .straw) are ignored and not treated as packages.
To clone your dotfiles repo to this path, use:
Note
If you already have your .dotfiles there, there's no need to clone. Make sure
you have your git repository initialized and that the origin remote url is set.
straw clone https://repository.com/your/.dotfiles.git --applyTo later sync your dotfiles:
straw syncor:
straw -sawhich stands for:
straw sync --sync-repo --applyYou can also use the --preview option to only log out the changes that would be
applied without applying them (note, the sync command won't happen, it'll only
check if there are any changes):
straw sync --previewor a shorthand version:
straw sync -pstraw uses a lua-based config inspired by the likes of WezTerm
or Neovim
The config file can be placed in ~/.dotfiles/.straw/config.lua.
Here is an example config:
local straw = require("straw")
local config = {}
config.git = {
remote = "origin",
branch = "main",
}
config.overrides = {}
if straw.platform == "windows" then
config.overrides["powershell"] = {
link = "%userprofile%/Documents/PowerShell/Microsoft.PowerShell_profile.ps1",
target = "Microsoft.PowerShell_profile.ps1",
}
config.overrides["nvim"] = {
link = "%localappdata%/nvim"
target = ".config/nvim",
}
config.overrides["yazi"] = {
link = "%appdata%/yazi/config"
target = ".config/yazi",
}
end
if straw.platform == "windows" then
config.ignores = { "fish" }
elseif straw.platform == "unix" then
config.ignores = { "komorebi", "whkd", "winfetch", "powershell", "wpm" }
end
return configIn the overrides:
- The
frompath is relative to the.dotfiles - You can use environment variables in the
topath- e.g.
%userprofile%on windows - e.g.
$HOMEon unix - you can also us
~as a home directory on all platforms
- e.g.
local straw = require("straw")
local config = {}
config.remote = "origin"
config.branch = "main"
config.merge_flavor = "Rebase"
config.commit_message = "auto: push changes from " .. straw.hostname
return config❯ straw --help
Usage: straw.exe [OPTIONS] [COMMAND]
Commands:
clone Clone a git repository into ~/.dotfiles
init Init a git repository in ~/.dotfiles, you can also provide the origin url
status Get git status
sync Synchronize the .dotfiles (commit, push, pull, merge/rebase) and apply the packages according to the config. Equivalend of `--sync-repo --apply` or `-sa`
clear Clear packages
copy-files Copy the specified package(s) over instead of creating symlinks. Useful in combination with ignores if you'd like to only copy the initial config and not manage with straw
adopt Adopt the package by moving the contents of a directory to the `.dotfiles` path and creating a symlink NOTE: This functionality is limited to the paths under your target directory
patch Patch your dotfiles with a file or a directory from a remote repository
run Run lua module
execute Execute lua script
help Print this message or the help of the given subcommand(s)
Options:
-p, --preview Preview the operation. Prints the messages, but doesn't perform any operations
-s, --sync-repo Synchronize the .dotfiles with a git repository. Performs Commit -> Pull -> Rebase/Merge -> Push
-a, --apply Apply the packages onto the system
-c, --clear Clear all deployed symlinks
--packages <PACKAGE>... Specify packages to apply. Implies `--apply`, overrides ignores from the config
--ignore <PACKAGE>... Specify packages to ignore when applying the config
--remote <REMOTE> Override git remote setting for this operation
--branch <BRANCH> Override git branch setting for this operation
--merge-commit Set the merge flavor to a merge commit
--rebase Set the merge flavor to rebase
-m, --message <MESSAGE> Set the commit message. Implies `--commit`
--pull Pull .dotfiles from the repository. This selectively enables the `pull` action, even if the `--sync-repo` flag is not set
--push Push .dotfiles to the repository. This selectively enables the `push` action, even if the `--sync-repo` flag is not set
--commit Commit .dotfiles to the repository. This selectively enables the `commit` action, even if the `--sync-repo` flag is not set
--adopt <PACKAGE> Adopt the package by moving the contents of a directory to the `.dotfiles` path and creating a symlink. NOTE: This functionality is limited to the paths under your target directory
--dotfiles <PATH> Override the default `~/.dotfiles` path
--target <PATH> Override the target path (default: `~`)
--ssh-key-path <PATH> Direct path to the ssh key (by default looks for a standard-named key in the `~/.ssh/` dir)
-h, --help Print help
-V, --version Print versionPre-release checklist:
- Document features
Features:
- lua hooks (callbacks, e.g. for applying a package/packages, etc.)
- simple test suite
Nice to haves:
- plugin manager
On Hold:
-
[!] additional option for dotfiles handling by replacing
dot-with a period.as in GNU Stow. this one is tricky, because this can only work up until some level in the directory structure -
[!] setting the env vars, also cached for ease of reverting them later (might not be feasible, on all platforms, also could be set by the shell profile for the most part)
Done:
-
[~] git lua bindings (unstable)
-
[~] swappable profiles (via the
.dotfilespath override) -
undo/clear
-
configurable one-time deploy by copying the file directly
-
patches - ability to get a specific directory/file from any dotfiles repository
-
utility functions in lua library
-
git ssh key selection
-
installing packages / running scripts
-
.dotfilespath override -
targetpath override -
cache deployed symlinks and add
--clearor a similar command -
use packages' directory structures when path folding
-
per-device (hostname) ignores/overrides - instead add hostname to lua module
-
per-username ignores/overrides - instead add username to lua module
-
replace json with lua for some added pizzaz
-
resolve
~in paths -
adopt
-
additional console args for overrides (especially useful for initial clone) things like: ignores, or ability to specify packages to apply
-
add
ssh2withopenssl-on-win32for windows to letgit2handle cloning overssh:// -
git merge flavor, remote and branch (repo config) override args
-
git - determine if there are any changes to push/commit
-
git status
-
git pull only
-
git push only
-
git sync with a commit message
-
git set the default commit message in the config
-
git init?