Files
dotwryn/setup/run
T

192 lines
5.2 KiB
Bash
Raw Normal View History

2026-09-21 06:48:49 -06:00
#!/usr/bin/env zsh
DOTWRYN_SETUP__SETUP_DIR="${0:a:h}"
#####################################################################
2026-09-21 06:48:49 -06:00
DOTWRYN_SETUP__FORCE_ROOT=false
DOTWRYN_SETUP__OVERWRITE_EXISTING=false
DOTWRYN_SETUP__USE_LOGFILE=true
DOTWRYN_SETUP__STRICT=false
DOTWRYN_SETUP__INSTALLATION_PROFILE=default
DOTWRYN_SETUP__EXCLUDE=()
DOTWRYN_SETUP__STEPS=(filesystem packages config)
2026-09-21 06:48:49 -06:00
setup.run._.usage() {
local run_file="${DOTWRYN_SETUP__SETUP_DIR}/run"
local line flags description
2026-09-21 06:48:49 -06:00
local found_function=false
while read -r line
do
case "${found_function}" in
( false ) [[ "${line}" == '() {' ]] && found_function=true ;;
( true )
[[ "${line}" =~ '^[[:space:]]*#[[:space:]]?(.*)$' ]] || break
echo "${match[1]}"
;;
esac
done < "${run_file}"
2026-09-21 06:48:49 -06:00
echo
echo 'options:'
2026-09-21 06:48:49 -06:00
while read -r line
do
[[ "${line}" =~ '^[[:space:]]*\([[:space:]]*(-[^)]*)\)[^#]*#[[:space:]]*(.*)$' ]] || continue
2026-09-21 06:48:49 -06:00
flags="${(j: :)${(z)match[1]}}"
flags="${flags// | /, }"
description="${match[2]}"
2026-09-21 06:48:49 -06:00
[[ "${description}" =~ '^(<[^>]*>)[[:space:]]+(.*)$' ]] \
&& flags="${flags} ${match[1]}" \
&& description="${match[2]}"
2026-09-21 06:48:49 -06:00
printf ' %-38s %s\n' "${flags}" "${description}"
done < "${run_file}"
2024-08-16 09:41:26 -06:00
2026-09-21 06:48:49 -06:00
echo
echo "steps: ${(j:, :)DOTWRYN_SETUP__STEPS}"
echo
2024-08-16 09:41:26 -06:00
}
2026-09-21 06:48:49 -06:00
#####################################################################
() {
# set up this machine from the .wryn dotfiles repository
#
# usage: setup/run [...options...]
local -a skip_steps only_steps
setup.run._.error() { echo "ERROR::${*}" >&2; return 1; }
local _s
while [[ "${#}" -gt 0 ]]
do
_s=1
case "${1}" in
( -h | --help ) # display this message and exit
setup.run._.usage
return 0
;;
( -p | --installation-profile ) _s=2 # <profile> only install dependencies belonging to <profile>
DOTWRYN_SETUP__INSTALLATION_PROFILE="${2}"
;;
( --min ) # shorthand for '--installation-profile min'
DOTWRYN_SETUP__INSTALLATION_PROFILE=min
;;
( --skip ) _s=2 # <step> don't run <step>; repeatable, incompatible with --only
skip_steps+=("${2}")
;;
( --only ) _s=2 # <step> only run <step>; repeatable, incompatible with --skip
only_steps+=("${2}")
;;
( --exclude ) _s=2 # <dependencies> comma-separated dependencies to neither install nor verify; repeatable
DOTWRYN_SETUP__EXCLUDE+=("${(s:,:)2}")
;;
( --overwrite ) # replace existing local configuration
DOTWRYN_SETUP__OVERWRITE_EXISTING=true
;;
( --force-root ) # allow setup to run as root
DOTWRYN_SETUP__FORCE_ROOT=true
;;
( --ci ) # automation mode; never prompts (pair with '--skip packages' to also skip installs)
export CI=true
;;
( --no-logfile ) # don't write a logfile for this run
DOTWRYN_SETUP__USE_LOGFILE=false
;;
( --strict ) # treat unresolved dependencies as a failure instead of prompting
DOTWRYN_SETUP__STRICT=true
;;
( * )
setup.run._.error "unknown option '${1}'; try '--help'"
return 2
;;
esac
shift "${_s}"
done
unset _s
#####################################################################
[[ "${#skip_steps[@]}" -eq 0 ]] || [[ "${#only_steps[@]}" -eq 0 ]] \
|| setup.run._.error "'--skip' and '--only' cannot be used together" \
|| return 2
local named_step
for named_step in "${skip_steps[@]}" "${only_steps[@]}"
do
(( ${DOTWRYN_SETUP__STEPS[(Ie)${named_step}]} )) \
|| setup.run._.error "no such setup step '${named_step}' (steps: ${(j:, :)DOTWRYN_SETUP__STEPS})" \
|| return 2
done
unset named_step
local -a steps
local step
for step in "${DOTWRYN_SETUP__STEPS[@]}"
do
case "${#only_steps[@]}" in
( 0 ) (( ${skip_steps[(Ie)${step}]} )) && continue ;;
( * ) (( ${only_steps[(Ie)${step}]} )) || continue ;;
esac
steps+=("${step}")
done
[[ "${#steps[@]}" -gt 0 ]] \
|| setup.run._.error 'every setup step was excluded; nothing to do' \
|| return 2
unset -f setup.run._.error
#####################################################################
source "${DOTWRYN_SETUP__SETUP_DIR}/prepare-zsh-utilities.zsh" || return 1
local -a installation_profiles
installation_profiles=("${(f)$(setup.packages.list-installation-profiles)}")
(( ${installation_profiles[(Ie)${DOTWRYN_SETUP__INSTALLATION_PROFILE}]} )) \
|| echo.error "no such installation profile '${DOTWRYN_SETUP__INSTALLATION_PROFILE}' (available: ${(j:, :)installation_profiles})" \
|| return 2
#####################################################################
local ERRORS=0
local logfile
case "${DOTWRYN_SETUP__USE_LOGFILE}" in
( true ) logfile="${DOTWRYN_SETUP__STATE_DIR}/setup.$(date +%Y-%m-%dT%H%M%S).log" ;;
( false ) logfile=/dev/null ;;
esac
echo.status "installation start : $(date)" 2>> "${logfile}"
echo.status "setup steps : ${(j:, :)steps}"
for step in "${steps[@]}"
do
setup.${step} > >(tee -a "${logfile}") 2>&1 \
|| echo.error "failed during ${step} setup (see above)" \
|| return ${ERRORS}
done
echo.status "installation complete: $(date)" 2>> "${logfile}"
[[ "${logfile}" == /dev/null ]] \
|| echo.reminder "logfile can be found at:\n\t${logfile}"
#####################################################################
echo.success "\n.wryn setup complete; have a nice day :)\n "
} "${@}"