Skip to content
/ straw Public

An opinionated take on GNU Stow with git-based sync capabilities and an optional lua-based config.

License

Notifications You must be signed in to change notification settings

daltongd/straw

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🥤 🍓 🧃 straw 🍹 🧋 👒

an opinionated take on GNU Stow with git-based sync capabilities with an optional lua-based config


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.

What is straw?

An opinionated and pretty basic dotfiles manager inspired by stow, yet with additional configuration options and a built-in git integration.

Installation

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.git

You can also clone this repo and compile it yourself.

Usage

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 --apply

To later sync your dotfiles:

straw sync

or:

straw -sa

which stands for:

straw sync --sync-repo --apply

You 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 --preview

or a shorthand version:

straw sync -p

Configuration

straw 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 config

In the overrides:

  • The from path is relative to the .dotfiles
  • You can use environment variables in the to path
    • e.g. %userprofile% on windows
    • e.g. $HOME on unix
    • you can also us ~ as a home directory on all platforms

Example git config

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

Help

❯ 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 version

Todos

Pre-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 .dotfiles path 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

  • .dotfiles path override

  • target path override

  • cache deployed symlinks and add --clear or 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 ssh2 with openssl-on-win32 for windows to let git2 handle cloning over ssh://

  • 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?

About

An opinionated take on GNU Stow with git-based sync capabilities and an optional lua-based config.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published