192 lines
5.2 KiB
Bash
Executable File
192 lines
5.2 KiB
Bash
Executable File
#!/usr/bin/env zsh
|
|
DOTWRYN_SETUP__SETUP_DIR="${0:a:h}"
|
|
#####################################################################
|
|
|
|
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)
|
|
|
|
|
|
setup.run._.usage() {
|
|
local run_file="${DOTWRYN_SETUP__SETUP_DIR}/run"
|
|
local line flags description
|
|
|
|
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}"
|
|
|
|
echo
|
|
echo 'options:'
|
|
|
|
while read -r line
|
|
do
|
|
[[ "${line}" =~ '^[[:space:]]*\([[:space:]]*(-[^)]*)\)[^#]*#[[:space:]]*(.*)$' ]] || continue
|
|
|
|
flags="${(j: :)${(z)match[1]}}"
|
|
flags="${flags// | /, }"
|
|
description="${match[2]}"
|
|
|
|
[[ "${description}" =~ '^(<[^>]*>)[[:space:]]+(.*)$' ]] \
|
|
&& flags="${flags} ${match[1]}" \
|
|
&& description="${match[2]}"
|
|
|
|
printf ' %-38s %s\n' "${flags}" "${description}"
|
|
done < "${run_file}"
|
|
|
|
echo
|
|
echo "steps: ${(j:, :)DOTWRYN_SETUP__STEPS}"
|
|
echo
|
|
}
|
|
|
|
#####################################################################
|
|
|
|
() {
|
|
# 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 "
|
|
} "${@}"
|