From 553fb254f7e772bfc96208a57b1035b3bdb73158 Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Tue, 5 Dec 2023 19:42:31 +1100 Subject: [PATCH 1/7] Add dots unlink/relink subcommands --- dot-local/bin/dots | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/dot-local/bin/dots b/dot-local/bin/dots index 996e03f..82e3dc1 100755 --- a/dot-local/bin/dots +++ b/dot-local/bin/dots @@ -65,6 +65,10 @@ clone-one() { git clone $url $DOTFILES/$package } +call-gnu-stow() { + $STOW --dotfiles -d $DOTFILES -t ~ --ignore=${^global_ignore} $argv +} + link() { local -a packages packages=($argv) @@ -80,8 +84,42 @@ link() { fi for nofold in $DOTFILES/${^packages}/.stow-no-folding(N); process-stow-no-folding $nofold + call-gnu-stow -S $packages +} - $STOW --dotfiles -d $DOTFILES -t ~ --ignore=${^global_ignore} $packages +unlink() { + local -a packages + packages=($argv) + if (( $#packages == 0 )); then + packages=( $DOTFILES/*(N:t) ) + if (( $#packages == 0 )); then + echo "No installed packages! There's nothing to unlink!" >&2 + return 1 + fi + echo "Unlinking all packages ($packages) from $HOME now..." >&2 + else + echo "Unlinking $packages from $HOME now..." >&2 + fi + + call-gnu-stow -D $packages +} + +relink() { + local -a packages + packages=($argv) + if (( $#packages == 0 )); then + packages=( $DOTFILES/*(N:t) ) + if (( $#packages == 0 )); then + echo "No installed packages! Do you want to clone some first?" >&2 + return 1 + fi + echo "Relinking all packages ($packages) into $HOME now..." >&2 + else + echo "Relinking $packages into $HOME now..." >&2 + fi + + for nofold in $DOTFILES/${^packages}/.stow-no-folding(N); process-stow-no-folding $nofold + call-gnu-stow -R $packages } process-stow-no-folding() { @@ -173,6 +211,8 @@ main() { clone) clone ${argv[2,-1]} ;; fetch) fetch ${argv[2,-1]} ;; link) link ${argv[2,-1]} ;; + unlink) unlink ${argv[2,-1]} ;; + relink) relink ${argv[2,-1]} ;; pull) pull ${argv[2,-1]} ;; st|status) status ${argv[2,-1]} ;; *) echo "Unknown subcommand $comm" >&2; return 2 ;; From f0baf4e02bb3c005e388603b13c97c6128931e6c Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Tue, 5 Dec 2023 19:45:13 +1100 Subject: [PATCH 2/7] Rename Stow subcommands to use stowing terminology --- dot-local/bin/dots | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dot-local/bin/dots b/dot-local/bin/dots index 82e3dc1..2005b7e 100755 --- a/dot-local/bin/dots +++ b/dot-local/bin/dots @@ -35,7 +35,7 @@ bootstrap() { fi clone dots git vim zsh || return $? - link + do-stow } install-custom-gnu-stow() { @@ -69,7 +69,7 @@ call-gnu-stow() { $STOW --dotfiles -d $DOTFILES -t ~ --ignore=${^global_ignore} $argv } -link() { +do-stow() { local -a packages packages=($argv) if (( $#packages == 0 )); then @@ -78,33 +78,33 @@ link() { echo "No installed packages! Do you want to clone some first?" >&2 return 1 fi - echo "Linking all packages ($packages) into $HOME now..." >&2 + echo "Stowing all packages ($packages) into $HOME now..." >&2 else - echo "Linking $packages into $HOME now..." >&2 + echo "Stowing $packages into $HOME now..." >&2 fi for nofold in $DOTFILES/${^packages}/.stow-no-folding(N); process-stow-no-folding $nofold call-gnu-stow -S $packages } -unlink() { +do-unstow() { local -a packages packages=($argv) if (( $#packages == 0 )); then packages=( $DOTFILES/*(N:t) ) if (( $#packages == 0 )); then - echo "No installed packages! There's nothing to unlink!" >&2 + echo "No installed packages! There's nothing to unstow!" >&2 return 1 fi - echo "Unlinking all packages ($packages) from $HOME now..." >&2 + echo "Unstowing all packages ($packages) from $HOME now..." >&2 else - echo "Unlinking $packages from $HOME now..." >&2 + echo "Unstowing $packages from $HOME now..." >&2 fi call-gnu-stow -D $packages } -relink() { +do-restow() { local -a packages packages=($argv) if (( $#packages == 0 )); then @@ -113,9 +113,9 @@ relink() { echo "No installed packages! Do you want to clone some first?" >&2 return 1 fi - echo "Relinking all packages ($packages) into $HOME now..." >&2 + echo "Restowing all packages ($packages) into $HOME now..." >&2 else - echo "Relinking $packages into $HOME now..." >&2 + echo "Restowing $packages into $HOME now..." >&2 fi for nofold in $DOTFILES/${^packages}/.stow-no-folding(N); process-stow-no-folding $nofold @@ -210,9 +210,9 @@ main() { bootstrap) bootstrap ;; clone) clone ${argv[2,-1]} ;; fetch) fetch ${argv[2,-1]} ;; - link) link ${argv[2,-1]} ;; - unlink) unlink ${argv[2,-1]} ;; - relink) relink ${argv[2,-1]} ;; + stow) do-stow ${argv[2,-1]} ;; + unstow) do-unstow ${argv[2,-1]} ;; + restow) do-restow ${argv[2,-1]} ;; pull) pull ${argv[2,-1]} ;; st|status) status ${argv[2,-1]} ;; *) echo "Unknown subcommand $comm" >&2; return 2 ;; From 008e82924eafb9ffb780cd8933192025ba6158f4 Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Tue, 5 Dec 2023 19:47:42 +1100 Subject: [PATCH 3/7] Preface all subcommand implementations with do- for clarity --- dot-local/bin/dots | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dot-local/bin/dots b/dot-local/bin/dots index 2005b7e..2e42f2d 100755 --- a/dot-local/bin/dots +++ b/dot-local/bin/dots @@ -15,7 +15,7 @@ supported_stow_versions=( 2.3.2-fixbug56727 ) -bootstrap() { +do-bootstrap() { echo 'Bootstrapping your dotfiles...' >&2 mkdir -p $DOTFILES touch $DOTFILES/.stow @@ -34,7 +34,7 @@ bootstrap() { install-custom-gnu-stow || return $? fi - clone dots git vim zsh || return $? + do-clone dots git vim zsh || return $? do-stow } @@ -43,7 +43,7 @@ install-custom-gnu-stow() { STOW=$DOTFILES/stow/dot-local/bin/stow } -clone() { +do-clone() { echo "Requested packages: $argv" >&2 for package in $argv; do clone-one $package || return $? @@ -132,7 +132,7 @@ process-stow-no-folding() { done } -fetch() { +do-fetch() { local -a packages packages=($argv) (( $#packages == 0 )) && packages=( $DOTFILES/*(N:t) ) @@ -142,7 +142,7 @@ fetch() { done } -pull() { +do-pull() { local -a packages packages=($argv) (( $#packages == 0 )) && packages=( $DOTFILES/*(N:t) ) @@ -153,7 +153,7 @@ pull() { } -status() { +do-status() { local -a packages packages=($argv) (( $#packages == 0 )) && packages=( $DOTFILES/*(N:t) ) @@ -207,14 +207,14 @@ main() { fi case $comm in - bootstrap) bootstrap ;; - clone) clone ${argv[2,-1]} ;; - fetch) fetch ${argv[2,-1]} ;; + bootstrap) do-bootstrap ;; + clone) do-clone ${argv[2,-1]} ;; + fetch) do-fetch ${argv[2,-1]} ;; stow) do-stow ${argv[2,-1]} ;; unstow) do-unstow ${argv[2,-1]} ;; restow) do-restow ${argv[2,-1]} ;; - pull) pull ${argv[2,-1]} ;; - st|status) status ${argv[2,-1]} ;; + pull) do-pull ${argv[2,-1]} ;; + st|status) do-status ${argv[2,-1]} ;; *) echo "Unknown subcommand $comm" >&2; return 2 ;; esac } From 136eddf8ddb6ee70c4b519db848af9e22be61894 Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Tue, 5 Dec 2023 19:55:50 +1100 Subject: [PATCH 4/7] Update _dots completion with new subcommands --- dot-config/zsh/functions/_dots | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dot-config/zsh/functions/_dots b/dot-config/zsh/functions/_dots index d5869bd..2083cda 100644 --- a/dot-config/zsh/functions/_dots +++ b/dot-config/zsh/functions/_dots @@ -9,7 +9,9 @@ commands=( bootstrap:'set up initial dotfiles on a new system' clone:'download dotfiles packages over Git' fetch:'retrieve updates to your packages' - link:'install downloaded packages into your ~' + stow:'stow downloaded packages into your ~' + unstow:'unstow installed packages (cleans up their symlinks)' + restow:'unstow then stow installed packages (may be useful if package layout changed)' pull:'fetch and apply package updates' status:'check whether your packages have changes' ) @@ -30,6 +32,6 @@ case $state in else _message 'all known packages are already installed, you can still enter a git url manually' fi ;; - fetch|link|pull|st|status) _values -w package $DOTFILES/*(/:t) ;; + fetch|*stow|pull|st|status) _values -w package $DOTFILES/*(/:t) ;; esac ;; esac From 1ef91ce5f25fa08dc47ef440764b9241071c1eb5 Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Tue, 5 Dec 2023 21:26:38 +1100 Subject: [PATCH 5/7] Support --verbose to get feedback from Stow and Git --- dot-local/bin/dots | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/dot-local/bin/dots b/dot-local/bin/dots index 2e42f2d..bb55417 100755 --- a/dot-local/bin/dots +++ b/dot-local/bin/dots @@ -15,6 +15,14 @@ supported_stow_versions=( 2.3.2-fixbug56727 ) +call-git() { + git $argv ${VERBOSE:+-v} +} + +call-gnu-stow() { + $STOW --dotfiles -d $DOTFILES -t ~ --ignore=${^global_ignore} ${VERBOSE:+-vvv} $argv +} + do-bootstrap() { echo 'Bootstrapping your dotfiles...' >&2 mkdir -p $DOTFILES @@ -62,11 +70,7 @@ clone-one() { return 1 fi echo "Retrieving $package from $url now..." >&2 - git clone $url $DOTFILES/$package -} - -call-gnu-stow() { - $STOW --dotfiles -d $DOTFILES -t ~ --ignore=${^global_ignore} $argv + call-git clone $url $DOTFILES/$package } do-stow() { @@ -138,7 +142,7 @@ do-fetch() { (( $#packages == 0 )) && packages=( $DOTFILES/*(N:t) ) for p in $packages; do cd $DOTFILES/$p - git fetch -p || return $? + call-git fetch -p || return $? done } @@ -148,7 +152,7 @@ do-pull() { (( $#packages == 0 )) && packages=( $DOTFILES/*(N:t) ) for p in $packages; do cd $DOTFILES/$p - git pull || return $? + call-git pull || return $? done } @@ -164,7 +168,7 @@ do-status() { printf %${length}s' ' $p # Check if the package is actually a repo. It might not be if it's brand-new. - git_status="$(git status --porcelain --ignore-submodules -unormal 2>/dev/null)" + git_status="$(call-git status --porcelain --ignore-submodules -unormal 2>/dev/null)" if (( $? != 0 )); then printf '%9s' '' # space across to the last column print -P %F{247}not a git repository%f @@ -197,6 +201,12 @@ do-status() { main() { : ${DOTFILES:=~/dotfiles} ${STOW:=stow} ${DOTS_SOURCE_PREFIX:=https://git.00dani.me/dot} + local opt_index=$argv[(I)(-v|--verbose)] + if (( opt_index != 0 )); then + VERBOSE=yes + argv[opt_index]=() + fi + comm=$1 if (( $# == 0 )); then if [[ -d $DOTFILES ]]; then From 40b97e0c152c499eb7bcc4c716e09386819012a4 Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Tue, 5 Dec 2023 21:26:57 +1100 Subject: [PATCH 6/7] Add --verbose to the completion def --- dot-config/zsh/functions/_dots | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/dot-config/zsh/functions/_dots b/dot-config/zsh/functions/_dots index 2083cda..b99c944 100644 --- a/dot-config/zsh/functions/_dots +++ b/dot-config/zsh/functions/_dots @@ -1,8 +1,5 @@ #compdef dots : ${DOTFILES:=~/dotfiles} -local context state state_descr line -typeset -A opt_args - local repo local -a commands repos new_repos commands=( @@ -15,23 +12,31 @@ commands=( pull:'fetch and apply package updates' status:'check whether your packages have changes' ) + if ! _retrieve_cache dots-repositories; then repos=($(curl -s -X GET "https://git.00dani.me/api/v1/orgs/dot/repos" -H "accept: application/json" | jq -r '.[].name')) _store_cache dots-repositories repos fi +for repo in $repos; [[ -d $DOTFILES/$repo ]] || new_repos+=$repo -for repo in $repos; [[ -d $DOTFILES/$repo ]] || new_repos+=($repo) -_arguments '1:cmds:->cmds' '*:: :->args' -case $state in - cmds) _describe -t commands command commands ;; - args) case $line[1] in +_dots_subcommands() { + _describe -t commands command commands +} + +_dots_subcommand_parameters() { + case $words[1] in bootstrap) _nothing ;; # no more arguments! - clone) - if (( $#new_repos )); then + clone) + if (( $#new_repos )); then _values -w package $new_repos else _message 'all known packages are already installed, you can still enter a git url manually' fi ;; fetch|*stow|pull|st|status) _values -w package $DOTFILES/*(/:t) ;; - esac ;; -esac + esac +} + +_arguments \ + '(-v --verbose)'{-v,--verbose}'[request verbose output from Git and Stow]' \ + ': :_dots_subcommands' \ + '*:: :_dots_subcommand_parameters' From c1b1767b120a72eba63714d3e9b083b4bf6f4ec6 Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Tue, 5 Dec 2023 21:28:53 +1100 Subject: [PATCH 7/7] Update README.md to note renamed subcommands --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 122a35a..471a960 100644 --- a/README.md +++ b/README.md @@ -50,10 +50,12 @@ Will clone one or more packages specified into your `DOTFILES` directory. Packag Will simply run `git fetch -p` for each of the specified package names. If there are no package names provided, will implicitly run over *all* packages. -### `link` +### `stow` Will employ GNU Stow to symlink each of the packages specified by name into your `HOME`. If no package names are provided, will implicitly link all packages. +Additionally, `unstow` and `restow` commands are available with the same interface. These three commands correspond to the `-S`, `-D`, and `-R` modes Stow can be run in. + ### `pull` Very similar to `fetch`. Will simply run `git pull` for each of the specified package names. If there are no package names provided, will implicitly run over *all* packages.