Convert indention from spaces to tabs

This commit is contained in:
T. R. Bernstein
2024-06-28 17:17:47 +02:00
committed by T. R. Bernstein
parent 4096da8d4d
commit 545d95bd9c
12 changed files with 912 additions and 913 deletions

View File

@@ -2,158 +2,158 @@
# vi: set ft=zsh tw=80 ts=2
function versionGT() {
[[ "${1%.*}" -gt "${2%.*}" ]] || [[ "${1%.*}" -eq "${2%.*}" && "${1#*.}" -gt "${2#*.}" ]]
[[ "${1%.*}" -gt "${2%.*}" ]] || [[ "${1%.*}" -eq "${2%.*}" && "${1#*.}" -gt "${2#*.}" ]]
}
function majorMinor() {
echo "${1%%.*}.$(x="${1#*.}" echo "${x%%.*}")"
echo "${1%%.*}.$(x="${1#*.}" echo "${x%%.*}")"
}
function shouldInstallCommandLineTools() {
local macosVersion=$(majorMinor $(/usr/bin/sw_vers -productVersion))
if version_gt "${macosVersion}" "10.13"
then
! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]]
else
! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]] ||
! [[ -e "/usr/include/iconv.h" ]]
fi
local macosVersion=$(majorMinor $(/usr/bin/sw_vers -productVersion))
if version_gt "${macosVersion}" "10.13"
then
! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]]
else
! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]] ||
! [[ -e "/usr/include/iconv.h" ]]
fi
}
function removeNewlines() {
printf "%s" "${1/"$'\n'"/}"
printf "%s" "${1/"$'\n'"/}"
}
function acceptXcodeLicense() {
xcodebuild -license accept
xcodebuild -license accept
}
function installCommandLineTools() {
shouldInstallCommandLineTools || return
cltPlaceholder="/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress"
touch ${cltPlaceholder}
shouldInstallCommandLineTools || return
cltPlaceholder="/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress"
touch ${cltPlaceholder}
cltLabelCommand="/usr/sbin/softwareupdate -l |
grep -B 1 -E 'Command Line Tools' |
awk -F'*' '/^ *\\*/ {print \$2}' |
sed -e 's/^ *Label: //' -e 's/^ *//' |
sort -V |
tail -n1"
cltLabel="$(removeNewlines "$(/bin/bash -c "${cltLabelCommand}")")"
cltLabelCommand="/usr/sbin/softwareupdate -l |
grep -B 1 -E 'Command Line Tools' |
awk -F'*' '/^ *\\*/ {print \$2}' |
sed -e 's/^ *Label: //' -e 's/^ *//' |
sort -V |
tail -n1"
cltLabel="$(removeNewlines "$(/bin/bash -c "${cltLabelCommand}")")"
if [[ -n "${cltLabel}" ]]
then
/usr/sbin/softwareupdate -i ${cltLabel}
/usr/bin/xcode-select --switch /Library/Developer/CommandLineTools
fi
rm -f ${cltPlaceholder}
if [[ -n "${cltLabel}" ]]
then
/usr/sbin/softwareupdate -i ${cltLabel}
/usr/bin/xcode-select --switch /Library/Developer/CommandLineTools
fi
rm -f ${cltPlaceholder}
}
function ensureCommandLineTools() {
installCommandLineTools
acceptXcodeLicense
installCommandLineTools
acceptXcodeLicense
}
function ensureDocopts() {
which docopts > /dev/null && return
local fileURL="${DOCOPTS_URL:-https://github.com/astzweig/docopts/releases/download/v.0.7.0/docopts_darwin_amd64}"
curl --output ./docopts -fsSL "${fileURL}" || return
chmod u+x ./docopts
PATH="${PATH}:`pwd`"
which docopts > /dev/null && return
local fileURL="${DOCOPTS_URL:-https://github.com/astzweig/docopts/releases/download/v.0.7.0/docopts_darwin_amd64}"
curl --output ./docopts -fsSL "${fileURL}" || return
chmod u+x ./docopts
PATH="${PATH}:`pwd`"
}
function cloneMacOSSystemRepo() {
local repoUrl="${MACOS_SYSTEM_REPO_URL:-https://github.com/astzweig/macos-system.git}"
git clone --depth 1 -q "${repoUrl}" . 2> /dev/null || return 10
[ -n "${MACOS_SYSTEM_REPO_BRANCH}" ] && git checkout -q ${MACOS_SYSTEM_REPO_BRANCH} 2> /dev/null || true
local repoUrl="${MACOS_SYSTEM_REPO_URL:-https://github.com/astzweig/macos-system.git}"
git clone --depth 1 -q "${repoUrl}" . 2> /dev/null || return 10
[ -n "${MACOS_SYSTEM_REPO_BRANCH}" ] && git checkout -q ${MACOS_SYSTEM_REPO_BRANCH} 2> /dev/null || true
}
function cloneZSHLibRepo() {
local zshlibRepoUrl="${ZSHLIB_REPO_URL:-https://github.com/astzweig/zshlib.git}"
git config --file=.gitmodules submodule.zshlib.url "${zshlibRepoUrl}"
git submodule -q sync
[ -n "${ZSHLIB_REPO_BRANCH}" ] && git submodule set-branch -b ${ZSHLIB_REPO_BRANCH} `git config --file=.gitmodules submodule.zshlib.path` 2> /dev/null || true
git submodule -q update --depth 1 --init --recursive --remote 2> /dev/null || return 10
local zshlibRepoUrl="${ZSHLIB_REPO_URL:-https://github.com/astzweig/zshlib.git}"
git config --file=.gitmodules submodule.zshlib.url "${zshlibRepoUrl}"
git submodule -q sync
[ -n "${ZSHLIB_REPO_BRANCH}" ] && git submodule set-branch -b ${ZSHLIB_REPO_BRANCH} `git config --file=.gitmodules submodule.zshlib.path` 2> /dev/null || true
git submodule -q update --depth 1 --init --recursive --remote 2> /dev/null || return 10
}
function isDebug() {
test "${DEBUG}" = true -o "${DEBUG}" = 1
test "${DEBUG}" = true -o "${DEBUG}" = 1
}
function printSuccess() {
print "${colors[green]}${*}${colors[reset]}"
print "${colors[green]}${*}${colors[reset]}"
}
function printError() {
print "${errColors[red]}${*}${errColors[reset]}" >&2
print "${errColors[red]}${*}${errColors[reset]}" >&2
}
function printFailedWithError() {
print "${colors[red]}failed.${colors[reset]}"
print "$*" >&2
print "${colors[red]}failed.${colors[reset]}"
print "$*" >&2
}
function defineColors() {
local -A colorCodes=(red "`tput setaf 9`" green "`tput setaf 10`" reset "`tput sgr0`")
[ -t 1 ] && colors=("${(kv)colorCodes[@]}")
[ -t 2 ] && errColors=("${(kv)colorCodes[@]}")
local -A colorCodes=(red "`tput setaf 9`" green "`tput setaf 10`" reset "`tput sgr0`")
[ -t 1 ] && colors=("${(kv)colorCodes[@]}")
[ -t 2 ] && errColors=("${(kv)colorCodes[@]}")
}
function ensureRepo() {
local repoName="$1" cmdName="${2}"
print -n "Installing ${1}..."
$cmdName || { printFailedWithError "This script requires $repoName but was not able to clone it. Please ensure access to the $repoName repository."; return 10}
printSuccess 'done'
local repoName="$1" cmdName="${2}"
print -n "Installing ${1}..."
$cmdName || { printFailedWithError "This script requires $repoName but was not able to clone it. Please ensure access to the $repoName repository."; return 10}
printSuccess 'done'
}
function ensureBinary() {
local binaryName="$1" cmdName="${2}"
print -n "Ensure ${1} is installed..."
$cmdName || { printFailedWithError "This script requires $binaryName but was neither able to locate and install it. Please install $binaryName and add it to one of the PATH directories."; return 10}
printSuccess 'done'
local binaryName="$1" cmdName="${2}"
print -n "Ensure ${1} is installed..."
$cmdName || { printFailedWithError "This script requires $binaryName but was neither able to locate and install it. Please install $binaryName and add it to one of the PATH directories."; return 10}
printSuccess 'done'
}
function configureTerminal() {
if [ -t 0 ]; then
traps+=("stty $(stty -g)")
stty -echo
fi
if [ -t 0 ]; then
traps+=("stty $(stty -g)")
stty -echo
fi
if [ -t 1 ]; then
traps+=('tput cnorm')
tput civis
export TERMINAL_CURSOR_HIDDEN=true
fi
if [ -t 1 ]; then
traps+=('tput cnorm')
tput civis
export TERMINAL_CURSOR_HIDDEN=true
fi
}
function main() {
local traps=()
local -A colors=() errColors=()
defineColors
local traps=()
local -A colors=() errColors=()
defineColors
configureTerminal
local tmpdir="`mktemp -d -t 'macos-system'`"
isDebug || traps+=("rm -fr -- '${tmpdir}'")
trap ${(j.;.)traps} INT TERM EXIT
pushd -q "${tmpdir}"
print -l "Working directory is: ${tmpdir}"
configureTerminal
local tmpdir="`mktemp -d -t 'macos-system'`"
isDebug || traps+=("rm -fr -- '${tmpdir}'")
trap ${(j.;.)traps} INT TERM EXIT
pushd -q "${tmpdir}"
print -l "Working directory is: ${tmpdir}"
print 'Ensure command line tools are available.'
ensureCommandLineTools
ensureRepo 'macos-system' cloneMacOSSystemRepo || return
ensureRepo 'zshlib' cloneZSHLibRepo || return
ensureBinary 'docopts' ensureDocopts || return
print 'Ensure command line tools are available.'
ensureCommandLineTools
ensureRepo 'macos-system' cloneMacOSSystemRepo || return
ensureRepo 'zshlib' cloneZSHLibRepo || return
ensureBinary 'docopts' ensureDocopts || return
print 'Will now run the installer.'
local -A colors=() errColors=()
[ -t 1 ] && tput cnorm
isDebug && export MACOS_SYSTEM_DEBUG=true
"${tmpdir}/install.sh" "$@"
[ -t 1 ] && tput civis
popd -q
print 'Will now run the installer.'
local -A colors=() errColors=()
[ -t 1 ] && tput cnorm
isDebug && export MACOS_SYSTEM_DEBUG=true
"${tmpdir}/install.sh" "$@"
[ -t 1 ] && tput civis
popd -q
}
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel || "${ZSH_EVAL_CONTEXT}" == cmdarg ]]; then
_DIR="${0:A:h}"
main "$@"
_DIR="${0:A:h}"
main "$@"
fi

View File

@@ -2,106 +2,105 @@
# vi: set ft=zsh tw=80 ts=2
runModule() {
"$@"
"$@"
}
function askNecessaryQuestions() {
local mod= configArgs=()
config setappname "de.astzweig.macos.system-setup"
if [ -n "${config_only}" ]; then
lop -- -d "Config only option given with value:" -d "${config_only}"
config setconfigfile "${config_only}"
elif [ -n "${config}" ]; then
config setconfigfile "${config}"
configArgs=(-x)
fi
askUserModuleQuestions ${configArgs} -c config -v moduleAnswers ${modulesToInstall}
local mod= configArgs=()
config setappname "de.astzweig.macos.system-setup"
if [ -n "${config_only}" ]; then
lop -- -d "Config only option given with value:" -d "${config_only}"
config setconfigfile "${config_only}"
elif [ -n "${config}" ]; then
config setconfigfile "${config}"
configArgs=(-x)
fi
askUserModuleQuestions ${configArgs} -c config -v moduleAnswers ${modulesToInstall}
}
function printModulesToInstall() {
lop -- -d 'Modules that will install are:' -d "${modulesToInstall}"
for mod in "${modulesToInstall[@]}"; do
print "${mod}"
done | abbreviatePaths
exit 0
lop -- -d 'Modules that will install are:' -d "${modulesToInstall}"
for mod in "${modulesToInstall[@]}"; do
print "${mod}"
done | abbreviatePaths
exit 0
}
function generateModuleOptions() {
local value answerKey optionKey argName
for answerKey in ${(k)moduleAnswers}; do
[[ ${answerKey} = ${mod}_* ]] || continue
optionKey="${answerKey#${mod}_}"
argName=${optionKey//_/-};
value="${moduleAnswers[${answerKey}]}"
if [[ "${optionKey}" =~ ^[[:alpha:]]$ ]]; then
moduleOptions+=("-${argName}" "${value}")
elif [[ "${optionKey}" =~ ^[[:alpha:]][-[:alpha:]]+$ ]]; then
moduleOptions+=("--${argName}" "${value}")
else
moduleOptions+=("${argName}" "${value}")
fi
done
local value answerKey optionKey argName
for answerKey in ${(k)moduleAnswers}; do
[[ ${answerKey} = ${mod}_* ]] || continue
optionKey="${answerKey#${mod}_}"
argName=${optionKey//_/-};
value="${moduleAnswers[${answerKey}]}"
if [[ "${optionKey}" =~ ^[[:alpha:]]$ ]]; then
moduleOptions+=("-${argName}" "${value}")
elif [[ "${optionKey}" =~ ^[[:alpha:]][-[:alpha:]]+$ ]]; then
moduleOptions+=("--${argName}" "${value}")
else
moduleOptions+=("${argName}" "${value}")
fi
done
}
function filterPasswordOptions() {
local opt= hide=false
for opt in ${moduleOptions}; do
[[ ${hide} = true ]] && { opt='******'; hide=false }
[[ $opt =~ ^--?.*password ]] && hide=true
filteredOptions+=($opt)
done
local opt= hide=false
for opt in ${moduleOptions}; do
[[ ${hide} = true ]] && { opt='******'; hide=false }
[[ $opt =~ ^--?.*password ]] && hide=true
filteredOptions+=($opt)
done
}
function installModules() {
local mod moduleOptions filteredOptions
for mod in ${modulesToInstall}; do
moduleOptions=()
filteredOptions=()
generateModuleOptions
filterPasswordOptions
[[ "${verbose}" == true ]] && moduleOptions+=(-v)
[[ -n ${logfile} ]] && moduleOptions+=(-d ${logfile})
[[ -n ${noninteractive} ]] && moduleOptions+=(--noninteractive)
lop -- -d "Running ${mod}" -d "with ${#moduleOptions} args:" -d "${filteredOptions}"
runModule ${mod} ${moduleOptions}
done
local mod moduleOptions filteredOptions
for mod in ${modulesToInstall}; do
moduleOptions=()
filteredOptions=()
generateModuleOptions
filterPasswordOptions
[[ "${verbose}" == true ]] && moduleOptions+=(-v)
[[ -n ${logfile} ]] && moduleOptions+=(-d ${logfile})
lop -- -d "Running ${mod}" -d "with ${#moduleOptions} args:" -d "${filteredOptions}"
runModule ${mod} ${moduleOptions}
done
}
function isMacOS() {
autoload is-at-least
[ "`uname -s`" = Darwin ] || return
is-at-least "10.13" "`sw_vers -productVersion 2> /dev/null`"
autoload is-at-least
[ "`uname -s`" = Darwin ] || return
is-at-least "10.13" "`sw_vers -productVersion 2> /dev/null`"
}
function isPlistBuddyInstalled() {
test -x /usr/libexec/PlistBuddy && return
which PlistBuddy >&! /dev/null && return
test -x /usr/libexec/PlistBuddy && return
which PlistBuddy >&! /dev/null && return
}
function checkPrerequisites() {
isMacOS || { lop -- -e 'This setup is only for macOS 10.13 and up.'; return 10 }
isPlistBuddyInstalled || { lop -- -e 'This setup requires PlistBuddy to be either at /usr/libexec or in any of the PATH directories.'; return 11 }
isMacOS || { lop -- -e 'This setup is only for macOS 10.13 and up.'; return 10 }
isPlistBuddyInstalled || { lop -- -e 'This setup requires PlistBuddy to be either at /usr/libexec or in any of the PATH directories.'; return 11 }
}
function configureTerminal() {
if [ -t 0 ]; then
traps+=("stty $(stty -g)")
stty -echo
fi
if [ -t 1 ]; then
traps+=('tput cnorm')
tput civis
export TERMINAL_CURSOR_HIDDEN=true
fi
if [ -t 0 ]; then
traps+=("stty $(stty -g)")
stty -echo
fi
if [ -t 1 ]; then
traps+=('tput cnorm')
tput civis
export TERMINAL_CURSOR_HIDDEN=true
fi
}
function main() {
local traps=()
configureTerminal
trap ${(j.;.)traps} INT TERM EXIT
autoloadZShLib || return
checkPrerequisites || return
eval "`docopts -f -V - -h - : "$@" <<- USAGE
local traps=()
configureTerminal
trap ${(j.;.)traps} INT TERM EXIT
autoloadZShLib || return
checkPrerequisites || return
eval "`docopts -f -V - -h - : "$@" <<- USAGE
Usage: $0 [options] [-m PATH]... [<module>...]
Install all modules in module search path. If any <module> arg is given,
@@ -127,28 +126,28 @@ function main() {
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
USAGE`"
local allModules=() modulesToInstall=()
local -A moduleAnswers
configureLogging
lop -- -d "Current working dir is: `pwd`"
lop -- -d "Called main with $# args: $*"
local allModules=() modulesToInstall=()
local -A moduleAnswers
configureLogging
lop -- -d "Current working dir is: `pwd`"
lop -- -d "Called main with $# args: $*"
[[ -n ${noninteractive} && -z ${config} ]] && { lop -- -e 'A config file must be provided in noninteractive mode.'; return 10 }
[[ -n ${noninteractive} && -z ${config} ]] && { lop -- -e 'A config file must be provided in noninteractive mode.'; return 10 }
modpath+=("${_DIR}/modules")
loadModules -v modulesToInstall ${$(echo -m):^^modpath} "${module[@]}"
[ "${list}" = true ] && printModulesToInstall
modpath+=("${_DIR}/modules")
loadModules -v modulesToInstall ${$(echo -m):^^modpath} "${module[@]}"
[ "${list}" = true ] && printModulesToInstall
askNecessaryQuestions
[ -z "${config_only}" ] || return 0
requireRootPrivileges
installModules
askNecessaryQuestions
[ -z "${config_only}" ] || return 0
requireRootPrivileges
installModules
}
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
_DIR="${0:A:h}"
export ASTZWEIG_MACOS_SYSTEM_LIB=${_DIR}/modules/lib.sh
export ASTZWEIG_ZSHLIB=${_DIR}/zshlib
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
main "$@"
_DIR="${0:A:h}"
export ASTZWEIG_MACOS_SYSTEM_LIB=${_DIR}/modules/lib.sh
export ASTZWEIG_ZSHLIB=${_DIR}/zshlib
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
main "$@"
fi

View File

@@ -2,32 +2,32 @@
# vi: set ft=zsh tw=80 ts=2
function getQuestionsPrerequisites() {
cmds=(
[systemsetup]=''
)
requireRootPrivileges
cmds=(
[systemsetup]=''
)
requireRootPrivileges
}
function getExecPrerequisites() {
cmds=(
[osascript]=''
[scutil]=''
[systemsetup]=''
[nvram]=''
[pmset]=''
[defaults]=''
[/usr/libexec/ApplicationFirewall/socketfilterfw]=''
[launchctl]=''
)
cmds=(
[osascript]=''
[scutil]=''
[systemsetup]=''
[nvram]=''
[pmset]=''
[defaults]=''
[/usr/libexec/ApplicationFirewall/socketfilterfw]=''
[launchctl]=''
)
}
function getQuestions() {
local timezones
timezones="`systemsetup -listtimezones | tail -n +2 | awk '{print $1}' | paste -sd, -`"
questions=(
'i: hostname=What shall the hostname of this host be?'
's: timezone=What shall the timezone of this host be? # choose from:'"${timezones};"
)
local timezones
timezones="`systemsetup -listtimezones | tail -n +2 | awk '{print $1}' | paste -sd, -`"
questions=(
'i: hostname=What shall the hostname of this host be?'
's: timezone=What shall the timezone of this host be? # choose from:'"${timezones};"
)
}
function quitSystemPreferences() {
@@ -35,93 +35,93 @@ function quitSystemPreferences() {
}
function setComputerName() {
scutil --set ComputerName "${hostname}"
scutil --set HostName "${hostname}"
scutil --set LocalHostName "${hostname}"
systemsetup -setcomputername "${hostname}"
systemsetup -setlocalsubnetname "${hostname}"
scutil --set ComputerName "${hostname}"
scutil --set HostName "${hostname}"
scutil --set LocalHostName "${hostname}"
systemsetup -setcomputername "${hostname}"
systemsetup -setlocalsubnetname "${hostname}"
}
function configureComputerHostname() {
local currentComputerName="`scutil --get ComputerName`"
if [[ "${currentComputerName}" != "${hostname}" ]]; then
lop -- -i 'Hostname of computer has not been set.' -i "Will set to ${hostname}."
indicateActivity -- 'Set computer name' setComputerName
else
lop -- -i 'Hostname of computer seems to have already been set. Skipping.' -i "Hostname: $currentComputerName"
fi
local currentComputerName="`scutil --get ComputerName`"
if [[ "${currentComputerName}" != "${hostname}" ]]; then
lop -- -i 'Hostname of computer has not been set.' -i "Will set to ${hostname}."
indicateActivity -- 'Set computer name' setComputerName
else
lop -- -i 'Hostname of computer seems to have already been set. Skipping.' -i "Hostname: $currentComputerName"
fi
}
function configureBasicSystem(){
# Disable the sound effects on boot
nvram SystemAudioVolume=" "
# Disable the sound effects on boot
nvram SystemAudioVolume=" "
systemsetup -settimezone "${timezone}" >&! /dev/null
systemsetup -setusingnetworktime on >&! /dev/null
systemsetup -setnetworktimeserver 'time.apple.com' >&! /dev/null
systemsetup -setsleep never >&! /dev/null
systemsetup -setwakeonnetworkaccess off >&! /dev/null
systemsetup -setrestartfreeze on >&! /dev/null
systemsetup -f -setremotelogin off >&! /dev/null
systemsetup -setremoteappleevents off >&! /dev/null
systemsetup -settimezone "${timezone}" >&! /dev/null
systemsetup -setusingnetworktime on >&! /dev/null
systemsetup -setnetworktimeserver 'time.apple.com' >&! /dev/null
systemsetup -setsleep never >&! /dev/null
systemsetup -setwakeonnetworkaccess off >&! /dev/null
systemsetup -setrestartfreeze on >&! /dev/null
systemsetup -f -setremotelogin off >&! /dev/null
systemsetup -setremoteappleevents off >&! /dev/null
}
function configurePowerManagement() {
cmd=(pmset -a)
${cmd} displaysleep 0
${cmd} disksleep 0
${cmd} sleep 0
${cmd} womp 0
${cmd} acwake 0
${cmd} proximitywake 0
${cmd} destroyfvkeyonstandby 1
pmset -b acwake 1
${cmd} lidwake 1
${cmd} halfdim 1
${cmd} powernap 1
${cmd} hibernatemode 0
cmd=(pmset -a)
${cmd} displaysleep 0
${cmd} disksleep 0
${cmd} sleep 0
${cmd} womp 0
${cmd} acwake 0
${cmd} proximitywake 0
${cmd} destroyfvkeyonstandby 1
pmset -b acwake 1
${cmd} lidwake 1
${cmd} halfdim 1
${cmd} powernap 1
${cmd} hibernatemode 0
}
function configureLoginWindow() {
cmd=(defaults write '/Library/Preferences/com.apple.loginwindow')
${cmd} DisableFDEAutoLogin -bool true
${cmd} SHOWFULLNAME -bool true
${cmd} AdminHostInfo -string HostName
${cmd} GuestEnabled -bool false
cmd=(defaults write '/Library/Preferences/com.apple.loginwindow')
${cmd} DisableFDEAutoLogin -bool true
${cmd} SHOWFULLNAME -bool true
${cmd} AdminHostInfo -string HostName
${cmd} GuestEnabled -bool false
}
function configureMacOSFirewall() {
cmd=(/usr/libexec/ApplicationFirewall/socketfilterfw)
${cmd} --setglobalstate on
${cmd} --setblockall off
${cmd} --setstealthmode on
${cmd} --setallowsigned on
${cmd} --setallowsignedapp on
cmd=(/usr/libexec/ApplicationFirewall/socketfilterfw)
${cmd} --setglobalstate on
${cmd} --setblockall off
${cmd} --setstealthmode on
${cmd} --setallowsigned on
${cmd} --setallowsignedapp on
}
function configure_system() {
lop -y h1 -- -i 'Configure System Settings'
quitSystemPreferences
configureComputerHostname
indicateActivity -- 'Configuring systemsetup and nvram' configureBasicSystem
indicateActivity -- 'Configuring power management' configurePowerManagement
indicateActivity -- 'Configuring login window' configureLoginWindow
indicateActivity -- 'Configure global umask' launchctl config user umask 027
indicateActivity -- 'Configure macOS firewall' configureMacOSFirewall
lop -y h1 -- -i 'Configure System Settings'
quitSystemPreferences
configureComputerHostname
indicateActivity -- 'Configuring systemsetup and nvram' configureBasicSystem
indicateActivity -- 'Configuring power management' configurePowerManagement
indicateActivity -- 'Configuring login window' configureLoginWindow
indicateActivity -- 'Configure global umask' launchctl config user umask 027
indicateActivity -- 'Configure macOS firewall' configureMacOSFirewall
}
function getUsage() {
local cmdName=$1 text=''
read -r -d '' text <<- USAGE
local cmdName=$1 text=''
read -r -d '' text <<- USAGE
Usage:
$cmdName show-questions [<modkey> <modans>]...
$cmdName [-v] [-d FILE] --hostname NAME --timezone ZONE
Set energy, basic network and host preferences.
Options:
--hostname NAME Set NAME as current host's host name.
--timezone ZONE Set ZONE as current host's timezone [default: Europe/Berlin].
--hostname NAME Set NAME as current host's host name.
--timezone ZONE Set ZONE as current host's timezone [default: Europe/Berlin].
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
-v, --verbose Be more verbose.
----
@@ -129,11 +129,11 @@ function getUsage() {
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
USAGE
print -- ${text}
print -- ${text}
}
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
fi

View File

@@ -2,138 +2,138 @@
# vi: set ft=zsh tw=80 ts=2
function getComputerName() {
local moduleAnswer
local computerName="`scutil --get ComputerName 2> /dev/null`"
getModuleAnswerByKeyRegEx '_hostname$' && computerName=$moduleAnswer
print -- $computerName
local moduleAnswer
local computerName="`scutil --get ComputerName 2> /dev/null`"
getModuleAnswerByKeyRegEx '_hostname$' && computerName=$moduleAnswer
print -- $computerName
}
function getDefaultFullname() {
local computerName="`getComputerName`"
lop -- -d 'Default full name based on current computer name is:' -d "$computerName"
print "${computerName}"
local computerName="`getComputerName`"
lop -- -d 'Default full name based on current computer name is:' -d "$computerName"
print "${computerName}"
}
function getDefaultUsername() {
local username="`getDefaultFullname | tr '[:upper:]' '[:lower:]' | tr -C '[:alnum:]\n' '-'`"
lop -- -d 'Default username based on current computer name is:' -d "$username"
print "${username}"
local username="`getDefaultFullname | tr '[:upper:]' '[:lower:]' | tr -C '[:alnum:]\n' '-'`"
lop -- -d 'Default username based on current computer name is:' -d "$username"
print "${username}"
}
function isAPFSFilesystem() {
[[ $(diskutil info / | awk 'sub(/File System Personality: /,""){print $0}') = *APFS* ]]
[[ $(diskutil info / | awk 'sub(/File System Personality: /,""){print $0}') = *APFS* ]]
}
function getUsersWithSecureToken() {
local username uuid
for uuid in ${$(diskutil apfs listUsers / | awk '/\+\-\-/ {print $2}')}; do
username="$(dscl . -search /Users GeneratedUID ${uuid} | awk 'NR==1{print $1}')"
checkSecureTokenForUser ${username} && secureTokenUsers+=("${username}")
done
local username uuid
for uuid in ${$(diskutil apfs listUsers / | awk '/\+\-\-/ {print $2}')}; do
username="$(dscl . -search /Users GeneratedUID ${uuid} | awk 'NR==1{print $1}')"
checkSecureTokenForUser ${username} && secureTokenUsers+=("${username}")
done
}
function getDefaultUserPictures() {
pushd -q '/Library/User Pictures'
defaultUserPictures=("${(@f)$(find -E . -type f -iregex '.*\.(tif|png|jpeg|jpg)' | abbreviatePaths)}")
popd -q
pushd -q '/Library/User Pictures'
defaultUserPictures=("${(@f)$(find -E . -type f -iregex '.*\.(tif|png|jpeg|jpg)' | abbreviatePaths)}")
popd -q
}
function convertPathToDefaultPicture() {
local resolved=''
lop -- -d 'Converting path' -d "${filevault_picture}" -d 'to default picture path if necessary.'
if [ -r "${filevault_picture}" ]; then
lop -- -d 'Path seems to be a valid path already. Skipping conversion.'
return
fi
pushd -q '/Library/User Pictures'
resolved="`find "$_" -type f -path "*${filevault_picture}" 2> /dev/null`"
lop -- -d 'Resolved path is' -d "${resolved}"
popd -q
[ -n "${resolved}" -a -r "${resolved}" ] && filevault_picture="${resolved}"
local resolved=''
lop -- -d 'Converting path' -d "${filevault_picture}" -d 'to default picture path if necessary.'
if [ -r "${filevault_picture}" ]; then
lop -- -d 'Path seems to be a valid path already. Skipping conversion.'
return
fi
pushd -q '/Library/User Pictures'
resolved="`find "$_" -type f -path "*${filevault_picture}" 2> /dev/null`"
lop -- -d 'Resolved path is' -d "${resolved}"
popd -q
[ -n "${resolved}" -a -r "${resolved}" ] && filevault_picture="${resolved}"
}
function _isPathToPicture() {
local filevault_picture=$1
convertPathToDefaultPicture
[ -r "${filevault_picture}" ] || { lop -- -d 'Resolved path is not a valid path. Returning.'; return 10 }
[[ "${filevault_picture:e:l}" =~ (tif|png|jpeg|jpg) ]] || return 11
local filevault_picture=$1
convertPathToDefaultPicture
[ -r "${filevault_picture}" ] || { lop -- -d 'Resolved path is not a valid path. Returning.'; return 10 }
[[ "${filevault_picture:e:l}" =~ (tif|png|jpeg|jpg) ]] || return 11
}
function isPathToPicture() {
indicateActivity -- "Verifying $1 as picture path" _isPathToPicture $1
indicateActivity -- "Verifying $1 as picture path" _isPathToPicture $1
}
function _checkSecureTokenForUser() {
local u=$1
sysadminctl -secureTokenStatus "${u}" 2>&1 | grep ENABLED >&! /dev/null
local u=$1
sysadminctl -secureTokenStatus "${u}" 2>&1 | grep ENABLED >&! /dev/null
}
function checkSecureTokenForUser() {
local u=$1
indicateActivity -- "Checking if user $u has a secure token set" _checkSecureTokenForUser $u
local u=$1
indicateActivity -- "Checking if user $u has a secure token set" _checkSecureTokenForUser $u
}
function _checkUserPassword() {
local username=$1 password=$2
dscl . -authonly ${username} ${password} >&! /dev/null
local username=$1 password=$2
dscl . -authonly ${username} ${password} >&! /dev/null
}
function checkSecureTokenUserPassword() {
indicateActivity -- "Checking password for user ${secure_token_user_username}" _checkUserPassword ${secure_token_user_username} ${secure_token_user_password}
indicateActivity -- "Checking password for user ${secure_token_user_username}" _checkUserPassword ${secure_token_user_username} ${secure_token_user_password}
}
function checkFileVaultUserPassword() {
indicateActivity -- "Checking password for user ${filevault_username}" _checkUserPassword ${filevault_username} ${filevault_password}
indicateActivity -- "Checking password for user ${filevault_username}" _checkUserPassword ${filevault_username} ${filevault_password}
}
function _doesFileVaultUserExist() {
dscl . -list /Users | grep "${filevault_username}" >&! /dev/null
dscl . -list /Users | grep "${filevault_username}" >&! /dev/null
}
function doesFileVaultUserExist() {
indicateActivity -- "Checking if ${filevault_username} already exists" _doesFileVaultUserExist
indicateActivity -- "Checking if ${filevault_username} already exists" _doesFileVaultUserExist
}
function _createFileVaultUser() {
local un=${filevault_username} fn=${filevault_fullname} pw=${filevault_password} result=
lop -- -d 'Creating FileVault user' -d "${un}"
sysadminctl -addUser ${un} -fullName ${fn} -shell /usr/bin/false -home /var/empty -password ${pw} -picture ${filevault_picture}
result=$?
lop -- -d 'Return value of sysadminctl is ' -d "$?"
return $result
local un=${filevault_username} fn=${filevault_fullname} pw=${filevault_password} result=
lop -- -d 'Creating FileVault user' -d "${un}"
sysadminctl -addUser ${un} -fullName ${fn} -shell /usr/bin/false -home /var/empty -password ${pw} -picture ${filevault_picture}
result=$?
lop -- -d 'Return value of sysadminctl is ' -d "$?"
return $result
}
function createFileVaultUser() {
indicateActivity -- "Creating FileVault user ${filevault_username}" _createFileVaultUser
indicateActivity -- "Creating FileVault user ${filevault_username}" _createFileVaultUser
}
function _configureFileVaultUser() {
local un=${filevault_username}
dscl . -create "/Users/${un}" IsHidden 1
chsh -s /usr/bin/false "${un}" >&! /dev/null
local un=${filevault_username}
dscl . -create "/Users/${un}" IsHidden 1
chsh -s /usr/bin/false "${un}" >&! /dev/null
}
function configureFileVaultUser() {
indicateActivity -- "Configuring FileVault user ${filevault_username}" _configureFileVaultUser
indicateActivity -- "Configuring FileVault user ${filevault_username}" _configureFileVaultUser
}
function configureSecureToken() {
local un=${filevault_username} up=${filevault_password}
local stun=${secure_token_user_username} stup=${secure_token_user_password}
indicateActivity -- "Enable secure token for ${un}" sysadminctl -secureTokenOn "${un}" -password "${up}" -adminUser "${stun}" -adminPassword "${stup}"
local un=${filevault_username} up=${filevault_password}
local stun=${secure_token_user_username} stup=${secure_token_user_password}
indicateActivity -- "Enable secure token for ${un}" sysadminctl -secureTokenOn "${un}" -password "${up}" -adminUser "${stun}" -adminPassword "${stup}"
}
function canUserUnlockDisk() {
local username=$1
for fdeuser in ${(f)"$(fdesetup list | cut -d',' -f1)"}; do
[[ ${fdeuser} = ${username} ]] && return
done
return 1
local username=$1
for fdeuser in ${(f)"$(fdesetup list | cut -d',' -f1)"}; do
[[ ${fdeuser} = ${username} ]] && return
done
return 1
}
function getFDESetupXMLForUser() {
local username="${1}" password="${2}"
cat <<- XML
local username="${1}" password="${2}"
cat <<- XML
<?xml version="1.0" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
@@ -148,157 +148,157 @@ function getFDESetupXMLForUser() {
}
function _enableFileVaultForSecureTokenUser() {
local username="${1}" password="${2}"
getFDESetupXMLForUser "${username}" "${password}" | fdesetup enable -inputplist
local username="${1}" password="${2}"
getFDESetupXMLForUser "${username}" "${password}" | fdesetup enable -inputplist
}
function enableFileVaultForSecureTokenUser() {
fdesetup isactive >&! /dev/null && return
indicateActivity -- "Enable FileVault for secure token" _enableFileVaultForSecureTokenUser ${secure_token_user_username} ${secure_token_user_password}
fdesetup isactive >&! /dev/null && return
indicateActivity -- "Enable FileVault for secure token" _enableFileVaultForSecureTokenUser ${secure_token_user_username} ${secure_token_user_password}
}
function _allowUserToUnlockDisk() {
local username="${1}" password="${2}"
getFDESetupXMLForUser ${username} ${password} | fdesetup add -inputplist
local username="${1}" password="${2}"
getFDESetupXMLForUser ${username} ${password} | fdesetup add -inputplist
}
function allowFileVaultUserToUnlockDisk() {
indicateActivity -- "Allow FileVault user to unlock disk" _allowUserToUnlockDisk ${filevault_username} ${filevault_password}
indicateActivity -- "Allow FileVault user to unlock disk" _allowUserToUnlockDisk ${filevault_username} ${filevault_password}
}
function _allowOnlyFileVaultUserToUnlock() {
local fdeuser
for fdeuser in ${(f)"$(fdesetup list | cut -d',' -f1)"}; do
[[ ${fdeuser} != ${filevault_username} ]] && fdesetup remove -user "${fdeuser}"
done
return 0
local fdeuser
for fdeuser in ${(f)"$(fdesetup list | cut -d',' -f1)"}; do
[[ ${fdeuser} != ${filevault_username} ]] && fdesetup remove -user "${fdeuser}"
done
return 0
}
function allowOnlyFileVaultUserToUnlock() {
indicateActivity -- "Disallow everyone else from unlocking disk" _allowOnlyFileVaultUserToUnlock
indicateActivity -- "Disallow everyone else from unlocking disk" _allowOnlyFileVaultUserToUnlock
}
function configure_system() {
lop -y h1 -- -i 'Setup FileVault System'
checkSecureTokenForUser "${secure_token_user_username}" || { lop -- -e 'The provided secure token user has no secure token.'; return 10 }
checkSecureTokenUserPassword || { lop -- -e 'The secure token user password is incorrect.'; return 11 }
indicateActivity -- "Resolving path of picture ${filevault_picture}" convertPathToDefaultPicture
isPathToPicture "${filevault_picture}" || { lop -- -e 'The provided FileVault user picture is not a valid path to a TIF, PNG or JPEG file.'; return 12 }
lop -y h1 -- -i 'Setup FileVault System'
checkSecureTokenForUser "${secure_token_user_username}" || { lop -- -e 'The provided secure token user has no secure token.'; return 10 }
checkSecureTokenUserPassword || { lop -- -e 'The secure token user password is incorrect.'; return 11 }
indicateActivity -- "Resolving path of picture ${filevault_picture}" convertPathToDefaultPicture
isPathToPicture "${filevault_picture}" || { lop -- -e 'The provided FileVault user picture is not a valid path to a TIF, PNG or JPEG file.'; return 12 }
if doesFileVaultUserExist; then
checkFileVaultUserPassword || { lop -- -e 'The FileVault user password is incorrect.'; return 13 }
else
createFileVaultUser || { lop -- -e 'Was not able to create FileVault user.'; return 14 }
fi
configureFileVaultUser || { lop -- -e 'Could not configure FileVault user.'; return 15 }
enableFileVaultForSecureTokenUser || { lop -- -e 'Could not enable FileVault for secure token user.'; return 16 }
checkSecureTokenForUser "${filevault_username}" || configureSecureToken || { lop -- -e 'Could not configure secure token for FileVault user.'; return 17 }
canUserUnlockDisk ${filevault_username} || allowFileVaultUserToUnlockDisk || { lop -- -e 'Was not able to allow FileVault user to unlock disk.'; return 18 }
allowOnlyFileVaultUserToUnlock "${filevault_username}" || { lop -- -e 'Was not able to deactivate all other user from unlocking disk.'; return 19 }
indicateActivity -- 'Update APFS preboot volume' diskutil apfs updatePreboot / || { lop -- -e 'Was not able to update APFS preboot volume.'; return 20 }
if doesFileVaultUserExist; then
checkFileVaultUserPassword || { lop -- -e 'The FileVault user password is incorrect.'; return 13 }
else
createFileVaultUser || { lop -- -e 'Was not able to create FileVault user.'; return 14 }
fi
configureFileVaultUser || { lop -- -e 'Could not configure FileVault user.'; return 15 }
enableFileVaultForSecureTokenUser || { lop -- -e 'Could not enable FileVault for secure token user.'; return 16 }
checkSecureTokenForUser "${filevault_username}" || configureSecureToken || { lop -- -e 'Could not configure secure token for FileVault user.'; return 17 }
canUserUnlockDisk ${filevault_username} || allowFileVaultUserToUnlockDisk || { lop -- -e 'Was not able to allow FileVault user to unlock disk.'; return 18 }
allowOnlyFileVaultUserToUnlock "${filevault_username}" || { lop -- -e 'Was not able to deactivate all other user from unlocking disk.'; return 19 }
indicateActivity -- 'Update APFS preboot volume' diskutil apfs updatePreboot / || { lop -- -e 'Was not able to update APFS preboot volume.'; return 20 }
}
function getHelpPrerequisites() {
cmds=(
[tr]=''
[scutil]=''
)
addDocoptsToCmds
cmds=(
[tr]=''
[scutil]=''
)
addDocoptsToCmds
}
function getQuestionsPrerequisites() {
cmds=(
[find]=''
[dscl]=''
[dseditgroup]=''
[awk]=''
[diskutil]=''
[sysadminctl]=''
)
isAPFSFilesystem || { lop -- -e 'This module requires an APFS filesystem.'; return 10 }
cmds=(
[find]=''
[dscl]=''
[dseditgroup]=''
[awk]=''
[diskutil]=''
[sysadminctl]=''
)
isAPFSFilesystem || { lop -- -e 'This module requires an APFS filesystem.'; return 10 }
}
function getExecPrerequisites() {
cmds=(
[cut]=''
[cat]=''
[fdesetup]=''
[base64]=''
[dsimport]=''
)
requireRootPrivileges
cmds=(
[cut]=''
[cat]=''
[fdesetup]=''
[base64]=''
[dsimport]=''
)
requireRootPrivileges
}
function getQuestions() {
local secureTokenUsers=() defaultUserPictures=()
local defaultUsername="`getDefaultUsername`" defaultFullname="`getDefaultFullname`"
getUsersWithSecureToken
getDefaultUserPictures
local defaultUsernameHint= defaultFullnameHint=
[ -n "${defaultUsername}" ] && defaultUsernameHint="default:${defaultUsername};"
[ -n "${defaultFullname}" ] && defaultFullnameHint="default:${defaultFullname};"
questions=(
'i: filevault-fullname=What shall the FileVault user'\''s full name be? # '"${defaultFullnameHint}"
'i: filevault-username=What shall the FileVault user'\''s username be? # '"${defaultUsernameHint}"
'p: filevault-password=What shall the FileVault user'\''s password be?'
's: filevault-picture=Select a picture for FileVault user or enter the path to your own picture # validator:'"${cmdPath}"',is-picture;choose from:'"${(j.,.)defaultUserPictures};"
's: secure-token-user-username=Which user with a secure token shall be used? # choose from:'"${(j.,.)secureTokenUsers};"
'p: secure-token-user-password=What is the secure token user'\''s password?'
)
local secureTokenUsers=() defaultUserPictures=()
local defaultUsername="`getDefaultUsername`" defaultFullname="`getDefaultFullname`"
getUsersWithSecureToken
getDefaultUserPictures
local defaultUsernameHint= defaultFullnameHint=
[ -n "${defaultUsername}" ] && defaultUsernameHint="default:${defaultUsername};"
[ -n "${defaultFullname}" ] && defaultFullnameHint="default:${defaultFullname};"
questions=(
'i: filevault-fullname=What shall the FileVault user'\''s full name be? # '"${defaultFullnameHint}"
'i: filevault-username=What shall the FileVault user'\''s username be? # '"${defaultUsernameHint}"
'p: filevault-password=What shall the FileVault user'\''s password be?'
's: filevault-picture=Select a picture for FileVault user or enter the path to your own picture # validator:'"${cmdPath}"',is-picture;choose from:'"${(j.,.)defaultUserPictures};"
's: secure-token-user-username=Which user with a secure token shall be used? # choose from:'"${(j.,.)secureTokenUsers};"
'p: secure-token-user-password=What is the secure token user'\''s password?'
)
}
function preQuestionHook() {
if [[ "${is_picture}" = true ]]; then
isPathToPicture ${pathstr}
exit $?
fi
if [[ "${is_picture}" = true ]]; then
isPathToPicture ${pathstr}
exit $?
fi
}
function getUsage() {
local cmdName=$1 text='' varname=
local defaultUsername="`getDefaultUsername`" defaultFullname="`getDefaultFullname`"
for varname in defaultUsername defaultFullname; do
local ${varname}Str=
[ -n "${(P)varname}" ] && local ${varname}Str=" [default: ${(P)varname}]"
done
read -r -d '' text <<- USAGE
local cmdName=$1 text='' varname=
local defaultUsername="`getDefaultUsername`" defaultFullname="`getDefaultFullname`"
for varname in defaultUsername defaultFullname; do
local ${varname}Str=
[ -n "${(P)varname}" ] && local ${varname}Str=" [default: ${(P)varname}]"
done
read -r -d '' text <<- USAGE
Usage:
$cmdName show-questions [<modkey> <modans>]...
$cmdName is-picture <pathstr>
$cmdName [-v] [-d FILE] --filevault-fullname NAME --filevault-username NAME --filevault-password PASSWORD --filevault-picture PATH_TO_PIC --secure-token-user-username NAME --secure-token-user-password PASSWORD
Create a designated FileVault user who may not login to the system but is the
only one able to unlock the disk. That way a secure password can be used to
unlock the disk as opposed to macOS standard, where each user is allowed to
unlock the disk with his password that may or may not be secure (in terms of
length and randomness).
Options:
--filevault-fullname NAME Full name of the designated FileVault user. An
existing FileVault user will be renamed to that
name${defaultFullnameStr}.
--filevault-username NAME Username of the designated FileVault user. An
existing FileVault user will be renamed to that
name${defaultUsernameStr}.
--filevault-password PASSWORD Password of the designated FileVault user. The password
an existing FileVault user will not be changed.
--filevault-picture PATH_TO_PIC The path to the picture that shall be made the FileVault
user picture. The picture of an existing FileVault user
will be updated.
--secure-token-user-username NAME The username of an user with a secure token.
--secure-token-user-password PASSWORD The password of the secure token user.
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
-v, --verbose Be more verbose.
--filevault-fullname NAME Full name of the designated FileVault user. An
existing FileVault user will be renamed to that
name ${defaultFullnameStr}.
--filevault-username NAME Username of the designated FileVault user. An
existing FileVault user will be renamed to that
name ${defaultUsernameStr}.
--filevault-password PASSWORD Password of the designated FileVault user. The password
an existing FileVault user will not be changed.
--filevault-picture PATH_TO_PIC The path to the picture that shall be made the FileVault
user picture. The picture of an existing FileVault user
will be updated.
--secure-token-user-username NAME The username of an user with a secure token.
--secure-token-user-password PASSWORD The password of the secure token user.
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
-v, --verbose Be more verbose.
----
$cmdName 0.1.0
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
USAGE
print -- ${text}
print -- ${text}
}
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
fi

View File

@@ -5,14 +5,14 @@ export HOMEBREW_NO_ANALYTICS_THIS_RUN=1
export HOMEBREW_NO_ANALYTICS_MESSAGE_OUTPUT=1
function doesUserExist() {
local username=$1
dscl . -list /Users | grep "^${username}$" 2> /dev/null >&2
local username=$1
dscl . -list /Users | grep "^${username}$" 2> /dev/null >&2
}
function runAsUser() {
local username=$1
shift
sudo -Hu "${username}" "${@}"
local username=$1
shift
sudo -Hu "${username}" "${@}"
}
function runAsHomebrewUser() {
@@ -20,95 +20,95 @@ function runAsHomebrewUser() {
}
function ensureUserIsInAdminGroup() {
local username=$1
dseditgroup -o edit -a "${username}" -t user admin
local username=$1
dseditgroup -o edit -a "${username}" -t user admin
}
function ensureUserCanRunPasswordlessSudo() {
local username=$1
local sudoersFile="/etc/sudoers.d/no-auth-sudo-for-${username}"
[[ -f ${sudoersFile} ]] && return
cat <<- SUDOERS > "${sudoersFile}"
local username=$1
local sudoersFile="/etc/sudoers.d/no-auth-sudo-for-${username}"
[[ -f ${sudoersFile} ]] && return
cat <<- SUDOERS > "${sudoersFile}"
Defaults:${username} !authenticate
SUDOERS
chown root:wheel "${sudoersFile}" || return 10
chmod u=rw,g=r,o= "${sudoersFile}" || return 20
chown root:wheel "${sudoersFile}" || return 10
chmod u=rw,g=r,o= "${sudoersFile}" || return 20
}
function getFirstFreeRoleAccountID() {
dscl . -list '/Users' UniqueID | grep '_.*' | sort -n -k2 | awk -v i=401 '$2>200 && $2<401 {if(i < $2) { print i; nextfile} else i=$2+1;}'
dscl . -list '/Users' UniqueID | grep '_.*' | sort -n -k2 | awk -v i=401 '$2>200 && $2<401 {if(i < $2) { print i; nextfile} else i=$2+1;}'
}
function createHomebrewUser() {
local username=$1
local userID=`getFirstFreeRoleAccountID`
sysadminctl -addUser "${username}" -fullName "Homebrew User" -shell /usr/bin/false -home '/var/empty' -roleAccount -UID "${userID}" > /dev/null 2>&1
local username=$1
local userID=`getFirstFreeRoleAccountID`
sysadminctl -addUser "${username}" -fullName "Homebrew User" -shell /usr/bin/false -home '/var/empty' -roleAccount -UID "${userID}" > /dev/null 2>&1
}
function createHomebrewUserIfNeccessary() {
if ! doesUserExist ${homebrew_username}; then
lop -y body:warn -y body -- -i "No Homebrew user named ${homebrew_username} found." -i 'Will create user.'
indicateActivity 'Creating Homebrew user' createHomebrewUser ${homebrew_username} || return 10
else
lop -y body:note -y body -- -i "Homebrew user named ${homebrew_username} already exists." -i 'Skipping.'
fi
if ! doesUserExist ${homebrew_username}; then
lop -y body:warn -y body -- -i "No Homebrew user named ${homebrew_username} found." -i 'Will create user.'
indicateActivity 'Creating Homebrew user' createHomebrewUser ${homebrew_username} || return 10
else
lop -y body:note -y body -- -i "Homebrew user named ${homebrew_username} already exists." -i 'Skipping.'
fi
}
function ensureDirectoryWithDefaultMod() {
local itemPath=${1}
mkdir -p ${itemPath}
ensureHomebrewOwnershipAndPermission ${itemPath}
local itemPath=${1}
mkdir -p ${itemPath}
ensureHomebrewOwnershipAndPermission ${itemPath}
}
function ensureHomebrewOwnershipAndPermission() {
local itemPath=${1}
local username=${homebrew_username}
[[ -f ${itemPath} || -d ${itemPath} ]] || return 1
chown -R "${username}:admin" ${itemPath}
chmod u=rwx,go=rx ${itemPath}
local itemPath=${1}
local username=${homebrew_username}
[[ -f ${itemPath} || -d ${itemPath} ]] || return 1
chown -R "${username}:admin" ${itemPath}
chmod u=rwx,go=rx ${itemPath}
}
function ensureHomebrewCacheDirectory() {
ensureDirectoryWithDefaultMod "${homebrew_cache}"
runAsHomebrewUser touch "${homebrew_cache}/.cleaned"
ensureDirectoryWithDefaultMod "${homebrew_cache}"
runAsHomebrewUser touch "${homebrew_cache}/.cleaned"
}
function ensureHomebrewLogDirectory() {
ensureDirectoryWithDefaultMod ${homebrew_log}
ensureDirectoryWithDefaultMod ${homebrew_log}
}
function ensureLocalBinFolder() {
local folder="/usr/local/bin"
if [ ! -d "${folder}" ]; then
mkdir -p "${folder}" 2> /dev/null || {
lop -- -e 'Could not create directory' -e $folder
return 10
}
chown root:admin "${folder}"
chmod ug=rwx,o=rx "${folder}"
fi
local folder="/usr/local/bin"
if [ ! -d "${folder}" ]; then
mkdir -p "${folder}" 2> /dev/null || {
lop -- -e 'Could not create directory' -e $folder
return 10
}
chown root:admin "${folder}"
chmod ug=rwx,o=rx "${folder}"
fi
}
function getHomebrewRepositoryPath() {
local uname_machine=$(/usr/bin/uname -m)
if [[ ${uname_machine} == "arm64" ]]; then
print -- "/opt/homebrew"
else
print "/usr/local/Homebrew"
fi
local uname_machine=$(/usr/bin/uname -m)
if [[ ${uname_machine} == "arm64" ]]; then
print -- "/opt/homebrew"
else
print "/usr/local/Homebrew"
fi
}
function createBrewCallerScript() {
ensureLocalBinFolder
local username=${homebrew_username}
local brewCallerPath="/usr/local/bin/brew"
[ -f "${brewCallerPath}" ] && rm "${brewCallerPath}"
cat <<- BREWCALLER > ${brewCallerPath}
ensureLocalBinFolder
local username=${homebrew_username}
local brewCallerPath="/usr/local/bin/brew"
[ -f "${brewCallerPath}" ] && rm "${brewCallerPath}"
cat <<- BREWCALLER > ${brewCallerPath}
#!/usr/bin/env zsh
if [ "\$(id -un)" != "${username}" ]; then
echo 'brew will be run as ${username} user.' >&2
sudo -E -u "${username}" "\$0" "\$@"
exit \$?
echo 'brew will be run as ${username} user.' >&2
sudo -E -u "${username}" "\$0" "\$@"
exit \$?
fi
export HOMEBREW_CACHE="${homebrew_cache}"
export HOMEBREW_LOGS="${homebrew_log}"
@@ -120,109 +120,109 @@ function createBrewCallerScript() {
umask 002
"$(getHomebrewRepositoryPath)/bin/brew" "\$@"
BREWCALLER
chown ${username}:admin ${brewCallerPath}
chmod ug+x,o-x ${brewCallerPath}
chown ${username}:admin ${brewCallerPath}
chmod ug+x,o-x ${brewCallerPath}
}
function installHomebrewCore() {
export NONINTERACTIVE=1
[ ! -d $(getHomebrewRepositoryPath) ] || return
sudo --preserve-env=NONINTERACTIVE -u "${homebrew_username}" /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
[ -d $(getHomebrewRepositoryPath) ]
export NONINTERACTIVE=1
[ ! -d $(getHomebrewRepositoryPath) ] || return
sudo --preserve-env=NONINTERACTIVE -u "${homebrew_username}" /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
[ -d $(getHomebrewRepositoryPath) ]
}
function createLaunchDaemonsPlist() {
local username=${homebrew_username}
local launcherName="de.astzweig.macos.launchdaemons.$1"
local launcherPath="/Library/LaunchDaemons/${launcherName}.plist"
[[ -f $launcherPath ]] && return
local brewCommand="$2"
cat <<- LAUNCHDPLIST > ${launcherPath}
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
local username=${homebrew_username}
local launcherName="de.astzweig.macos.launchdaemons.$1"
local launcherPath="/Library/LaunchDaemons/${launcherName}.plist"
[[ -f $launcherPath ]] && return
local brewCommand="$2"
cat <<- LAUNCHDPLIST > ${launcherPath}
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
<key>Label</key>
<string>${launcherName}</string>
<key>Program</key>
<string>/usr/local/bin/brew</string>
<key>ProgramArguments</key>
<array>
<string>${brewCommand}</string>
</array>
<key>StartInterval</key>
<integer>1800</integer>
<key>UserName</key>
<string>${username}</string>
<key>GroupName</key>
<string>admin</string>
<key>Umask</key>
<integer>2</integer>
<key>Label</key>
<string>${launcherName}</string>
<key>Program</key>
<string>/usr/local/bin/brew</string>
<key>ProgramArguments</key>
<array>
<string>${brewCommand}</string>
</array>
<key>StartInterval</key>
<integer>1800</integer>
<key>UserName</key>
<string>${username}</string>
<key>GroupName</key>
<string>admin</string>
<key>Umask</key>
<integer>2</integer>
</dict>
</plist>"
LAUNCHDPLIST
chown root:wheel ${launcherPath}
chmod u=rw,go=r ${launcherPath}
launchctl bootstrap system ${launcherPath}
chown root:wheel ${launcherPath}
chmod u=rw,go=r ${launcherPath}
launchctl bootstrap system ${launcherPath}
}
function installHomebrewUpdater() {
createLaunchDaemonsPlist brew-updater update
createLaunchDaemonsPlist brew-upgrader upgrade
return
createLaunchDaemonsPlist brew-updater update
createLaunchDaemonsPlist brew-upgrader upgrade
return
}
function configure_system() {
lop -y h1 -- -i 'Install System Homebrew'
createHomebrewUserIfNeccessary || return 10
indicateActivity 'Ensure Homebrew user is in admin group' ensureUserIsInAdminGroup ${homebrew_username} || return 11
indicateActivity 'Ensure Homebrew user can run passwordless sudo' ensureUserCanRunPasswordlessSudo ${homebrew_username} || return 12
ensureHomebrewCacheDirectory || return 13
ensureHomebrewLogDirectory || return 14
indicateActivity 'Install Homebrew core' installHomebrewCore || return 15
indicateActivity 'Create brew caller script' createBrewCallerScript || return 16
indicateActivity 'Install Homebrew updater' installHomebrewUpdater || return 17
lop -y h1 -- -i 'Install System Homebrew'
createHomebrewUserIfNeccessary || return 10
indicateActivity 'Ensure Homebrew user is in admin group' ensureUserIsInAdminGroup ${homebrew_username} || return 11
indicateActivity 'Ensure Homebrew user can run passwordless sudo' ensureUserCanRunPasswordlessSudo ${homebrew_username} || return 12
ensureHomebrewCacheDirectory || return 13
ensureHomebrewLogDirectory || return 14
indicateActivity 'Install Homebrew core' installHomebrewCore || return 15
indicateActivity 'Create brew caller script' createBrewCallerScript || return 16
indicateActivity 'Install Homebrew updater' installHomebrewUpdater || return 17
}
function getExecPrerequisites() {
cmds=(
[dscl]=''
[dseditgroup]=''
[chown]=''
[chmod]=''
[sudo]=''
[grep]=''
[git]=''
[sort]=''
[awk]=''
[launchctl]=''
[sysadminctl]=''
)
requireRootPrivileges
cmds=(
[dscl]=''
[dseditgroup]=''
[chown]=''
[chmod]=''
[sudo]=''
[grep]=''
[git]=''
[sort]=''
[awk]=''
[launchctl]=''
[sysadminctl]=''
)
requireRootPrivileges
}
function getDefaultHomebrewUsername() {
print -- _homebrew
print -- _homebrew
}
function getDefaultHomebrewCachePath() {
print -- /Library/Caches/Homebrew
print -- /Library/Caches/Homebrew
}
function getDefaultHomebrewLogPath() {
print -- /var/log/Homebrew
print -- /var/log/Homebrew
}
function getQuestions() {
questions=(
'i: homebrew-username=What shall the Homebrew user'\''s username be? # default:'"$(getDefaultHomebrewUsername)"
'i: homebrew-cache=What shall the Homebrew cache directory be? # default:'"$(getDefaultHomebrewCachePath)"
'i: homebrew-log=What shall the Homebrew log directory be? # default:'"$(getDefaultHomebrewLogPath)"
)
questions=(
'i: homebrew-username=What shall the Homebrew user'\''s username be? # default:'"$(getDefaultHomebrewUsername)"
'i: homebrew-cache=What shall the Homebrew cache directory be? # default:'"$(getDefaultHomebrewCachePath)"
'i: homebrew-log=What shall the Homebrew log directory be? # default:'"$(getDefaultHomebrewLogPath)"
)
}
function getUsage() {
read -r -d '' text <<- USAGE
read -r -d '' text <<- USAGE
Usage:
$cmdName show-questions [<modkey> <modans>]...
$cmdName [-v] [-d FILE] --homebrew-username NAME --homebrew-cache PATH --homebrew-log PATH
@@ -232,24 +232,24 @@ function getUsage() {
given PREFIX and make the new Homebrew user the owner of that.
Options:
--homebrew-cache PATH Path to folder that shall be used as the
cache for Homebrew [default: $(getDefaultHomebrewCachePath)].
--homebrew-log PATH Path to folder that shall be used as the log
directory for Homebrew [default: $(getDefaultHomebrewLogPath)].
--homebrew-username NAME Username of the designated Homebrew user.
[default: $(getDefaultHomebrewUsername)].
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
-v, --verbose Be more verbose.
--homebrew-cache PATH Path to folder that shall be used as the
cache for Homebrew [default: $(getDefaultHomebrewCachePath)].
--homebrew-log PATH Path to folder that shall be used as the log
directory for Homebrew [default: $(getDefaultHomebrewLogPath)].
--homebrew-username NAME Username of the designated Homebrew user.
[default: $(getDefaultHomebrewUsername)].
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
-v, --verbose Be more verbose.
----
$cmdName 0.1.0
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
USAGE
print -- ${text}
print -- ${text}
}
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
fi

View File

@@ -2,89 +2,89 @@
# vi: set ft=zsh tw=80 ts=2
function brewInstall() {
local identifier="$1"
local cask="${2:+--cask}"
indicateActivity -- "Installing ${identifier}${cask:+ (Cask)}" ${homebrew_path} install -q ${cask} ${identifier}
local identifier="$1"
local cask="${2:+--cask}"
indicateActivity -- "Installing ${identifier}${cask:+ (Cask)}" ${homebrew_path} install -q ${cask} ${identifier}
}
function installCask() {
brewInstall $1 cask
brewInstall $1 cask
}
function installBrew() {
brewInstall $1
brewInstall $1
}
function installCasks() {
lop -y body:h1 -- -i 'Installing Homebrew casks'
if ! isDebug; then
installCask sketch
installCask nova
installCask transmit
installCask automattic-texts
installCask synology-drive
installCask sf-symbols
installCask prizmo
fi
lop -y body:h1 -- -i 'Installing Homebrew casks'
if ! isDebug; then
installCask sketch
installCask nova
installCask transmit
installCask automattic-texts
installCask synology-drive
installCask sf-symbols
installCask prizmo
fi
}
function installFonts() {
}
function installBrews() {
lop -y body:h1 -- -i 'Installing Homebrew formulas'
installBrew mas
if ! isDebug; then
installBrew python
installBrew rcm
installBrew php
installBrew composer
installBrew curl
installBrew exiftool
installBrew ffmpeg
installBrew gnupg
installBrew node
installBrew nmap
installBrew tree
fi
lop -y body:h1 -- -i 'Installing Homebrew formulas'
installBrew mas
if ! isDebug; then
installBrew python
installBrew rcm
installBrew php
installBrew composer
installBrew curl
installBrew exiftool
installBrew ffmpeg
installBrew gnupg
installBrew node
installBrew nmap
installBrew tree
fi
}
function configure_system() {
lop -y h1 -- -i 'Install Homebrew Applications'
pushd -q /
installBrews
installCasks
installFonts
popd -q
lop -y h1 -- -i 'Install Homebrew Applications'
pushd -q /
installBrews
installCasks
installFonts
popd -q
}
function getExecPrerequisites() {
cmds=(
[brew]=''
[find]=''
[head]=''
[installer]=''
[hdiutil]=''
)
id -nG | grep admin >&! /dev/null || { lop -- -e 'This module requires the user to be in admin group. Please run again as either root or an admin user.'; return 11 }
checkCommands
cmds=(
[brew]=''
[find]=''
[head]=''
[installer]=''
[hdiutil]=''
)
id -nG | grep admin >&! /dev/null || { lop -- -e 'This module requires the user to be in admin group. Please run again as either root or an admin user.'; return 11 }
checkCommands
}
function getDefaultHomebrewPath() {
local moduleAnswer
local hbpath=`whence -p brew`
getModuleAnswerByKeyRegEx '_homebrew-prefix$' && hbpath=$moduleAnswer/bin/brew
print -- ${hbpath}
local moduleAnswer
local hbpath=`whence -p brew`
getModuleAnswerByKeyRegEx '_homebrew-prefix$' && hbpath=$moduleAnswer/bin/brew
print -- ${hbpath}
}
function getQuestions() {
questions=(
'i: homebrew-path=Which Homebrew binary shall be used? # default:'"$(getDefaultHomebrewPath)"
)
questions=(
'i: homebrew-path=Which Homebrew binary shall be used? # default:'"$(getDefaultHomebrewPath)"
)
}
function getUsage() {
read -r -d '' text <<- USAGE
read -r -d '' text <<- USAGE
Usage:
$cmdName show-questions [<modkey> <modans>]...
$cmdName [-v] [-d FILE] --homebrew-path PATH
@@ -92,19 +92,19 @@ function getUsage() {
Install cli tools, macOS apps and fonts via Homebrew.
Options:
--homebrew-path PATH Path to Homebrew binary [default: $(getDefaultHomebrewPath)].
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
-v, --verbose Be more verbose.
--homebrew-path PATH Path to Homebrew binary [default: $(getDefaultHomebrewPath)].
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
-v, --verbose Be more verbose.
----
$cmdName 0.1.0
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
USAGE
print -- ${text}
print -- ${text}
}
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
fi

View File

@@ -2,166 +2,166 @@
# vi: set ft=zsh tw=80 ts=2
function ensureRightAccess() {
local filesystemItem="$1"
chown root:wheel ${filesystemItem}
chmod ugo=rx ${filesystemItem}
local filesystemItem="$1"
chown root:wheel ${filesystemItem}
chmod ugo=rx ${filesystemItem}
}
function getDataForMicrosoftKeyboard() {
local name="$1"
[ "$name" = "ProductID" ] && echo '0x7a5'
[ "$name" = "VendorID" ] && echo '0x45e'
[ "$name" = "LaunchdServiceName" ] && echo 'de.astzweig.macos.launchdaemons.microsoft-keymapper'
[ "$name" = "BinaryName" ] && echo 'remap-keys-microsoft'
[ "$name" = "KeyMappings" ] && cat <<- KEYMAPPINGS
{"HIDKeyboardModifierMappingSrc": 0x700000065, "HIDKeyboardModifierMappingDst": 0x7000000e7},
{"HIDKeyboardModifierMappingSrc": 0x7000000e3, "HIDKeyboardModifierMappingDst": 0x7000000e2},
{"HIDKeyboardModifierMappingSrc": 0x7000000e2, "HIDKeyboardModifierMappingDst": 0x7000000e3}
local name="$1"
[ "$name" = "ProductID" ] && echo '0x7a5'
[ "$name" = "VendorID" ] && echo '0x45e'
[ "$name" = "LaunchdServiceName" ] && echo 'de.astzweig.macos.launchdaemons.microsoft-keymapper'
[ "$name" = "BinaryName" ] && echo 'remap-keys-microsoft'
[ "$name" = "KeyMappings" ] && cat <<- KEYMAPPINGS
{"HIDKeyboardModifierMappingSrc": 0x700000065, "HIDKeyboardModifierMappingDst": 0x7000000e7},
{"HIDKeyboardModifierMappingSrc": 0x7000000e3, "HIDKeyboardModifierMappingDst": 0x7000000e2},
{"HIDKeyboardModifierMappingSrc": 0x7000000e2, "HIDKeyboardModifierMappingDst": 0x7000000e3}
KEYMAPPINGS
}
function getDataForLogitechKeyboard() {
local name="$1"
[ "$name" = "ProductID" ] && echo '0xc52b'
[ "$name" = "VendorID" ] && echo '0x46d'
[ "$name" = "LaunchdServiceName" ] && echo 'de.astzweig.macos.launchdaemons.logitech-keymapper'
[ "$name" = "BinaryName" ] && echo 'remap-keys-logitech'
[ "$name" = "KeyMappings" ] && cat <<- KEYMAPPINGS
{"HIDKeyboardModifierMappingSrc": 0x7000000e6, "HIDKeyboardModifierMappingDst": 0x7000000e7},
{"HIDKeyboardModifierMappingSrc": 0x7000000e7, "HIDKeyboardModifierMappingDst": 0x7000000e6}
local name="$1"
[ "$name" = "ProductID" ] && echo '0xc52b'
[ "$name" = "VendorID" ] && echo '0x46d'
[ "$name" = "LaunchdServiceName" ] && echo 'de.astzweig.macos.launchdaemons.logitech-keymapper'
[ "$name" = "BinaryName" ] && echo 'remap-keys-logitech'
[ "$name" = "KeyMappings" ] && cat <<- KEYMAPPINGS
{"HIDKeyboardModifierMappingSrc": 0x7000000e6, "HIDKeyboardModifierMappingDst": 0x7000000e7},
{"HIDKeyboardModifierMappingSrc": 0x7000000e7, "HIDKeyboardModifierMappingDst": 0x7000000e6}
KEYMAPPINGS
}
function createXPCConsumer() {
[[ -x ${xpcConsumerPath} ]] && return
clang -framework Foundation -x objective-c -o ${xpcConsumerPath} - <<- BINARY
[[ -x ${xpcConsumerPath} ]] && return
clang -framework Foundation -x objective-c -o ${xpcConsumerPath} - <<- BINARY
#import <Foundation/Foundation.h>
#include <xpc/xpc.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
xpc_set_event_stream_handler("com.apple.iokit.matching", NULL, ^(xpc_object_t _Nonnull object) {
const char *event = xpc_dictionary_get_string(object, XPC_EVENT_KEY_NAME);
NSLog(@"%s", event);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
if(argc >= 2) {
execv(argv[1], (char **)argv+1);
}
}
@autoreleasepool {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
xpc_set_event_stream_handler("com.apple.iokit.matching", NULL, ^(xpc_object_t _Nonnull object) {
const char *event = xpc_dictionary_get_string(object, XPC_EVENT_KEY_NAME);
NSLog(@"%s", event);
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
if(argc >= 2) {
execv(argv[1], (char **)argv+1);
}
}
}
BINARY
ensureRightAccess ${xpcConsumerPath}
ensureRightAccess ${xpcConsumerPath}
}
function getProductPlistDict() {
cat <<- PLISTDICT
cat <<- PLISTDICT
<dict>
<key>idProduct</key>
<integer>$(($($dataProvider ProductID)))</integer>
<key>idVendor</key>
<integer>$(($($dataProvider VendorID)))</integer>
<key>IOProviderClass</key>
<string>IOUSBDevice</string>
<key>IOMatchLaunchStream</key>
<true/>
<key>idProduct</key>
<integer>$(($($dataProvider ProductID)))</integer>
<key>idVendor</key>
<integer>$(($($dataProvider VendorID)))</integer>
<key>IOProviderClass</key>
<string>IOUSBDevice</string>
<key>IOMatchLaunchStream</key>
<true/>
</dict>
PLISTDICT
}
function createRemapKeysBinary() {
cat > ${binaryPath} <<- BINARY
cat > ${binaryPath} <<- BINARY
#!/bin/zsh
PRODUCT_MATCHER='{"ProductID":$($dataProvider ProductID),"VendorID":$($dataProvider VendorID)}'
hasMappingBeenAlreadyActivated() {
local currentModifierKeyMappings="\`hidutil property --get UserKeyMapping -m "\${PRODUCT_MATCHER}" | grep HIDKeyboardModifierMappingDst | wc -l\`"
test "\${currentModifierKeyMappings}" -gt 1
local currentModifierKeyMappings="\`hidutil property --get UserKeyMapping -m "\${PRODUCT_MATCHER}" | grep HIDKeyboardModifierMappingDst | wc -l\`"
test "\${currentModifierKeyMappings}" -gt 1
}
hasMappingBeenAlreadyActivated || \
hidutil property --matching "\${PRODUCT_MATCHER}" --set '{"UserKeyMapping": [
$($dataProvider KeyMappings)
$($dataProvider KeyMappings)
]}' > /dev/null 2>&1
BINARY
ensureRightAccess ${binaryPath}
ensureRightAccess ${binaryPath}
}
function createLaunchDaemon() {
cat > ${launchDaemonPath} <<- LDAEMON
cat > ${launchDaemonPath} <<- LDAEMON
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>$($dataProvider LaunchdServiceName)</string>
<key>ProgramArguments</key>
<array>
<string>${xpcConsumerPath}</string>
<string>${remapKeysPath}</string>
</array>
<key>LaunchEvents</key>
<dict>
<key>com.apple.iokit.matching</key>
<dict>
<key>com.apple.device-attach</key>
$(getProductPlistDict)
</dict>
</dict>
</dict>
<dict>
<key>Label</key>
<string>$($dataProvider LaunchdServiceName)</string>
<key>ProgramArguments</key>
<array>
<string>${xpcConsumerPath}</string>
<string>${remapKeysPath}</string>
</array>
<key>LaunchEvents</key>
<dict>
<key>com.apple.iokit.matching</key>
<dict>
<key>com.apple.device-attach</key>
$(getProductPlistDict)
</dict>
</dict>
</dict>
</plist>
LDAEMON
ensureRightAccess ${launchDaemonPath}
ensureRightAccess ${launchDaemonPath}
}
function enableLaunchDaemon() {
launchctl enable system/${launchDaemonPath%.*}
launchctl bootstrap system ${launchDaemonPath}
launchctl enable system/${launchDaemonPath%.*}
launchctl bootstrap system ${launchDaemonPath}
}
function createLaunchdService() {
local launchDaemonPath="/Library/LaunchDaemons/$($dataProvider LaunchdServiceName).plist"
[[ -f ${launchDaemonPath} ]] || indicateActivity -- 'Create Launch Daemon' createLaunchDaemon
indicateActivity -- 'Enable Launch Daemon' enableLaunchDaemon
local launchDaemonPath="/Library/LaunchDaemons/$($dataProvider LaunchdServiceName).plist"
[[ -f ${launchDaemonPath} ]] || indicateActivity -- 'Create Launch Daemon' createLaunchDaemon
indicateActivity -- 'Enable Launch Daemon' enableLaunchDaemon
}
function configureKeymappers() {
local mapper= dataProvider= binaryPath=
for mapper dataProvider in ${(kv)mappers}; do
lop -y h1 -- -i "Configure ${mapper} Keymapper"
binaryPath="${dstDir}/$($dataProvider BinaryName)"
createRemapKeysBinary
createLaunchdService
done
local mapper= dataProvider= binaryPath=
for mapper dataProvider in ${(kv)mappers}; do
lop -y h1 -- -i "Configure ${mapper} Keymapper"
binaryPath="${dstDir}/$($dataProvider BinaryName)"
createRemapKeysBinary
createLaunchdService
done
}
function configure_system() {
typeset -A mappers=(
[Microsoft]=getDataForMicrosoftKeyboard
[Logitech]=getDataForLogitechKeyboard
)
local dstDir='/usr/local/bin'
local xpcConsumerPath="${dstDir}/astzweig-xpc-consumer"
typeset -A mappers=(
[Microsoft]=getDataForMicrosoftKeyboard
[Logitech]=getDataForLogitechKeyboard
)
local dstDir='/usr/local/bin'
local xpcConsumerPath="${dstDir}/astzweig-xpc-consumer"
ensurePathOrLogError ${dstDir} 'Could not create destination dir for remap-keys binary.' || return 10
indicateActivity -- 'Create XPC event consumer' createXPCConsumer
configureKeymappers
ensurePathOrLogError ${dstDir} 'Could not create destination dir for remap-keys binary.' || return 10
indicateActivity -- 'Create XPC event consumer' createXPCConsumer
configureKeymappers
}
function getExecPrerequisites() {
cmds=(
[clang]=''
[launchctl]=''
[cp]=''
[chown]=''
[chmod]=''
)
cmds=(
[clang]=''
[launchctl]=''
[cp]=''
[chown]=''
[chmod]=''
)
}
function getUsage() {
read -r -d '' text <<- USAGE
read -r -d '' text <<- USAGE
Usage:
$cmdName show-questions [<modkey> <modans>]...
$cmdName [-v] [-d FILE]
@@ -170,18 +170,18 @@ function getUsage() {
macOS nativ hidutil, in order to swap command and option key.
Options:
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
-v, --verbose Be more verbose.
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
-v, --verbose Be more verbose.
----
$cmdName 0.1.0
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
USAGE
print -- ${text}
print -- ${text}
}
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
fi

View File

@@ -2,47 +2,47 @@
# vi: set ft=zsh tw=80 ts=2
function installMASApp() {
local currentUser="`who am i | cut -d' ' -f1`"
local appName="$1"
local id="$2"
indicateActivity -- "Install ${appName} app" sudo -u ${currentUser} mas install ${id}
local currentUser="`who am i | cut -d' ' -f1`"
local appName="$1"
local id="$2"
indicateActivity -- "Install ${appName} app" sudo -u ${currentUser} mas install ${id}
}
function configure_system() {
lop -y h1 -- -i 'Install Mac AppStore Apps'
installMASApp Keka 470158793
lop -y h1 -- -i 'Install Mac AppStore Apps'
installMASApp Keka 470158793
if ! isDebug; then
installMASApp Pages 409201541
installMASApp Numbers 409203825
if ! isDebug; then
installMASApp Pages 409201541
installMASApp Numbers 409203825
installMASApp Outbank 1094255754
installMASApp Outbank 1094255754
installMASApp 'Final Cut Pro' 424389933
installMASApp GarageBand 682658836
installMASApp Motion 434290957
installMASApp Compressor 424390742
installMASApp 'Logic Pro' 634148309
fi
installMASApp 'Final Cut Pro' 424389933
installMASApp GarageBand 682658836
installMASApp Motion 434290957
installMASApp Compressor 424390742
installMASApp 'Logic Pro' 634148309
fi
}
function getExecPrerequisites() {
cmds=(
[mas]=''
[sudo]=''
[who]=''
[cut]=''
)
cmds=(
[mas]=''
[sudo]=''
[who]=''
[cut]=''
)
}
function getQuestions {
questions=(
'c: logged-in=Have you ensured a user is logged in to the macOS App Store?'
)
questions=(
'c: logged-in=Have you ensured a user is logged in to the macOS App Store?'
)
}
function getUsage() {
read -r -d '' text <<- USAGE
read -r -d '' text <<- USAGE
Usage:
$cmdName show-questions [<modkey> <modans>]...
$cmdName [-v] [-d FILE] --logged-in ANS
@@ -59,11 +59,11 @@ function getUsage() {
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
USAGE
print -- ${text}
print -- ${text}
}
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
fi

View File

@@ -2,63 +2,63 @@
# vi: set ft=zsh tw=80 ts=2
function ensureRightAccess() {
local filesystemItem="$1"
chown root:admin "${filesystemItem}"
chmod ugo=rx "${filesystemItem}"
local filesystemItem="$1"
chown root:admin "${filesystemItem}"
chmod ugo=rx "${filesystemItem}"
}
function copyUtilityBinaries() {
for file in ${_DIR}/../bin/*; do
indicateActivity -- "Copying ${file##*/}" cp ${file} ${dstDir}
ensureRightAccess ${file}
done
for file in ${_DIR}/../bin/*; do
indicateActivity -- "Copying ${file##*/}" cp ${file} ${dstDir}
ensureRightAccess ${file}
done
}
function installDocopts() {
local destPath='/usr/local/bin/docopts'
[[ -x ${destPath} ]] && return
indicateActivity -- 'Downloading docpts' curl --output ${destPath} -fsSL ${docopts_url} || return
ensureRightAccess ${destPath}
local destPath='/usr/local/bin/docopts'
[[ -x ${destPath} ]] && return
indicateActivity -- 'Downloading docpts' curl --output ${destPath} -fsSL ${docopts_url} || return
ensureRightAccess ${destPath}
}
function configure_system() {
lop -y h1 -- -i 'Install Utility Binaries'
local dstDir='/usr/local/bin'
ensurePathOrLogError ${dstDir} 'Could not install binaries.' || return 10
indicateActivity -- "Set sticky bit to ${dstDir} folder" chmod +t ${dstDir}
installDocopts
copyUtilityBinaries
lop -y h1 -- -i 'Install Utility Binaries'
local dstDir='/usr/local/bin'
ensurePathOrLogError ${dstDir} 'Could not install binaries.' || return 10
indicateActivity -- "Set sticky bit to ${dstDir} folder" chmod +t ${dstDir}
installDocopts
copyUtilityBinaries
}
function getExecPrerequisites() {
cmds=(
[cp]=''
[chown]=''
[chmod]=''
[curl]=''
[install]=''
)
cmds=(
[cp]=''
[chown]=''
[chmod]=''
[curl]=''
[install]=''
)
}
function getDefaultDocoptsURL() {
local fileURL="${DOCOPTS_URL:-https://github.com/astzweig/docopts/releases/download/v.0.7.0/docopts_darwin_amd64}"
print -- ${fileURL}
local fileURL="${DOCOPTS_URL:-https://github.com/astzweig/docopts/releases/download/v.0.7.0/docopts_darwin_amd64}"
print -- ${fileURL}
}
function getQuestions() {
questions=(
'i: docopts-url=From which URL shall the docopts binary be downloaded? # default:'"$(getDefaultDocoptsURL)"
)
questions=(
'i: docopts-url=From which URL shall the docopts binary be downloaded? # default:'"$(getDefaultDocoptsURL)"
)
}
function getUsage() {
read -r -d '' text <<- USAGE
read -r -d '' text <<- USAGE
Usage:
$cmdName show-questions [<modkey> <modans>]...
$cmdName [-v] [-d FILE] --docopts-url URL
Install convenient binaries for all users.
Options:
--docopts-url URL The URL from which to download the docopts binary
[default: $(getDefaultDocoptsURL)].
@@ -69,12 +69,12 @@ function getUsage() {
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
USAGE
print -- ${text}
print -- ${text}
}
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
_DIR="${0:A:h}"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
_DIR="${0:A:h}"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
fi

View File

@@ -5,48 +5,48 @@ function addLibToStartupFile() {
}
function installZshlib() {
local zshlibPath=${libDir}/astzweig_zshlib
if [[ -d ${ASTZWEIG_ZSHLIB} ]]; then
pushd -q ${ASTZWEIG_ZSHLIB}
zcompile -z -U ${zshlibPath} $(find . -type f -perm +u=x -maxdepth 1)
libs+=(${zshlibPath}.zwc)
popd -q
elif [[ -f ${ASTZWEIG_ZSHLIB} ]]; then
cp ${ASTZWEIG_ZSHLIB} ${zshlibPath}.zwc;
fi
chmod ugo=r ${zshlibPath}.zwc
local zshlibPath=${libDir}/astzweig_zshlib
if [[ -d ${ASTZWEIG_ZSHLIB} ]]; then
pushd -q ${ASTZWEIG_ZSHLIB}
zcompile -z -U ${zshlibPath} $(find . -type f -perm +u=x -maxdepth 1)
libs+=(${zshlibPath}.zwc)
popd -q
elif [[ -f ${ASTZWEIG_ZSHLIB} ]]; then
cp ${ASTZWEIG_ZSHLIB} ${zshlibPath}.zwc;
fi
chmod ugo=r ${zshlibPath}.zwc
}
function modifyGlobalFpath() {
local startupFile=/etc/zshenv
cat ${startupFile} | grep "${(q)libs}" >&! /dev/null && return
print -- "fpath+=(${(q)libs})" >> ${startupFile}
chown root:wheel ${startupFile}
chmod u=rw,go=r ${startupFile}
local startupFile=/etc/zshenv
cat ${startupFile} | grep "${(q)libs}" >&! /dev/null && return
print -- "fpath+=(${(q)libs})" >> ${startupFile}
chown root:wheel ${startupFile}
chmod u=rw,go=r ${startupFile}
}
function configure_system() {
lop -y h1 -- -i 'Install ZSh Libraries'
local libDir=/usr/local/share/zsh/site-functions
local libs=()
ensurePathOrLogError ${libDir} 'Could not install zsh libraries.' || return 10
lop -- -d "ASTZWEIG_ZSHLIB is ${ASTZWEIG_ZSHLIB}"
indicateActivity 'Install zshlib' installZshlib
indicateActivity 'Modify global fpath' modifyGlobalFpath
lop -y h1 -- -i 'Install ZSh Libraries'
local libDir=/usr/local/share/zsh/site-functions
local libs=()
ensurePathOrLogError ${libDir} 'Could not install zsh libraries.' || return 10
lop -- -d "ASTZWEIG_ZSHLIB is ${ASTZWEIG_ZSHLIB}"
indicateActivity 'Install zshlib' installZshlib
indicateActivity 'Modify global fpath' modifyGlobalFpath
}
function getExecPrerequisites() {
cmds=(
[cat]=''
[grep]=''
[chown]=''
[chmod]=''
[install]=''
)
cmds=(
[cat]=''
[grep]=''
[chown]=''
[chmod]=''
[install]=''
)
}
function getUsage() {
read -r -d '' text <<- USAGE
read -r -d '' text <<- USAGE
Usage:
$cmdName show-questions [<modkey> <modans>]...
$cmdName [-v] [-d FILE]
@@ -61,12 +61,12 @@ function getUsage() {
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
USAGE
print -- ${text}
print -- ${text}
}
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
_DIR="${0:A:h}"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
_DIR="${0:A:h}"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
fi

View File

@@ -2,41 +2,41 @@
# vi: set ft=zsh tw=80 ts=2
function installGoogleFonts() {
local fontsDir=/Library/Fonts/Google-Fonts
[[ -d ${fontsDir} ]] && return
indicateActivity 'Download Google Fonts' git clone "${git_google_fonts}" "${fontsDir}"
indicateActivity 'Fix Directory Permissions' find ${fontsDir} -type d -mindepth 1 -exec chmod g+rwx,o+rx {} \;
indicateActivity 'Fix File Permissions' find ${fontsDir} -type f -mindepth 1 -exec chmod g+rw,o+r {} \;
local fontsDir=/Library/Fonts/Google-Fonts
[[ -d ${fontsDir} ]] && return
indicateActivity 'Download Google Fonts' git clone "${git_google_fonts}" "${fontsDir}"
indicateActivity 'Fix Directory Permissions' find ${fontsDir} -type d -mindepth 1 -exec chmod g+rwx,o+rx {} \;
indicateActivity 'Fix File Permissions' find ${fontsDir} -type f -mindepth 1 -exec chmod g+rw,o+r {} \;
}
function configure_system() {
lop -y h1 -- -i 'Install Fonts'
lop -y h1 -- -i 'Install Fonts'
}
function getExecPrerequisites() {
cmds=(
[git]=''
)
cmds=(
[git]=''
)
}
function getDefaultGitGoogleFontsURL() {
print -- ${GOOGLE_FONTS_GIT_REMOTE:-https://github.com/google/fonts.git}
print -- ${GOOGLE_FONTS_GIT_REMOTE:-https://github.com/google/fonts.git}
}
function getQuestions() {
questions=(
'i: git-google-fonts=Which Git repository shall be used to install Google Fonts from? # default:'"$(getDefaultGitGoogleFontsURL)"
)
questions=(
'i: git-google-fonts=Which Git repository shall be used to install Google Fonts from? # default:'"$(getDefaultGitGoogleFontsURL)"
)
}
function getUsage() {
read -r -d '' text <<- USAGE
read -r -d '' text <<- USAGE
Usage:
$cmdName show-questions [<modkey> <modans>]...
$cmdName [-v] [-d FILE] --git-google-fonts URL
Install different fonts system wide (for all users).
Options:
--git-google-fonts URL Git URL to the Google Fonts repository [default: $(getDefaultGitGoogleFontsURL)].
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
@@ -46,12 +46,12 @@ function getUsage() {
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
USAGE
print -- ${text}
print -- ${text}
}
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
_DIR="${0:A:h}"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
_DIR="${0:A:h}"
test -f "${ASTZWEIG_MACOS_SYSTEM_LIB}" || { echo 'This module requires macos-system library. Please run again with macos-system library provieded as a path in ASTZWEIG_MACOS_SYSTEM_LIB env variable.'; return 10 }
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
module_main $0 "$@"
fi

View File

@@ -2,107 +2,107 @@
# vi: set ft=zsh tw=80 ts=2
function autoloadZShLib() {
test -d "${ASTZWEIG_ZSHLIB}" || { echo "This module needs astzweig/zshlib to work." >&2; return 99 }
FPATH="${ASTZWEIG_ZSHLIB}:${FPATH}"
fpath+=(${ASTZWEIG_ZSHLIB})
if [[ -d ${ASTZWEIG_ZSHLIB} ]]; then
local funcNames=($(find "${ASTZWEIG_ZSHLIB}" -type f -perm +u=x -maxdepth 1 | awk -F/ '{ print $NF }'))
autoload -Uz ${funcNames}
elif [[ -f ${ASTZWEIG_ZSHLIB} ]]; then
autoload -Uzw ${ASTZWEIG_ZSHLIB}
fi
test -d "${ASTZWEIG_ZSHLIB}" || { echo "This module needs astzweig/zshlib to work." >&2; return 99 }
FPATH="${ASTZWEIG_ZSHLIB}:${FPATH}"
fpath+=(${ASTZWEIG_ZSHLIB})
if [[ -d ${ASTZWEIG_ZSHLIB} ]]; then
local funcNames=($(find "${ASTZWEIG_ZSHLIB}" -type f -perm +u=x -maxdepth 1 | awk -F/ '{ print $NF }'))
autoload -Uz ${funcNames}
elif [[ -f ${ASTZWEIG_ZSHLIB} ]]; then
autoload -Uzw ${ASTZWEIG_ZSHLIB}
fi
}
function isDebug() {
test "${MACOS_SYSTEM_DEBUG}" = true -o "${MACOS_SYSTEM_DEBUG}" = 1
test "${MACOS_SYSTEM_DEBUG}" = true -o "${MACOS_SYSTEM_DEBUG}" = 1
}
function configureLogging() {
local output=tostdout level=info
[ -n "${logfile}" ] && output=${logfile}
[ "${verbose}" = true ] && level=debug
lop setoutput -l ${level} ${output}
local output=tostdout level=info
[ -n "${logfile}" ] && output=${logfile}
[ "${verbose}" = true ] && level=debug
lop setoutput -l ${level} ${output}
}
function getModuleAnswerByKeyRegEx() {
local key value
local searchRegEx=$1
for key moduleAnswer in ${modkey:^modans}; do
[[ $key =~ $searchRegEx ]] && return 0
done
return 1
local key value
local searchRegEx=$1
for key moduleAnswer in ${modkey:^modans}; do
[[ $key =~ $searchRegEx ]] && return 0
done
return 1
}
function ensurePathOrLogError() {
local dir=$1 msg=$2
[[ -d ${dir} ]] || install -m $(umask -S) -d $(getMissingPaths ${dir}) || {
lop -- -e "$msg" -e "Directory ${dir} does not exist and could not be created."
return 10
}
local dir=$1 msg=$2
[[ -d ${dir} ]] || install -m $(umask -S) -d $(getMissingPaths ${dir}) || {
lop -- -e "$msg" -e "Directory ${dir} does not exist and could not be created."
return 10
}
}
function checkHelpPrerequisites() {
local -A cmds
getHelpPrerequisites || return
checkCommands ${(k)cmds}
local -A cmds
getHelpPrerequisites || return
checkCommands ${(k)cmds}
}
function addDocoptsToCmds() {
cmds+=(docopts '(with -f option supported)')
cmds+=(docopts '(with -f option supported)')
}
function requireRootPrivileges() {
test "`id -u`" -eq 0 || { lop -- -e 'This module requires root access. Please run as root.'; return 11 }
test "`id -u`" -eq 0 || { lop -- -e 'This module requires root access. Please run as root.'; return 11 }
}
whence getHelpPrerequisites >&! /dev/null || function $_() {
addDocoptsToCmds
addDocoptsToCmds
}
function checkQuestionsPrerequisites() {
local -A cmds
getQuestionsPrerequisites || return
checkCommands ${(k)cmds}
local -A cmds
getQuestionsPrerequisites || return
checkCommands ${(k)cmds}
}
function checkExecPrerequisites() {
local -A cmds
getExecPrerequisites || return
checkCommands ${(k)cmds}
local -A cmds
getExecPrerequisites || return
checkCommands ${(k)cmds}
}
function showQuestions() {
local questions=()
getQuestions
for question in ${questions}; do
hio -- body "${question}"
done
local questions=()
getQuestions
for question in ${questions}; do
hio -- body "${question}"
done
}
function module_main() {
local cmdPath=${1} cmdName=${1:t} hookBag=()
local -A traps=()
preCommandNameHook "$@" || return
shift
autoloadZShLib || return
preHelpHook "$@" || return
checkHelpPrerequisites || return
configureLogging
trap 'traps call int; return 70' INT
trap 'traps call term; return 80' TERM
trap 'traps call exit' EXIT
eval "`getUsage $cmdName | docopts -f -V - -h - : "$@"`"
preQuestionHook "$@" || return
checkQuestionsPrerequisites || return
[ "${show_questions}" = true ] && { showQuestions; return }
preExecHook "$@" || return
checkExecPrerequisites || return
configure_system
local cmdPath=${1} cmdName=${1:t} hookBag=()
local -A traps=()
preCommandNameHook "$@" || return
shift
autoloadZShLib || return
preHelpHook "$@" || return
checkHelpPrerequisites || return
configureLogging
trap 'traps call int; return 70' INT
trap 'traps call term; return 80' TERM
trap 'traps call exit' EXIT
eval "`getUsage $cmdName | docopts -f -V - -h - : "$@"`"
preQuestionHook "$@" || return
checkQuestionsPrerequisites || return
[ "${show_questions}" = true ] && { showQuestions; return }
preExecHook "$@" || return
checkExecPrerequisites || return
configure_system
}
function {
local name
for name in preCommandNameHook preHelpHook preQuestionHook preExecHook getQuestionsPrerequisites getExecPrerequisites getQuestions getUsage; do
whence ${name} >&! /dev/null || function $_() {}
done
local name
for name in preCommandNameHook preHelpHook preQuestionHook preExecHook getQuestionsPrerequisites getExecPrerequisites getQuestions getUsage; do
whence ${name} >&! /dev/null || function $_() {}
done
}