diff --git a/.dotter/dots-with-systemwide.toml b/.dotter/dots-with-systemwide.toml new file mode 100644 index 0000000..50c86f6 --- /dev/null +++ b/.dotter/dots-with-systemwide.toml @@ -0,0 +1,6 @@ +includes = [".dotter/incl-systemwide.toml"] +packages = ["system", "workstation"] + +[files] + +[variables] diff --git a/.dotter/dots.toml b/.dotter/dots.toml new file mode 100644 index 0000000..f649759 --- /dev/null +++ b/.dotter/dots.toml @@ -0,0 +1,6 @@ +includes = [] +packages = ["workstation"] + +[files] + +[variables] diff --git a/.dotter/global.toml b/.dotter/global.toml new file mode 100644 index 0000000..220b247 --- /dev/null +++ b/.dotter/global.toml @@ -0,0 +1,81 @@ +[helpers] + +[base] +depends = ["shell", "git", "nvim", "scripts", "ssh", "terminal"] + +[linux] +depends = [ + "base", + "disks", + "pass", + "office", + "services", + "social", + "writing", +] + +[system] + +[workstation] +depends = ["linux", "desktop", "multimedia", "qutebrowser"] + +[shell.files] +"sh/README.md" = { target = "~/README.md", type = "symbolic", if = "false" } +sh = "~" + +[desktop.files] +"desktop/.config/flavours/templates" = { target = "~/.config/flavours/templates", type = "symbolic" } +"desktop/.config/waybar/config" = { target = "~/.config/waybar/config", type = "symbolic" } +"desktop/README.md" = { target = "~/README.md", type = "symbolic", if = "false" } +desktop = "~" + +[disks.files] +"disks/README.md" = { target = "~/README.md", type = "symbolic", if = "false" } +disks = "~" + +[git.files] +"git/README.md" = { target = "~/README.md", type = "symbolic", if = "false" } +git = "~" + +[multimedia.files] +"multimedia/README.md" = { target = "~/README.md", type = "symbolic", if = "false" } +"multimedia/.config/mpv/scripts" = { target = "~/.config/mpv/scripts", type = "symbolic" } +"multimedia/.config/ncmpcpp/config" = { target = "~/.config/ncmpcpp/config", type = "symbolic" } +multimedia = "~" + +[nvim.files] +nvim = "~" + +[office.files] +"office/README.md" = { target = "~/README.md", type = "symbolic", if = "false" } +"office/.config/glow/email.json" = { target = "~/.config/glow/email.json", type = "symbolic" } +office = "~" + +[pass.files] +"pass/README.md" = { target = "~/README.md", type = "symbolic", if = "false" } +pass = "~" + +[qutebrowser.files] +qutebrowser = "~" + +[scripts.files] +"scripts/README.md" = { target = "~/README.md", type = "symbolic", if = "false" } +scripts = "~" + +[services.files] +"services/README.md" = { target = "~/README.md", type = "symbolic", if = "false" } +services = "~" + +[social.files] +social = "~" + +[ssh.files] +ssh = "~" + +[terminal.files] +"terminal/.config/vifm" = { target = "~/.config/vifm", type = "symbolic" } +terminal = "~" + +[writing.files] +"writing/README.md" = { target = "~/README.md", type = "symbolic", if = "false" } +writing = "~" diff --git a/.dotter/incl-systemwide.toml b/.dotter/incl-systemwide.toml new file mode 100644 index 0000000..2806e6e --- /dev/null +++ b/.dotter/incl-systemwide.toml @@ -0,0 +1,7 @@ +[system] + +[system.files] +"bootstrap/system-packages" = { target = "/", type = "symbolic", owner = "root" } + +[system.variables] + diff --git a/install.sh b/install.sh index 273981a..fd5f496 100755 --- a/install.sh +++ b/install.sh @@ -9,27 +9,33 @@ # # Finally, symlinks all dotfiles into their correct locations using stow -bootstrap_dir="${BOOTSTRAP_DIRECTORY:-./bootstrap}" +bootstrap_dir="${DOT_BOOTSTRAP_DIR:-./bootstrap}" +unattended_install="${DOT_UNATTENDED_INSTALL:-false}" +link_systemfiles="${DOT_LINK_SYSTEMFILES:-true}" + +help() { + printf "Usage: install [-f|--force][-v|--version][-h|--help]\n\n-f Do not ask for any confirmations but force update and installation.\n" + exit "${1:-0}" +} main() { local cmd="" local ret=0 - - case "$1" in - -v | --version) - printf "Personal system bootstrap script.\n\nby Marty Oehme\n\nv0.2\n" - ;; - -h | --help) - printf "Usage: install [-f|--force][-v|--version][-h|--help]\n\n-f Do not ask for any confirmations but force update and installation.\n" - ;; - -f | --force) - install true - ;; - *) - install false - ;; - esac - shift + case "$1" in + -v | --version) + printf "Personal system bootstrap script.\n\nby Marty Oehme\n\nv0.2\n" + ;; + -h | --help) + help 0 + ;; + -f | --force) + unattended_install=true + ;; + *) + install + ;; + esac + shift $cmd "$@" ret=$((ret + $?)) @@ -39,93 +45,94 @@ main() { # takes default value (y/n), question, abort message as arguments # automatically answers yes if unattended install check_consent() { - if [ "$UNATTENDED" == "true" ]; then - true - else - [[ "$1" == "y" ]] && default_consent="[Y/n]" || default_consent="[y/N]" - printf "%b %b " "$2" "$default_consent" - read -r answer - if [[ "$1" == "n" ]] && [[ "$answer" != y* ]]; then - printf "%s\n" "$3" - false - elif [[ "$1" == "y" ]] && [[ "$answer" == n* ]]; then - printf "%s\n" "$3" - false - else - true - fi - fi + if [ "$unattended_install" == "true" ]; then + true + else + [[ "$1" == "y" ]] && default_consent="[Y/n]" || default_consent="[y/N]" + printf "%b %b " "$2" "$default_consent" + read -r answer + if [[ "$1" == "n" ]] && [[ "$answer" != y* ]]; then + printf "%s\n" "$3" + false + elif [[ "$1" == "y" ]] && [[ "$answer" == n* ]]; then + printf "%s\n" "$3" + false + else + true + fi + fi } entry_question() { - check_consent n "This will take a while and install many packages and link dotfiles all over the place depending on your selections.\nYou need to be in the base directory of the dotfiles repository.\nProceed?" "Aborting." || exit + check_consent n "This will take a while and install many packages and link dotfiles all over the place depending on your selections.\nYou need to be in the base directory of the dotfiles repository.\nProceed?" "Aborting." || exit } enable_git_hooks() { - check_consent y "Should we enable git hooks for this repository, so that installed packages are automatically compared when committing?" "Not changing repository settings." || return - git config --local core.hooksPath .githooks/ - echo "Changed repository settings." + check_consent y "Should we enable git hooks for this repository, so that missing or additionally installed packages are automatically compared to the repository when committing?" "Not changing repository settings." || return + git config --local core.hooksPath .githooks/ + echo "Changed repository settings." } -stow_dotfiles() { - check_consent y "Link home directory dot files?" "Not linking dotfiles." || return - # get all top level directories, remove their slashes and dots - # finally get rid of .dot-directories, since they are for the repo not for my homedir - targets="$(find . -maxdepth 1 -type d | sed -e 's/^\.\/\(.*\)$/\1/' | sed -e '/^\./d')" - - # shellcheck disable=2086 - # -- for some reason stow only works with unqoted var expansion - stow -R ${targets} 2> >(grep -v 'Absolute/relative mismatch between Stow dir' 1>&2) - echo "Linked dotfiles." +manage_dotfiles() { + check_consent y "Link dot files?" "Not linking dotfiles." || return + check_consent n "Link system settings files? This will require sudo access but will not overwrite existing files." "Not touching system files." || link_systemfiles=false + if [ "$link_systemfiles" == "false" ]; then + dotter deploy -l .dotter/dots.toml + echo "Linked dotfiles." + else + if [ -e "/etc/pacman.conf" ]; then + check_consent n "Found an existing pacman.conf file, installation will error if it exists. Remove file?" && run_elevated rm "/etc/pacman.conf" + fi + dotter deploy -l .dotter/dots-with-systemwide.toml + echo "Linked dotfiles and system files." + fi } run_elevated() { - if command -v doas >/dev/null 2>&1; then - doas "$@" - elif command -v sudo >/dev/null 2>&1; then - sudo "$@" - fi + if command -v doas >/dev/null 2>&1; then + doas "$@" + elif command -v sudo >/dev/null 2>&1; then + sudo "$@" + fi } -stow_system_packages() { - check_consent n "Link system settings files? This will require sudo access and may overwrite existing files." "Not touching system files." || return - if [ -e "/etc/pacman.conf" ]; then - check_consent n "Found an existing pacman.conf file, installation will error if it exists. Remove file?" && run_elevated rm "/etc/pacman.conf" - fi - run_elevated stow --dir="$bootstrap_dir" --target="/" -R system-packages/ - echo "Linked system files." -} install_packages() { - check_consent n "Install pre-designated packages? This will take a while, install a lot of packages and require super user privileges." "Not installing packages." || return - if ! "$UNATTENDED"; then - "$bootstrap_dir"/install_packages.sh - else - "$bootstrap_dir"/install_packages.sh -f - fi - echo "Installed packages." + check_consent n "Install pre-designated packages? This will take a while, install a lot of packages and require super user privileges." "Not installing packages." || return + if [ "$unattended_install" == "true" ]; then + "$bootstrap_dir"/install_packages.sh -f + else + "$bootstrap_dir"/install_packages.sh + fi + echo "Installed packages." +} + +headline() { + len="${#1}" + target_len=85 + side_len=$(((target_len - len) / 2)) + for ((i = 1; i <= side_len; i++)); do printf '='; done + printf " %s " "$1" + for ((i = 1; i <= side_len; i++)); do printf '='; done + printf "\n" } install() { - UNATTENDED=$1 - if ! "$UNATTENDED"; then - entry_question - fi + if [ "$unattended_install" == false ] ; then + entry_question + fi - echo "====================== BEGINNING SYSTEM FILE MANAGEMENT =============================" - stow_system_packages + headline "BEGINNING PACKAGE INSTALLATION" + install_packages - echo "====================== BEGINNING PACKAGE INSTALLATION =============================" - install_packages + headline "BEGINNING DOTFILE MANAGEMENT" + manage_dotfiles - echo "=================== BEGINNING DOTFILE MANAGEMENT ==========================" - stow_dotfiles + headline "ENABLING GIT REPOSITORY HOOKS" + enable_git_hooks - echo "================== ENABLING GIT REPOSITORY HOOKS ==========================" - enable_git_hooks - - echo "====================== INSTALLATION FINISHED ==============================" - exit 0 + echo "INSTALLATION FINISHED" + exit 0 } main "$@"