dots/.local/bin/dots

101 lines
2.2 KiB
Text
Raw Normal View History

#!/usr/bin/env zsh
zmodload zsh/mapfile
bootstrap() {
echo 'Bootstrapping your dotfiles...' >&2
mkdir -p $DOTFILES
touch $DOTFILES/.stow
if ! hash stow 2>/dev/null; then
echo 'GNU Stow is not installed, fetching it...' >&2
clone-one stow || return $?
STOW=$DOTFILES/stow/.local/bin/stow
fi
clone dots vim zsh || return $?
link
}
clone() {
echo "Requested packages: $argv" >&2
for package in $argv; do
clone-one $package || return $?
done
}
clone-one() {
local url=$1
local package=${${url##*/}%.git}
# Simple package names are fetched from my GitHub repos.
[[ $url != */* ]] && url=$GITHUB_USER/dot-$package
# user/repo packages are fetched from that user's repos.
[[ $url != *:* ]] && url=https://github.com/$url
if [[ -d $DOTFILES/$package ]]; then
echo "Looks like you already have $package cloned." >&2
return 1
fi
echo "Retrieving $package from $url now..." >&2
git clone $url $DOTFILES/$package
}
link() {
local 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 "Linking all packages ($packages) into $HOME now..." >&2
else
echo "Linking $packages into $HOME now..." >&2
fi
for nofold in $DOTFILES/${^packages}/.stow-no-fold(N); process-stow-no-fold $nofold
$STOW -d $DOTFILES -t ~ --ignore '^\.stow-no-fold' $packages
}
process-stow-no-fold() {
for file in ${(f)mapfile[$1]}; do
file=~/$file
[[ -e $file ]] && continue
mkdir -p ${file:h}
touch $file
done
}
status() {
local packages=($argv)
(( $#packages == 0 )) && packages=( $DOTFILES/*(N:t) )
local length=${#${(O@)packages//?/X}[1]}
cd $DOTFILES
for p in $packages; do
pushd $p
printf "%${length}s " $p
if [[ -z "$(command git status --porcelain --ignore-submodules -unormal)" ]]; then
print -P "%F{green}clean%f"
else
print -P "%F{red}unclean%f"
fi
popd
done
}
: ${DOTFILES:=~/dotfiles} ${STOW:=stow} ${GITHUB_USER:=00dani}
local comm=$1
if (( $# == 0 )); then
if [[ -d $DOTFILES ]]; then
comm=status
else
comm=bootstrap
fi
fi
case $comm in
bootstrap) bootstrap ;;
clone) clone ${argv[2,-1]} ;;
link) link ${argv[2,-1]} ;;
st|status) status ${argv[2,-1]} ;;
esac