[Sync] Lua Hyprland chain, licence cleanup

This commit is contained in:
Coja committed 2026-11-09 18:25:35 +01:00
1 parent 93b4f695ce
commit 47166d877f
183 files changed
+5618 -5839

No files matched your search

+84 -34
View File
@@ -93,6 +93,29 @@ HOST="${ARGS[0]:-${RECORDED:-$(hostname -s)}}"
echo "error: no host resolved — pass one (./install.sh <host>) or write it to ~/.config/dots-host" >&2
exit 1
}
# a host must be a plain top-level package name. common/gui are base LAYERS: as a host, the layer
# is released, restowed and then re-stowed with --override, and the name is recorded so every later
# run (and dotsync) repeats it. bin/ is tooling, never a package. Anything with a leading dot or a
# slash (`.`, `..`, `.git`, `a/b`) would let stow treat the repo root or a non-package as one —
# the same hazard as the empty HOST above.
host_ok() { # host_ok <name> — is <name> something install.sh may stow as a host overlay?
case "$1" in
common | gui | bin | .* | */* | -* | "") return 1 ;;
esac
}
if ! host_ok "$HOST"; then
case "$HOST" in
common | gui)
echo "error: '$HOST' is a base layer, not a host package — a terminal-only machine runs" >&2
echo " 'touch ~/.config/dots-headless; ./install.sh' with no host argument" >&2
;;
*) echo "error: '$HOST' is not a host package name (top-level dir like wm, lw, fl)" >&2 ;;
esac
[ "$HOST" = "$RECORDED" ] && echo " (it is recorded in ~/.config/dots-host — rm that file first)" >&2
exit 2
fi
# a bad recorded name with a valid explicit host: don't release it in step 1, just replace it
host_ok "$RECORDED" || RECORDED=""
DOTS="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
command -v stow >/dev/null 2>&1 || {
@@ -112,6 +135,35 @@ fi
gui=true
[ -e "$HEADLESS_MARKER" ] && gui=false
# Every stow call goes through stow_cmd, so --no-folding is never forgotten on one of them. It
# matters on -D as much as on -S: an unstow REFOLDS each dir it walks whose remaining links all
# come from one package — even a package that was never deployed. A bare `-D gui` on headless
# hosts collapsed ~/.config/fish/functions and fish/conf.d (gui ships files in both) into single
# links to common/, so anything written there (funcsave, fisher) landed in the repo.
stow_cmd() { stow --no-folding -d "$DOTS" -t "$HOME" "$@"; }
FAIL=0
# unstow one package, then prune the dirs it would have created under ~/.config if they are now
# empty. Only the package's own .config dirs are candidates (deepest first, rmdir = empty only),
# so an empty dir the user or an app made elsewhere is never touched. A failed unstow is reported
# with stow's own message and fails the run — it never passes silently as "done".
unstow_pkg() { # unstow_pkg <pkg>; returns stow's status
local p="$1" out rel
[ -d "$DOTS/$p" ] || return 0
if ! out=$(stow_cmd $DRY -D "$p" 2>&1); then
echo " FAILED to unstow $p:" >&2
printf '%s\n' "$out" | sed 's/^/ /' >&2
FAIL=1
return 1
fi
if [ -z "$DRY" ] && [ -d "$DOTS/$p/.config" ]; then
while IFS= read -r rel; do
[ -d "$HOME/$rel" ] && [ ! -L "$HOME/$rel" ] && rmdir "$HOME/$rel" 2>/dev/null
done < <(cd "$DOTS/$p" && find .config -mindepth 1 -depth -type d)
fi
return 0
}
echo "host=$HOST dots=$DOTS gui=$gui${DRY:+ (dry-run)}"
# --- revert mode: unstow this host's packages (reverse of deploy), leave repo + real files intact ---
@@ -120,18 +172,12 @@ if [ "$UNSTOW" -eq 1 ]; then
[ -n "$DRY" ] && verb="would unstow"
for p in "$HOST" gui common; do
[ -d "$DOTS/$p" ] || continue
if stow $DRY -d "$DOTS" -t "$HOME" -D "$p" 2>/dev/null; then
echo " $verb $p"
fi
# prune the now-empty dirs this package created under ~/.config (empty only — never real files)
if [ -z "$DRY" ] && [ -d "$DOTS/$p/.config" ]; then
for d in "$DOTS/$p"/.config/*/; do
t="$HOME/.config/$(basename "$d")"
[ -d "$t" ] && find "$t" -type d -empty -delete 2>/dev/null || true
done
fi
unstow_pkg "$p" && echo " $verb $p"
done
if [ -n "$DRY" ]; then
if [ "$FAIL" -ne 0 ]; then
echo "FAILED: some packages could not be unstowed (see above)." >&2
exit 1
elif [ -n "$DRY" ]; then
echo "(dry-run) nothing changed."
else
echo "reverted — removed this host's stow symlinks. ~/.dots and any real files are untouched."
@@ -183,13 +229,18 @@ fi
# --- keep a live Hyprland session quiet while symlinks are removed/recreated ---
# Step 1 releases the host overlay before restowing, and Hyprland's config watcher reloads
# the moment a sourced file vanishes (monitors.conf/host.conf, hyprland.conf:58/60 — the two
# that come from the overlay): that parse aborts and the session sits on a partial config
# until a manual Super+Shift+R. So pause the watcher and reload once at the end, when every
# the moment a watched file flickers (under the Lua chain that's ~/.config/hypr/*.lua —
# hyprland.lua/host.lua both come from packages this run re-links): every re-parse makes the
# session visibly jump/resize. So pause the watcher and reload once at the end, when every
# link is back. The final reload also re-reads misc:disable_autoreload from the config,
# undoing the runtime keyword — no state is left behind.
# undoing the runtime override — no state is left behind.
# The pause command differs by config mode (same branch as HyDE's color.set.sh): in Lua mode
# `hyprctl keyword` is gone — runtime config goes through `hyprctl eval` + hl.config.
if [ -z "$DRY" ] && [ -n "${HYPRLAND_INSTANCE_SIGNATURE:-}" ] && command -v hyprctl >/dev/null 2>&1; then
hyprctl keyword misc:disable_autoreload true >/dev/null 2>&1
case "${HYPRLAND_CONFIG:-}" in
*.lua) hyprctl eval 'hl.config({misc = {disable_autoreload = true}})' >/dev/null 2>&1 ;;
*) hyprctl keyword misc:disable_autoreload true >/dev/null 2>&1 ;;
esac
trap 'hyprctl reload >/dev/null 2>&1' EXIT
fi
@@ -197,20 +248,17 @@ fi
# The PREVIOUSLY recorded host is released too, so switching a machine to another overlay
# works: its leftover links are "stowed to a different package" as far as the step-2 restows
# are concerned, which would abort those whole packages. Releasing an already-released
# package is a harmless no-op, so the repeat when nothing changed costs nothing.
# package is a harmless no-op (exit 0), so a failure here is real and is reported.
if [ -z "$DRY" ]; then
for p in "$HOST" "$RECORDED"; do
[ -n "$p" ] && [ -d "$DOTS/$p" ] && stow -d "$DOTS" -t "$HOME" -D "$p" 2>/dev/null
done
true # a release that found nothing to do must not fail the run
unstow_pkg "$HOST"
[ -n "$RECORDED" ] && [ "$RECORDED" != "$HOST" ] && unstow_pkg "$RECORDED"
fi
# stow one package; track failures instead of silently continuing and reporting success
FAIL=0
stow_pkg() { # stow_pkg <label> <stow args...>
local label="$1"
shift
if stow $DRY $ADOPT --no-folding -d "$DOTS" -t "$HOME" "$@"; then
if stow_cmd $DRY $ADOPT "$@"; then
echo " stowed $label"
else
FAIL=1
@@ -228,16 +276,7 @@ if [ "$gui" = true ]; then
stow_pkg gui $DRYOVR -R gui
else
# headless: ensure no stray gui is left deployed (self-heals a prior wrong run)
if stow $DRY -d "$DOTS" -t "$HOME" -D gui 2>/dev/null; then
test -z "$DRY" && echo " ensured gui not deployed (headless)"
fi
# prune the now-empty dirs that unstowing gui leaves behind (only removes empty ones)
if [ -z "$DRY" ] && [ -d "$DOTS/gui/.config" ]; then
for d in "$DOTS"/gui/.config/*/; do
t="$HOME/.config/$(basename "$d")"
[ -d "$t" ] && find "$t" -type d -empty -delete 2>/dev/null || true
done
fi
unstow_pkg gui && test -z "$DRY" && echo " ensured gui not deployed (headless)"
fi
# 3. stow the host overlay last, overriding base files
@@ -269,6 +308,17 @@ if [ "$gui" = true ]; then
fi
fi
# 3.6 fill the dots-icons overlay (flat tray icons at every size) with links into this host's
# Tela-circle-dracula — the repo can't ship Tela's SVGs (no upstream licence). A failure only
# warns: the overlay inherits Tela, so the worst case is the coloured 44px circles again.
if [ "$gui" = true ]; then
"$DOTS/bin/dots-icons-link.sh" $DRY || echo " WARN: dots-icons overlay incomplete (see above)" >&2
fi
# 3.7 download the upstream theme files the configs use but the repo doesn't ship (aichat's
# One Half Dark), pinned by commit + sha256. Every host; offline only warns (built-in theme).
"$DOTS/bin/dots-themes-fetch.sh" $DRY || echo " WARN: theme download incomplete (see above)" >&2
# 4. surface Claude config into ~/.claude. Deliberately NOT gated on stow success: link.sh's
# drift heal is what clears the usual stow failure (a ~/.config/claude file severed by one
# of Claude's atomic rewrites), so running it only after a clean stow made that failure
@@ -284,7 +334,7 @@ fi
# fail loudly with a non-zero exit so callers / re-runs can tell it did not apply
if [ "$FAIL" -ne 0 ]; then
echo "FAILED: some packages could not be stowed (conflicts above)." >&2
echo "FAILED: some packages could not be stowed or unstowed (see above)." >&2
echo " first run on a machine with existing real files? re-run with -a to adopt them" >&2
echo " (-a rewrites the repo working tree with the live copies — it refuses to run while" >&2
echo " the repo has uncommitted edits, so commit/stash first)." >&2