diff --git a/utils/debian.sh b/utils/debian.sh index ecfe53e..468a10c 100755 --- a/utils/debian.sh +++ b/utils/debian.sh @@ -1,25 +1,53 @@ #!/bin/sh -set -e +set -eu -USERNAME="fernando" -DOTFILES_URL="https://git.schauenburg.me/fernando/dotfiles.git" +# See `parse_args()` for enabling dry run. +dry_run="no" -if [ -t 1 ]; then - sgr0="$(printf '\033[0m')" - red="$(printf '\033[31m')" - yellow="$(printf '\033[33m')" - blue="$(printf '\033[34m')" -else - sgr0='' - red='' - yellow='' - blue='' -fi +is_dry_run() { + test "${dry_run}" = "yes" +} + +setup_colors() { + if [ -t 1 ]; then + sgr0="$(printf '\033[0m')" + bold="$(printf '\033[1m')" + red="$(printf '\033[31m')" + yellow="$(printf '\033[33m')" + blue="$(printf '\033[34m')" + else + sgr0='' + bold='' + red='' + yellow='' + blue='' + fi +} + +setup_commands() { + dry='' + is_dry_run && dry="echo " + + APT="${dry}apt" + APT_FILE="${dry}apt-file" + CD="${dry}cd" + CHSH="${dry}chsh" + LN="${dry}ln" + MKDIR="${dry}mkdir" + RM="${dry}rm" + RMDIR="${dry}rmdir" + SED="${dry}sed" + SU="${dry}su" + UPDATE_GRUB="${dry}update-grub" + USERADD="${dry}useradd" + USERMOD="${dry}usermod" +} usage() { - echo "Usage: $(basename "$0") [-h]" + echo "Usage: $(basename "$0") [-h] [-n]" echo "" - echo " -h print this help and exit" + echo " -h print this help and exit." + echo " -n dry run, don't make changes." } error() { @@ -28,7 +56,7 @@ error() { } title() { - echo "${blue}=> ${1}${sgr0}" + echo "${blue}${bold}=> ${1}${sgr0}" } skipped() { @@ -38,7 +66,8 @@ skipped() { apt_install() { title "Install APT packages" - apt update && apt install -y \ + ${APT} update + ${APT} install -y \ apt-file \ ascii \ build-essential \ @@ -70,14 +99,14 @@ apt_install() { tmux \ unzip \ zsh - apt-file update + ${APT_FILE} update } grub_disable_timeout() { title "Disable GRUB timeout" - sed -i.original -e 's/^GRUB_TIMEOUT=.*/GRUB_TIMEOUT=0/' /etc/default/grub - update-grub + ${SED} -i.original -e 's/^GRUB_TIMEOUT=.*/GRUB_TIMEOUT=0/' /etc/default/grub + ${UPDATE_GRUB} } ensure_usr_bin_fd() { @@ -85,7 +114,7 @@ ensure_usr_bin_fd() { fd_executable='/usr/local/bin/fdfind' if [ -x "${fd_executable}" ]; then - ln -svf "${fd_executable}" /usr/local/bin/fd + ${LN} -svf "${fd_executable}" /usr/local/bin/fd else skipped "${fd_executable} does not exist" fi @@ -93,7 +122,8 @@ ensure_usr_bin_fd() { ensure_usr_local_man_manN() { title "Make sure we have directories for all man page sections" - mkdir -vp $(seq -f '/usr/local/man/man%.0f' 9) + + ${MKDIR} -vp $(seq -f '/usr/local/man/man%.0f' 9) } user_setup() { @@ -117,71 +147,91 @@ user_exists() { user_new() { empty_skel="$(mktemp -d)" - useradd \ + ${USERADD} \ -m ` # Create home directory.` \ -k "$empty_skel" ` # Copy files from this directory into the new home.` \ -U ` # Create a groups with the same name as the user.` \ -G staff ` # Other groups the new user will be a member of.` \ -s /bin/zsh ` # The new user's login shell. ` \ "$1" ` # The new user's name.` \ - >/dev/null 2>&1 ` # Silently.` \ + 2>&1 ` # Silently.` \ - rmdir "$empty_skel" + ${RMDIR} "$empty_skel" } # Add user $1 to the `staff` group... # ...and change shell to `zsh` and get rid of bash files. user_update() { - usermod -aG staff "$1" - chsh -s /bin/zsh "$1" - rm -vf "$(printf "/home/$1/%s " .bash_history .bash_logout .bashrc .profile)" + ${USERMOD} -aG staff "$1" + ${CHSH} -s /bin/zsh "$1" + ${RM} -vf "$(printf "/home/$1/%s " .bash_history .bash_logout .bashrc .profile)" } # Allow `sudo` without password for user $1. user_allow_sudo_nopasswd() { - echo "$1 ALL=(ALL:ALL) NOPASSWD:ALL" >"/etc/sudoers.d/${1}_nopasswd" + contents="$1 ALL=(ALL:ALL) NOPASSWD:ALL" + sudoers_file="/etc/sudoers.d/${1}_nopasswd" + if is_dry_run; then + echo "echo \"$contents\" >$sudoers_file" + else + echo "$contents" >"$sudoers_file" + fi } +# Deploy dotfiles for user $1 from URL $2. deploy_dotfiles() { title "Deploy dotfiles" - dotfiles_dir="/home/$USERNAME/.dotfiles" + dotfiles_dir="/home/$1/.dotfiles" if [ -d "${dotfiles_dir}" ]; then skipped "${dotfiles_dir} exists" else - su "$USERNAME" -c "git clone $DOTFILES_URL ${dotfiles_dir}" + ${SU} "$1" -c "git clone $2 ${dotfiles_dir}" ( - cd "${dotfiles_dir}" - su "$USERNAME" -c "./install.sh -y" + ${CD} "${dotfiles_dir}" + ${SU} "$1" -c "./install.sh -y" ) fi } -execute() { - apt_install - grub_disable_timeout - ensure_usr_bin_fd - ensure_usr_local_man_manN - user_setup "$USERNAME" - deploy_dotfiles -} - -main() { +parse_args() { while getopts 'hn' opt; do case "$opt" in h) # help usage exit 0 ;; + n) # dry run + dry_run="yes" + ;; *) # invalid argument usage exit 1 ;; esac done +} +require_root() { [ "$(id -u)" -eq 0 ] || error "This script must be run as root!" - execute +} + +user="fernando" +dotfiles_url="https://git.schauenburg.me/fernando/dotfiles.git" + +main() { + setup_colors + parse_args "$@" + setup_commands + + require_root + + apt_install + grub_disable_timeout + ensure_usr_bin_fd + ensure_usr_local_man_manN + user_setup "$user" + deploy_dotfiles "$user" "$dotfiles_url" } main "$@"