121 lines
2.6 KiB
Bash
121 lines
2.6 KiB
Bash
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/as-root.sh"
|
|
|
|
say() {
|
|
printf '%s\n' "$1"
|
|
}
|
|
|
|
note_change() {
|
|
changes=$((changes + 1))
|
|
}
|
|
|
|
unit_search_dirs=(
|
|
/etc/systemd/system
|
|
/run/systemd/system
|
|
/usr/local/lib/systemd/system
|
|
/usr/lib/systemd/system
|
|
)
|
|
|
|
system_unit_exists() {
|
|
local unit="$1" dir
|
|
|
|
systemctl cat -- "$unit" &>/dev/null && return 0
|
|
|
|
for dir in "${unit_search_dirs[@]}"; do
|
|
[[ -e $dir/$unit ]] && return 0
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
user_manager_available() {
|
|
systemctl --user show-environment &>/dev/null
|
|
}
|
|
|
|
system_unit_state() {
|
|
systemctl is-enabled -- "$1" 2>/dev/null || true
|
|
}
|
|
|
|
user_unit_state() {
|
|
systemctl --user is-enabled -- "$1" 2>/dev/null || true
|
|
}
|
|
|
|
# Copy a file only when the destination is missing or matches what we last
|
|
# wrote. A destination that differs is a local edit, reported and kept unless
|
|
# --force says otherwise.
|
|
install_file() {
|
|
local source="$1" dest="$2" label="$3"
|
|
|
|
if [[ ! -e $source ]]; then
|
|
say "SKIP $label (missing in repo)"
|
|
return 0
|
|
fi
|
|
|
|
if [[ -e $dest ]] && cmp -s "$source" "$dest"; then
|
|
say "ok $label"
|
|
return 0
|
|
fi
|
|
|
|
note_change
|
|
|
|
if [[ -e $dest ]] && [[ $force == false ]]; then
|
|
say "DIFF $label (local changes kept; --force to overwrite)"
|
|
return 0
|
|
fi
|
|
|
|
if [[ $check == true ]]; then
|
|
say "would write $label"
|
|
return 0
|
|
fi
|
|
|
|
mkdir -p "$(dirname "$dest")"
|
|
[[ -e $dest ]] && cp "$dest" "$dest.bak"
|
|
cp "$source" "$dest"
|
|
say "write $label"
|
|
}
|
|
|
|
install_tree() {
|
|
local source="$1" dest="$2" label="$3"
|
|
|
|
if [[ ! -d $source ]]; then
|
|
say "SKIP $label (missing in repo)"
|
|
return 0
|
|
fi
|
|
|
|
local relative
|
|
while IFS= read -r relative; do
|
|
install_file "$source/$relative" "$dest/$relative" "$label/$relative"
|
|
done < <(cd "$source" && find . -type f -printf '%P\n' | sort)
|
|
}
|
|
|
|
# Same reporting as install_file for a destination outside $HOME. The mode is
|
|
# explicit because these land in /etc and /usr/local, and no .bak is kept: the
|
|
# only writer of these paths is the installer.
|
|
install_root_file() {
|
|
local source="$1" dest="$2" label="$3" mode="${4:-0644}"
|
|
|
|
if [[ ! -e $source ]]; then
|
|
say "SKIP $label (missing in repo)"
|
|
return 0
|
|
fi
|
|
|
|
if [[ -e $dest ]] && cmp -s "$source" "$dest"; then
|
|
say "ok $label"
|
|
return 0
|
|
fi
|
|
|
|
note_change
|
|
|
|
if [[ -e $dest ]] && [[ $force == false ]]; then
|
|
say "DIFF $label (local changes kept; --force to overwrite)"
|
|
return 0
|
|
fi
|
|
|
|
if [[ $check == true ]]; then
|
|
say "would write $label (needs sudo)"
|
|
return 0
|
|
fi
|
|
|
|
as_root install -Dm "$mode" "$source" "$dest"
|
|
say "write $label"
|
|
}
|