Convert indention from spaces to tabs
This commit is contained in:
committed by
T. R. Bernstein
parent
4096da8d4d
commit
545d95bd9c
182
bootstrap.sh
182
bootstrap.sh
@@ -2,158 +2,158 @@
|
|||||||
# vi: set ft=zsh tw=80 ts=2
|
# vi: set ft=zsh tw=80 ts=2
|
||||||
|
|
||||||
function versionGT() {
|
function versionGT() {
|
||||||
[[ "${1%.*}" -gt "${2%.*}" ]] || [[ "${1%.*}" -eq "${2%.*}" && "${1#*.}" -gt "${2#*.}" ]]
|
[[ "${1%.*}" -gt "${2%.*}" ]] || [[ "${1%.*}" -eq "${2%.*}" && "${1#*.}" -gt "${2#*.}" ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
function majorMinor() {
|
function majorMinor() {
|
||||||
echo "${1%%.*}.$(x="${1#*.}" echo "${x%%.*}")"
|
echo "${1%%.*}.$(x="${1#*.}" echo "${x%%.*}")"
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldInstallCommandLineTools() {
|
function shouldInstallCommandLineTools() {
|
||||||
local macosVersion=$(majorMinor $(/usr/bin/sw_vers -productVersion))
|
local macosVersion=$(majorMinor $(/usr/bin/sw_vers -productVersion))
|
||||||
if version_gt "${macosVersion}" "10.13"
|
if version_gt "${macosVersion}" "10.13"
|
||||||
then
|
then
|
||||||
! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]]
|
! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]]
|
||||||
else
|
else
|
||||||
! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]] ||
|
! [[ -e "/Library/Developer/CommandLineTools/usr/bin/git" ]] ||
|
||||||
! [[ -e "/usr/include/iconv.h" ]]
|
! [[ -e "/usr/include/iconv.h" ]]
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeNewlines() {
|
function removeNewlines() {
|
||||||
printf "%s" "${1/"$'\n'"/}"
|
printf "%s" "${1/"$'\n'"/}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function acceptXcodeLicense() {
|
function acceptXcodeLicense() {
|
||||||
xcodebuild -license accept
|
xcodebuild -license accept
|
||||||
}
|
}
|
||||||
|
|
||||||
function installCommandLineTools() {
|
function installCommandLineTools() {
|
||||||
shouldInstallCommandLineTools || return
|
shouldInstallCommandLineTools || return
|
||||||
cltPlaceholder="/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress"
|
cltPlaceholder="/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress"
|
||||||
touch ${cltPlaceholder}
|
touch ${cltPlaceholder}
|
||||||
|
|
||||||
cltLabelCommand="/usr/sbin/softwareupdate -l |
|
cltLabelCommand="/usr/sbin/softwareupdate -l |
|
||||||
grep -B 1 -E 'Command Line Tools' |
|
grep -B 1 -E 'Command Line Tools' |
|
||||||
awk -F'*' '/^ *\\*/ {print \$2}' |
|
awk -F'*' '/^ *\\*/ {print \$2}' |
|
||||||
sed -e 's/^ *Label: //' -e 's/^ *//' |
|
sed -e 's/^ *Label: //' -e 's/^ *//' |
|
||||||
sort -V |
|
sort -V |
|
||||||
tail -n1"
|
tail -n1"
|
||||||
cltLabel="$(removeNewlines "$(/bin/bash -c "${cltLabelCommand}")")"
|
cltLabel="$(removeNewlines "$(/bin/bash -c "${cltLabelCommand}")")"
|
||||||
|
|
||||||
if [[ -n "${cltLabel}" ]]
|
if [[ -n "${cltLabel}" ]]
|
||||||
then
|
then
|
||||||
/usr/sbin/softwareupdate -i ${cltLabel}
|
/usr/sbin/softwareupdate -i ${cltLabel}
|
||||||
/usr/bin/xcode-select --switch /Library/Developer/CommandLineTools
|
/usr/bin/xcode-select --switch /Library/Developer/CommandLineTools
|
||||||
fi
|
fi
|
||||||
rm -f ${cltPlaceholder}
|
rm -f ${cltPlaceholder}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureCommandLineTools() {
|
function ensureCommandLineTools() {
|
||||||
installCommandLineTools
|
installCommandLineTools
|
||||||
acceptXcodeLicense
|
acceptXcodeLicense
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureDocopts() {
|
function ensureDocopts() {
|
||||||
which docopts > /dev/null && return
|
which docopts > /dev/null && return
|
||||||
local fileURL="${DOCOPTS_URL:-https://github.com/astzweig/docopts/releases/download/v.0.7.0/docopts_darwin_amd64}"
|
local fileURL="${DOCOPTS_URL:-https://github.com/astzweig/docopts/releases/download/v.0.7.0/docopts_darwin_amd64}"
|
||||||
curl --output ./docopts -fsSL "${fileURL}" || return
|
curl --output ./docopts -fsSL "${fileURL}" || return
|
||||||
chmod u+x ./docopts
|
chmod u+x ./docopts
|
||||||
PATH="${PATH}:`pwd`"
|
PATH="${PATH}:`pwd`"
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneMacOSSystemRepo() {
|
function cloneMacOSSystemRepo() {
|
||||||
local repoUrl="${MACOS_SYSTEM_REPO_URL:-https://github.com/astzweig/macos-system.git}"
|
local repoUrl="${MACOS_SYSTEM_REPO_URL:-https://github.com/astzweig/macos-system.git}"
|
||||||
git clone --depth 1 -q "${repoUrl}" . 2> /dev/null || return 10
|
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
|
[ -n "${MACOS_SYSTEM_REPO_BRANCH}" ] && git checkout -q ${MACOS_SYSTEM_REPO_BRANCH} 2> /dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneZSHLibRepo() {
|
function cloneZSHLibRepo() {
|
||||||
local zshlibRepoUrl="${ZSHLIB_REPO_URL:-https://github.com/astzweig/zshlib.git}"
|
local zshlibRepoUrl="${ZSHLIB_REPO_URL:-https://github.com/astzweig/zshlib.git}"
|
||||||
git config --file=.gitmodules submodule.zshlib.url "${zshlibRepoUrl}"
|
git config --file=.gitmodules submodule.zshlib.url "${zshlibRepoUrl}"
|
||||||
git submodule -q sync
|
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
|
[ -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
|
git submodule -q update --depth 1 --init --recursive --remote 2> /dev/null || return 10
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDebug() {
|
function isDebug() {
|
||||||
test "${DEBUG}" = true -o "${DEBUG}" = 1
|
test "${DEBUG}" = true -o "${DEBUG}" = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function printSuccess() {
|
function printSuccess() {
|
||||||
print "${colors[green]}${*}${colors[reset]}"
|
print "${colors[green]}${*}${colors[reset]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function printError() {
|
function printError() {
|
||||||
print "${errColors[red]}${*}${errColors[reset]}" >&2
|
print "${errColors[red]}${*}${errColors[reset]}" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
function printFailedWithError() {
|
function printFailedWithError() {
|
||||||
print "${colors[red]}failed.${colors[reset]}"
|
print "${colors[red]}failed.${colors[reset]}"
|
||||||
print "$*" >&2
|
print "$*" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
function defineColors() {
|
function defineColors() {
|
||||||
local -A colorCodes=(red "`tput setaf 9`" green "`tput setaf 10`" reset "`tput sgr0`")
|
local -A colorCodes=(red "`tput setaf 9`" green "`tput setaf 10`" reset "`tput sgr0`")
|
||||||
[ -t 1 ] && colors=("${(kv)colorCodes[@]}")
|
[ -t 1 ] && colors=("${(kv)colorCodes[@]}")
|
||||||
[ -t 2 ] && errColors=("${(kv)colorCodes[@]}")
|
[ -t 2 ] && errColors=("${(kv)colorCodes[@]}")
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureRepo() {
|
function ensureRepo() {
|
||||||
local repoName="$1" cmdName="${2}"
|
local repoName="$1" cmdName="${2}"
|
||||||
print -n "Installing ${1}..."
|
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}
|
$cmdName || { printFailedWithError "This script requires $repoName but was not able to clone it. Please ensure access to the $repoName repository."; return 10}
|
||||||
printSuccess 'done'
|
printSuccess 'done'
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureBinary() {
|
function ensureBinary() {
|
||||||
local binaryName="$1" cmdName="${2}"
|
local binaryName="$1" cmdName="${2}"
|
||||||
print -n "Ensure ${1} is installed..."
|
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}
|
$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'
|
printSuccess 'done'
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureTerminal() {
|
function configureTerminal() {
|
||||||
if [ -t 0 ]; then
|
if [ -t 0 ]; then
|
||||||
traps+=("stty $(stty -g)")
|
traps+=("stty $(stty -g)")
|
||||||
stty -echo
|
stty -echo
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -t 1 ]; then
|
if [ -t 1 ]; then
|
||||||
traps+=('tput cnorm')
|
traps+=('tput cnorm')
|
||||||
tput civis
|
tput civis
|
||||||
export TERMINAL_CURSOR_HIDDEN=true
|
export TERMINAL_CURSOR_HIDDEN=true
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
local traps=()
|
local traps=()
|
||||||
local -A colors=() errColors=()
|
local -A colors=() errColors=()
|
||||||
defineColors
|
defineColors
|
||||||
|
|
||||||
configureTerminal
|
configureTerminal
|
||||||
local tmpdir="`mktemp -d -t 'macos-system'`"
|
local tmpdir="`mktemp -d -t 'macos-system'`"
|
||||||
isDebug || traps+=("rm -fr -- '${tmpdir}'")
|
isDebug || traps+=("rm -fr -- '${tmpdir}'")
|
||||||
trap ${(j.;.)traps} INT TERM EXIT
|
trap ${(j.;.)traps} INT TERM EXIT
|
||||||
pushd -q "${tmpdir}"
|
pushd -q "${tmpdir}"
|
||||||
print -l "Working directory is: ${tmpdir}"
|
print -l "Working directory is: ${tmpdir}"
|
||||||
|
|
||||||
print 'Ensure command line tools are available.'
|
print 'Ensure command line tools are available.'
|
||||||
ensureCommandLineTools
|
ensureCommandLineTools
|
||||||
ensureRepo 'macos-system' cloneMacOSSystemRepo || return
|
ensureRepo 'macos-system' cloneMacOSSystemRepo || return
|
||||||
ensureRepo 'zshlib' cloneZSHLibRepo || return
|
ensureRepo 'zshlib' cloneZSHLibRepo || return
|
||||||
ensureBinary 'docopts' ensureDocopts || return
|
ensureBinary 'docopts' ensureDocopts || return
|
||||||
|
|
||||||
print 'Will now run the installer.'
|
print 'Will now run the installer.'
|
||||||
local -A colors=() errColors=()
|
local -A colors=() errColors=()
|
||||||
[ -t 1 ] && tput cnorm
|
[ -t 1 ] && tput cnorm
|
||||||
isDebug && export MACOS_SYSTEM_DEBUG=true
|
isDebug && export MACOS_SYSTEM_DEBUG=true
|
||||||
"${tmpdir}/install.sh" "$@"
|
"${tmpdir}/install.sh" "$@"
|
||||||
[ -t 1 ] && tput civis
|
[ -t 1 ] && tput civis
|
||||||
popd -q
|
popd -q
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel || "${ZSH_EVAL_CONTEXT}" == cmdarg ]]; then
|
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel || "${ZSH_EVAL_CONTEXT}" == cmdarg ]]; then
|
||||||
_DIR="${0:A:h}"
|
_DIR="${0:A:h}"
|
||||||
main "$@"
|
main "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
175
install.sh
175
install.sh
@@ -2,106 +2,105 @@
|
|||||||
# vi: set ft=zsh tw=80 ts=2
|
# vi: set ft=zsh tw=80 ts=2
|
||||||
|
|
||||||
runModule() {
|
runModule() {
|
||||||
"$@"
|
"$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
function askNecessaryQuestions() {
|
function askNecessaryQuestions() {
|
||||||
local mod= configArgs=()
|
local mod= configArgs=()
|
||||||
config setappname "de.astzweig.macos.system-setup"
|
config setappname "de.astzweig.macos.system-setup"
|
||||||
if [ -n "${config_only}" ]; then
|
if [ -n "${config_only}" ]; then
|
||||||
lop -- -d "Config only option given with value:" -d "${config_only}"
|
lop -- -d "Config only option given with value:" -d "${config_only}"
|
||||||
config setconfigfile "${config_only}"
|
config setconfigfile "${config_only}"
|
||||||
elif [ -n "${config}" ]; then
|
elif [ -n "${config}" ]; then
|
||||||
config setconfigfile "${config}"
|
config setconfigfile "${config}"
|
||||||
configArgs=(-x)
|
configArgs=(-x)
|
||||||
fi
|
fi
|
||||||
askUserModuleQuestions ${configArgs} -c config -v moduleAnswers ${modulesToInstall}
|
askUserModuleQuestions ${configArgs} -c config -v moduleAnswers ${modulesToInstall}
|
||||||
}
|
}
|
||||||
|
|
||||||
function printModulesToInstall() {
|
function printModulesToInstall() {
|
||||||
lop -- -d 'Modules that will install are:' -d "${modulesToInstall}"
|
lop -- -d 'Modules that will install are:' -d "${modulesToInstall}"
|
||||||
for mod in "${modulesToInstall[@]}"; do
|
for mod in "${modulesToInstall[@]}"; do
|
||||||
print "${mod}"
|
print "${mod}"
|
||||||
done | abbreviatePaths
|
done | abbreviatePaths
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateModuleOptions() {
|
function generateModuleOptions() {
|
||||||
local value answerKey optionKey argName
|
local value answerKey optionKey argName
|
||||||
for answerKey in ${(k)moduleAnswers}; do
|
for answerKey in ${(k)moduleAnswers}; do
|
||||||
[[ ${answerKey} = ${mod}_* ]] || continue
|
[[ ${answerKey} = ${mod}_* ]] || continue
|
||||||
optionKey="${answerKey#${mod}_}"
|
optionKey="${answerKey#${mod}_}"
|
||||||
argName=${optionKey//_/-};
|
argName=${optionKey//_/-};
|
||||||
value="${moduleAnswers[${answerKey}]}"
|
value="${moduleAnswers[${answerKey}]}"
|
||||||
if [[ "${optionKey}" =~ ^[[:alpha:]]$ ]]; then
|
if [[ "${optionKey}" =~ ^[[:alpha:]]$ ]]; then
|
||||||
moduleOptions+=("-${argName}" "${value}")
|
moduleOptions+=("-${argName}" "${value}")
|
||||||
elif [[ "${optionKey}" =~ ^[[:alpha:]][-[:alpha:]]+$ ]]; then
|
elif [[ "${optionKey}" =~ ^[[:alpha:]][-[:alpha:]]+$ ]]; then
|
||||||
moduleOptions+=("--${argName}" "${value}")
|
moduleOptions+=("--${argName}" "${value}")
|
||||||
else
|
else
|
||||||
moduleOptions+=("${argName}" "${value}")
|
moduleOptions+=("${argName}" "${value}")
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterPasswordOptions() {
|
function filterPasswordOptions() {
|
||||||
local opt= hide=false
|
local opt= hide=false
|
||||||
for opt in ${moduleOptions}; do
|
for opt in ${moduleOptions}; do
|
||||||
[[ ${hide} = true ]] && { opt='******'; hide=false }
|
[[ ${hide} = true ]] && { opt='******'; hide=false }
|
||||||
[[ $opt =~ ^--?.*password ]] && hide=true
|
[[ $opt =~ ^--?.*password ]] && hide=true
|
||||||
filteredOptions+=($opt)
|
filteredOptions+=($opt)
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function installModules() {
|
function installModules() {
|
||||||
local mod moduleOptions filteredOptions
|
local mod moduleOptions filteredOptions
|
||||||
for mod in ${modulesToInstall}; do
|
for mod in ${modulesToInstall}; do
|
||||||
moduleOptions=()
|
moduleOptions=()
|
||||||
filteredOptions=()
|
filteredOptions=()
|
||||||
generateModuleOptions
|
generateModuleOptions
|
||||||
filterPasswordOptions
|
filterPasswordOptions
|
||||||
[[ "${verbose}" == true ]] && moduleOptions+=(-v)
|
[[ "${verbose}" == true ]] && moduleOptions+=(-v)
|
||||||
[[ -n ${logfile} ]] && moduleOptions+=(-d ${logfile})
|
[[ -n ${logfile} ]] && moduleOptions+=(-d ${logfile})
|
||||||
[[ -n ${noninteractive} ]] && moduleOptions+=(--noninteractive)
|
lop -- -d "Running ${mod}" -d "with ${#moduleOptions} args:" -d "${filteredOptions}"
|
||||||
lop -- -d "Running ${mod}" -d "with ${#moduleOptions} args:" -d "${filteredOptions}"
|
runModule ${mod} ${moduleOptions}
|
||||||
runModule ${mod} ${moduleOptions}
|
done
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMacOS() {
|
function isMacOS() {
|
||||||
autoload is-at-least
|
autoload is-at-least
|
||||||
[ "`uname -s`" = Darwin ] || return
|
[ "`uname -s`" = Darwin ] || return
|
||||||
is-at-least "10.13" "`sw_vers -productVersion 2> /dev/null`"
|
is-at-least "10.13" "`sw_vers -productVersion 2> /dev/null`"
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPlistBuddyInstalled() {
|
function isPlistBuddyInstalled() {
|
||||||
test -x /usr/libexec/PlistBuddy && return
|
test -x /usr/libexec/PlistBuddy && return
|
||||||
which PlistBuddy >&! /dev/null && return
|
which PlistBuddy >&! /dev/null && return
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkPrerequisites() {
|
function checkPrerequisites() {
|
||||||
isMacOS || { lop -- -e 'This setup is only for macOS 10.13 and up.'; return 10 }
|
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 }
|
isPlistBuddyInstalled || { lop -- -e 'This setup requires PlistBuddy to be either at /usr/libexec or in any of the PATH directories.'; return 11 }
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureTerminal() {
|
function configureTerminal() {
|
||||||
if [ -t 0 ]; then
|
if [ -t 0 ]; then
|
||||||
traps+=("stty $(stty -g)")
|
traps+=("stty $(stty -g)")
|
||||||
stty -echo
|
stty -echo
|
||||||
fi
|
fi
|
||||||
if [ -t 1 ]; then
|
if [ -t 1 ]; then
|
||||||
traps+=('tput cnorm')
|
traps+=('tput cnorm')
|
||||||
tput civis
|
tput civis
|
||||||
export TERMINAL_CURSOR_HIDDEN=true
|
export TERMINAL_CURSOR_HIDDEN=true
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
local traps=()
|
local traps=()
|
||||||
configureTerminal
|
configureTerminal
|
||||||
trap ${(j.;.)traps} INT TERM EXIT
|
trap ${(j.;.)traps} INT TERM EXIT
|
||||||
autoloadZShLib || return
|
autoloadZShLib || return
|
||||||
checkPrerequisites || return
|
checkPrerequisites || return
|
||||||
eval "`docopts -f -V - -h - : "$@" <<- USAGE
|
eval "`docopts -f -V - -h - : "$@" <<- USAGE
|
||||||
Usage: $0 [options] [-m PATH]... [<module>...]
|
Usage: $0 [options] [-m PATH]... [<module>...]
|
||||||
|
|
||||||
Install all modules in module search path. If any <module> arg is given,
|
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
|
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
||||||
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
||||||
USAGE`"
|
USAGE`"
|
||||||
local allModules=() modulesToInstall=()
|
local allModules=() modulesToInstall=()
|
||||||
local -A moduleAnswers
|
local -A moduleAnswers
|
||||||
configureLogging
|
configureLogging
|
||||||
lop -- -d "Current working dir is: `pwd`"
|
lop -- -d "Current working dir is: `pwd`"
|
||||||
lop -- -d "Called main with $# args: $*"
|
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")
|
modpath+=("${_DIR}/modules")
|
||||||
loadModules -v modulesToInstall ${$(echo -m):^^modpath} "${module[@]}"
|
loadModules -v modulesToInstall ${$(echo -m):^^modpath} "${module[@]}"
|
||||||
[ "${list}" = true ] && printModulesToInstall
|
[ "${list}" = true ] && printModulesToInstall
|
||||||
|
|
||||||
askNecessaryQuestions
|
askNecessaryQuestions
|
||||||
[ -z "${config_only}" ] || return 0
|
[ -z "${config_only}" ] || return 0
|
||||||
requireRootPrivileges
|
requireRootPrivileges
|
||||||
installModules
|
installModules
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
||||||
_DIR="${0:A:h}"
|
_DIR="${0:A:h}"
|
||||||
export ASTZWEIG_MACOS_SYSTEM_LIB=${_DIR}/modules/lib.sh
|
export ASTZWEIG_MACOS_SYSTEM_LIB=${_DIR}/modules/lib.sh
|
||||||
export ASTZWEIG_ZSHLIB=${_DIR}/zshlib
|
export ASTZWEIG_ZSHLIB=${_DIR}/zshlib
|
||||||
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
|
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
|
||||||
main "$@"
|
main "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -2,32 +2,32 @@
|
|||||||
# vi: set ft=zsh tw=80 ts=2
|
# vi: set ft=zsh tw=80 ts=2
|
||||||
|
|
||||||
function getQuestionsPrerequisites() {
|
function getQuestionsPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[systemsetup]=''
|
[systemsetup]=''
|
||||||
)
|
)
|
||||||
requireRootPrivileges
|
requireRootPrivileges
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExecPrerequisites() {
|
function getExecPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[osascript]=''
|
[osascript]=''
|
||||||
[scutil]=''
|
[scutil]=''
|
||||||
[systemsetup]=''
|
[systemsetup]=''
|
||||||
[nvram]=''
|
[nvram]=''
|
||||||
[pmset]=''
|
[pmset]=''
|
||||||
[defaults]=''
|
[defaults]=''
|
||||||
[/usr/libexec/ApplicationFirewall/socketfilterfw]=''
|
[/usr/libexec/ApplicationFirewall/socketfilterfw]=''
|
||||||
[launchctl]=''
|
[launchctl]=''
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getQuestions() {
|
function getQuestions() {
|
||||||
local timezones
|
local timezones
|
||||||
timezones="`systemsetup -listtimezones | tail -n +2 | awk '{print $1}' | paste -sd, -`"
|
timezones="`systemsetup -listtimezones | tail -n +2 | awk '{print $1}' | paste -sd, -`"
|
||||||
questions=(
|
questions=(
|
||||||
'i: hostname=What shall the hostname of this host be?'
|
'i: hostname=What shall the hostname of this host be?'
|
||||||
's: timezone=What shall the timezone of this host be? # choose from:'"${timezones};"
|
's: timezone=What shall the timezone of this host be? # choose from:'"${timezones};"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function quitSystemPreferences() {
|
function quitSystemPreferences() {
|
||||||
@@ -35,84 +35,84 @@ function quitSystemPreferences() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setComputerName() {
|
function setComputerName() {
|
||||||
scutil --set ComputerName "${hostname}"
|
scutil --set ComputerName "${hostname}"
|
||||||
scutil --set HostName "${hostname}"
|
scutil --set HostName "${hostname}"
|
||||||
scutil --set LocalHostName "${hostname}"
|
scutil --set LocalHostName "${hostname}"
|
||||||
systemsetup -setcomputername "${hostname}"
|
systemsetup -setcomputername "${hostname}"
|
||||||
systemsetup -setlocalsubnetname "${hostname}"
|
systemsetup -setlocalsubnetname "${hostname}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureComputerHostname() {
|
function configureComputerHostname() {
|
||||||
local currentComputerName="`scutil --get ComputerName`"
|
local currentComputerName="`scutil --get ComputerName`"
|
||||||
if [[ "${currentComputerName}" != "${hostname}" ]]; then
|
if [[ "${currentComputerName}" != "${hostname}" ]]; then
|
||||||
lop -- -i 'Hostname of computer has not been set.' -i "Will set to ${hostname}."
|
lop -- -i 'Hostname of computer has not been set.' -i "Will set to ${hostname}."
|
||||||
indicateActivity -- 'Set computer name' setComputerName
|
indicateActivity -- 'Set computer name' setComputerName
|
||||||
else
|
else
|
||||||
lop -- -i 'Hostname of computer seems to have already been set. Skipping.' -i "Hostname: $currentComputerName"
|
lop -- -i 'Hostname of computer seems to have already been set. Skipping.' -i "Hostname: $currentComputerName"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureBasicSystem(){
|
function configureBasicSystem(){
|
||||||
# Disable the sound effects on boot
|
# Disable the sound effects on boot
|
||||||
nvram SystemAudioVolume=" "
|
nvram SystemAudioVolume=" "
|
||||||
|
|
||||||
systemsetup -settimezone "${timezone}" >&! /dev/null
|
systemsetup -settimezone "${timezone}" >&! /dev/null
|
||||||
systemsetup -setusingnetworktime on >&! /dev/null
|
systemsetup -setusingnetworktime on >&! /dev/null
|
||||||
systemsetup -setnetworktimeserver 'time.apple.com' >&! /dev/null
|
systemsetup -setnetworktimeserver 'time.apple.com' >&! /dev/null
|
||||||
systemsetup -setsleep never >&! /dev/null
|
systemsetup -setsleep never >&! /dev/null
|
||||||
systemsetup -setwakeonnetworkaccess off >&! /dev/null
|
systemsetup -setwakeonnetworkaccess off >&! /dev/null
|
||||||
systemsetup -setrestartfreeze on >&! /dev/null
|
systemsetup -setrestartfreeze on >&! /dev/null
|
||||||
systemsetup -f -setremotelogin off >&! /dev/null
|
systemsetup -f -setremotelogin off >&! /dev/null
|
||||||
systemsetup -setremoteappleevents off >&! /dev/null
|
systemsetup -setremoteappleevents off >&! /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
function configurePowerManagement() {
|
function configurePowerManagement() {
|
||||||
cmd=(pmset -a)
|
cmd=(pmset -a)
|
||||||
${cmd} displaysleep 0
|
${cmd} displaysleep 0
|
||||||
${cmd} disksleep 0
|
${cmd} disksleep 0
|
||||||
${cmd} sleep 0
|
${cmd} sleep 0
|
||||||
${cmd} womp 0
|
${cmd} womp 0
|
||||||
${cmd} acwake 0
|
${cmd} acwake 0
|
||||||
${cmd} proximitywake 0
|
${cmd} proximitywake 0
|
||||||
${cmd} destroyfvkeyonstandby 1
|
${cmd} destroyfvkeyonstandby 1
|
||||||
pmset -b acwake 1
|
pmset -b acwake 1
|
||||||
${cmd} lidwake 1
|
${cmd} lidwake 1
|
||||||
${cmd} halfdim 1
|
${cmd} halfdim 1
|
||||||
${cmd} powernap 1
|
${cmd} powernap 1
|
||||||
${cmd} hibernatemode 0
|
${cmd} hibernatemode 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureLoginWindow() {
|
function configureLoginWindow() {
|
||||||
cmd=(defaults write '/Library/Preferences/com.apple.loginwindow')
|
cmd=(defaults write '/Library/Preferences/com.apple.loginwindow')
|
||||||
${cmd} DisableFDEAutoLogin -bool true
|
${cmd} DisableFDEAutoLogin -bool true
|
||||||
${cmd} SHOWFULLNAME -bool true
|
${cmd} SHOWFULLNAME -bool true
|
||||||
${cmd} AdminHostInfo -string HostName
|
${cmd} AdminHostInfo -string HostName
|
||||||
${cmd} GuestEnabled -bool false
|
${cmd} GuestEnabled -bool false
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureMacOSFirewall() {
|
function configureMacOSFirewall() {
|
||||||
cmd=(/usr/libexec/ApplicationFirewall/socketfilterfw)
|
cmd=(/usr/libexec/ApplicationFirewall/socketfilterfw)
|
||||||
${cmd} --setglobalstate on
|
${cmd} --setglobalstate on
|
||||||
${cmd} --setblockall off
|
${cmd} --setblockall off
|
||||||
${cmd} --setstealthmode on
|
${cmd} --setstealthmode on
|
||||||
${cmd} --setallowsigned on
|
${cmd} --setallowsigned on
|
||||||
${cmd} --setallowsignedapp on
|
${cmd} --setallowsignedapp on
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure_system() {
|
function configure_system() {
|
||||||
lop -y h1 -- -i 'Configure System Settings'
|
lop -y h1 -- -i 'Configure System Settings'
|
||||||
quitSystemPreferences
|
quitSystemPreferences
|
||||||
configureComputerHostname
|
configureComputerHostname
|
||||||
indicateActivity -- 'Configuring systemsetup and nvram' configureBasicSystem
|
indicateActivity -- 'Configuring systemsetup and nvram' configureBasicSystem
|
||||||
indicateActivity -- 'Configuring power management' configurePowerManagement
|
indicateActivity -- 'Configuring power management' configurePowerManagement
|
||||||
indicateActivity -- 'Configuring login window' configureLoginWindow
|
indicateActivity -- 'Configuring login window' configureLoginWindow
|
||||||
indicateActivity -- 'Configure global umask' launchctl config user umask 027
|
indicateActivity -- 'Configure global umask' launchctl config user umask 027
|
||||||
indicateActivity -- 'Configure macOS firewall' configureMacOSFirewall
|
indicateActivity -- 'Configure macOS firewall' configureMacOSFirewall
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsage() {
|
function getUsage() {
|
||||||
local cmdName=$1 text=''
|
local cmdName=$1 text=''
|
||||||
read -r -d '' text <<- USAGE
|
read -r -d '' text <<- USAGE
|
||||||
Usage:
|
Usage:
|
||||||
$cmdName show-questions [<modkey> <modans>]...
|
$cmdName show-questions [<modkey> <modans>]...
|
||||||
$cmdName [-v] [-d FILE] --hostname NAME --timezone ZONE
|
$cmdName [-v] [-d FILE] --hostname NAME --timezone ZONE
|
||||||
@@ -120,8 +120,8 @@ function getUsage() {
|
|||||||
Set energy, basic network and host preferences.
|
Set energy, basic network and host preferences.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--hostname NAME Set NAME as current host's host name.
|
--hostname NAME Set NAME as current host's host name.
|
||||||
--timezone ZONE Set ZONE as current host's timezone [default: Europe/Berlin].
|
--timezone ZONE Set ZONE as current host's timezone [default: Europe/Berlin].
|
||||||
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
|
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
|
||||||
-v, --verbose Be more verbose.
|
-v, --verbose Be more verbose.
|
||||||
----
|
----
|
||||||
@@ -129,11 +129,11 @@ function getUsage() {
|
|||||||
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
||||||
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
||||||
USAGE
|
USAGE
|
||||||
print -- ${text}
|
print -- ${text}
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
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 }
|
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}"
|
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
|
||||||
module_main $0 "$@"
|
module_main $0 "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -2,138 +2,138 @@
|
|||||||
# vi: set ft=zsh tw=80 ts=2
|
# vi: set ft=zsh tw=80 ts=2
|
||||||
|
|
||||||
function getComputerName() {
|
function getComputerName() {
|
||||||
local moduleAnswer
|
local moduleAnswer
|
||||||
local computerName="`scutil --get ComputerName 2> /dev/null`"
|
local computerName="`scutil --get ComputerName 2> /dev/null`"
|
||||||
getModuleAnswerByKeyRegEx '_hostname$' && computerName=$moduleAnswer
|
getModuleAnswerByKeyRegEx '_hostname$' && computerName=$moduleAnswer
|
||||||
print -- $computerName
|
print -- $computerName
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultFullname() {
|
function getDefaultFullname() {
|
||||||
local computerName="`getComputerName`"
|
local computerName="`getComputerName`"
|
||||||
lop -- -d 'Default full name based on current computer name is:' -d "$computerName"
|
lop -- -d 'Default full name based on current computer name is:' -d "$computerName"
|
||||||
print "${computerName}"
|
print "${computerName}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultUsername() {
|
function getDefaultUsername() {
|
||||||
local username="`getDefaultFullname | tr '[:upper:]' '[:lower:]' | tr -C '[:alnum:]\n' '-'`"
|
local username="`getDefaultFullname | tr '[:upper:]' '[:lower:]' | tr -C '[:alnum:]\n' '-'`"
|
||||||
lop -- -d 'Default username based on current computer name is:' -d "$username"
|
lop -- -d 'Default username based on current computer name is:' -d "$username"
|
||||||
print "${username}"
|
print "${username}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAPFSFilesystem() {
|
function isAPFSFilesystem() {
|
||||||
[[ $(diskutil info / | awk 'sub(/File System Personality: /,""){print $0}') = *APFS* ]]
|
[[ $(diskutil info / | awk 'sub(/File System Personality: /,""){print $0}') = *APFS* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsersWithSecureToken() {
|
function getUsersWithSecureToken() {
|
||||||
local username uuid
|
local username uuid
|
||||||
for uuid in ${$(diskutil apfs listUsers / | awk '/\+\-\-/ {print $2}')}; do
|
for uuid in ${$(diskutil apfs listUsers / | awk '/\+\-\-/ {print $2}')}; do
|
||||||
username="$(dscl . -search /Users GeneratedUID ${uuid} | awk 'NR==1{print $1}')"
|
username="$(dscl . -search /Users GeneratedUID ${uuid} | awk 'NR==1{print $1}')"
|
||||||
checkSecureTokenForUser ${username} && secureTokenUsers+=("${username}")
|
checkSecureTokenForUser ${username} && secureTokenUsers+=("${username}")
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultUserPictures() {
|
function getDefaultUserPictures() {
|
||||||
pushd -q '/Library/User Pictures'
|
pushd -q '/Library/User Pictures'
|
||||||
defaultUserPictures=("${(@f)$(find -E . -type f -iregex '.*\.(tif|png|jpeg|jpg)' | abbreviatePaths)}")
|
defaultUserPictures=("${(@f)$(find -E . -type f -iregex '.*\.(tif|png|jpeg|jpg)' | abbreviatePaths)}")
|
||||||
popd -q
|
popd -q
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertPathToDefaultPicture() {
|
function convertPathToDefaultPicture() {
|
||||||
local resolved=''
|
local resolved=''
|
||||||
lop -- -d 'Converting path' -d "${filevault_picture}" -d 'to default picture path if necessary.'
|
lop -- -d 'Converting path' -d "${filevault_picture}" -d 'to default picture path if necessary.'
|
||||||
if [ -r "${filevault_picture}" ]; then
|
if [ -r "${filevault_picture}" ]; then
|
||||||
lop -- -d 'Path seems to be a valid path already. Skipping conversion.'
|
lop -- -d 'Path seems to be a valid path already. Skipping conversion.'
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
pushd -q '/Library/User Pictures'
|
pushd -q '/Library/User Pictures'
|
||||||
resolved="`find "$_" -type f -path "*${filevault_picture}" 2> /dev/null`"
|
resolved="`find "$_" -type f -path "*${filevault_picture}" 2> /dev/null`"
|
||||||
lop -- -d 'Resolved path is' -d "${resolved}"
|
lop -- -d 'Resolved path is' -d "${resolved}"
|
||||||
popd -q
|
popd -q
|
||||||
[ -n "${resolved}" -a -r "${resolved}" ] && filevault_picture="${resolved}"
|
[ -n "${resolved}" -a -r "${resolved}" ] && filevault_picture="${resolved}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function _isPathToPicture() {
|
function _isPathToPicture() {
|
||||||
local filevault_picture=$1
|
local filevault_picture=$1
|
||||||
convertPathToDefaultPicture
|
convertPathToDefaultPicture
|
||||||
[ -r "${filevault_picture}" ] || { lop -- -d 'Resolved path is not a valid path. Returning.'; return 10 }
|
[ -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
|
[[ "${filevault_picture:e:l}" =~ (tif|png|jpeg|jpg) ]] || return 11
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPathToPicture() {
|
function isPathToPicture() {
|
||||||
indicateActivity -- "Verifying $1 as picture path" _isPathToPicture $1
|
indicateActivity -- "Verifying $1 as picture path" _isPathToPicture $1
|
||||||
}
|
}
|
||||||
|
|
||||||
function _checkSecureTokenForUser() {
|
function _checkSecureTokenForUser() {
|
||||||
local u=$1
|
local u=$1
|
||||||
sysadminctl -secureTokenStatus "${u}" 2>&1 | grep ENABLED >&! /dev/null
|
sysadminctl -secureTokenStatus "${u}" 2>&1 | grep ENABLED >&! /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSecureTokenForUser() {
|
function checkSecureTokenForUser() {
|
||||||
local u=$1
|
local u=$1
|
||||||
indicateActivity -- "Checking if user $u has a secure token set" _checkSecureTokenForUser $u
|
indicateActivity -- "Checking if user $u has a secure token set" _checkSecureTokenForUser $u
|
||||||
}
|
}
|
||||||
|
|
||||||
function _checkUserPassword() {
|
function _checkUserPassword() {
|
||||||
local username=$1 password=$2
|
local username=$1 password=$2
|
||||||
dscl . -authonly ${username} ${password} >&! /dev/null
|
dscl . -authonly ${username} ${password} >&! /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSecureTokenUserPassword() {
|
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() {
|
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() {
|
function _doesFileVaultUserExist() {
|
||||||
dscl . -list /Users | grep "${filevault_username}" >&! /dev/null
|
dscl . -list /Users | grep "${filevault_username}" >&! /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
function doesFileVaultUserExist() {
|
function doesFileVaultUserExist() {
|
||||||
indicateActivity -- "Checking if ${filevault_username} already exists" _doesFileVaultUserExist
|
indicateActivity -- "Checking if ${filevault_username} already exists" _doesFileVaultUserExist
|
||||||
}
|
}
|
||||||
|
|
||||||
function _createFileVaultUser() {
|
function _createFileVaultUser() {
|
||||||
local un=${filevault_username} fn=${filevault_fullname} pw=${filevault_password} result=
|
local un=${filevault_username} fn=${filevault_fullname} pw=${filevault_password} result=
|
||||||
lop -- -d 'Creating FileVault user' -d "${un}"
|
lop -- -d 'Creating FileVault user' -d "${un}"
|
||||||
sysadminctl -addUser ${un} -fullName ${fn} -shell /usr/bin/false -home /var/empty -password ${pw} -picture ${filevault_picture}
|
sysadminctl -addUser ${un} -fullName ${fn} -shell /usr/bin/false -home /var/empty -password ${pw} -picture ${filevault_picture}
|
||||||
result=$?
|
result=$?
|
||||||
lop -- -d 'Return value of sysadminctl is ' -d "$?"
|
lop -- -d 'Return value of sysadminctl is ' -d "$?"
|
||||||
return $result
|
return $result
|
||||||
}
|
}
|
||||||
|
|
||||||
function createFileVaultUser() {
|
function createFileVaultUser() {
|
||||||
indicateActivity -- "Creating FileVault user ${filevault_username}" _createFileVaultUser
|
indicateActivity -- "Creating FileVault user ${filevault_username}" _createFileVaultUser
|
||||||
}
|
}
|
||||||
|
|
||||||
function _configureFileVaultUser() {
|
function _configureFileVaultUser() {
|
||||||
local un=${filevault_username}
|
local un=${filevault_username}
|
||||||
dscl . -create "/Users/${un}" IsHidden 1
|
dscl . -create "/Users/${un}" IsHidden 1
|
||||||
chsh -s /usr/bin/false "${un}" >&! /dev/null
|
chsh -s /usr/bin/false "${un}" >&! /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureFileVaultUser() {
|
function configureFileVaultUser() {
|
||||||
indicateActivity -- "Configuring FileVault user ${filevault_username}" _configureFileVaultUser
|
indicateActivity -- "Configuring FileVault user ${filevault_username}" _configureFileVaultUser
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureSecureToken() {
|
function configureSecureToken() {
|
||||||
local un=${filevault_username} up=${filevault_password}
|
local un=${filevault_username} up=${filevault_password}
|
||||||
local stun=${secure_token_user_username} stup=${secure_token_user_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}"
|
indicateActivity -- "Enable secure token for ${un}" sysadminctl -secureTokenOn "${un}" -password "${up}" -adminUser "${stun}" -adminPassword "${stup}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function canUserUnlockDisk() {
|
function canUserUnlockDisk() {
|
||||||
local username=$1
|
local username=$1
|
||||||
for fdeuser in ${(f)"$(fdesetup list | cut -d',' -f1)"}; do
|
for fdeuser in ${(f)"$(fdesetup list | cut -d',' -f1)"}; do
|
||||||
[[ ${fdeuser} = ${username} ]] && return
|
[[ ${fdeuser} = ${username} ]] && return
|
||||||
done
|
done
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFDESetupXMLForUser() {
|
function getFDESetupXMLForUser() {
|
||||||
local username="${1}" password="${2}"
|
local username="${1}" password="${2}"
|
||||||
cat <<- XML
|
cat <<- XML
|
||||||
<?xml version="1.0" encoding=\"UTF-8\"?>
|
<?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\">
|
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
|
||||||
<plist version=\"1.0\">
|
<plist version=\"1.0\">
|
||||||
@@ -148,120 +148,120 @@ function getFDESetupXMLForUser() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _enableFileVaultForSecureTokenUser() {
|
function _enableFileVaultForSecureTokenUser() {
|
||||||
local username="${1}" password="${2}"
|
local username="${1}" password="${2}"
|
||||||
getFDESetupXMLForUser "${username}" "${password}" | fdesetup enable -inputplist
|
getFDESetupXMLForUser "${username}" "${password}" | fdesetup enable -inputplist
|
||||||
}
|
}
|
||||||
|
|
||||||
function enableFileVaultForSecureTokenUser() {
|
function enableFileVaultForSecureTokenUser() {
|
||||||
fdesetup isactive >&! /dev/null && return
|
fdesetup isactive >&! /dev/null && return
|
||||||
indicateActivity -- "Enable FileVault for secure token" _enableFileVaultForSecureTokenUser ${secure_token_user_username} ${secure_token_user_password}
|
indicateActivity -- "Enable FileVault for secure token" _enableFileVaultForSecureTokenUser ${secure_token_user_username} ${secure_token_user_password}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _allowUserToUnlockDisk() {
|
function _allowUserToUnlockDisk() {
|
||||||
local username="${1}" password="${2}"
|
local username="${1}" password="${2}"
|
||||||
getFDESetupXMLForUser ${username} ${password} | fdesetup add -inputplist
|
getFDESetupXMLForUser ${username} ${password} | fdesetup add -inputplist
|
||||||
}
|
}
|
||||||
|
|
||||||
function allowFileVaultUserToUnlockDisk() {
|
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() {
|
function _allowOnlyFileVaultUserToUnlock() {
|
||||||
local fdeuser
|
local fdeuser
|
||||||
for fdeuser in ${(f)"$(fdesetup list | cut -d',' -f1)"}; do
|
for fdeuser in ${(f)"$(fdesetup list | cut -d',' -f1)"}; do
|
||||||
[[ ${fdeuser} != ${filevault_username} ]] && fdesetup remove -user "${fdeuser}"
|
[[ ${fdeuser} != ${filevault_username} ]] && fdesetup remove -user "${fdeuser}"
|
||||||
done
|
done
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function allowOnlyFileVaultUserToUnlock() {
|
function allowOnlyFileVaultUserToUnlock() {
|
||||||
indicateActivity -- "Disallow everyone else from unlocking disk" _allowOnlyFileVaultUserToUnlock
|
indicateActivity -- "Disallow everyone else from unlocking disk" _allowOnlyFileVaultUserToUnlock
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure_system() {
|
function configure_system() {
|
||||||
lop -y h1 -- -i 'Setup FileVault 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 }
|
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 }
|
checkSecureTokenUserPassword || { lop -- -e 'The secure token user password is incorrect.'; return 11 }
|
||||||
indicateActivity -- "Resolving path of picture ${filevault_picture}" convertPathToDefaultPicture
|
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 }
|
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
|
if doesFileVaultUserExist; then
|
||||||
checkFileVaultUserPassword || { lop -- -e 'The FileVault user password is incorrect.'; return 13 }
|
checkFileVaultUserPassword || { lop -- -e 'The FileVault user password is incorrect.'; return 13 }
|
||||||
else
|
else
|
||||||
createFileVaultUser || { lop -- -e 'Was not able to create FileVault user.'; return 14 }
|
createFileVaultUser || { lop -- -e 'Was not able to create FileVault user.'; return 14 }
|
||||||
fi
|
fi
|
||||||
configureFileVaultUser || { lop -- -e 'Could not configure FileVault user.'; return 15 }
|
configureFileVaultUser || { lop -- -e 'Could not configure FileVault user.'; return 15 }
|
||||||
enableFileVaultForSecureTokenUser || { lop -- -e 'Could not enable FileVault for secure token user.'; return 16 }
|
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 }
|
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 }
|
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 }
|
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 }
|
indicateActivity -- 'Update APFS preboot volume' diskutil apfs updatePreboot / || { lop -- -e 'Was not able to update APFS preboot volume.'; return 20 }
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHelpPrerequisites() {
|
function getHelpPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[tr]=''
|
[tr]=''
|
||||||
[scutil]=''
|
[scutil]=''
|
||||||
)
|
)
|
||||||
addDocoptsToCmds
|
addDocoptsToCmds
|
||||||
}
|
}
|
||||||
|
|
||||||
function getQuestionsPrerequisites() {
|
function getQuestionsPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[find]=''
|
[find]=''
|
||||||
[dscl]=''
|
[dscl]=''
|
||||||
[dseditgroup]=''
|
[dseditgroup]=''
|
||||||
[awk]=''
|
[awk]=''
|
||||||
[diskutil]=''
|
[diskutil]=''
|
||||||
[sysadminctl]=''
|
[sysadminctl]=''
|
||||||
)
|
)
|
||||||
isAPFSFilesystem || { lop -- -e 'This module requires an APFS filesystem.'; return 10 }
|
isAPFSFilesystem || { lop -- -e 'This module requires an APFS filesystem.'; return 10 }
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExecPrerequisites() {
|
function getExecPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[cut]=''
|
[cut]=''
|
||||||
[cat]=''
|
[cat]=''
|
||||||
[fdesetup]=''
|
[fdesetup]=''
|
||||||
[base64]=''
|
[base64]=''
|
||||||
[dsimport]=''
|
[dsimport]=''
|
||||||
)
|
)
|
||||||
requireRootPrivileges
|
requireRootPrivileges
|
||||||
}
|
}
|
||||||
|
|
||||||
function getQuestions() {
|
function getQuestions() {
|
||||||
local secureTokenUsers=() defaultUserPictures=()
|
local secureTokenUsers=() defaultUserPictures=()
|
||||||
local defaultUsername="`getDefaultUsername`" defaultFullname="`getDefaultFullname`"
|
local defaultUsername="`getDefaultUsername`" defaultFullname="`getDefaultFullname`"
|
||||||
getUsersWithSecureToken
|
getUsersWithSecureToken
|
||||||
getDefaultUserPictures
|
getDefaultUserPictures
|
||||||
local defaultUsernameHint= defaultFullnameHint=
|
local defaultUsernameHint= defaultFullnameHint=
|
||||||
[ -n "${defaultUsername}" ] && defaultUsernameHint="default:${defaultUsername};"
|
[ -n "${defaultUsername}" ] && defaultUsernameHint="default:${defaultUsername};"
|
||||||
[ -n "${defaultFullname}" ] && defaultFullnameHint="default:${defaultFullname};"
|
[ -n "${defaultFullname}" ] && defaultFullnameHint="default:${defaultFullname};"
|
||||||
questions=(
|
questions=(
|
||||||
'i: filevault-fullname=What shall the FileVault user'\''s full name be? # '"${defaultFullnameHint}"
|
'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}"
|
'i: filevault-username=What shall the FileVault user'\''s username be? # '"${defaultUsernameHint}"
|
||||||
'p: filevault-password=What shall the FileVault user'\''s password be?'
|
'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: 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};"
|
'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?'
|
'p: secure-token-user-password=What is the secure token user'\''s password?'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function preQuestionHook() {
|
function preQuestionHook() {
|
||||||
if [[ "${is_picture}" = true ]]; then
|
if [[ "${is_picture}" = true ]]; then
|
||||||
isPathToPicture ${pathstr}
|
isPathToPicture ${pathstr}
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsage() {
|
function getUsage() {
|
||||||
local cmdName=$1 text='' varname=
|
local cmdName=$1 text='' varname=
|
||||||
local defaultUsername="`getDefaultUsername`" defaultFullname="`getDefaultFullname`"
|
local defaultUsername="`getDefaultUsername`" defaultFullname="`getDefaultFullname`"
|
||||||
for varname in defaultUsername defaultFullname; do
|
for varname in defaultUsername defaultFullname; do
|
||||||
local ${varname}Str=
|
local ${varname}Str=
|
||||||
[ -n "${(P)varname}" ] && local ${varname}Str=" [default: ${(P)varname}]"
|
[ -n "${(P)varname}" ] && local ${varname}Str=" [default: ${(P)varname}]"
|
||||||
done
|
done
|
||||||
read -r -d '' text <<- USAGE
|
read -r -d '' text <<- USAGE
|
||||||
Usage:
|
Usage:
|
||||||
$cmdName show-questions [<modkey> <modans>]...
|
$cmdName show-questions [<modkey> <modans>]...
|
||||||
$cmdName is-picture <pathstr>
|
$cmdName is-picture <pathstr>
|
||||||
@@ -274,31 +274,31 @@ function getUsage() {
|
|||||||
length and randomness).
|
length and randomness).
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--filevault-fullname NAME Full name of the designated FileVault user. An
|
--filevault-fullname NAME Full name of the designated FileVault user. An
|
||||||
existing FileVault user will be renamed to that
|
existing FileVault user will be renamed to that
|
||||||
name${defaultFullnameStr}.
|
name ${defaultFullnameStr}.
|
||||||
--filevault-username NAME Username of the designated FileVault user. An
|
--filevault-username NAME Username of the designated FileVault user. An
|
||||||
existing FileVault user will be renamed to that
|
existing FileVault user will be renamed to that
|
||||||
name${defaultUsernameStr}.
|
name ${defaultUsernameStr}.
|
||||||
--filevault-password PASSWORD Password of the designated FileVault user. The password
|
--filevault-password PASSWORD Password of the designated FileVault user. The password
|
||||||
an existing FileVault user will not be changed.
|
an existing FileVault user will not be changed.
|
||||||
--filevault-picture PATH_TO_PIC The path to the picture that shall be made the FileVault
|
--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
|
user picture. The picture of an existing FileVault user
|
||||||
will be updated.
|
will be updated.
|
||||||
--secure-token-user-username NAME The username of an user with a secure token.
|
--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.
|
--secure-token-user-password PASSWORD The password of the secure token user.
|
||||||
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
|
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
|
||||||
-v, --verbose Be more verbose.
|
-v, --verbose Be more verbose.
|
||||||
----
|
----
|
||||||
$cmdName 0.1.0
|
$cmdName 0.1.0
|
||||||
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
||||||
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
||||||
USAGE
|
USAGE
|
||||||
print -- ${text}
|
print -- ${text}
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
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 }
|
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}"
|
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
|
||||||
module_main $0 "$@"
|
module_main $0 "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ export HOMEBREW_NO_ANALYTICS_THIS_RUN=1
|
|||||||
export HOMEBREW_NO_ANALYTICS_MESSAGE_OUTPUT=1
|
export HOMEBREW_NO_ANALYTICS_MESSAGE_OUTPUT=1
|
||||||
|
|
||||||
function doesUserExist() {
|
function doesUserExist() {
|
||||||
local username=$1
|
local username=$1
|
||||||
dscl . -list /Users | grep "^${username}$" 2> /dev/null >&2
|
dscl . -list /Users | grep "^${username}$" 2> /dev/null >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
function runAsUser() {
|
function runAsUser() {
|
||||||
local username=$1
|
local username=$1
|
||||||
shift
|
shift
|
||||||
sudo -Hu "${username}" "${@}"
|
sudo -Hu "${username}" "${@}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function runAsHomebrewUser() {
|
function runAsHomebrewUser() {
|
||||||
@@ -20,95 +20,95 @@ function runAsHomebrewUser() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ensureUserIsInAdminGroup() {
|
function ensureUserIsInAdminGroup() {
|
||||||
local username=$1
|
local username=$1
|
||||||
dseditgroup -o edit -a "${username}" -t user admin
|
dseditgroup -o edit -a "${username}" -t user admin
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureUserCanRunPasswordlessSudo() {
|
function ensureUserCanRunPasswordlessSudo() {
|
||||||
local username=$1
|
local username=$1
|
||||||
local sudoersFile="/etc/sudoers.d/no-auth-sudo-for-${username}"
|
local sudoersFile="/etc/sudoers.d/no-auth-sudo-for-${username}"
|
||||||
[[ -f ${sudoersFile} ]] && return
|
[[ -f ${sudoersFile} ]] && return
|
||||||
cat <<- SUDOERS > "${sudoersFile}"
|
cat <<- SUDOERS > "${sudoersFile}"
|
||||||
Defaults:${username} !authenticate
|
Defaults:${username} !authenticate
|
||||||
SUDOERS
|
SUDOERS
|
||||||
chown root:wheel "${sudoersFile}" || return 10
|
chown root:wheel "${sudoersFile}" || return 10
|
||||||
chmod u=rw,g=r,o= "${sudoersFile}" || return 20
|
chmod u=rw,g=r,o= "${sudoersFile}" || return 20
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFirstFreeRoleAccountID() {
|
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() {
|
function createHomebrewUser() {
|
||||||
local username=$1
|
local username=$1
|
||||||
local userID=`getFirstFreeRoleAccountID`
|
local userID=`getFirstFreeRoleAccountID`
|
||||||
sysadminctl -addUser "${username}" -fullName "Homebrew User" -shell /usr/bin/false -home '/var/empty' -roleAccount -UID "${userID}" > /dev/null 2>&1
|
sysadminctl -addUser "${username}" -fullName "Homebrew User" -shell /usr/bin/false -home '/var/empty' -roleAccount -UID "${userID}" > /dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
function createHomebrewUserIfNeccessary() {
|
function createHomebrewUserIfNeccessary() {
|
||||||
if ! doesUserExist ${homebrew_username}; then
|
if ! doesUserExist ${homebrew_username}; then
|
||||||
lop -y body:warn -y body -- -i "No Homebrew user named ${homebrew_username} found." -i 'Will create user.'
|
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
|
indicateActivity 'Creating Homebrew user' createHomebrewUser ${homebrew_username} || return 10
|
||||||
else
|
else
|
||||||
lop -y body:note -y body -- -i "Homebrew user named ${homebrew_username} already exists." -i 'Skipping.'
|
lop -y body:note -y body -- -i "Homebrew user named ${homebrew_username} already exists." -i 'Skipping.'
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureDirectoryWithDefaultMod() {
|
function ensureDirectoryWithDefaultMod() {
|
||||||
local itemPath=${1}
|
local itemPath=${1}
|
||||||
mkdir -p ${itemPath}
|
mkdir -p ${itemPath}
|
||||||
ensureHomebrewOwnershipAndPermission ${itemPath}
|
ensureHomebrewOwnershipAndPermission ${itemPath}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureHomebrewOwnershipAndPermission() {
|
function ensureHomebrewOwnershipAndPermission() {
|
||||||
local itemPath=${1}
|
local itemPath=${1}
|
||||||
local username=${homebrew_username}
|
local username=${homebrew_username}
|
||||||
[[ -f ${itemPath} || -d ${itemPath} ]] || return 1
|
[[ -f ${itemPath} || -d ${itemPath} ]] || return 1
|
||||||
chown -R "${username}:admin" ${itemPath}
|
chown -R "${username}:admin" ${itemPath}
|
||||||
chmod u=rwx,go=rx ${itemPath}
|
chmod u=rwx,go=rx ${itemPath}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureHomebrewCacheDirectory() {
|
function ensureHomebrewCacheDirectory() {
|
||||||
ensureDirectoryWithDefaultMod "${homebrew_cache}"
|
ensureDirectoryWithDefaultMod "${homebrew_cache}"
|
||||||
runAsHomebrewUser touch "${homebrew_cache}/.cleaned"
|
runAsHomebrewUser touch "${homebrew_cache}/.cleaned"
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureHomebrewLogDirectory() {
|
function ensureHomebrewLogDirectory() {
|
||||||
ensureDirectoryWithDefaultMod ${homebrew_log}
|
ensureDirectoryWithDefaultMod ${homebrew_log}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureLocalBinFolder() {
|
function ensureLocalBinFolder() {
|
||||||
local folder="/usr/local/bin"
|
local folder="/usr/local/bin"
|
||||||
if [ ! -d "${folder}" ]; then
|
if [ ! -d "${folder}" ]; then
|
||||||
mkdir -p "${folder}" 2> /dev/null || {
|
mkdir -p "${folder}" 2> /dev/null || {
|
||||||
lop -- -e 'Could not create directory' -e $folder
|
lop -- -e 'Could not create directory' -e $folder
|
||||||
return 10
|
return 10
|
||||||
}
|
}
|
||||||
chown root:admin "${folder}"
|
chown root:admin "${folder}"
|
||||||
chmod ug=rwx,o=rx "${folder}"
|
chmod ug=rwx,o=rx "${folder}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHomebrewRepositoryPath() {
|
function getHomebrewRepositoryPath() {
|
||||||
local uname_machine=$(/usr/bin/uname -m)
|
local uname_machine=$(/usr/bin/uname -m)
|
||||||
if [[ ${uname_machine} == "arm64" ]]; then
|
if [[ ${uname_machine} == "arm64" ]]; then
|
||||||
print -- "/opt/homebrew"
|
print -- "/opt/homebrew"
|
||||||
else
|
else
|
||||||
print "/usr/local/Homebrew"
|
print "/usr/local/Homebrew"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function createBrewCallerScript() {
|
function createBrewCallerScript() {
|
||||||
ensureLocalBinFolder
|
ensureLocalBinFolder
|
||||||
local username=${homebrew_username}
|
local username=${homebrew_username}
|
||||||
local brewCallerPath="/usr/local/bin/brew"
|
local brewCallerPath="/usr/local/bin/brew"
|
||||||
[ -f "${brewCallerPath}" ] && rm "${brewCallerPath}"
|
[ -f "${brewCallerPath}" ] && rm "${brewCallerPath}"
|
||||||
cat <<- BREWCALLER > ${brewCallerPath}
|
cat <<- BREWCALLER > ${brewCallerPath}
|
||||||
#!/usr/bin/env zsh
|
#!/usr/bin/env zsh
|
||||||
if [ "\$(id -un)" != "${username}" ]; then
|
if [ "\$(id -un)" != "${username}" ]; then
|
||||||
echo 'brew will be run as ${username} user.' >&2
|
echo 'brew will be run as ${username} user.' >&2
|
||||||
sudo -E -u "${username}" "\$0" "\$@"
|
sudo -E -u "${username}" "\$0" "\$@"
|
||||||
exit \$?
|
exit \$?
|
||||||
fi
|
fi
|
||||||
export HOMEBREW_CACHE="${homebrew_cache}"
|
export HOMEBREW_CACHE="${homebrew_cache}"
|
||||||
export HOMEBREW_LOGS="${homebrew_log}"
|
export HOMEBREW_LOGS="${homebrew_log}"
|
||||||
@@ -120,109 +120,109 @@ function createBrewCallerScript() {
|
|||||||
umask 002
|
umask 002
|
||||||
"$(getHomebrewRepositoryPath)/bin/brew" "\$@"
|
"$(getHomebrewRepositoryPath)/bin/brew" "\$@"
|
||||||
BREWCALLER
|
BREWCALLER
|
||||||
chown ${username}:admin ${brewCallerPath}
|
chown ${username}:admin ${brewCallerPath}
|
||||||
chmod ug+x,o-x ${brewCallerPath}
|
chmod ug+x,o-x ${brewCallerPath}
|
||||||
}
|
}
|
||||||
|
|
||||||
function installHomebrewCore() {
|
function installHomebrewCore() {
|
||||||
export NONINTERACTIVE=1
|
export NONINTERACTIVE=1
|
||||||
[ ! -d $(getHomebrewRepositoryPath) ] || return
|
[ ! -d $(getHomebrewRepositoryPath) ] || return
|
||||||
sudo --preserve-env=NONINTERACTIVE -u "${homebrew_username}" /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
sudo --preserve-env=NONINTERACTIVE -u "${homebrew_username}" /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||||
[ -d $(getHomebrewRepositoryPath) ]
|
[ -d $(getHomebrewRepositoryPath) ]
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLaunchDaemonsPlist() {
|
function createLaunchDaemonsPlist() {
|
||||||
local username=${homebrew_username}
|
local username=${homebrew_username}
|
||||||
local launcherName="de.astzweig.macos.launchdaemons.$1"
|
local launcherName="de.astzweig.macos.launchdaemons.$1"
|
||||||
local launcherPath="/Library/LaunchDaemons/${launcherName}.plist"
|
local launcherPath="/Library/LaunchDaemons/${launcherName}.plist"
|
||||||
[[ -f $launcherPath ]] && return
|
[[ -f $launcherPath ]] && return
|
||||||
local brewCommand="$2"
|
local brewCommand="$2"
|
||||||
cat <<- LAUNCHDPLIST > ${launcherPath}
|
cat <<- LAUNCHDPLIST > ${launcherPath}
|
||||||
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
<?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\">
|
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
|
||||||
<plist version=\"1.0\">
|
<plist version=\"1.0\">
|
||||||
<dict>
|
<dict>
|
||||||
<key>Label</key>
|
<key>Label</key>
|
||||||
<string>${launcherName}</string>
|
<string>${launcherName}</string>
|
||||||
<key>Program</key>
|
<key>Program</key>
|
||||||
<string>/usr/local/bin/brew</string>
|
<string>/usr/local/bin/brew</string>
|
||||||
<key>ProgramArguments</key>
|
<key>ProgramArguments</key>
|
||||||
<array>
|
<array>
|
||||||
<string>${brewCommand}</string>
|
<string>${brewCommand}</string>
|
||||||
</array>
|
</array>
|
||||||
<key>StartInterval</key>
|
<key>StartInterval</key>
|
||||||
<integer>1800</integer>
|
<integer>1800</integer>
|
||||||
<key>UserName</key>
|
<key>UserName</key>
|
||||||
<string>${username}</string>
|
<string>${username}</string>
|
||||||
<key>GroupName</key>
|
<key>GroupName</key>
|
||||||
<string>admin</string>
|
<string>admin</string>
|
||||||
<key>Umask</key>
|
<key>Umask</key>
|
||||||
<integer>2</integer>
|
<integer>2</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>"
|
</plist>"
|
||||||
LAUNCHDPLIST
|
LAUNCHDPLIST
|
||||||
chown root:wheel ${launcherPath}
|
chown root:wheel ${launcherPath}
|
||||||
chmod u=rw,go=r ${launcherPath}
|
chmod u=rw,go=r ${launcherPath}
|
||||||
launchctl bootstrap system ${launcherPath}
|
launchctl bootstrap system ${launcherPath}
|
||||||
}
|
}
|
||||||
|
|
||||||
function installHomebrewUpdater() {
|
function installHomebrewUpdater() {
|
||||||
createLaunchDaemonsPlist brew-updater update
|
createLaunchDaemonsPlist brew-updater update
|
||||||
createLaunchDaemonsPlist brew-upgrader upgrade
|
createLaunchDaemonsPlist brew-upgrader upgrade
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure_system() {
|
function configure_system() {
|
||||||
lop -y h1 -- -i 'Install System Homebrew'
|
lop -y h1 -- -i 'Install System Homebrew'
|
||||||
createHomebrewUserIfNeccessary || return 10
|
createHomebrewUserIfNeccessary || return 10
|
||||||
indicateActivity 'Ensure Homebrew user is in admin group' ensureUserIsInAdminGroup ${homebrew_username} || return 11
|
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
|
indicateActivity 'Ensure Homebrew user can run passwordless sudo' ensureUserCanRunPasswordlessSudo ${homebrew_username} || return 12
|
||||||
ensureHomebrewCacheDirectory || return 13
|
ensureHomebrewCacheDirectory || return 13
|
||||||
ensureHomebrewLogDirectory || return 14
|
ensureHomebrewLogDirectory || return 14
|
||||||
indicateActivity 'Install Homebrew core' installHomebrewCore || return 15
|
indicateActivity 'Install Homebrew core' installHomebrewCore || return 15
|
||||||
indicateActivity 'Create brew caller script' createBrewCallerScript || return 16
|
indicateActivity 'Create brew caller script' createBrewCallerScript || return 16
|
||||||
indicateActivity 'Install Homebrew updater' installHomebrewUpdater || return 17
|
indicateActivity 'Install Homebrew updater' installHomebrewUpdater || return 17
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExecPrerequisites() {
|
function getExecPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[dscl]=''
|
[dscl]=''
|
||||||
[dseditgroup]=''
|
[dseditgroup]=''
|
||||||
[chown]=''
|
[chown]=''
|
||||||
[chmod]=''
|
[chmod]=''
|
||||||
[sudo]=''
|
[sudo]=''
|
||||||
[grep]=''
|
[grep]=''
|
||||||
[git]=''
|
[git]=''
|
||||||
[sort]=''
|
[sort]=''
|
||||||
[awk]=''
|
[awk]=''
|
||||||
[launchctl]=''
|
[launchctl]=''
|
||||||
[sysadminctl]=''
|
[sysadminctl]=''
|
||||||
)
|
)
|
||||||
requireRootPrivileges
|
requireRootPrivileges
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultHomebrewUsername() {
|
function getDefaultHomebrewUsername() {
|
||||||
print -- _homebrew
|
print -- _homebrew
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultHomebrewCachePath() {
|
function getDefaultHomebrewCachePath() {
|
||||||
print -- /Library/Caches/Homebrew
|
print -- /Library/Caches/Homebrew
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultHomebrewLogPath() {
|
function getDefaultHomebrewLogPath() {
|
||||||
print -- /var/log/Homebrew
|
print -- /var/log/Homebrew
|
||||||
}
|
}
|
||||||
|
|
||||||
function getQuestions() {
|
function getQuestions() {
|
||||||
questions=(
|
questions=(
|
||||||
'i: homebrew-username=What shall the Homebrew user'\''s username be? # default:'"$(getDefaultHomebrewUsername)"
|
'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-cache=What shall the Homebrew cache directory be? # default:'"$(getDefaultHomebrewCachePath)"
|
||||||
'i: homebrew-log=What shall the Homebrew log directory be? # default:'"$(getDefaultHomebrewLogPath)"
|
'i: homebrew-log=What shall the Homebrew log directory be? # default:'"$(getDefaultHomebrewLogPath)"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsage() {
|
function getUsage() {
|
||||||
read -r -d '' text <<- USAGE
|
read -r -d '' text <<- USAGE
|
||||||
Usage:
|
Usage:
|
||||||
$cmdName show-questions [<modkey> <modans>]...
|
$cmdName show-questions [<modkey> <modans>]...
|
||||||
$cmdName [-v] [-d FILE] --homebrew-username NAME --homebrew-cache PATH --homebrew-log PATH
|
$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.
|
given PREFIX and make the new Homebrew user the owner of that.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--homebrew-cache PATH Path to folder that shall be used as the
|
--homebrew-cache PATH Path to folder that shall be used as the
|
||||||
cache for Homebrew [default: $(getDefaultHomebrewCachePath)].
|
cache for Homebrew [default: $(getDefaultHomebrewCachePath)].
|
||||||
--homebrew-log PATH Path to folder that shall be used as the log
|
--homebrew-log PATH Path to folder that shall be used as the log
|
||||||
directory for Homebrew [default: $(getDefaultHomebrewLogPath)].
|
directory for Homebrew [default: $(getDefaultHomebrewLogPath)].
|
||||||
--homebrew-username NAME Username of the designated Homebrew user.
|
--homebrew-username NAME Username of the designated Homebrew user.
|
||||||
[default: $(getDefaultHomebrewUsername)].
|
[default: $(getDefaultHomebrewUsername)].
|
||||||
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
|
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
|
||||||
-v, --verbose Be more verbose.
|
-v, --verbose Be more verbose.
|
||||||
----
|
----
|
||||||
$cmdName 0.1.0
|
$cmdName 0.1.0
|
||||||
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
||||||
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
||||||
USAGE
|
USAGE
|
||||||
print -- ${text}
|
print -- ${text}
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
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 }
|
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}"
|
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
|
||||||
module_main $0 "$@"
|
module_main $0 "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -2,89 +2,89 @@
|
|||||||
# vi: set ft=zsh tw=80 ts=2
|
# vi: set ft=zsh tw=80 ts=2
|
||||||
|
|
||||||
function brewInstall() {
|
function brewInstall() {
|
||||||
local identifier="$1"
|
local identifier="$1"
|
||||||
local cask="${2:+--cask}"
|
local cask="${2:+--cask}"
|
||||||
indicateActivity -- "Installing ${identifier}${cask:+ (Cask)}" ${homebrew_path} install -q ${cask} ${identifier}
|
indicateActivity -- "Installing ${identifier}${cask:+ (Cask)}" ${homebrew_path} install -q ${cask} ${identifier}
|
||||||
}
|
}
|
||||||
|
|
||||||
function installCask() {
|
function installCask() {
|
||||||
brewInstall $1 cask
|
brewInstall $1 cask
|
||||||
}
|
}
|
||||||
|
|
||||||
function installBrew() {
|
function installBrew() {
|
||||||
brewInstall $1
|
brewInstall $1
|
||||||
}
|
}
|
||||||
|
|
||||||
function installCasks() {
|
function installCasks() {
|
||||||
lop -y body:h1 -- -i 'Installing Homebrew casks'
|
lop -y body:h1 -- -i 'Installing Homebrew casks'
|
||||||
if ! isDebug; then
|
if ! isDebug; then
|
||||||
installCask sketch
|
installCask sketch
|
||||||
installCask nova
|
installCask nova
|
||||||
installCask transmit
|
installCask transmit
|
||||||
installCask automattic-texts
|
installCask automattic-texts
|
||||||
installCask synology-drive
|
installCask synology-drive
|
||||||
installCask sf-symbols
|
installCask sf-symbols
|
||||||
installCask prizmo
|
installCask prizmo
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function installFonts() {
|
function installFonts() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function installBrews() {
|
function installBrews() {
|
||||||
lop -y body:h1 -- -i 'Installing Homebrew formulas'
|
lop -y body:h1 -- -i 'Installing Homebrew formulas'
|
||||||
installBrew mas
|
installBrew mas
|
||||||
if ! isDebug; then
|
if ! isDebug; then
|
||||||
installBrew python
|
installBrew python
|
||||||
installBrew rcm
|
installBrew rcm
|
||||||
installBrew php
|
installBrew php
|
||||||
installBrew composer
|
installBrew composer
|
||||||
installBrew curl
|
installBrew curl
|
||||||
installBrew exiftool
|
installBrew exiftool
|
||||||
installBrew ffmpeg
|
installBrew ffmpeg
|
||||||
installBrew gnupg
|
installBrew gnupg
|
||||||
installBrew node
|
installBrew node
|
||||||
installBrew nmap
|
installBrew nmap
|
||||||
installBrew tree
|
installBrew tree
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure_system() {
|
function configure_system() {
|
||||||
lop -y h1 -- -i 'Install Homebrew Applications'
|
lop -y h1 -- -i 'Install Homebrew Applications'
|
||||||
pushd -q /
|
pushd -q /
|
||||||
installBrews
|
installBrews
|
||||||
installCasks
|
installCasks
|
||||||
installFonts
|
installFonts
|
||||||
popd -q
|
popd -q
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExecPrerequisites() {
|
function getExecPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[brew]=''
|
[brew]=''
|
||||||
[find]=''
|
[find]=''
|
||||||
[head]=''
|
[head]=''
|
||||||
[installer]=''
|
[installer]=''
|
||||||
[hdiutil]=''
|
[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 }
|
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
|
checkCommands
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultHomebrewPath() {
|
function getDefaultHomebrewPath() {
|
||||||
local moduleAnswer
|
local moduleAnswer
|
||||||
local hbpath=`whence -p brew`
|
local hbpath=`whence -p brew`
|
||||||
getModuleAnswerByKeyRegEx '_homebrew-prefix$' && hbpath=$moduleAnswer/bin/brew
|
getModuleAnswerByKeyRegEx '_homebrew-prefix$' && hbpath=$moduleAnswer/bin/brew
|
||||||
print -- ${hbpath}
|
print -- ${hbpath}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getQuestions() {
|
function getQuestions() {
|
||||||
questions=(
|
questions=(
|
||||||
'i: homebrew-path=Which Homebrew binary shall be used? # default:'"$(getDefaultHomebrewPath)"
|
'i: homebrew-path=Which Homebrew binary shall be used? # default:'"$(getDefaultHomebrewPath)"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsage() {
|
function getUsage() {
|
||||||
read -r -d '' text <<- USAGE
|
read -r -d '' text <<- USAGE
|
||||||
Usage:
|
Usage:
|
||||||
$cmdName show-questions [<modkey> <modans>]...
|
$cmdName show-questions [<modkey> <modans>]...
|
||||||
$cmdName [-v] [-d FILE] --homebrew-path PATH
|
$cmdName [-v] [-d FILE] --homebrew-path PATH
|
||||||
@@ -92,19 +92,19 @@ function getUsage() {
|
|||||||
Install cli tools, macOS apps and fonts via Homebrew.
|
Install cli tools, macOS apps and fonts via Homebrew.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--homebrew-path PATH Path to Homebrew binary [default: $(getDefaultHomebrewPath)].
|
--homebrew-path PATH Path to Homebrew binary [default: $(getDefaultHomebrewPath)].
|
||||||
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
|
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
|
||||||
-v, --verbose Be more verbose.
|
-v, --verbose Be more verbose.
|
||||||
----
|
----
|
||||||
$cmdName 0.1.0
|
$cmdName 0.1.0
|
||||||
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
||||||
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
||||||
USAGE
|
USAGE
|
||||||
print -- ${text}
|
print -- ${text}
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
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 }
|
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}"
|
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
|
||||||
module_main $0 "$@"
|
module_main $0 "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -2,166 +2,166 @@
|
|||||||
# vi: set ft=zsh tw=80 ts=2
|
# vi: set ft=zsh tw=80 ts=2
|
||||||
|
|
||||||
function ensureRightAccess() {
|
function ensureRightAccess() {
|
||||||
local filesystemItem="$1"
|
local filesystemItem="$1"
|
||||||
chown root:wheel ${filesystemItem}
|
chown root:wheel ${filesystemItem}
|
||||||
chmod ugo=rx ${filesystemItem}
|
chmod ugo=rx ${filesystemItem}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDataForMicrosoftKeyboard() {
|
function getDataForMicrosoftKeyboard() {
|
||||||
local name="$1"
|
local name="$1"
|
||||||
[ "$name" = "ProductID" ] && echo '0x7a5'
|
[ "$name" = "ProductID" ] && echo '0x7a5'
|
||||||
[ "$name" = "VendorID" ] && echo '0x45e'
|
[ "$name" = "VendorID" ] && echo '0x45e'
|
||||||
[ "$name" = "LaunchdServiceName" ] && echo 'de.astzweig.macos.launchdaemons.microsoft-keymapper'
|
[ "$name" = "LaunchdServiceName" ] && echo 'de.astzweig.macos.launchdaemons.microsoft-keymapper'
|
||||||
[ "$name" = "BinaryName" ] && echo 'remap-keys-microsoft'
|
[ "$name" = "BinaryName" ] && echo 'remap-keys-microsoft'
|
||||||
[ "$name" = "KeyMappings" ] && cat <<- KEYMAPPINGS
|
[ "$name" = "KeyMappings" ] && cat <<- KEYMAPPINGS
|
||||||
{"HIDKeyboardModifierMappingSrc": 0x700000065, "HIDKeyboardModifierMappingDst": 0x7000000e7},
|
{"HIDKeyboardModifierMappingSrc": 0x700000065, "HIDKeyboardModifierMappingDst": 0x7000000e7},
|
||||||
{"HIDKeyboardModifierMappingSrc": 0x7000000e3, "HIDKeyboardModifierMappingDst": 0x7000000e2},
|
{"HIDKeyboardModifierMappingSrc": 0x7000000e3, "HIDKeyboardModifierMappingDst": 0x7000000e2},
|
||||||
{"HIDKeyboardModifierMappingSrc": 0x7000000e2, "HIDKeyboardModifierMappingDst": 0x7000000e3}
|
{"HIDKeyboardModifierMappingSrc": 0x7000000e2, "HIDKeyboardModifierMappingDst": 0x7000000e3}
|
||||||
KEYMAPPINGS
|
KEYMAPPINGS
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDataForLogitechKeyboard() {
|
function getDataForLogitechKeyboard() {
|
||||||
local name="$1"
|
local name="$1"
|
||||||
[ "$name" = "ProductID" ] && echo '0xc52b'
|
[ "$name" = "ProductID" ] && echo '0xc52b'
|
||||||
[ "$name" = "VendorID" ] && echo '0x46d'
|
[ "$name" = "VendorID" ] && echo '0x46d'
|
||||||
[ "$name" = "LaunchdServiceName" ] && echo 'de.astzweig.macos.launchdaemons.logitech-keymapper'
|
[ "$name" = "LaunchdServiceName" ] && echo 'de.astzweig.macos.launchdaemons.logitech-keymapper'
|
||||||
[ "$name" = "BinaryName" ] && echo 'remap-keys-logitech'
|
[ "$name" = "BinaryName" ] && echo 'remap-keys-logitech'
|
||||||
[ "$name" = "KeyMappings" ] && cat <<- KEYMAPPINGS
|
[ "$name" = "KeyMappings" ] && cat <<- KEYMAPPINGS
|
||||||
{"HIDKeyboardModifierMappingSrc": 0x7000000e6, "HIDKeyboardModifierMappingDst": 0x7000000e7},
|
{"HIDKeyboardModifierMappingSrc": 0x7000000e6, "HIDKeyboardModifierMappingDst": 0x7000000e7},
|
||||||
{"HIDKeyboardModifierMappingSrc": 0x7000000e7, "HIDKeyboardModifierMappingDst": 0x7000000e6}
|
{"HIDKeyboardModifierMappingSrc": 0x7000000e7, "HIDKeyboardModifierMappingDst": 0x7000000e6}
|
||||||
KEYMAPPINGS
|
KEYMAPPINGS
|
||||||
}
|
}
|
||||||
|
|
||||||
function createXPCConsumer() {
|
function createXPCConsumer() {
|
||||||
[[ -x ${xpcConsumerPath} ]] && return
|
[[ -x ${xpcConsumerPath} ]] && return
|
||||||
clang -framework Foundation -x objective-c -o ${xpcConsumerPath} - <<- BINARY
|
clang -framework Foundation -x objective-c -o ${xpcConsumerPath} - <<- BINARY
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#include <xpc/xpc.h>
|
#include <xpc/xpc.h>
|
||||||
|
|
||||||
int main(int argc, const char * argv[]) {
|
int main(int argc, const char * argv[]) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||||
xpc_set_event_stream_handler("com.apple.iokit.matching", NULL, ^(xpc_object_t _Nonnull object) {
|
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);
|
const char *event = xpc_dictionary_get_string(object, XPC_EVENT_KEY_NAME);
|
||||||
NSLog(@"%s", event);
|
NSLog(@"%s", event);
|
||||||
dispatch_semaphore_signal(semaphore);
|
dispatch_semaphore_signal(semaphore);
|
||||||
});
|
});
|
||||||
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
||||||
if(argc >= 2) {
|
if(argc >= 2) {
|
||||||
execv(argv[1], (char **)argv+1);
|
execv(argv[1], (char **)argv+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BINARY
|
BINARY
|
||||||
ensureRightAccess ${xpcConsumerPath}
|
ensureRightAccess ${xpcConsumerPath}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProductPlistDict() {
|
function getProductPlistDict() {
|
||||||
cat <<- PLISTDICT
|
cat <<- PLISTDICT
|
||||||
<dict>
|
<dict>
|
||||||
<key>idProduct</key>
|
<key>idProduct</key>
|
||||||
<integer>$(($($dataProvider ProductID)))</integer>
|
<integer>$(($($dataProvider ProductID)))</integer>
|
||||||
<key>idVendor</key>
|
<key>idVendor</key>
|
||||||
<integer>$(($($dataProvider VendorID)))</integer>
|
<integer>$(($($dataProvider VendorID)))</integer>
|
||||||
<key>IOProviderClass</key>
|
<key>IOProviderClass</key>
|
||||||
<string>IOUSBDevice</string>
|
<string>IOUSBDevice</string>
|
||||||
<key>IOMatchLaunchStream</key>
|
<key>IOMatchLaunchStream</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
PLISTDICT
|
PLISTDICT
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRemapKeysBinary() {
|
function createRemapKeysBinary() {
|
||||||
cat > ${binaryPath} <<- BINARY
|
cat > ${binaryPath} <<- BINARY
|
||||||
#!/bin/zsh
|
#!/bin/zsh
|
||||||
PRODUCT_MATCHER='{"ProductID":$($dataProvider ProductID),"VendorID":$($dataProvider VendorID)}'
|
PRODUCT_MATCHER='{"ProductID":$($dataProvider ProductID),"VendorID":$($dataProvider VendorID)}'
|
||||||
|
|
||||||
hasMappingBeenAlreadyActivated() {
|
hasMappingBeenAlreadyActivated() {
|
||||||
local currentModifierKeyMappings="\`hidutil property --get UserKeyMapping -m "\${PRODUCT_MATCHER}" | grep HIDKeyboardModifierMappingDst | wc -l\`"
|
local currentModifierKeyMappings="\`hidutil property --get UserKeyMapping -m "\${PRODUCT_MATCHER}" | grep HIDKeyboardModifierMappingDst | wc -l\`"
|
||||||
test "\${currentModifierKeyMappings}" -gt 1
|
test "\${currentModifierKeyMappings}" -gt 1
|
||||||
}
|
}
|
||||||
|
|
||||||
hasMappingBeenAlreadyActivated || \
|
hasMappingBeenAlreadyActivated || \
|
||||||
hidutil property --matching "\${PRODUCT_MATCHER}" --set '{"UserKeyMapping": [
|
hidutil property --matching "\${PRODUCT_MATCHER}" --set '{"UserKeyMapping": [
|
||||||
$($dataProvider KeyMappings)
|
$($dataProvider KeyMappings)
|
||||||
]}' > /dev/null 2>&1
|
]}' > /dev/null 2>&1
|
||||||
BINARY
|
BINARY
|
||||||
ensureRightAccess ${binaryPath}
|
ensureRightAccess ${binaryPath}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLaunchDaemon() {
|
function createLaunchDaemon() {
|
||||||
cat > ${launchDaemonPath} <<- LDAEMON
|
cat > ${launchDaemonPath} <<- LDAEMON
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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">
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>Label</key>
|
<key>Label</key>
|
||||||
<string>$($dataProvider LaunchdServiceName)</string>
|
<string>$($dataProvider LaunchdServiceName)</string>
|
||||||
<key>ProgramArguments</key>
|
<key>ProgramArguments</key>
|
||||||
<array>
|
<array>
|
||||||
<string>${xpcConsumerPath}</string>
|
<string>${xpcConsumerPath}</string>
|
||||||
<string>${remapKeysPath}</string>
|
<string>${remapKeysPath}</string>
|
||||||
</array>
|
</array>
|
||||||
<key>LaunchEvents</key>
|
<key>LaunchEvents</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.iokit.matching</key>
|
<key>com.apple.iokit.matching</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.device-attach</key>
|
<key>com.apple.device-attach</key>
|
||||||
$(getProductPlistDict)
|
$(getProductPlistDict)
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
LDAEMON
|
LDAEMON
|
||||||
ensureRightAccess ${launchDaemonPath}
|
ensureRightAccess ${launchDaemonPath}
|
||||||
}
|
}
|
||||||
|
|
||||||
function enableLaunchDaemon() {
|
function enableLaunchDaemon() {
|
||||||
launchctl enable system/${launchDaemonPath%.*}
|
launchctl enable system/${launchDaemonPath%.*}
|
||||||
launchctl bootstrap system ${launchDaemonPath}
|
launchctl bootstrap system ${launchDaemonPath}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLaunchdService() {
|
function createLaunchdService() {
|
||||||
local launchDaemonPath="/Library/LaunchDaemons/$($dataProvider LaunchdServiceName).plist"
|
local launchDaemonPath="/Library/LaunchDaemons/$($dataProvider LaunchdServiceName).plist"
|
||||||
[[ -f ${launchDaemonPath} ]] || indicateActivity -- 'Create Launch Daemon' createLaunchDaemon
|
[[ -f ${launchDaemonPath} ]] || indicateActivity -- 'Create Launch Daemon' createLaunchDaemon
|
||||||
indicateActivity -- 'Enable Launch Daemon' enableLaunchDaemon
|
indicateActivity -- 'Enable Launch Daemon' enableLaunchDaemon
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureKeymappers() {
|
function configureKeymappers() {
|
||||||
local mapper= dataProvider= binaryPath=
|
local mapper= dataProvider= binaryPath=
|
||||||
for mapper dataProvider in ${(kv)mappers}; do
|
for mapper dataProvider in ${(kv)mappers}; do
|
||||||
lop -y h1 -- -i "Configure ${mapper} Keymapper"
|
lop -y h1 -- -i "Configure ${mapper} Keymapper"
|
||||||
binaryPath="${dstDir}/$($dataProvider BinaryName)"
|
binaryPath="${dstDir}/$($dataProvider BinaryName)"
|
||||||
createRemapKeysBinary
|
createRemapKeysBinary
|
||||||
createLaunchdService
|
createLaunchdService
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure_system() {
|
function configure_system() {
|
||||||
typeset -A mappers=(
|
typeset -A mappers=(
|
||||||
[Microsoft]=getDataForMicrosoftKeyboard
|
[Microsoft]=getDataForMicrosoftKeyboard
|
||||||
[Logitech]=getDataForLogitechKeyboard
|
[Logitech]=getDataForLogitechKeyboard
|
||||||
)
|
)
|
||||||
local dstDir='/usr/local/bin'
|
local dstDir='/usr/local/bin'
|
||||||
local xpcConsumerPath="${dstDir}/astzweig-xpc-consumer"
|
local xpcConsumerPath="${dstDir}/astzweig-xpc-consumer"
|
||||||
|
|
||||||
ensurePathOrLogError ${dstDir} 'Could not create destination dir for remap-keys binary.' || return 10
|
ensurePathOrLogError ${dstDir} 'Could not create destination dir for remap-keys binary.' || return 10
|
||||||
indicateActivity -- 'Create XPC event consumer' createXPCConsumer
|
indicateActivity -- 'Create XPC event consumer' createXPCConsumer
|
||||||
configureKeymappers
|
configureKeymappers
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExecPrerequisites() {
|
function getExecPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[clang]=''
|
[clang]=''
|
||||||
[launchctl]=''
|
[launchctl]=''
|
||||||
[cp]=''
|
[cp]=''
|
||||||
[chown]=''
|
[chown]=''
|
||||||
[chmod]=''
|
[chmod]=''
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsage() {
|
function getUsage() {
|
||||||
read -r -d '' text <<- USAGE
|
read -r -d '' text <<- USAGE
|
||||||
Usage:
|
Usage:
|
||||||
$cmdName show-questions [<modkey> <modans>]...
|
$cmdName show-questions [<modkey> <modans>]...
|
||||||
$cmdName [-v] [-d FILE]
|
$cmdName [-v] [-d FILE]
|
||||||
@@ -170,18 +170,18 @@ function getUsage() {
|
|||||||
macOS nativ hidutil, in order to swap command and option key.
|
macOS nativ hidutil, in order to swap command and option key.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
|
-d FILE, --logfile FILE Print log message to logfile instead of stdout.
|
||||||
-v, --verbose Be more verbose.
|
-v, --verbose Be more verbose.
|
||||||
----
|
----
|
||||||
$cmdName 0.1.0
|
$cmdName 0.1.0
|
||||||
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
||||||
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
||||||
USAGE
|
USAGE
|
||||||
print -- ${text}
|
print -- ${text}
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
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 }
|
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}"
|
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
|
||||||
module_main $0 "$@"
|
module_main $0 "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -2,47 +2,47 @@
|
|||||||
# vi: set ft=zsh tw=80 ts=2
|
# vi: set ft=zsh tw=80 ts=2
|
||||||
|
|
||||||
function installMASApp() {
|
function installMASApp() {
|
||||||
local currentUser="`who am i | cut -d' ' -f1`"
|
local currentUser="`who am i | cut -d' ' -f1`"
|
||||||
local appName="$1"
|
local appName="$1"
|
||||||
local id="$2"
|
local id="$2"
|
||||||
indicateActivity -- "Install ${appName} app" sudo -u ${currentUser} mas install ${id}
|
indicateActivity -- "Install ${appName} app" sudo -u ${currentUser} mas install ${id}
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure_system() {
|
function configure_system() {
|
||||||
lop -y h1 -- -i 'Install Mac AppStore Apps'
|
lop -y h1 -- -i 'Install Mac AppStore Apps'
|
||||||
installMASApp Keka 470158793
|
installMASApp Keka 470158793
|
||||||
|
|
||||||
if ! isDebug; then
|
if ! isDebug; then
|
||||||
installMASApp Pages 409201541
|
installMASApp Pages 409201541
|
||||||
installMASApp Numbers 409203825
|
installMASApp Numbers 409203825
|
||||||
|
|
||||||
installMASApp Outbank 1094255754
|
installMASApp Outbank 1094255754
|
||||||
|
|
||||||
installMASApp 'Final Cut Pro' 424389933
|
installMASApp 'Final Cut Pro' 424389933
|
||||||
installMASApp GarageBand 682658836
|
installMASApp GarageBand 682658836
|
||||||
installMASApp Motion 434290957
|
installMASApp Motion 434290957
|
||||||
installMASApp Compressor 424390742
|
installMASApp Compressor 424390742
|
||||||
installMASApp 'Logic Pro' 634148309
|
installMASApp 'Logic Pro' 634148309
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExecPrerequisites() {
|
function getExecPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[mas]=''
|
[mas]=''
|
||||||
[sudo]=''
|
[sudo]=''
|
||||||
[who]=''
|
[who]=''
|
||||||
[cut]=''
|
[cut]=''
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getQuestions {
|
function getQuestions {
|
||||||
questions=(
|
questions=(
|
||||||
'c: logged-in=Have you ensured a user is logged in to the macOS App Store?'
|
'c: logged-in=Have you ensured a user is logged in to the macOS App Store?'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsage() {
|
function getUsage() {
|
||||||
read -r -d '' text <<- USAGE
|
read -r -d '' text <<- USAGE
|
||||||
Usage:
|
Usage:
|
||||||
$cmdName show-questions [<modkey> <modans>]...
|
$cmdName show-questions [<modkey> <modans>]...
|
||||||
$cmdName [-v] [-d FILE] --logged-in ANS
|
$cmdName [-v] [-d FILE] --logged-in ANS
|
||||||
@@ -59,11 +59,11 @@ function getUsage() {
|
|||||||
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
||||||
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
||||||
USAGE
|
USAGE
|
||||||
print -- ${text}
|
print -- ${text}
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
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 }
|
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}"
|
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
|
||||||
module_main $0 "$@"
|
module_main $0 "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -2,57 +2,57 @@
|
|||||||
# vi: set ft=zsh tw=80 ts=2
|
# vi: set ft=zsh tw=80 ts=2
|
||||||
|
|
||||||
function ensureRightAccess() {
|
function ensureRightAccess() {
|
||||||
local filesystemItem="$1"
|
local filesystemItem="$1"
|
||||||
chown root:admin "${filesystemItem}"
|
chown root:admin "${filesystemItem}"
|
||||||
chmod ugo=rx "${filesystemItem}"
|
chmod ugo=rx "${filesystemItem}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyUtilityBinaries() {
|
function copyUtilityBinaries() {
|
||||||
for file in ${_DIR}/../bin/*; do
|
for file in ${_DIR}/../bin/*; do
|
||||||
indicateActivity -- "Copying ${file##*/}" cp ${file} ${dstDir}
|
indicateActivity -- "Copying ${file##*/}" cp ${file} ${dstDir}
|
||||||
ensureRightAccess ${file}
|
ensureRightAccess ${file}
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function installDocopts() {
|
function installDocopts() {
|
||||||
local destPath='/usr/local/bin/docopts'
|
local destPath='/usr/local/bin/docopts'
|
||||||
[[ -x ${destPath} ]] && return
|
[[ -x ${destPath} ]] && return
|
||||||
indicateActivity -- 'Downloading docpts' curl --output ${destPath} -fsSL ${docopts_url} || return
|
indicateActivity -- 'Downloading docpts' curl --output ${destPath} -fsSL ${docopts_url} || return
|
||||||
ensureRightAccess ${destPath}
|
ensureRightAccess ${destPath}
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure_system() {
|
function configure_system() {
|
||||||
lop -y h1 -- -i 'Install Utility Binaries'
|
lop -y h1 -- -i 'Install Utility Binaries'
|
||||||
local dstDir='/usr/local/bin'
|
local dstDir='/usr/local/bin'
|
||||||
ensurePathOrLogError ${dstDir} 'Could not install binaries.' || return 10
|
ensurePathOrLogError ${dstDir} 'Could not install binaries.' || return 10
|
||||||
indicateActivity -- "Set sticky bit to ${dstDir} folder" chmod +t ${dstDir}
|
indicateActivity -- "Set sticky bit to ${dstDir} folder" chmod +t ${dstDir}
|
||||||
installDocopts
|
installDocopts
|
||||||
copyUtilityBinaries
|
copyUtilityBinaries
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExecPrerequisites() {
|
function getExecPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[cp]=''
|
[cp]=''
|
||||||
[chown]=''
|
[chown]=''
|
||||||
[chmod]=''
|
[chmod]=''
|
||||||
[curl]=''
|
[curl]=''
|
||||||
[install]=''
|
[install]=''
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultDocoptsURL() {
|
function getDefaultDocoptsURL() {
|
||||||
local fileURL="${DOCOPTS_URL:-https://github.com/astzweig/docopts/releases/download/v.0.7.0/docopts_darwin_amd64}"
|
local fileURL="${DOCOPTS_URL:-https://github.com/astzweig/docopts/releases/download/v.0.7.0/docopts_darwin_amd64}"
|
||||||
print -- ${fileURL}
|
print -- ${fileURL}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getQuestions() {
|
function getQuestions() {
|
||||||
questions=(
|
questions=(
|
||||||
'i: docopts-url=From which URL shall the docopts binary be downloaded? # default:'"$(getDefaultDocoptsURL)"
|
'i: docopts-url=From which URL shall the docopts binary be downloaded? # default:'"$(getDefaultDocoptsURL)"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsage() {
|
function getUsage() {
|
||||||
read -r -d '' text <<- USAGE
|
read -r -d '' text <<- USAGE
|
||||||
Usage:
|
Usage:
|
||||||
$cmdName show-questions [<modkey> <modans>]...
|
$cmdName show-questions [<modkey> <modans>]...
|
||||||
$cmdName [-v] [-d FILE] --docopts-url URL
|
$cmdName [-v] [-d FILE] --docopts-url URL
|
||||||
@@ -69,12 +69,12 @@ function getUsage() {
|
|||||||
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
||||||
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
||||||
USAGE
|
USAGE
|
||||||
print -- ${text}
|
print -- ${text}
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
||||||
_DIR="${0:A:h}"
|
_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 }
|
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}"
|
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
|
||||||
module_main $0 "$@"
|
module_main $0 "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,48 +5,48 @@ function addLibToStartupFile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function installZshlib() {
|
function installZshlib() {
|
||||||
local zshlibPath=${libDir}/astzweig_zshlib
|
local zshlibPath=${libDir}/astzweig_zshlib
|
||||||
if [[ -d ${ASTZWEIG_ZSHLIB} ]]; then
|
if [[ -d ${ASTZWEIG_ZSHLIB} ]]; then
|
||||||
pushd -q ${ASTZWEIG_ZSHLIB}
|
pushd -q ${ASTZWEIG_ZSHLIB}
|
||||||
zcompile -z -U ${zshlibPath} $(find . -type f -perm +u=x -maxdepth 1)
|
zcompile -z -U ${zshlibPath} $(find . -type f -perm +u=x -maxdepth 1)
|
||||||
libs+=(${zshlibPath}.zwc)
|
libs+=(${zshlibPath}.zwc)
|
||||||
popd -q
|
popd -q
|
||||||
elif [[ -f ${ASTZWEIG_ZSHLIB} ]]; then
|
elif [[ -f ${ASTZWEIG_ZSHLIB} ]]; then
|
||||||
cp ${ASTZWEIG_ZSHLIB} ${zshlibPath}.zwc;
|
cp ${ASTZWEIG_ZSHLIB} ${zshlibPath}.zwc;
|
||||||
fi
|
fi
|
||||||
chmod ugo=r ${zshlibPath}.zwc
|
chmod ugo=r ${zshlibPath}.zwc
|
||||||
}
|
}
|
||||||
|
|
||||||
function modifyGlobalFpath() {
|
function modifyGlobalFpath() {
|
||||||
local startupFile=/etc/zshenv
|
local startupFile=/etc/zshenv
|
||||||
cat ${startupFile} | grep "${(q)libs}" >&! /dev/null && return
|
cat ${startupFile} | grep "${(q)libs}" >&! /dev/null && return
|
||||||
print -- "fpath+=(${(q)libs})" >> ${startupFile}
|
print -- "fpath+=(${(q)libs})" >> ${startupFile}
|
||||||
chown root:wheel ${startupFile}
|
chown root:wheel ${startupFile}
|
||||||
chmod u=rw,go=r ${startupFile}
|
chmod u=rw,go=r ${startupFile}
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure_system() {
|
function configure_system() {
|
||||||
lop -y h1 -- -i 'Install ZSh Libraries'
|
lop -y h1 -- -i 'Install ZSh Libraries'
|
||||||
local libDir=/usr/local/share/zsh/site-functions
|
local libDir=/usr/local/share/zsh/site-functions
|
||||||
local libs=()
|
local libs=()
|
||||||
ensurePathOrLogError ${libDir} 'Could not install zsh libraries.' || return 10
|
ensurePathOrLogError ${libDir} 'Could not install zsh libraries.' || return 10
|
||||||
lop -- -d "ASTZWEIG_ZSHLIB is ${ASTZWEIG_ZSHLIB}"
|
lop -- -d "ASTZWEIG_ZSHLIB is ${ASTZWEIG_ZSHLIB}"
|
||||||
indicateActivity 'Install zshlib' installZshlib
|
indicateActivity 'Install zshlib' installZshlib
|
||||||
indicateActivity 'Modify global fpath' modifyGlobalFpath
|
indicateActivity 'Modify global fpath' modifyGlobalFpath
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExecPrerequisites() {
|
function getExecPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[cat]=''
|
[cat]=''
|
||||||
[grep]=''
|
[grep]=''
|
||||||
[chown]=''
|
[chown]=''
|
||||||
[chmod]=''
|
[chmod]=''
|
||||||
[install]=''
|
[install]=''
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsage() {
|
function getUsage() {
|
||||||
read -r -d '' text <<- USAGE
|
read -r -d '' text <<- USAGE
|
||||||
Usage:
|
Usage:
|
||||||
$cmdName show-questions [<modkey> <modans>]...
|
$cmdName show-questions [<modkey> <modans>]...
|
||||||
$cmdName [-v] [-d FILE]
|
$cmdName [-v] [-d FILE]
|
||||||
@@ -61,12 +61,12 @@ function getUsage() {
|
|||||||
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
||||||
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
||||||
USAGE
|
USAGE
|
||||||
print -- ${text}
|
print -- ${text}
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
||||||
_DIR="${0:A:h}"
|
_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 }
|
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}"
|
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
|
||||||
module_main $0 "$@"
|
module_main $0 "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -2,35 +2,35 @@
|
|||||||
# vi: set ft=zsh tw=80 ts=2
|
# vi: set ft=zsh tw=80 ts=2
|
||||||
|
|
||||||
function installGoogleFonts() {
|
function installGoogleFonts() {
|
||||||
local fontsDir=/Library/Fonts/Google-Fonts
|
local fontsDir=/Library/Fonts/Google-Fonts
|
||||||
[[ -d ${fontsDir} ]] && return
|
[[ -d ${fontsDir} ]] && return
|
||||||
indicateActivity 'Download Google Fonts' git clone "${git_google_fonts}" "${fontsDir}"
|
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 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 {} \;
|
indicateActivity 'Fix File Permissions' find ${fontsDir} -type f -mindepth 1 -exec chmod g+rw,o+r {} \;
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure_system() {
|
function configure_system() {
|
||||||
lop -y h1 -- -i 'Install Fonts'
|
lop -y h1 -- -i 'Install Fonts'
|
||||||
}
|
}
|
||||||
|
|
||||||
function getExecPrerequisites() {
|
function getExecPrerequisites() {
|
||||||
cmds=(
|
cmds=(
|
||||||
[git]=''
|
[git]=''
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultGitGoogleFontsURL() {
|
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() {
|
function getQuestions() {
|
||||||
questions=(
|
questions=(
|
||||||
'i: git-google-fonts=Which Git repository shall be used to install Google Fonts from? # default:'"$(getDefaultGitGoogleFontsURL)"
|
'i: git-google-fonts=Which Git repository shall be used to install Google Fonts from? # default:'"$(getDefaultGitGoogleFontsURL)"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUsage() {
|
function getUsage() {
|
||||||
read -r -d '' text <<- USAGE
|
read -r -d '' text <<- USAGE
|
||||||
Usage:
|
Usage:
|
||||||
$cmdName show-questions [<modkey> <modans>]...
|
$cmdName show-questions [<modkey> <modans>]...
|
||||||
$cmdName [-v] [-d FILE] --git-google-fonts URL
|
$cmdName [-v] [-d FILE] --git-google-fonts URL
|
||||||
@@ -46,12 +46,12 @@ function getUsage() {
|
|||||||
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
Copyright (C) 2022 Rezart Qelibari, Astzweig GmbH & Co. KG
|
||||||
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
License EUPL-1.2. There is NO WARRANTY, to the extent permitted by law.
|
||||||
USAGE
|
USAGE
|
||||||
print -- ${text}
|
print -- ${text}
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
if [[ "${ZSH_EVAL_CONTEXT}" == toplevel ]]; then
|
||||||
_DIR="${0:A:h}"
|
_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 }
|
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}"
|
source "${ASTZWEIG_MACOS_SYSTEM_LIB}"
|
||||||
module_main $0 "$@"
|
module_main $0 "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
128
modules/lib.sh
128
modules/lib.sh
@@ -2,107 +2,107 @@
|
|||||||
# vi: set ft=zsh tw=80 ts=2
|
# vi: set ft=zsh tw=80 ts=2
|
||||||
|
|
||||||
function autoloadZShLib() {
|
function autoloadZShLib() {
|
||||||
test -d "${ASTZWEIG_ZSHLIB}" || { echo "This module needs astzweig/zshlib to work." >&2; return 99 }
|
test -d "${ASTZWEIG_ZSHLIB}" || { echo "This module needs astzweig/zshlib to work." >&2; return 99 }
|
||||||
FPATH="${ASTZWEIG_ZSHLIB}:${FPATH}"
|
FPATH="${ASTZWEIG_ZSHLIB}:${FPATH}"
|
||||||
fpath+=(${ASTZWEIG_ZSHLIB})
|
fpath+=(${ASTZWEIG_ZSHLIB})
|
||||||
if [[ -d ${ASTZWEIG_ZSHLIB} ]]; then
|
if [[ -d ${ASTZWEIG_ZSHLIB} ]]; then
|
||||||
local funcNames=($(find "${ASTZWEIG_ZSHLIB}" -type f -perm +u=x -maxdepth 1 | awk -F/ '{ print $NF }'))
|
local funcNames=($(find "${ASTZWEIG_ZSHLIB}" -type f -perm +u=x -maxdepth 1 | awk -F/ '{ print $NF }'))
|
||||||
autoload -Uz ${funcNames}
|
autoload -Uz ${funcNames}
|
||||||
elif [[ -f ${ASTZWEIG_ZSHLIB} ]]; then
|
elif [[ -f ${ASTZWEIG_ZSHLIB} ]]; then
|
||||||
autoload -Uzw ${ASTZWEIG_ZSHLIB}
|
autoload -Uzw ${ASTZWEIG_ZSHLIB}
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDebug() {
|
function isDebug() {
|
||||||
test "${MACOS_SYSTEM_DEBUG}" = true -o "${MACOS_SYSTEM_DEBUG}" = 1
|
test "${MACOS_SYSTEM_DEBUG}" = true -o "${MACOS_SYSTEM_DEBUG}" = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureLogging() {
|
function configureLogging() {
|
||||||
local output=tostdout level=info
|
local output=tostdout level=info
|
||||||
[ -n "${logfile}" ] && output=${logfile}
|
[ -n "${logfile}" ] && output=${logfile}
|
||||||
[ "${verbose}" = true ] && level=debug
|
[ "${verbose}" = true ] && level=debug
|
||||||
lop setoutput -l ${level} ${output}
|
lop setoutput -l ${level} ${output}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getModuleAnswerByKeyRegEx() {
|
function getModuleAnswerByKeyRegEx() {
|
||||||
local key value
|
local key value
|
||||||
local searchRegEx=$1
|
local searchRegEx=$1
|
||||||
for key moduleAnswer in ${modkey:^modans}; do
|
for key moduleAnswer in ${modkey:^modans}; do
|
||||||
[[ $key =~ $searchRegEx ]] && return 0
|
[[ $key =~ $searchRegEx ]] && return 0
|
||||||
done
|
done
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensurePathOrLogError() {
|
function ensurePathOrLogError() {
|
||||||
local dir=$1 msg=$2
|
local dir=$1 msg=$2
|
||||||
[[ -d ${dir} ]] || install -m $(umask -S) -d $(getMissingPaths ${dir}) || {
|
[[ -d ${dir} ]] || install -m $(umask -S) -d $(getMissingPaths ${dir}) || {
|
||||||
lop -- -e "$msg" -e "Directory ${dir} does not exist and could not be created."
|
lop -- -e "$msg" -e "Directory ${dir} does not exist and could not be created."
|
||||||
return 10
|
return 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkHelpPrerequisites() {
|
function checkHelpPrerequisites() {
|
||||||
local -A cmds
|
local -A cmds
|
||||||
getHelpPrerequisites || return
|
getHelpPrerequisites || return
|
||||||
checkCommands ${(k)cmds}
|
checkCommands ${(k)cmds}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addDocoptsToCmds() {
|
function addDocoptsToCmds() {
|
||||||
cmds+=(docopts '(with -f option supported)')
|
cmds+=(docopts '(with -f option supported)')
|
||||||
}
|
}
|
||||||
|
|
||||||
function requireRootPrivileges() {
|
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 $_() {
|
whence getHelpPrerequisites >&! /dev/null || function $_() {
|
||||||
addDocoptsToCmds
|
addDocoptsToCmds
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkQuestionsPrerequisites() {
|
function checkQuestionsPrerequisites() {
|
||||||
local -A cmds
|
local -A cmds
|
||||||
getQuestionsPrerequisites || return
|
getQuestionsPrerequisites || return
|
||||||
checkCommands ${(k)cmds}
|
checkCommands ${(k)cmds}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkExecPrerequisites() {
|
function checkExecPrerequisites() {
|
||||||
local -A cmds
|
local -A cmds
|
||||||
getExecPrerequisites || return
|
getExecPrerequisites || return
|
||||||
checkCommands ${(k)cmds}
|
checkCommands ${(k)cmds}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showQuestions() {
|
function showQuestions() {
|
||||||
local questions=()
|
local questions=()
|
||||||
getQuestions
|
getQuestions
|
||||||
for question in ${questions}; do
|
for question in ${questions}; do
|
||||||
hio -- body "${question}"
|
hio -- body "${question}"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function module_main() {
|
function module_main() {
|
||||||
local cmdPath=${1} cmdName=${1:t} hookBag=()
|
local cmdPath=${1} cmdName=${1:t} hookBag=()
|
||||||
local -A traps=()
|
local -A traps=()
|
||||||
preCommandNameHook "$@" || return
|
preCommandNameHook "$@" || return
|
||||||
shift
|
shift
|
||||||
autoloadZShLib || return
|
autoloadZShLib || return
|
||||||
preHelpHook "$@" || return
|
preHelpHook "$@" || return
|
||||||
checkHelpPrerequisites || return
|
checkHelpPrerequisites || return
|
||||||
configureLogging
|
configureLogging
|
||||||
trap 'traps call int; return 70' INT
|
trap 'traps call int; return 70' INT
|
||||||
trap 'traps call term; return 80' TERM
|
trap 'traps call term; return 80' TERM
|
||||||
trap 'traps call exit' EXIT
|
trap 'traps call exit' EXIT
|
||||||
eval "`getUsage $cmdName | docopts -f -V - -h - : "$@"`"
|
eval "`getUsage $cmdName | docopts -f -V - -h - : "$@"`"
|
||||||
preQuestionHook "$@" || return
|
preQuestionHook "$@" || return
|
||||||
checkQuestionsPrerequisites || return
|
checkQuestionsPrerequisites || return
|
||||||
[ "${show_questions}" = true ] && { showQuestions; return }
|
[ "${show_questions}" = true ] && { showQuestions; return }
|
||||||
preExecHook "$@" || return
|
preExecHook "$@" || return
|
||||||
checkExecPrerequisites || return
|
checkExecPrerequisites || return
|
||||||
configure_system
|
configure_system
|
||||||
}
|
}
|
||||||
|
|
||||||
function {
|
function {
|
||||||
local name
|
local name
|
||||||
for name in preCommandNameHook preHelpHook preQuestionHook preExecHook getQuestionsPrerequisites getExecPrerequisites getQuestions getUsage; do
|
for name in preCommandNameHook preHelpHook preQuestionHook preExecHook getQuestionsPrerequisites getExecPrerequisites getQuestions getUsage; do
|
||||||
whence ${name} >&! /dev/null || function $_() {}
|
whence ${name} >&! /dev/null || function $_() {}
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user