Skip to content

Instantly share code, notes, and snippets.

@kaushalmodi kaushalmodi/stow_it.sh
Last active May 29, 2018

Embed
What would you like to do?
#!/usr/bin/env bash
# Time-stamp: <2018-05-11 15:59:07 kmodi>
# Script to stow packages from ${STOW_PKGS_ROOT} to ~/stowed
# Usage: stow_it.sh (That's it; from any directory)
# This script uses the unofficial strict mode as explained in
# http://redsymbol.net/articles/unofficial-bash-strict-mode
# Also checks have been done with www.shellcheck.net to have a level of
# confidence that this script will be free of loopholes.. or is it? :)
set -euo pipefail # http://redsymbol.net/articles/unofficial-bash-strict-mode
IFS=$'\n\t'
pkgs=("stow | master"
"ripgrep | master"
"boxes | master"
"progress | master"
"tokei | master"
"tmux | master"
"python | 3.6.2"
"node | 8.11.1"
"make | 4.2"
"nim | devel"
"asciidoc | 8.6.9" # Required to build git man page
"docbook2X | 0.8.8" # Required to build git Info manual
"git | master"
"shellcheck | master"
"eless | master"
"perl5 | master"
"nnn | master"
"pandoc | 2.0.1.1"
"ctags | master"
"global | 6.5.7"
"ack | master"
"libgit2 | master" # Required for stagit
"stagit | master"
"renameutils | 0.12.0"
"moreutils | 0.61"
# "gettext | 0.19.8.1" # Required for coreutils only when building it from git
# "texinfo | 6.4" # Required for coreutils only when building it from git.
"gmp | 6.1.2" # Required for coreutils
"coreutils | v8.28"
"gdb | 8.0.1"
"ag | master"
"hugo | master"
"exa | master"
"ncurses | 6.0" # For tmux, ncurses built with --enable-widec for htop, built with -fPIC for guile
"htop | master"
"libtool | 2.4.6" # For libltdl, required for guile
"libunistring | 0.9.7" # Required for guile
"gc | 7.2g" # For bdw-gc, required for guile
"guile | master"
"ncdu | 1.13"
"bfs | master"
"minify | master"
"scattered | master"
"peco | master"
"tidy_html5 | next"
"inim | master"
"xapian_core | 1.4.5"
)
dotfiles=("tcsh"
"git"
"tmuxp"
"noti"
"misc"
"ripgrep"
"modules"
"isso"
)
pub_dotfiles=("Xdefaults"
"ack"
"ctags"
"emacs"
"gem"
"global"
"keysnail"
"percol"
"tmux"
"python_stuff"
)
pub_config_dotfiles=("ranger"
"peco"
"fontconfig"
)
if [[ -z ${STOW_PKGS_ROOT+x} ]]
then
export STOW_PKGS_ROOT="${HOME}/stow/pkgs"
fi
if [[ -z ${STOW_DOTFILES_ROOT+x} ]]
then
export STOW_DOTFILES_ROOT="${HOME}/stow/dotfiles"
fi
if [[ -z ${STOW_PUB_DOTFILES_ROOT+x} ]]
then
export STOW_PUB_DOTFILES_ROOT="${HOME}/stow/pub_dotfiles"
fi
# STOW_PKGS_TARGET is where stow will create all the symlinks
if [[ -z ${STOW_PKGS_TARGET+x} ]]
then
export STOW_PKGS_TARGET="${HOME}/stowed"
fi
verbose_switch='--verbose=0' # levels are from 0 to 5
# Do not manage info/dir files as that causes stow conflicts
# https://unix.stackexchange.com/a/73433/57923
# Later re-build the dir file.
# Do not stow files that have ".nostow." in their names, like "README.nostow.org".
ignore_switch="--ignore='info\\/dir$' --ignore='\\.nostow\\..+' --ignore='\\.bkp'"
# The stow binary is installed in ${STOW_PKGS_ROOT}/stow/master/bin
PATH=${STOW_PKGS_ROOT}/stow/master/bin:$PATH
here=$(pwd)
# Generate a directory structure for the target directory
cd "${STOW_PKGS_ROOT}"/.. || exit # https://github.com/koalaman/shellcheck/wiki/SC2164
rm -rf dir_struct
mkdir -p dir_struct/{bin,etc,include,lib/{pkgconfig,perl5},lib64,libexec,share/{aclocal,doc,info,locale/{af,be,bg,ca,ca.us-ascii,cs,da,de,de.us-ascii,de_AT,el,en@boldquot,en@quot,eo,es,et,eu,fi,fr,ga,gl,he,hr,hu,id,is,it,ja,ko,ms,nb,nl,nn,no.us-ascii,pa,pl,pt,pt.us-ascii,pt_BR,pt_BR.us-ascii,pt_PT,ro,ru,rw,sk,sl,sr,sv,tr,uk,vi,zh_CN,zh_HK,zh_TW}/LC_MESSAGES,man/man{1..8}}}
touch dir_struct/{bin,etc,include,lib/{pkgconfig,perl5},lib64,libexec,share/{aclocal,doc,info,locale/{af,be,bg,ca,ca.us-ascii,cs,da,de,de.us-ascii,de_AT,el,en@boldquot,en@quot,eo,es,et,eu,fi,fr,ga,gl,he,hr,hu,id,is,it,ja,ko,ms,nb,nl,nn,no.us-ascii,pa,pl,pt,pt.us-ascii,pt_BR,pt_BR.us-ascii,pt_PT,ro,ru,rw,sk,sl,sr,sv,tr,uk,vi,zh_CN,zh_HK,zh_TW}/LC_MESSAGES,man/man{1..8}}}/.gitkeep
mkdir -p "${STOW_PKGS_TARGET}"
stow --target="${STOW_PKGS_TARGET}" --no-folding dir_struct
# Without the above, you will get this error after running the first stow command
# below.
# WARNING! stowing master would cause conflicts:
# * existing target is not owned by stow: bin
# All operations aborted.
# Final structure of the stow/ dir:
# stow
# ├── dir_struct
# ├── dotfiles <-- This is ${STOW_DOTFILES_ROOT}
# ├── pub_dotfiles <-- This is ${STOW_PUB_DOTFILES_ROOT}
# └── pkgs <-- This is ${STOW_PKGS_ROOT}
echo "STOW_PKGS_ROOT = ${STOW_PKGS_ROOT}"
echo "STOW_PKGS_TARGET = ${STOW_PKGS_TARGET}"
echo "STOW_DOTFILES_ROOT = ${STOW_DOTFILES_ROOT}"
echo "STOW_PUB_DOTFILES_ROOT = ${STOW_PUB_DOTFILES_ROOT}"
echo ""
echo "Stowing .."
for pkg in "${pkgs[@]}"
do
pkg_name=$(echo "${pkg}" | grep -Po '^[^ ]+(?=\s*\|\s*.+)')
pkg_ver=$(echo "${pkg}" | grep -Po '^.+\|\s*\K[^ ]+')
# https://unix.stackexchange.com/a/59250/57923
printf " %-15s version %s\\n" "${pkg_name}" "${pkg_ver}"
eval "stow --target=${STOW_PKGS_TARGET} \
${verbose_switch} ${ignore_switch} \
--dir=${STOW_PKGS_ROOT}/${pkg_name} \
--restow ${pkg_ver}"
done
echo ""
stowed_info_dir="${STOW_PKGS_TARGET}/share/info"
echo "Updating the ${stowed_info_dir}/dir file with .."
cd "${stowed_info_dir}"
for infofile in *.info
do
echo " ${stowed_info_dir}/${infofile}"
install-info "${infofile}" "${stowed_info_dir}/dir"
done
echo ""
echo "Stowing 'work' dotfiles from ${STOW_DOTFILES_ROOT} .."
cd "${STOW_DOTFILES_ROOT}" || exit
IFS=$' ' # Join array elements with spaces
echo " ${dotfiles[*]}"
eval "stow --dotfiles ${ignore_switch} --target=${HOME} ${dotfiles[*]}"
echo ""
echo "Stowing 'public' dotfiles from ${STOW_PUB_DOTFILES_ROOT} .."
cd "${STOW_PUB_DOTFILES_ROOT}" || exit
IFS=$' ' # Join array elements with spaces
echo " to $HOME: ${pub_dotfiles[*]} .."
eval "stow --dotfiles ${ignore_switch} --target=${HOME} ${pub_dotfiles[*]}"
echo " to $HOME/.config: ${pub_config_dotfiles[*]} .."
eval "stow --dotfiles ${ignore_switch} --target=${HOME}/.config ${pub_config_dotfiles[*]}"
echo ""
cd "${here}" || exit
echo "Stowed!"
# http://git.savannah.gnu.org/cgit/stow.git/plain/NEWS
# When using --dotfiles option, if a stow package contains a "dot-foo" file or
# dir, then ".foo" link is created in the target. (Note that a hyphen (-) is
# needed after "dot"; underscore (_) will not work.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.