mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 17:47:05 +01:00
Flatten i3-configuration and misc/testsAndMisc-bash
i3 config was filed under periodic_background, which it never was. It is now linux_configuration/i3/ (config + installer) and linux_configuration/i3blocks/ (the status scripts), both at depth 2. misc/testsAndMisc-bash/ was a directory named after the repo it already lived in, so its contents moved up to misc/. Its stray .gitignore came along, keeping the media rules working from the new location; its .vscode/tasks.json did not, because it invoked Bash/transcribe.sh, a path this repo dropped long ago. Most of this commit is the references the previous flatten missed. Its regex skipped anything with a variable prefix, which left 16 files -- including check_and_enable_services.sh and install_core_system.sh, the orchestrators -- still naming $CONFIG_DIR/scripts/periodic_background/... It had also rewritten three i3 paths into scripts/i3blocks/, a directory that has never existed; the i3blocks suites caught that by failing. 13 more symlinks broke on the i3 move. Repointed, and cpu_monitor/volume/ disk were run again to confirm the bar still reports. Depth 139 -> 104. Roughly 47 of the remainder sit in digital_wellbeing and hosts, still deferred. The rest encode real structure -- a C project, Python package directories, artgate's routes/styles, systemd unit dirs -- so flattening them further would destroy information rather than taxonomy. Verified: 1798 tests at 100%, both i3blocks suites pass, the shell coverage gate is clean, and the relocated media rules still ignore what they should while test_fw.srt stays tracked. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
This commit is contained in:
parent
4f2b0ccdf7
commit
08aac8d7d1
@ -206,11 +206,11 @@ cached snapshot tools, some builds don't refresh them between calls.
|
||||
|
||||
## Reference implementations in this repo
|
||||
|
||||
- `linux_configuration/i3-configuration/i3blocks/volume.sh` — persist mode with `pactl subscribe`.
|
||||
- `linux_configuration/i3-configuration/i3blocks/gpu_monitor.sh` — persist mode with `nvidia-smi --loop`.
|
||||
- `linux_configuration/i3-configuration/i3blocks/battery_status.sh` — zero-fork via `/sys/class/power_supply`.
|
||||
- `linux_configuration/i3-configuration/i3blocks/cpu_monitor.sh` — zero-fork via `/proc/loadavg` + `/sys/class/hwmon`.
|
||||
- `linux_configuration/i3-configuration/i3blocks/motherboard_temp.sh` — zero-fork via `/sys/class/hwmon`.
|
||||
- `linux_configuration/i3blocks/volume.sh` — persist mode with `pactl subscribe`.
|
||||
- `linux_configuration/i3blocks/gpu_monitor.sh` — persist mode with `nvidia-smi --loop`.
|
||||
- `linux_configuration/i3blocks/battery_status.sh` — zero-fork via `/sys/class/power_supply`.
|
||||
- `linux_configuration/i3blocks/cpu_monitor.sh` — zero-fork via `/proc/loadavg` + `/sys/class/hwmon`.
|
||||
- `linux_configuration/i3blocks/motherboard_temp.sh` — zero-fork via `/sys/class/hwmon`.
|
||||
- `linux_configuration/system-maintenance/systemd/monitors.slice` — resource-cap slice.
|
||||
- `phone_focus_mode/dns_enforcer.sh::chain_intact()`/`expected_rule_count()` — R9's hash/count-gate pattern, fixed 2026-07-03 after it was found pegging Android's `netd` at ~50% CPU.
|
||||
- `phone_focus_mode/hosts_enforcer.sh::sync_magisk_module` — the original hash-before-write pattern R9 mirrors.
|
||||
|
||||
@ -218,7 +218,7 @@ repos:
|
||||
(?x)^(
|
||||
Bash/.*|
|
||||
\.venv/.*|
|
||||
linux_configuration/misc/testsAndMisc-bash/tools/.*
|
||||
linux_configuration/misc/tools/.*
|
||||
)$
|
||||
additional_dependencies:
|
||||
- types-requests
|
||||
|
||||
@ -48,19 +48,19 @@ its timer next fires.
|
||||
4:export PYTHONPATH="/home/kuhy/testsAndMisc${PYTHONPATH:+:$PYTHONPATH}"
|
||||
|
||||
## symlinks into the repo
|
||||
/home/kuhy/.config/i3blocks/claude_usage.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/claude_usage.sh
|
||||
/home/kuhy/.config/i3blocks/config -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/config
|
||||
/home/kuhy/.config/i3blocks/cpu_monitor.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/cpu_monitor.sh
|
||||
/home/kuhy/.config/i3blocks/disk.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/disk.sh
|
||||
/home/kuhy/.config/i3blocks/ethernet.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/ethernet.sh
|
||||
/home/kuhy/.config/i3blocks/gpu_monitor.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/gpu_monitor.sh
|
||||
/home/kuhy/.config/i3blocks/memory.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/memory.sh
|
||||
/home/kuhy/.config/i3blocks/motherboard_temp.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/motherboard_temp.sh
|
||||
/home/kuhy/.config/i3blocks/pc_startup_status.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/pc_startup_status.sh
|
||||
/home/kuhy/.config/i3blocks/persist_common.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/persist_common.sh
|
||||
/home/kuhy/.config/i3blocks/shutdown_countdown.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/shutdown_countdown.sh
|
||||
/home/kuhy/.config/i3blocks/time.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/time.sh
|
||||
/home/kuhy/.config/i3blocks/volume.sh -> /home/kuhy/testsAndMisc/linux_configuration/periodic_background/i3-configuration/i3blocks/volume.sh
|
||||
/home/kuhy/.config/i3blocks/claude_usage.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/claude_usage.sh
|
||||
/home/kuhy/.config/i3blocks/config -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/config
|
||||
/home/kuhy/.config/i3blocks/cpu_monitor.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/cpu_monitor.sh
|
||||
/home/kuhy/.config/i3blocks/disk.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/disk.sh
|
||||
/home/kuhy/.config/i3blocks/ethernet.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/ethernet.sh
|
||||
/home/kuhy/.config/i3blocks/gpu_monitor.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/gpu_monitor.sh
|
||||
/home/kuhy/.config/i3blocks/memory.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/memory.sh
|
||||
/home/kuhy/.config/i3blocks/motherboard_temp.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/motherboard_temp.sh
|
||||
/home/kuhy/.config/i3blocks/pc_startup_status.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/pc_startup_status.sh
|
||||
/home/kuhy/.config/i3blocks/persist_common.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/persist_common.sh
|
||||
/home/kuhy/.config/i3blocks/shutdown_countdown.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/shutdown_countdown.sh
|
||||
/home/kuhy/.config/i3blocks/time.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/time.sh
|
||||
/home/kuhy/.config/i3blocks/volume.sh -> /home/kuhy/testsAndMisc/linux_configuration/i3blocks/volume.sh
|
||||
/home/kuhy/.local/bin/keepass-open -> /home/kuhy/testsAndMisc/linux_configuration/features/keepass-open.sh
|
||||
/home/kuhy/.local/bin/line-speed-probe.sh -> /home/kuhy/testsAndMisc/linux_configuration/diagnostics/line-speed-probe.sh
|
||||
/home/kuhy/.local/bin/steam-download-duty.sh -> /home/kuhy/testsAndMisc/linux_configuration/diagnostics/steam-download-duty.sh
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "Flatten i3-configuration and misc/testsAndMisc-bash, and repair the references the first flatten missed",
|
||||
"objective": "Finish the flattening for the two remaining pure-taxonomy nestings, and close out the path rewrites that the previous commit's regex did not reach. The first flatten proved that the moves are easy and the references are the risk, so this change is mostly about finding references that a diff review would not surface.",
|
||||
"acceptance_criteria": [
|
||||
"i3 config no longer sits under periodic_background, where it never belonged; both resulting directories are at depth 2.",
|
||||
"misc/ no longer contains a directory named after the repo it lives in.",
|
||||
"The media-ignore rules from the moved .gitignore still apply at their new location, and no previously tracked file becomes ignored.",
|
||||
"Every $VAR/scripts/... reference is rewritten, including the orchestrators that name the still-deferred subsystems.",
|
||||
"Both i3blocks test suites pass, having been RUN rather than eyeballed.",
|
||||
"The repo-wide pytest gate still reports 100%.",
|
||||
"Every $HOME symlink broken by the move is repointed, and the i3blocks scripts are run to prove the bar works.",
|
||||
"pre-commit passes without --no-verify."
|
||||
],
|
||||
"out_of_scope": [
|
||||
"digital_wellbeing and hosts, deferred pending the guard-lib repoint; their references are updated to the new scheme but the directories stay.",
|
||||
"The ~57 remaining violations that encode real structure (a C project, Python package dirs, artgate's routes/styles, systemd unit dirs) rather than taxonomy."
|
||||
],
|
||||
"verifier": "check_directory_depth.sh --all falls 139 -> 104; both test_i3blocks_*.sh pass; pytest_changed_packages.py reports 1798 passed at 100%; find ~ -xtype l finds nothing; git check-ignore confirms the relocated media rules; check_shell_coverage.sh --all exits 0."
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
{
|
||||
"intent": "Continue the depth-2 flattening: lift i3 config out of periodic_background, drop the redundant misc/testsAndMisc-bash nesting, and fix the path references the previous flattening commit missed.",
|
||||
"scope": [
|
||||
"periodic_background/i3-configuration/ -> linux_configuration/i3/ + linux_configuration/i3blocks/",
|
||||
"misc/testsAndMisc-bash/* -> misc/",
|
||||
"16 path references and 13 more $HOME symlinks repointed",
|
||||
"Non-goal: digital_wellbeing and hosts, still deferred"
|
||||
],
|
||||
"changes": [
|
||||
"i3-configuration was never periodic background work; it is desktop config. Split into linux_configuration/i3/ (the i3 config and installer) and linux_configuration/i3blocks/ (the status scripts), both at depth 2.",
|
||||
"misc/testsAndMisc-bash/ was a directory named after the repo it already lives in. Its contents moved up to misc/, and its stray .gitignore moved with them so the media-ignore rules keep applying.",
|
||||
"Deleted misc/testsAndMisc-bash/.vscode/tasks.json: it invoked Bash/transcribe.sh, a path removed from this repo long ago.",
|
||||
"Fixed 16 files whose references carried a $VAR/scripts/ prefix that the previous commit's regex skipped -- including check_and_enable_services.sh and install_core_system.sh, the orchestrators that name digital_wellbeing and hosts paths.",
|
||||
"Fixed conftest.py's tools path and the three i3 test/installer paths that the earlier bulk rewrite mangled into scripts/i3blocks/."
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "check_directory_depth.sh --all",
|
||||
"result": "pass (improvement)",
|
||||
"evidence": "139 -> 104 violations. About 47 of the remainder are inside the deferred digital_wellbeing and hosts."
|
||||
},
|
||||
{
|
||||
"command": "bash linux_configuration/tests/test_i3blocks_{persist_common,efficiency}.sh",
|
||||
"result": "fail then pass",
|
||||
"evidence": "First run: 'scripts/i3blocks/persist_common.sh: No such file or directory' - the earlier rewrite had produced a path that never existed. Both pass after the fix."
|
||||
},
|
||||
{
|
||||
"command": "pytest_changed_packages.py",
|
||||
"result": "pass",
|
||||
"evidence": "1798 passed, TOTAL coverage 100.00%."
|
||||
},
|
||||
{
|
||||
"command": "find ~ -xtype l; then run the i3blocks scripts",
|
||||
"result": "pass",
|
||||
"evidence": "13 symlinks broke on the i3 move and were repointed; zero broken after. cpu_monitor, volume and disk emit real output ('52°C, 1.18', '100%', '1.5T/3.6T')."
|
||||
},
|
||||
{
|
||||
"command": "git check-ignore on the relocated media rules",
|
||||
"result": "pass",
|
||||
"evidence": "misc/x.mp4 and misc/tools/y.wav are still ignored from misc/.gitignore's new location, and the tracked test_fw.srt is still tracked."
|
||||
},
|
||||
{
|
||||
"command": "check_shell_coverage.sh --all",
|
||||
"result": "pass",
|
||||
"evidence": "Exit 0."
|
||||
}
|
||||
],
|
||||
"risks": [
|
||||
"check_and_enable_services.sh and install_core_system.sh now name the NEW digital_wellbeing and hosts paths. Those two subsystems have not moved yet, so the references are correct today and will need updating again when they do.",
|
||||
"The remaining ~57 non-deferred violations are structurally meaningful - a C project, Python package dirs, a Flutter-style routes/styles split, systemd unit dirs - rather than taxonomy, so flattening them further would lose information."
|
||||
],
|
||||
"rollback": [
|
||||
"git revert, then repoint the 13 i3blocks symlinks back with the same substitution reversed.",
|
||||
"Re-run the two i3 suites and pytest_changed_packages.py."
|
||||
]
|
||||
}
|
||||
@ -92,7 +92,7 @@ jscpd_output=$("$JSCPD_BIN" \
|
||||
--min-tokens 25 \
|
||||
--threshold 2 \
|
||||
--reporters "console" \
|
||||
--ignore "**/node_modules/**,**/.git/**,**/misc/testsAndMisc-bash/**,**/*.txt,**/.venv/**,**/lib/tests/**,**/tests/**" \
|
||||
--ignore "**/node_modules/**,**/.git/**,**/misc/**,**/*.txt,**/.venv/**,**/lib/tests/**,**/tests/**" \
|
||||
. 2>&1) || jscpd_exit=$?
|
||||
|
||||
if [[ ${jscpd_exit:-0} -ne 0 ]]; then
|
||||
|
||||
@ -13,7 +13,7 @@ This repo automates Linux desktop bootstrap, hardening, and i3 setup. It’s pri
|
||||
- `install_pacman_wrapper.sh` backs up `/usr/bin/pacman` to `pacman.orig` and symlinks to the wrapper.
|
||||
- periodic_background/system-maintenance/: templates and installer for periodic jobs and monitoring.
|
||||
- `setup_periodic_system.sh` installs: `/usr/local/bin/periodic-system-maintenance.sh`, a timer (`periodic-system-maintenance.timer`), a startup oneshot, and `hosts-file-monitor.service` that restores `/etc/hosts` if tampered. Also installs a browser pre-exec wrapper that re-runs the hosts installer before launching common browsers.
|
||||
- i3-configuration/: installs i3 and i3blocks configs with small font sizing logic (`i3-configuration/install.sh`).
|
||||
- i3/ + i3blocks/: install i3 and i3blocks configs with small font sizing logic (`i3/install.sh`).
|
||||
|
||||
## Conventions you should follow
|
||||
|
||||
@ -31,7 +31,7 @@ This repo automates Linux desktop bootstrap, hardening, and i3 setup. It’s pri
|
||||
- `sudo hosts/install.sh` to (re)build `/etc/hosts` from cache/upstream then lock it.
|
||||
- Guard layers (hosts/nsswitch/resolved) are managed by `guardctl file-guard <install|status|unlock|uninstall> <name>`; see `./fixes/migrate_hosts_guard_to_guard_lib.sh` to (re)install them.
|
||||
- To edit a guarded file: `sudo guardctl file-guard unlock <name>`, edit, then let the path-watcher re-lock it (or `guardctl file-guard enforce <name>`).
|
||||
- i3 config: `i3-configuration/install.sh` (copies `i3` and `i3blocks`, adjusts font size; installs required tools conditionally for Arch/Ubuntu).
|
||||
- i3 config: `i3/install.sh` (copies `i3` and `i3blocks`, adjusts font size; installs required tools conditionally for Arch/Ubuntu).
|
||||
|
||||
## Integration points and gotchas
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ SERVICE_NAME="media-organizer"
|
||||
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
|
||||
|
||||
DEFAULT_ORGANIZE_SCRIPT="/home/kuhy/testsAndMisc/linux_configuration/utils/organize_downloads.sh"
|
||||
LEGACY_ORGANIZE_SCRIPT="/home/kuhy/linux-configuration/scripts/utils/organize_downloads.sh"
|
||||
LEGACY_ORGANIZE_SCRIPT="/home/kuhy/linux-configuration/utils/organize_downloads.sh"
|
||||
if [[ -f $DEFAULT_ORGANIZE_SCRIPT ]]; then
|
||||
ORGANIZE_SCRIPT="$DEFAULT_ORGANIZE_SCRIPT"
|
||||
elif [[ -f $LEGACY_ORGANIZE_SCRIPT ]]; then
|
||||
|
||||
@ -66,7 +66,7 @@ fix_media_organizer() {
|
||||
local script_path=""
|
||||
local candidates=(
|
||||
"${ORGANIZE_SCRIPT_CANDIDATES:-/home/kuhy/testsAndMisc/linux_configuration/utils/organize_downloads.sh}"
|
||||
"/home/kuhy/linux-configuration/scripts/utils/organize_downloads.sh"
|
||||
"/home/kuhy/linux-configuration/utils/organize_downloads.sh"
|
||||
)
|
||||
for candidate in "${candidates[@]}"; do
|
||||
if [[ -f $candidate ]]; then
|
||||
|
||||
@ -71,7 +71,7 @@ _t_lacks "$(_t_calls)" "systemctl disable" \
|
||||
# candidate paths are absolute; the first is overridden into the tmpdir and
|
||||
# the second is a real home path that does not exist on this machine.
|
||||
arch_reset
|
||||
if [[ -f /home/kuhy/linux-configuration/scripts/utils/organize_downloads.sh ]]; then
|
||||
if [[ -f /home/kuhy/linux-configuration/utils/organize_downloads.sh ]]; then
|
||||
_t_pass "fix_media_organizer: SKIP not-found case (the second candidate exists here)"
|
||||
else
|
||||
out="$(fix_media_organizer 2>&1)"
|
||||
|
||||
@ -6,7 +6,6 @@ set -e
|
||||
# shellcheck source=lib/packages.sh
|
||||
. "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/packages.sh"
|
||||
|
||||
|
||||
# Trap errors and call the play_error_sound function
|
||||
trap 'play_error_sound' ERR
|
||||
|
||||
@ -15,18 +14,15 @@ git config --global init.defaultBranch main
|
||||
|
||||
# GPU detection (now split vendor-specific logic)
|
||||
if [ -f "./detect_gpu.sh" ]; then
|
||||
# shellcheck source=./detect_gpu.sh disable=SC1091
|
||||
. ./detect_gpu.sh
|
||||
# shellcheck source=./detect_gpu.sh disable=SC1091
|
||||
. ./detect_gpu.sh
|
||||
elif [ -f "./detect_gpu_and_install.sh" ]; then
|
||||
# shellcheck source=./detect_gpu_and_install.sh disable=SC1091
|
||||
. ./detect_gpu_and_install.sh
|
||||
# shellcheck source=./detect_gpu_and_install.sh disable=SC1091
|
||||
. ./detect_gpu_and_install.sh
|
||||
else
|
||||
echo "GPU detection scripts not found; continuing without GPU specific installation."
|
||||
echo "GPU detection scripts not found; continuing without GPU specific installation."
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
sudo cp /etc/makepkg.conf /etc/makepkg.conf.bak
|
||||
sudo cp ./makepkg.conf /etc/makepkg.conf
|
||||
sudo cp /etc/pacman.conf /etc/pacman.conf.bak
|
||||
@ -35,155 +31,154 @@ sudo cp ./pacman.conf /etc/pacman.conf
|
||||
# sudo cp ./mkinitcpio.conf /etc/mkinitcpio.conf
|
||||
# mkinitcpio -P
|
||||
# Reflector install / service management (idempotent & resilient)
|
||||
if pacman -Qi reflector > /dev/null 2>&1; then
|
||||
echo "reflector already installed"
|
||||
if pacman -Qi reflector >/dev/null 2>&1; then
|
||||
echo "reflector already installed"
|
||||
else
|
||||
yes | sudo pacman -Sy --noconfirm reflector || echo "Warning: reflector install failed (continuing)"
|
||||
yes | sudo pacman -Sy --noconfirm reflector || echo "Warning: reflector install failed (continuing)"
|
||||
fi
|
||||
# Prefer timer over service (Arch default)
|
||||
if systemctl list-unit-files | grep -q '^reflector.timer'; then
|
||||
if systemctl is-enabled reflector.timer > /dev/null 2>&1; then
|
||||
echo "reflector.timer already enabled"
|
||||
else
|
||||
sudo systemctl enable reflector.timer || echo "Warning: could not enable reflector.timer"
|
||||
fi
|
||||
if systemctl is-active reflector.timer > /dev/null 2>&1; then
|
||||
echo "reflector.timer already active"
|
||||
else
|
||||
if ! sudo systemctl start reflector.timer; then
|
||||
echo "Warning: failed to start reflector.timer (check: systemctl status reflector.timer; journalctl -xeu reflector.timer)"
|
||||
fi
|
||||
fi
|
||||
if systemctl is-enabled reflector.timer >/dev/null 2>&1; then
|
||||
echo "reflector.timer already enabled"
|
||||
else
|
||||
sudo systemctl enable reflector.timer || echo "Warning: could not enable reflector.timer"
|
||||
fi
|
||||
if systemctl is-active reflector.timer >/dev/null 2>&1; then
|
||||
echo "reflector.timer already active"
|
||||
else
|
||||
if ! sudo systemctl start reflector.timer; then
|
||||
echo "Warning: failed to start reflector.timer (check: systemctl status reflector.timer; journalctl -xeu reflector.timer)"
|
||||
fi
|
||||
fi
|
||||
elif systemctl list-unit-files | grep -q '^reflector.service'; then
|
||||
if systemctl is-enabled reflector.service > /dev/null 2>&1; then
|
||||
echo "reflector.service already enabled"
|
||||
else
|
||||
sudo systemctl enable reflector.service || echo "Warning: could not enable reflector.service"
|
||||
fi
|
||||
if systemctl is-active reflector.service > /dev/null 2>&1; then
|
||||
echo "reflector.service already running"
|
||||
else
|
||||
if ! sudo systemctl start reflector.service; then
|
||||
echo "Warning: failed to start reflector.service (check: systemctl status reflector.service; journalctl -xeu reflector.service)"
|
||||
fi
|
||||
fi
|
||||
if systemctl is-enabled reflector.service >/dev/null 2>&1; then
|
||||
echo "reflector.service already enabled"
|
||||
else
|
||||
sudo systemctl enable reflector.service || echo "Warning: could not enable reflector.service"
|
||||
fi
|
||||
if systemctl is-active reflector.service >/dev/null 2>&1; then
|
||||
echo "reflector.service already running"
|
||||
else
|
||||
if ! sudo systemctl start reflector.service; then
|
||||
echo "Warning: failed to start reflector.service (check: systemctl status reflector.service; journalctl -xeu reflector.service)"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "reflector systemd unit not found (neither timer nor service)"
|
||||
echo "reflector systemd unit not found (neither timer nor service)"
|
||||
fi
|
||||
# Read AUR packages from file (needed before pacman processing)
|
||||
declare -a aur_packages=()
|
||||
declare -a aur_package_names=()
|
||||
while IFS= read -r line; do
|
||||
if [[ -n $line && $line =~ ^[a-z0-9] ]]; then
|
||||
aur_packages+=("$line")
|
||||
aur_package_names+=("${line%% *}")
|
||||
fi
|
||||
done < "aur_packages.txt"
|
||||
|
||||
if [[ -n $line && $line =~ ^[a-z0-9] ]]; then
|
||||
aur_packages+=("$line")
|
||||
aur_package_names+=("${line%% *}")
|
||||
fi
|
||||
done <"aur_packages.txt"
|
||||
|
||||
# Read pacman packages from file
|
||||
declare -a pacman_packages
|
||||
while IFS= read -r line; do
|
||||
# Skip empty lines and comments (lines not starting with alphanumeric characters)
|
||||
if [[ -n $line && $line =~ ^[a-z0-9] ]]; then
|
||||
pacman_packages+=("$line")
|
||||
fi
|
||||
done < "pacman_packages.txt"
|
||||
# Skip empty lines and comments (lines not starting with alphanumeric characters)
|
||||
if [[ -n $line && $line =~ ^[a-z0-9] ]]; then
|
||||
pacman_packages+=("$line")
|
||||
fi
|
||||
done <"pacman_packages.txt"
|
||||
|
||||
for pkg in "${pacman_packages[@]}"; do
|
||||
# Skip NVIDIA packages if GPU is not NVIDIA
|
||||
if [ "$GPU_VENDOR" != "nvidia" ] && { [ "$pkg" = "nvidia" ] || [ "$pkg" = "nvidia-utils" ] || [ "$pkg" = "lib32-nvidia-utils" ]; }; then
|
||||
echo "Skipping $pkg (GPU vendor: $GPU_VENDOR)"
|
||||
continue
|
||||
fi
|
||||
# Check for texlive subpackages
|
||||
if [ "$pkg" == "texlive" ]; then
|
||||
# shellcheck disable=SC2034 # Used via nameref in all_subpackages_installed
|
||||
texlive_sub_pkgs=(
|
||||
texlive-basic texlive-bibtexextra texlive-binextra texlive-context texlive-fontsextra
|
||||
texlive-fontsrecommended texlive-fontutils texlive-formatsextra texlive-games texlive-humanities
|
||||
texlive-latex texlive-latexextra texlive-latexrecommended texlive-luatex texlive-mathscience
|
||||
texlive-metapost texlive-music texlive-pictures texlive-plaingeneric texlive-pstricks
|
||||
texlive-publishers texlive-xetex
|
||||
)
|
||||
if all_subpackages_installed texlive_sub_pkgs; then
|
||||
echo "All texlive subpackages are installed, skipping texlive"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
# Skip NVIDIA packages if GPU is not NVIDIA
|
||||
if [ "$GPU_VENDOR" != "nvidia" ] && { [ "$pkg" = "nvidia" ] || [ "$pkg" = "nvidia-utils" ] || [ "$pkg" = "lib32-nvidia-utils" ]; }; then
|
||||
echo "Skipping $pkg (GPU vendor: $GPU_VENDOR)"
|
||||
continue
|
||||
fi
|
||||
# Check for texlive subpackages
|
||||
if [ "$pkg" == "texlive" ]; then
|
||||
# shellcheck disable=SC2034 # Used via nameref in all_subpackages_installed
|
||||
texlive_sub_pkgs=(
|
||||
texlive-basic texlive-bibtexextra texlive-binextra texlive-context texlive-fontsextra
|
||||
texlive-fontsrecommended texlive-fontutils texlive-formatsextra texlive-games texlive-humanities
|
||||
texlive-latex texlive-latexextra texlive-latexrecommended texlive-luatex texlive-mathscience
|
||||
texlive-metapost texlive-music texlive-pictures texlive-plaingeneric texlive-pstricks
|
||||
texlive-publishers texlive-xetex
|
||||
)
|
||||
if all_subpackages_installed texlive_sub_pkgs; then
|
||||
echo "All texlive subpackages are installed, skipping texlive"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for texlive-lang subpackages
|
||||
if [ "$pkg" == "texlive-lang" ]; then
|
||||
# shellcheck disable=SC2034 # Used via nameref in all_subpackages_installed
|
||||
texlive_lang_sub_pkgs=(
|
||||
texlive-langarabic texlive-langchinese texlive-langcjk texlive-langcyrillic
|
||||
texlive-langczechslovak texlive-langenglish texlive-langeuropean texlive-langfrench
|
||||
texlive-langgerman texlive-langgreek texlive-langitalian texlive-langjapanese
|
||||
texlive-langkorean texlive-langother texlive-langpolish texlive-langportuguese
|
||||
texlive-langspanish
|
||||
)
|
||||
if all_subpackages_installed texlive_lang_sub_pkgs; then
|
||||
echo "All texlive-lang subpackages are installed, skipping texlive-lang"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
# Check for texlive-lang subpackages
|
||||
if [ "$pkg" == "texlive-lang" ]; then
|
||||
# shellcheck disable=SC2034 # Used via nameref in all_subpackages_installed
|
||||
texlive_lang_sub_pkgs=(
|
||||
texlive-langarabic texlive-langchinese texlive-langcjk texlive-langcyrillic
|
||||
texlive-langczechslovak texlive-langenglish texlive-langeuropean texlive-langfrench
|
||||
texlive-langgerman texlive-langgreek texlive-langitalian texlive-langjapanese
|
||||
texlive-langkorean texlive-langother texlive-langpolish texlive-langportuguese
|
||||
texlive-langspanish
|
||||
)
|
||||
if all_subpackages_installed texlive_lang_sub_pkgs; then
|
||||
echo "All texlive-lang subpackages are installed, skipping texlive-lang"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! pacman -Qi "$pkg" &> /dev/null; then
|
||||
if ! printf '%s
|
||||
if ! pacman -Qi "$pkg" &>/dev/null; then
|
||||
if ! printf '%s
|
||||
' "${aur_package_names[@]}" | grep -Fxq "$pkg"; then
|
||||
yes | sudo pacman -Sy --noconfirm "$pkg"
|
||||
else
|
||||
echo "$pkg exists in AUR packages, skipping pacman installation"
|
||||
fi
|
||||
else
|
||||
echo "$pkg is already installed"
|
||||
fi
|
||||
yes | sudo pacman -Sy --noconfirm "$pkg"
|
||||
else
|
||||
echo "$pkg exists in AUR packages, skipping pacman installation"
|
||||
fi
|
||||
else
|
||||
echo "$pkg is already installed"
|
||||
fi
|
||||
done
|
||||
if ! command -v nvm &> /dev/null; then
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
|
||||
if ! command -v nvm &>/dev/null; then
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
|
||||
else
|
||||
echo "nvm is already installed"
|
||||
echo "nvm is already installed"
|
||||
fi
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
if [ -s "$NVM_DIR/nvm.sh" ]; then
|
||||
# shellcheck source=/dev/null
|
||||
. "$NVM_DIR/nvm.sh"
|
||||
# shellcheck source=/dev/null
|
||||
. "$NVM_DIR/nvm.sh"
|
||||
else
|
||||
echo "nvm.sh not found at $NVM_DIR/nvm.sh" >&2
|
||||
echo "nvm.sh not found at $NVM_DIR/nvm.sh" >&2
|
||||
fi
|
||||
if command -v nvm &> /dev/null; then
|
||||
nvm i v18.20.5
|
||||
nvm install --lts
|
||||
if command -v nvm &>/dev/null; then
|
||||
nvm i v18.20.5
|
||||
nvm install --lts
|
||||
else
|
||||
echo "nvm command unavailable; skipping Node installation" >&2
|
||||
echo "nvm command unavailable; skipping Node installation" >&2
|
||||
fi
|
||||
sudo systemctl enable bluetooth.service
|
||||
sudo systemctl start bluetooth.service
|
||||
|
||||
for entry in "${aur_packages[@]}"; do
|
||||
pkg_name=${entry%% *}
|
||||
repo_url=${entry#* }
|
||||
if [ "$repo_url" = "$pkg_name" ] || [ -z "$repo_url" ]; then
|
||||
repo_url="https://aur.archlinux.org/${pkg_name}.git"
|
||||
fi
|
||||
install_from_aur "$repo_url" "$pkg_name"
|
||||
pkg_name=${entry%% *}
|
||||
repo_url=${entry#* }
|
||||
if [ "$repo_url" = "$pkg_name" ] || [ -z "$repo_url" ]; then
|
||||
repo_url="https://aur.archlinux.org/${pkg_name}.git"
|
||||
fi
|
||||
install_from_aur "$repo_url" "$pkg_name"
|
||||
done
|
||||
|
||||
cd ~/linux-configuration/fresh-install
|
||||
if [ ! -d "$HOME/.config/mpv" ]; then
|
||||
mkdir -p "$HOME/.config/mpv"
|
||||
mkdir -p "$HOME/.config/mpv"
|
||||
fi
|
||||
cp mpv.conf "$HOME/.config/mpv/mpv.conf"
|
||||
|
||||
if [ ! -d "$HOME/.oh-my-zsh" ]; then
|
||||
yes | sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
|
||||
yes | sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
|
||||
else
|
||||
echo "Oh My Zsh is already installed"
|
||||
echo "Oh My Zsh is already installed"
|
||||
fi
|
||||
|
||||
cd ~/linux-configuration
|
||||
sudo periodic_background/hosts/install.sh
|
||||
periodic_background/i3-configuration/install.sh
|
||||
i3/install.sh
|
||||
periodic_background/digital_wellbeing/pacman/install_pacman_wrapper.sh
|
||||
fixes/nvidia_troubleshoot.sh
|
||||
sudo features/setup_activitywatch.sh
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
# SECONDARY modules (prompted unless --all / --none given):
|
||||
# 4. Steam backlog enforcer – python_pkg/steam_backlog_enforcer/
|
||||
# 5. Pacman wrapper – periodic_background/digital_wellbeing/pacman/
|
||||
# 6. i3 configuration – periodic_background/i3-configuration/
|
||||
# 6. i3 configuration – i3/
|
||||
# 7. Compulsive opening block – block_compulsive_opening.sh
|
||||
#
|
||||
# Usage:
|
||||
@ -129,10 +129,10 @@ run_installer "Workout screen locker" \
|
||||
bash "$REPO_ROOT/python_pkg/screen_locker/install_systemd.sh"
|
||||
|
||||
run_installer "Hosts blocking" \
|
||||
bash "$LINUX_CONFIG/scripts/periodic_background/hosts/install.sh"
|
||||
bash "$LINUX_CONFIG/periodic_background/hosts/install.sh"
|
||||
|
||||
run_installer "Midnight shutdown timer" \
|
||||
bash "$LINUX_CONFIG/scripts/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh"
|
||||
bash "$LINUX_CONFIG/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh"
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# SECONDARY MODULES (prompted unless --all / --none)
|
||||
@ -143,13 +143,13 @@ ask_install "Steam backlog enforcer" \
|
||||
sudo bash "$REPO_ROOT/python_pkg/steam_backlog_enforcer/install.sh"
|
||||
|
||||
ask_install "Pacman wrapper" \
|
||||
bash "$LINUX_CONFIG/scripts/periodic_background/digital_wellbeing/pacman/install_pacman_wrapper.sh"
|
||||
bash "$LINUX_CONFIG/periodic_background/digital_wellbeing/pacman/install_pacman_wrapper.sh"
|
||||
|
||||
ask_install "i3 configuration" \
|
||||
bash "$LINUX_CONFIG/scripts/periodic_background/i3-configuration/install.sh"
|
||||
bash "$LINUX_CONFIG/i3/install.sh"
|
||||
|
||||
ask_install "Compulsive opening blockade" \
|
||||
sudo bash "$LINUX_CONFIG/scripts/periodic_background/digital_wellbeing/block_compulsive_opening.sh" install
|
||||
sudo bash "$LINUX_CONFIG/periodic_background/digital_wellbeing/block_compulsive_opening.sh" install
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
print_summary
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
# Source this file at the beginning of scripts that need shared functionality
|
||||
#
|
||||
# Usage: source "$(dirname "$(readlink -f "$0")")/../lib/common.sh"
|
||||
# Or: source "/path/to/scripts/lib/common.sh"
|
||||
# Or: source "/path/to/lib/common.sh"
|
||||
|
||||
# Prevent multiple sourcing
|
||||
[[ -n ${_LIB_COMMON_LOADED:-} ]] && return 0
|
||||
|
||||
@ -20,8 +20,8 @@ IFS=$'\n\t'
|
||||
|
||||
# Source common library for log functions
|
||||
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
||||
# shellcheck source=../../lib/common.sh
|
||||
source "$SCRIPT_DIR/../../lib/common.sh"
|
||||
# shellcheck source=../lib/common.sh
|
||||
source "$SCRIPT_DIR/../lib/common.sh"
|
||||
|
||||
DO_POLICY=false
|
||||
SET_DEFAULT=false
|
||||
@ -26,8 +26,8 @@ SCRIPT_NAME="$(basename "$0")"
|
||||
|
||||
# Source common library for log functions
|
||||
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
||||
# shellcheck source=../../lib/common.sh
|
||||
source "$SCRIPT_DIR/../../lib/common.sh"
|
||||
# shellcheck source=../lib/common.sh
|
||||
source "$SCRIPT_DIR/../lib/common.sh"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
@ -13,8 +13,8 @@ set -euo pipefail
|
||||
|
||||
# Source common library for shared functions
|
||||
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
||||
# shellcheck source=../../lib/common.sh
|
||||
source "$SCRIPT_DIR/../../lib/common.sh"
|
||||
# shellcheck source=../lib/common.sh
|
||||
source "$SCRIPT_DIR/../lib/common.sh"
|
||||
|
||||
YES=false
|
||||
while [[ $# -gt 0 ]]; do
|
||||
@ -9,8 +9,8 @@ set -euo pipefail
|
||||
|
||||
# Source common library for shared functions
|
||||
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
||||
# shellcheck source=../../lib/common.sh
|
||||
source "$SCRIPT_DIR/../../lib/common.sh"
|
||||
# shellcheck source=../lib/common.sh
|
||||
source "$SCRIPT_DIR/../lib/common.sh"
|
||||
|
||||
print_info() {
|
||||
echo "[info] $*"
|
||||
@ -4,8 +4,8 @@ set -euo pipefail
|
||||
|
||||
# Source common library for shared functions
|
||||
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
||||
# shellcheck source=../../lib/common.sh
|
||||
source "$SCRIPT_DIR/../../lib/common.sh"
|
||||
# shellcheck source=../lib/common.sh
|
||||
source "$SCRIPT_DIR/../lib/common.sh"
|
||||
|
||||
SCRIPT_NAME="$(basename "$0")"
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Transcribe tiny online smoke test",
|
||||
"type": "shell",
|
||||
"command": "bash",
|
||||
"args": [
|
||||
"/home/kuhy/testsAndMisc/Bash/transcribe.sh",
|
||||
"--online",
|
||||
"-m",
|
||||
"tiny"
|
||||
],
|
||||
"isBackground": false,
|
||||
"problemMatcher": ["$gcc"],
|
||||
"group": "build"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -58,20 +58,20 @@ SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
||||
CONFIG_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||
|
||||
# Script paths
|
||||
PACMAN_WRAPPER_INSTALL="$CONFIG_DIR/scripts/periodic_background/digital_wellbeing/pacman/install_pacman_wrapper.sh"
|
||||
MAKEPKG_WRAPPER_INSTALL="$CONFIG_DIR/scripts/periodic_background/digital_wellbeing/pacman/install_makepkg_wrapper.sh"
|
||||
PACMAN_WRAPPER_INSTALL="$CONFIG_DIR/periodic_background/digital_wellbeing/pacman/install_pacman_wrapper.sh"
|
||||
MAKEPKG_WRAPPER_INSTALL="$CONFIG_DIR/periodic_background/digital_wellbeing/pacman/install_makepkg_wrapper.sh"
|
||||
# Drift manifests written by the two installers above (see deployment_drift).
|
||||
PACMAN_WRAPPER_MANIFEST="/var/lib/pacman-wrapper/source.sha256"
|
||||
MAKEPKG_WRAPPER_MANIFEST="/var/lib/pacman-wrapper/makepkg-source.sha256"
|
||||
MIDNIGHT_SHUTDOWN_SCRIPT="$CONFIG_DIR/scripts/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh"
|
||||
STARTUP_MONITOR_SCRIPT="$CONFIG_DIR/scripts/periodic_background/digital_wellbeing/setup_pc_startup_monitor.sh"
|
||||
PERIODIC_SYSTEM_SCRIPT="$CONFIG_DIR/scripts/periodic_background/setup_periodic_system.sh"
|
||||
HOSTS_INSTALL_SCRIPT="$CONFIG_DIR/scripts/periodic_background/hosts/install.sh"
|
||||
MIDNIGHT_SHUTDOWN_SCRIPT="$CONFIG_DIR/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh"
|
||||
STARTUP_MONITOR_SCRIPT="$CONFIG_DIR/periodic_background/digital_wellbeing/setup_pc_startup_monitor.sh"
|
||||
PERIODIC_SYSTEM_SCRIPT="$CONFIG_DIR/periodic_background/setup_periodic_system.sh"
|
||||
HOSTS_INSTALL_SCRIPT="$CONFIG_DIR/periodic_background/hosts/install.sh"
|
||||
GUARD_LIB_MIGRATE_SCRIPT="$CONFIG_DIR/./fixes/migrate_hosts_guard_to_guard_lib.sh"
|
||||
COMPULSIVE_BLOCK_SCRIPT="$CONFIG_DIR/scripts/periodic_background/digital_wellbeing/block_compulsive_opening.sh"
|
||||
LEECHBLOCK_SCRIPT="$CONFIG_DIR/scripts/periodic_background/digital_wellbeing/install_leechblock.sh"
|
||||
REMOVE_GUEST_MODE_SCRIPT="$CONFIG_DIR/scripts/periodic_background/digital_wellbeing/remove_guest_mode.sh"
|
||||
VBOX_HOSTS_SCRIPT="$CONFIG_DIR/scripts/periodic_background/digital_wellbeing/virtualbox/enforce_vbox_hosts.sh"
|
||||
COMPULSIVE_BLOCK_SCRIPT="$CONFIG_DIR/periodic_background/digital_wellbeing/block_compulsive_opening.sh"
|
||||
LEECHBLOCK_SCRIPT="$CONFIG_DIR/periodic_background/digital_wellbeing/install_leechblock.sh"
|
||||
REMOVE_GUEST_MODE_SCRIPT="$CONFIG_DIR/periodic_background/digital_wellbeing/remove_guest_mode.sh"
|
||||
VBOX_HOSTS_SCRIPT="$CONFIG_DIR/periodic_background/digital_wellbeing/virtualbox/enforce_vbox_hosts.sh"
|
||||
# screen-locker was EXTRACTED out of this monorepo into its own repo
|
||||
# (github.com/kuhyx/screen-locker, checked out at ~/screen-locker), so these
|
||||
# paths deliberately live outside testsAndMisc. They used to point at
|
||||
|
||||
@ -119,7 +119,7 @@ ensure_periodic_maintenance() {
|
||||
"$self_dir/setup_periodic_system.sh"
|
||||
"$real_home/testsAndMisc/linux_configuration/periodic_background/setup_periodic_system.sh"
|
||||
"$real_home/linux_configuration/periodic_background/setup_periodic_system.sh"
|
||||
"$real_home/linux-configuration/scripts/periodic_background/setup_periodic_system.sh"
|
||||
"$real_home/linux-configuration/periodic_background/setup_periodic_system.sh"
|
||||
)
|
||||
local candidate
|
||||
for candidate in "${setup_candidates[@]}"; do
|
||||
|
||||
@ -17,10 +17,10 @@ init_setup_script "Periodic System Setup - Pacman Wrapper & Hosts File" "$@"
|
||||
CONFIG_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||
|
||||
# Define paths
|
||||
PACMAN_WRAPPER_SCRIPT="$CONFIG_DIR/scripts/periodic_background/digital_wellbeing/pacman/pacman_wrapper.sh"
|
||||
PACMAN_WRAPPER_INSTALL="$CONFIG_DIR/scripts/periodic_background/digital_wellbeing/pacman/install_pacman_wrapper.sh"
|
||||
MAKEPKG_WRAPPER_INSTALL="$CONFIG_DIR/scripts/periodic_background/digital_wellbeing/pacman/install_makepkg_wrapper.sh"
|
||||
HOSTS_INSTALL_SCRIPT="$CONFIG_DIR/scripts/periodic_background/hosts/install.sh"
|
||||
PACMAN_WRAPPER_SCRIPT="$CONFIG_DIR/periodic_background/digital_wellbeing/pacman/pacman_wrapper.sh"
|
||||
PACMAN_WRAPPER_INSTALL="$CONFIG_DIR/periodic_background/digital_wellbeing/pacman/install_pacman_wrapper.sh"
|
||||
MAKEPKG_WRAPPER_INSTALL="$CONFIG_DIR/periodic_background/digital_wellbeing/pacman/install_makepkg_wrapper.sh"
|
||||
HOSTS_INSTALL_SCRIPT="$CONFIG_DIR/periodic_background/hosts/install.sh"
|
||||
|
||||
echo ""
|
||||
echo "Configuration directory: $CONFIG_DIR"
|
||||
@ -29,7 +29,7 @@ echo "Pacman wrapper installer: $PACMAN_WRAPPER_INSTALL"
|
||||
echo "Hosts install script: $HOSTS_INSTALL_SCRIPT"
|
||||
|
||||
# Templates directory (version-controlled files)
|
||||
TEMPLATES_BASE="$CONFIG_DIR/scripts/periodic_background/system-maintenance"
|
||||
TEMPLATES_BASE="$CONFIG_DIR/periodic_background/system-maintenance"
|
||||
BIN_TEMPLATES="$TEMPLATES_BASE/bin"
|
||||
SYSTEMD_TEMPLATES="$TEMPLATES_BASE/systemd"
|
||||
LOGROTATE_TEMPLATES="$TEMPLATES_BASE/logrotate"
|
||||
@ -49,127 +49,127 @@ TEMPLATE_LOGROTATE="$LOGROTATE_TEMPLATES/periodic-system-maintenance"
|
||||
|
||||
# Function to verify required files exist
|
||||
verify_files() {
|
||||
echo ""
|
||||
echo "1. Verifying Required Files..."
|
||||
echo "=============================="
|
||||
echo ""
|
||||
echo "1. Verifying Required Files..."
|
||||
echo "=============================="
|
||||
|
||||
local missing_files=()
|
||||
local missing_files=()
|
||||
|
||||
if [[ ! -f $PACMAN_WRAPPER_SCRIPT ]]; then
|
||||
missing_files+=("$PACMAN_WRAPPER_SCRIPT")
|
||||
fi
|
||||
if [[ ! -f $PACMAN_WRAPPER_SCRIPT ]]; then
|
||||
missing_files+=("$PACMAN_WRAPPER_SCRIPT")
|
||||
fi
|
||||
|
||||
if [[ ! -f $PACMAN_WRAPPER_INSTALL ]]; then
|
||||
missing_files+=("$PACMAN_WRAPPER_INSTALL")
|
||||
fi
|
||||
if [[ ! -f $PACMAN_WRAPPER_INSTALL ]]; then
|
||||
missing_files+=("$PACMAN_WRAPPER_INSTALL")
|
||||
fi
|
||||
|
||||
if [[ ! -f $MAKEPKG_WRAPPER_INSTALL ]]; then
|
||||
missing_files+=("$MAKEPKG_WRAPPER_INSTALL")
|
||||
fi
|
||||
if [[ ! -f $MAKEPKG_WRAPPER_INSTALL ]]; then
|
||||
missing_files+=("$MAKEPKG_WRAPPER_INSTALL")
|
||||
fi
|
||||
|
||||
if [[ ! -f $HOSTS_INSTALL_SCRIPT ]]; then
|
||||
missing_files+=("$HOSTS_INSTALL_SCRIPT")
|
||||
fi
|
||||
if [[ ! -f $HOSTS_INSTALL_SCRIPT ]]; then
|
||||
missing_files+=("$HOSTS_INSTALL_SCRIPT")
|
||||
fi
|
||||
|
||||
# Check template files as well
|
||||
for tmpl in \
|
||||
"$TEMPLATE_MAINT_SCRIPT" \
|
||||
"$TEMPLATE_HOSTS_MONITOR" \
|
||||
"$TEMPLATE_BROWSER_WRAPPER" \
|
||||
"$TEMPLATE_SVC_MAINT" \
|
||||
"$TEMPLATE_TIMER" \
|
||||
"$TEMPLATE_STARTUP" \
|
||||
"$TEMPLATE_HOSTS_SVC" \
|
||||
"$TEMPLATE_AUTO_UPDATE" \
|
||||
"$TEMPLATE_AUTO_UPDATE_SVC" \
|
||||
"$TEMPLATE_AUTO_UPDATE_TIMER" \
|
||||
"$TEMPLATE_LOGROTATE"; do
|
||||
if [[ ! -f $tmpl ]]; then
|
||||
missing_files+=("$tmpl")
|
||||
fi
|
||||
done
|
||||
# Check template files as well
|
||||
for tmpl in \
|
||||
"$TEMPLATE_MAINT_SCRIPT" \
|
||||
"$TEMPLATE_HOSTS_MONITOR" \
|
||||
"$TEMPLATE_BROWSER_WRAPPER" \
|
||||
"$TEMPLATE_SVC_MAINT" \
|
||||
"$TEMPLATE_TIMER" \
|
||||
"$TEMPLATE_STARTUP" \
|
||||
"$TEMPLATE_HOSTS_SVC" \
|
||||
"$TEMPLATE_AUTO_UPDATE" \
|
||||
"$TEMPLATE_AUTO_UPDATE_SVC" \
|
||||
"$TEMPLATE_AUTO_UPDATE_TIMER" \
|
||||
"$TEMPLATE_LOGROTATE"; do
|
||||
if [[ ! -f $tmpl ]]; then
|
||||
missing_files+=("$tmpl")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#missing_files[@]} -gt 0 ]]; then
|
||||
echo "Error: The following required files are missing:"
|
||||
for file in "${missing_files[@]}"; do
|
||||
echo " - $file"
|
||||
done
|
||||
exit 1
|
||||
fi
|
||||
if [[ ${#missing_files[@]} -gt 0 ]]; then
|
||||
echo "Error: The following required files are missing:"
|
||||
for file in "${missing_files[@]}"; do
|
||||
echo " - $file"
|
||||
done
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ All required files found"
|
||||
echo "✓ All required files found"
|
||||
}
|
||||
|
||||
# Function to create the combined execution script
|
||||
create_execution_script() {
|
||||
echo ""
|
||||
echo "2. Creating Combined Execution Script..."
|
||||
echo "======================================="
|
||||
echo ""
|
||||
echo "2. Creating Combined Execution Script..."
|
||||
echo "======================================="
|
||||
|
||||
local exec_script="/usr/local/bin/periodic-system-maintenance.sh"
|
||||
local exec_script="/usr/local/bin/periodic-system-maintenance.sh"
|
||||
|
||||
# Install from template with path substitutions
|
||||
sed \
|
||||
-e "s|__PACMAN_WRAPPER_INSTALL__|$PACMAN_WRAPPER_INSTALL|g" \
|
||||
-e "s|__MAKEPKG_WRAPPER_INSTALL__|$MAKEPKG_WRAPPER_INSTALL|g" \
|
||||
-e "s|__HOSTS_INSTALL_SCRIPT__|$HOSTS_INSTALL_SCRIPT|g" \
|
||||
"$TEMPLATE_MAINT_SCRIPT" > "$exec_script"
|
||||
# Install from template with path substitutions
|
||||
sed \
|
||||
-e "s|__PACMAN_WRAPPER_INSTALL__|$PACMAN_WRAPPER_INSTALL|g" \
|
||||
-e "s|__MAKEPKG_WRAPPER_INSTALL__|$MAKEPKG_WRAPPER_INSTALL|g" \
|
||||
-e "s|__HOSTS_INSTALL_SCRIPT__|$HOSTS_INSTALL_SCRIPT|g" \
|
||||
"$TEMPLATE_MAINT_SCRIPT" >"$exec_script"
|
||||
|
||||
chmod +x "$exec_script"
|
||||
echo "✓ Installed execution script from template: $exec_script"
|
||||
chmod +x "$exec_script"
|
||||
echo "✓ Installed execution script from template: $exec_script"
|
||||
}
|
||||
|
||||
# Function to create systemd service
|
||||
create_systemd_service() {
|
||||
echo ""
|
||||
echo "3. Creating Systemd Service..."
|
||||
echo "============================="
|
||||
echo ""
|
||||
echo "3. Creating Systemd Service..."
|
||||
echo "============================="
|
||||
|
||||
local service_file="/etc/systemd/system/periodic-system-maintenance.service"
|
||||
install -m 0644 "$TEMPLATE_SVC_MAINT" "$service_file"
|
||||
echo "✓ Installed systemd service from template: $service_file"
|
||||
local service_file="/etc/systemd/system/periodic-system-maintenance.service"
|
||||
install -m 0644 "$TEMPLATE_SVC_MAINT" "$service_file"
|
||||
echo "✓ Installed systemd service from template: $service_file"
|
||||
}
|
||||
|
||||
# Function to create systemd timer for hourly execution
|
||||
create_systemd_timer() {
|
||||
echo ""
|
||||
echo "4. Creating Systemd Timer..."
|
||||
echo "============================"
|
||||
echo ""
|
||||
echo "4. Creating Systemd Timer..."
|
||||
echo "============================"
|
||||
|
||||
local timer_file="/etc/systemd/system/periodic-system-maintenance.timer"
|
||||
install -m 0644 "$TEMPLATE_TIMER" "$timer_file"
|
||||
echo "✓ Installed systemd timer from template: $timer_file"
|
||||
local timer_file="/etc/systemd/system/periodic-system-maintenance.timer"
|
||||
install -m 0644 "$TEMPLATE_TIMER" "$timer_file"
|
||||
echo "✓ Installed systemd timer from template: $timer_file"
|
||||
}
|
||||
|
||||
# Function to create startup service (additional to timer)
|
||||
create_startup_service() {
|
||||
echo ""
|
||||
echo "5. Creating Startup Service..."
|
||||
echo "=============================="
|
||||
echo ""
|
||||
echo "5. Creating Startup Service..."
|
||||
echo "=============================="
|
||||
|
||||
local startup_service="/etc/systemd/system/periodic-system-startup.service"
|
||||
install -m 0644 "$TEMPLATE_STARTUP" "$startup_service"
|
||||
echo "✓ Installed startup service from template: $startup_service"
|
||||
local startup_service="/etc/systemd/system/periodic-system-startup.service"
|
||||
install -m 0644 "$TEMPLATE_STARTUP" "$startup_service"
|
||||
echo "✓ Installed startup service from template: $startup_service"
|
||||
}
|
||||
|
||||
# Function to create hosts file monitor service
|
||||
create_hosts_monitor_service() {
|
||||
echo ""
|
||||
echo "6. Creating Hosts File Monitor Service..."
|
||||
echo "========================================"
|
||||
echo ""
|
||||
echo "6. Creating Hosts File Monitor Service..."
|
||||
echo "========================================"
|
||||
|
||||
local monitor_script="/usr/local/bin/hosts-file-monitor.sh"
|
||||
local monitor_service="/etc/systemd/system/hosts-file-monitor.service"
|
||||
local monitor_script="/usr/local/bin/hosts-file-monitor.sh"
|
||||
local monitor_service="/etc/systemd/system/hosts-file-monitor.service"
|
||||
|
||||
# Install the monitor script from template with substitution
|
||||
sed -e "s|__HOSTS_INSTALL_SCRIPT__|$HOSTS_INSTALL_SCRIPT|g" \
|
||||
"$TEMPLATE_HOSTS_MONITOR" > "$monitor_script"
|
||||
chmod +x "$monitor_script"
|
||||
echo "✓ Installed hosts monitor script from template: $monitor_script"
|
||||
# Install the monitor script from template with substitution
|
||||
sed -e "s|__HOSTS_INSTALL_SCRIPT__|$HOSTS_INSTALL_SCRIPT|g" \
|
||||
"$TEMPLATE_HOSTS_MONITOR" >"$monitor_script"
|
||||
chmod +x "$monitor_script"
|
||||
echo "✓ Installed hosts monitor script from template: $monitor_script"
|
||||
|
||||
# Install the systemd service from template
|
||||
install -m 0644 "$TEMPLATE_HOSTS_SVC" "$monitor_service"
|
||||
echo "✓ Installed hosts monitor service from template: $monitor_service"
|
||||
# Install the systemd service from template
|
||||
install -m 0644 "$TEMPLATE_HOSTS_SVC" "$monitor_service"
|
||||
echo "✓ Installed hosts monitor service from template: $monitor_service"
|
||||
}
|
||||
|
||||
# shellcheck source=lib/periodic_browser.sh
|
||||
|
||||
@ -27,7 +27,6 @@ _SCRIPT_DIRS = (
|
||||
_REPO_ROOT
|
||||
/ "linux_configuration"
|
||||
/ "misc"
|
||||
/ "testsAndMisc-bash"
|
||||
/ "tools", # transcribe_fw and its helpers
|
||||
)
|
||||
|
||||
|
||||
@ -6,35 +6,35 @@
|
||||
|
||||
i3_tests_config_and_guards() {
|
||||
printf 'Checking config uses dedicated low-fork scripts...\n'
|
||||
grep -q '^command=~/.config/i3blocks/time.sh$' "$CONFIG_FILE" \
|
||||
|| fail 'time block should call time.sh'
|
||||
grep -q '^interval=persist$' "$CONFIG_FILE" \
|
||||
|| fail 'config should use persist interval for time block'
|
||||
grep -q '^command=~/.config/i3blocks/memory.sh$' "$CONFIG_FILE" \
|
||||
|| fail 'memory block should call memory.sh'
|
||||
grep -q '^command=~/.config/i3blocks/ethernet.sh$' "$CONFIG_FILE" \
|
||||
|| fail 'ethernet block should call ethernet.sh'
|
||||
grep -q '^command=~/.config/i3blocks/disk.sh$' "$CONFIG_FILE" \
|
||||
|| fail 'disk block should call disk.sh'
|
||||
grep -q '^interval=10$' "$CONFIG_FILE" \
|
||||
|| fail 'cpu block should poll at 10s interval'
|
||||
grep -A2 '^\[motherboard_temperature\]$' "$CONFIG_FILE" | grep -q '^interval=30$' \
|
||||
|| fail 'motherboard block should poll at 30s interval'
|
||||
grep -A2 '^\[memory\]$' "$CONFIG_FILE" | grep -q '^interval=30$' \
|
||||
|| fail 'memory block should poll at 30s interval'
|
||||
grep -A2 '^\[ethernet\]$' "$CONFIG_FILE" | grep -q '^interval=persist$' \
|
||||
|| fail 'ethernet block should use persist mode'
|
||||
grep -A2 '^\[claude_usage\]$' "$CONFIG_FILE" | grep -q '^interval=60$' \
|
||||
|| fail 'claude_usage block should poll at 60s interval'
|
||||
grep -q '^command=~/.config/i3blocks/claude_usage.sh$' "$CONFIG_FILE" \
|
||||
|| fail 'claude_usage block should call claude_usage.sh'
|
||||
grep -q '^command=~/.config/i3blocks/time.sh$' "$CONFIG_FILE" ||
|
||||
fail 'time block should call time.sh'
|
||||
grep -q '^interval=persist$' "$CONFIG_FILE" ||
|
||||
fail 'config should use persist interval for time block'
|
||||
grep -q '^command=~/.config/i3blocks/memory.sh$' "$CONFIG_FILE" ||
|
||||
fail 'memory block should call memory.sh'
|
||||
grep -q '^command=~/.config/i3blocks/ethernet.sh$' "$CONFIG_FILE" ||
|
||||
fail 'ethernet block should call ethernet.sh'
|
||||
grep -q '^command=~/.config/i3blocks/disk.sh$' "$CONFIG_FILE" ||
|
||||
fail 'disk block should call disk.sh'
|
||||
grep -q '^interval=10$' "$CONFIG_FILE" ||
|
||||
fail 'cpu block should poll at 10s interval'
|
||||
grep -A2 '^\[motherboard_temperature\]$' "$CONFIG_FILE" | grep -q '^interval=30$' ||
|
||||
fail 'motherboard block should poll at 30s interval'
|
||||
grep -A2 '^\[memory\]$' "$CONFIG_FILE" | grep -q '^interval=30$' ||
|
||||
fail 'memory block should poll at 30s interval'
|
||||
grep -A2 '^\[ethernet\]$' "$CONFIG_FILE" | grep -q '^interval=persist$' ||
|
||||
fail 'ethernet block should use persist mode'
|
||||
grep -A2 '^\[claude_usage\]$' "$CONFIG_FILE" | grep -q '^interval=60$' ||
|
||||
fail 'claude_usage block should poll at 60s interval'
|
||||
grep -q '^command=~/.config/i3blocks/claude_usage.sh$' "$CONFIG_FILE" ||
|
||||
fail 'claude_usage block should call claude_usage.sh'
|
||||
|
||||
# Blocks for hardware/software absent from this machine were removed; make sure
|
||||
# they do not silently return. Each rendered permanently-dead text in the bar.
|
||||
for removed_block in bluetooth battery wifi activitywatch warp network_monitor; do
|
||||
if grep -q "^\[${removed_block}\]$" "$CONFIG_FILE"; then
|
||||
fail "removed block [${removed_block}] should not be in the config"
|
||||
fi
|
||||
if grep -q "^\[${removed_block}\]$" "$CONFIG_FILE"; then
|
||||
fail "removed block [${removed_block}] should not be in the config"
|
||||
fi
|
||||
done
|
||||
|
||||
printf 'Checking status icons avoid Font Awesome private-use codepoints...\n'
|
||||
@ -43,31 +43,31 @@ i3_tests_config_and_guards() {
|
||||
# rendered the ethernet icon as a star and the wifi icon as Cyrillic. Plain
|
||||
# Unicode/emoji resolve consistently instead.
|
||||
for icon_script in "$I3BLOCKS_DIR"/*.sh; do
|
||||
if grep -qP '[\x{E000}-\x{F8FF}]|\\u[eEfF][0-9a-fA-F]{3}' "$icon_script"; then
|
||||
fail "$(basename "$icon_script") should not use private-use-area icon codepoints"
|
||||
fi
|
||||
if grep -qP '[\x{E000}-\x{F8FF}]|\\u[eEfF][0-9a-fA-F]{3}' "$icon_script"; then
|
||||
fail "$(basename "$icon_script") should not use private-use-area icon codepoints"
|
||||
fi
|
||||
done
|
||||
|
||||
printf 'Checking focus detection path avoids extra xdotool lookups...\n'
|
||||
! grep -Fq "xdotool getwindowname \"\$wid\"" "$REPO_DIR/scripts/lib/common.sh" \
|
||||
|| fail 'focus detection should not call xdotool getwindowname in hot path'
|
||||
! grep -Fq "xdotool getwindowname \"\$wid\"" "$REPO_DIR/lib/common.sh" ||
|
||||
fail 'focus detection should not call xdotool getwindowname in hot path'
|
||||
|
||||
printf 'Checking GPU dedupe guards exist...\n'
|
||||
grep -Fq 'emit_if_changed()' "$I3BLOCKS_DIR/gpu_monitor.sh" \
|
||||
|| fail 'gpu monitor should dedupe repeated identical samples'
|
||||
grep -Fq "source \"\$SCRIPT_DIR/persist_common.sh\"" "$I3BLOCKS_DIR/ethernet.sh" \
|
||||
|| fail 'ethernet script should use shared persist helper'
|
||||
grep -Fq "source \"\$SCRIPT_DIR/persist_common.sh\"" "$I3BLOCKS_DIR/gpu_monitor.sh" \
|
||||
|| fail 'gpu script should use shared persist helper'
|
||||
grep -Fq 'i3blocks_update_if_changed_key "ethernet_output"' "$I3BLOCKS_DIR/ethernet.sh" \
|
||||
|| fail 'ethernet script should dedupe unchanged output'
|
||||
grep -Fq 'emit_if_changed()' "$I3BLOCKS_DIR/gpu_monitor.sh" ||
|
||||
fail 'gpu monitor should dedupe repeated identical samples'
|
||||
grep -Fq "source \"\$SCRIPT_DIR/persist_common.sh\"" "$I3BLOCKS_DIR/ethernet.sh" ||
|
||||
fail 'ethernet script should use shared persist helper'
|
||||
grep -Fq "source \"\$SCRIPT_DIR/persist_common.sh\"" "$I3BLOCKS_DIR/gpu_monitor.sh" ||
|
||||
fail 'gpu script should use shared persist helper'
|
||||
grep -Fq 'i3blocks_update_if_changed_key "ethernet_output"' "$I3BLOCKS_DIR/ethernet.sh" ||
|
||||
fail 'ethernet script should dedupe unchanged output'
|
||||
|
||||
printf 'Checking ethernet picks a physical NIC over virtual bridges...\n'
|
||||
# Regression: the old loop returned the first non-loopback interface, which on a
|
||||
# machine with docker installed is a `br-*` bridge (always "down", and sorted
|
||||
# before enp*/eth*), so the bar reported "down" on a live wired connection.
|
||||
grep -Fq 'iface_path}/device' "$I3BLOCKS_DIR/ethernet.sh" \
|
||||
|| fail 'ethernet script should require a real device to skip virtual interfaces'
|
||||
grep -Fq 'iface_path}/device' "$I3BLOCKS_DIR/ethernet.sh" ||
|
||||
fail 'ethernet script should require a real device to skip virtual interfaces'
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ sec_tests_compulsive_block() {
|
||||
# ==================================================================
|
||||
echo "--- COMPULSIVE OPENING BLOCK ---"
|
||||
|
||||
compulsive_dir="$REPO_DIR/scripts/periodic_background/digital_wellbeing"
|
||||
compulsive_dir="$REPO_DIR/periodic_background/digital_wellbeing"
|
||||
compulsive_file="$compulsive_dir/block_compulsive_opening.sh"
|
||||
|
||||
# The blocker was split into lib/cco_*.sh under the 250-line cap, so these
|
||||
|
||||
@ -23,7 +23,7 @@ sec_tests_pacman_wrapper() {
|
||||
live_section 0 # repository checks from here on
|
||||
|
||||
# Test 13: google-chrome is blocked
|
||||
blocked_file="$REPO_DIR/scripts/periodic_background/digital_wellbeing/pacman/pacman_blocked_keywords.txt"
|
||||
blocked_file="$REPO_DIR/periodic_background/digital_wellbeing/pacman/pacman_blocked_keywords.txt"
|
||||
if [[ -f "$blocked_file" ]]; then
|
||||
if grep -qi "google-chrome" "$blocked_file"; then
|
||||
test_result "google-chrome in blocked list" "pass"
|
||||
@ -57,7 +57,7 @@ sec_tests_pacman_wrapper() {
|
||||
live_section 0
|
||||
|
||||
# Test 16: LeechBlock auto-install function exists in wrapper
|
||||
wrapper_file="$REPO_DIR/scripts/periodic_background/digital_wellbeing/pacman/pacman_wrapper.sh"
|
||||
wrapper_file="$REPO_DIR/periodic_background/digital_wellbeing/pacman/pacman_wrapper.sh"
|
||||
if [[ -f "$wrapper_file" ]]; then
|
||||
if grep -q "auto_install_leechblock" "$wrapper_file"; then
|
||||
test_result "LeechBlock auto-install function exists" "pass"
|
||||
|
||||
@ -12,7 +12,7 @@ set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
WRAPPER_FILE="$REPO_DIR/scripts/periodic_background/digital_wellbeing/pacman/pacman_wrapper.sh"
|
||||
WRAPPER_FILE="$REPO_DIR/periodic_background/digital_wellbeing/pacman/pacman_wrapper.sh"
|
||||
# The wrapper was split into flat pw_*.sh libs under the 250-line cap, so a
|
||||
# function-definition check has to search the entry script AND its libs.
|
||||
# Grepping the entry script alone reports "not found" for code that simply
|
||||
|
||||
@ -5,7 +5,7 @@ set -euo pipefail
|
||||
|
||||
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||
REPO_DIR=$(cd -- "$SCRIPT_DIR/.." && pwd)
|
||||
I3BLOCKS_DIR="$REPO_DIR/scripts/periodic_background/i3-configuration/i3blocks"
|
||||
I3BLOCKS_DIR="$REPO_DIR/i3blocks"
|
||||
CONFIG_FILE="$I3BLOCKS_DIR/config"
|
||||
|
||||
printf 'Running persist_common helper regression checks...\n'
|
||||
@ -16,43 +16,43 @@ BIN_DIR="$TMP_DIR/bin"
|
||||
mkdir -p "$BIN_DIR"
|
||||
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
fail() {
|
||||
printf 'FAIL: %s\n' "$1" >&2
|
||||
exit 1
|
||||
printf 'FAIL: %s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
assert_equals() {
|
||||
local expected="$1"
|
||||
local actual="$2"
|
||||
local context="$3"
|
||||
if [[ "$expected" != "$actual" ]]; then
|
||||
fail "$context (expected: '$expected', actual: '$actual')"
|
||||
fi
|
||||
local expected="$1"
|
||||
local actual="$2"
|
||||
local context="$3"
|
||||
if [[ "$expected" != "$actual" ]]; then
|
||||
fail "$context (expected: '$expected', actual: '$actual')"
|
||||
fi
|
||||
}
|
||||
|
||||
assert_le() {
|
||||
local actual="$1"
|
||||
local expected_max="$2"
|
||||
local context="$3"
|
||||
if (( actual > expected_max )); then
|
||||
fail "$context (expected <= $expected_max, actual: $actual)"
|
||||
fi
|
||||
local actual="$1"
|
||||
local expected_max="$2"
|
||||
local context="$3"
|
||||
if ((actual > expected_max)); then
|
||||
fail "$context (expected <= $expected_max, actual: $actual)"
|
||||
fi
|
||||
}
|
||||
|
||||
epoch_utc() {
|
||||
TZ=UTC date -d "$1" +%s
|
||||
TZ=UTC date -d "$1" +%s
|
||||
}
|
||||
|
||||
count_execs() {
|
||||
local script_path="$1"
|
||||
local log_file="$TMP_DIR/trace.log"
|
||||
PATH="$BIN_DIR:$PATH" strace -f -o "$log_file" -e trace=execve bash "$script_path" \
|
||||
>/dev/null 2>&1
|
||||
grep -c 'execve(' "$log_file"
|
||||
local script_path="$1"
|
||||
local log_file="$TMP_DIR/trace.log"
|
||||
PATH="$BIN_DIR:$PATH" strace -f -o "$log_file" -e trace=execve bash "$script_path" \
|
||||
>/dev/null 2>&1
|
||||
grep -c 'execve(' "$log_file"
|
||||
}
|
||||
|
||||
cat >"$BIN_DIR/pacman" <<'EOF'
|
||||
@ -143,32 +143,32 @@ i3_tests_claude_usage
|
||||
printf 'Checking disk block behavior and fork count...\n'
|
||||
disk_output=$(PATH="$BIN_DIR:$PATH" bash "$I3BLOCKS_DIR/disk.sh")
|
||||
assert_equals '💾 15G/100G' "$disk_output" \
|
||||
'disk script should show used and total disk space'
|
||||
'disk script should show used and total disk space'
|
||||
assert_le "$(count_execs "$I3BLOCKS_DIR/disk.sh")" 2 \
|
||||
'disk script should stay at one external helper plus bash'
|
||||
'disk script should stay at one external helper plus bash'
|
||||
|
||||
printf 'Checking PC startup block behavior and fork count...\n'
|
||||
pc_live_epoch=$(epoch_utc '2026-05-01 06:30:00')
|
||||
pc_live_output=$(TZ=UTC NOW_EPOCH="$pc_live_epoch" UPTIME_SECONDS=1800 PATH="$BIN_DIR:$PATH" bash "$I3BLOCKS_DIR/pc_startup_status.sh")
|
||||
assert_equals 'PC:live' "$(printf '%s\n' "$pc_live_output" | sed -n '1p')" \
|
||||
'pc startup script should show live during the monitored startup window'
|
||||
'pc startup script should show live during the monitored startup window'
|
||||
assert_le "$(count_execs "$I3BLOCKS_DIR/pc_startup_status.sh")" 1 \
|
||||
'pc startup script should avoid date and text-processing helpers'
|
||||
'pc startup script should avoid date and text-processing helpers'
|
||||
|
||||
pc_ok_epoch=$(epoch_utc '2026-05-01 10:00:00')
|
||||
pc_ok_output=$(TZ=UTC NOW_EPOCH="$pc_ok_epoch" UPTIME_SECONDS=14400 PATH="$BIN_DIR:$PATH" bash "$I3BLOCKS_DIR/pc_startup_status.sh")
|
||||
assert_equals 'PC:ok' "$(printf '%s\n' "$pc_ok_output" | sed -n '1p')" \
|
||||
'pc startup script should show ok when boot happened inside the startup window'
|
||||
'pc startup script should show ok when boot happened inside the startup window'
|
||||
|
||||
pc_warn_epoch=$(epoch_utc '2026-05-01 10:00:00')
|
||||
pc_warn_output=$(TZ=UTC NOW_EPOCH="$pc_warn_epoch" UPTIME_SECONDS=1800 PATH="$BIN_DIR:$PATH" bash "$I3BLOCKS_DIR/pc_startup_status.sh")
|
||||
assert_equals 'PC:warn' "$(printf '%s\n' "$pc_warn_output" | sed -n '1p')" \
|
||||
'pc startup script should warn when boot happened outside the startup window'
|
||||
'pc startup script should warn when boot happened outside the startup window'
|
||||
|
||||
pc_skip_epoch=$(epoch_utc '2026-04-30 10:00:00')
|
||||
pc_skip_output=$(TZ=UTC NOW_EPOCH="$pc_skip_epoch" UPTIME_SECONDS=1800 PATH="$BIN_DIR:$PATH" bash "$I3BLOCKS_DIR/pc_startup_status.sh")
|
||||
assert_equals 'PC:skip' "$(printf '%s\n' "$pc_skip_output" | sed -n '1p')" \
|
||||
'pc startup script should skip on unmonitored days'
|
||||
'pc startup script should skip on unmonitored days'
|
||||
|
||||
printf 'Checking shutdown countdown behavior and fork count...\n'
|
||||
shutdown_config_file="$TMP_DIR/shutdown-schedule.conf"
|
||||
@ -179,7 +179,7 @@ EOF
|
||||
|
||||
# Isolate from the machine's real override file so these assertions are hermetic.
|
||||
shutdown_overrides_empty="$TMP_DIR/shutdown-overrides-empty.conf"
|
||||
: > "$shutdown_overrides_empty"
|
||||
: >"$shutdown_overrides_empty"
|
||||
|
||||
# 2026-05-01 is a Friday -> THU_SUN_HOUR=21 applies; at 19:30 the next shutdown
|
||||
# is 21:00. The block shows the exact clock time of the shutdown, not a
|
||||
@ -187,16 +187,16 @@ shutdown_overrides_empty="$TMP_DIR/shutdown-overrides-empty.conf"
|
||||
shutdown_countdown_epoch=$(epoch_utc '2026-05-01 19:30:00')
|
||||
shutdown_countdown_output=$(TZ=UTC NOW_EPOCH="$shutdown_countdown_epoch" SHUTDOWN_CONFIG="$shutdown_config_file" OVERRIDES_FILE="$shutdown_overrides_empty" PATH="$BIN_DIR:$PATH" bash "$I3BLOCKS_DIR/shutdown_countdown.sh")
|
||||
assert_equals '⏻ 21:00' "$(printf '%s\n' "$shutdown_countdown_output" | sed -n '1p')" \
|
||||
'shutdown countdown should show the exact clock time of the next shutdown'
|
||||
'shutdown countdown should show the exact clock time of the next shutdown'
|
||||
assert_equals '#F1FA8C' "$(printf '%s\n' "$shutdown_countdown_output" | sed -n '3p')" \
|
||||
'shutdown countdown should show yellow for two hours or less remaining'
|
||||
'shutdown countdown should show yellow for two hours or less remaining'
|
||||
assert_le "$(count_execs "$I3BLOCKS_DIR/shutdown_countdown.sh")" 1 \
|
||||
'shutdown countdown should avoid date helpers in the hot path'
|
||||
'shutdown countdown should avoid date helpers in the hot path'
|
||||
|
||||
shutdown_window_epoch=$(epoch_utc '2026-05-01 21:15:00')
|
||||
shutdown_window_output=$(TZ=UTC NOW_EPOCH="$shutdown_window_epoch" SHUTDOWN_CONFIG="$shutdown_config_file" OVERRIDES_FILE="$shutdown_overrides_empty" PATH="$BIN_DIR:$PATH" bash "$I3BLOCKS_DIR/shutdown_countdown.sh")
|
||||
assert_equals '⏻ SHUTDOWN' "$(printf '%s\n' "$shutdown_window_output" | sed -n '1p')" \
|
||||
'shutdown countdown should show SHUTDOWN inside the blocked window'
|
||||
'shutdown countdown should show SHUTDOWN inside the blocked window'
|
||||
|
||||
# An active override (shutdown-override-manager.sh) rescues the shutdown: the
|
||||
# block should show the overridden end time in green instead of a countdown or
|
||||
@ -204,11 +204,11 @@ assert_equals '⏻ SHUTDOWN' "$(printf '%s\n' "$shutdown_window_output" | sed -n
|
||||
shutdown_overrides_active="$TMP_DIR/shutdown-overrides-active.conf"
|
||||
override_start=$(epoch_utc '2026-05-01 19:00:00')
|
||||
override_end=$(epoch_utc '2026-05-01 23:00:00')
|
||||
printf '%s|%s|%s|%s\n' "$override_start" "$override_end" "$override_start" 'regression test override' > "$shutdown_overrides_active"
|
||||
printf '%s|%s|%s|%s\n' "$override_start" "$override_end" "$override_start" 'regression test override' >"$shutdown_overrides_active"
|
||||
shutdown_override_output=$(TZ=UTC NOW_EPOCH="$shutdown_countdown_epoch" SHUTDOWN_CONFIG="$shutdown_config_file" OVERRIDES_FILE="$shutdown_overrides_active" PATH="$BIN_DIR:$PATH" bash "$I3BLOCKS_DIR/shutdown_countdown.sh")
|
||||
assert_equals '▶ 23:00 (override)' "$(printf '%s\n' "$shutdown_override_output" | sed -n '1p')" \
|
||||
'shutdown countdown should show the overridden end time when an override is active'
|
||||
'shutdown countdown should show the overridden end time when an override is active'
|
||||
assert_equals '#50FA7B' "$(printf '%s\n' "$shutdown_override_output" | sed -n '3p')" \
|
||||
'shutdown countdown should show green while an override is active'
|
||||
'shutdown countdown should show green while an override is active'
|
||||
|
||||
printf 'All i3blocks efficiency regression tests passed.\n'
|
||||
|
||||
@ -5,7 +5,7 @@ set -euo pipefail
|
||||
|
||||
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||
REPO_DIR=$(cd -- "$SCRIPT_DIR/.." && pwd)
|
||||
HELPER="$REPO_DIR/scripts/periodic_background/i3-configuration/i3blocks/persist_common.sh"
|
||||
HELPER="$REPO_DIR/i3blocks/persist_common.sh"
|
||||
TMP_DIR=$(mktemp -d)
|
||||
|
||||
cleanup() {
|
||||
@ -13,7 +13,7 @@ cleanup() {
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# shellcheck source=linux_configuration/periodic_background/i3-configuration/i3blocks/persist_common.sh
|
||||
# shellcheck source=linux_configuration/i3blocks/persist_common.sh
|
||||
source "$HELPER"
|
||||
|
||||
fail() {
|
||||
@ -136,7 +136,7 @@ cat >"$fork_probe" <<EOF
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# shellcheck source=linux_configuration/periodic_background/i3-configuration/i3blocks/persist_common.sh
|
||||
# shellcheck source=linux_configuration/i3blocks/persist_common.sh
|
||||
source "$HELPER"
|
||||
|
||||
I3BLOCKS_LAST_TS=()
|
||||
|
||||
@ -5,11 +5,11 @@ set -euo pipefail
|
||||
|
||||
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||
REPO_DIR=$(cd -- "$SCRIPT_DIR/.." && pwd)
|
||||
WRAPPER="$REPO_DIR/scripts/periodic_background/digital_wellbeing/pacman/makepkg_capped.sh"
|
||||
WRAPPER="$REPO_DIR/periodic_background/digital_wellbeing/pacman/makepkg_capped.sh"
|
||||
|
||||
fail() {
|
||||
printf 'FAIL: %s\n' "$1" >&2
|
||||
exit 1
|
||||
printf 'FAIL: %s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
printf 'Checking makepkg_capped exists...\n'
|
||||
|
||||
@ -5,7 +5,7 @@ set -euo pipefail
|
||||
|
||||
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||
REPO_DIR=$(cd -- "$SCRIPT_DIR/.." && pwd)
|
||||
TARGET_SCRIPT="$REPO_DIR/scripts/periodic_background/digital_wellbeing/music_parallelism.sh"
|
||||
TARGET_SCRIPT="$REPO_DIR/periodic_background/digital_wellbeing/music_parallelism.sh"
|
||||
|
||||
fail() {
|
||||
printf 'FAIL: %s\n' "$1" >&2
|
||||
@ -42,9 +42,9 @@ if [[ "$TARGET_REL" == "$TARGET_SCRIPT" ]]; then
|
||||
fail "TARGET_SCRIPT ($TARGET_SCRIPT) is not below REPO_DIR ($REPO_DIR)"
|
||||
fi
|
||||
WORKTREE_SCRIPT="$WORKTREE/$TARGET_REL"
|
||||
# The library lives at <repo>/scripts/lib/common.sh; keep it relative to the
|
||||
# The library lives at <repo>/lib/common.sh; keep it relative to the
|
||||
# same root rather than assuming how deep the script itself is nested.
|
||||
WORKTREE_LIB="$WORKTREE/scripts/lib/common.sh"
|
||||
WORKTREE_LIB="$WORKTREE/lib/common.sh"
|
||||
|
||||
mkdir -p "$(dirname "$WORKTREE_SCRIPT")" "$(dirname "$WORKTREE_LIB")" "$BIN_DIR"
|
||||
cp "$TARGET_SCRIPT" "$WORKTREE_SCRIPT"
|
||||
|
||||
@ -19,7 +19,7 @@ if [[ ! -f $TARGET_SCRIPT ]]; then
|
||||
printf 'SKIP: shutdown-timer-monitor.sh not found (set SYSTEM_MAINTENANCE_DIR)\n'
|
||||
exit 0
|
||||
fi
|
||||
SETUP_SCRIPT="$REPO_DIR/scripts/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh"
|
||||
SETUP_SCRIPT="$REPO_DIR/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh"
|
||||
# The installer was split into lib/ms_*.sh under the 250-line cap, so these
|
||||
# template checks search the entry script AND its libs: the monitor template
|
||||
# now lives in lib/ms_monitor.sh, it did not disappear.
|
||||
@ -50,8 +50,8 @@ trap cleanup EXIT
|
||||
|
||||
WORKTREE="$TMP_DIR/worktree"
|
||||
BIN_DIR="$TMP_DIR/bin"
|
||||
mkdir -p "$WORKTREE/scripts/system-maintenance/bin" "$BIN_DIR"
|
||||
cp "$TARGET_SCRIPT" "$WORKTREE/scripts/system-maintenance/bin/shutdown-timer-monitor.sh"
|
||||
mkdir -p "$WORKTREE/system-maintenance/bin" "$BIN_DIR"
|
||||
cp "$TARGET_SCRIPT" "$WORKTREE/system-maintenance/bin/shutdown-timer-monitor.sh"
|
||||
|
||||
cat >"$BIN_DIR/busctl" <<'EOF'
|
||||
#!/bin/bash
|
||||
@ -113,7 +113,7 @@ run_case() {
|
||||
fi
|
||||
|
||||
mode=$(env -i PATH="$BIN_DIR" SLEEP_LOG="$sleep_log" SHUTDOWN_TIMER_MONITOR_SKIP_MAIN=1 /bin/bash -c \
|
||||
"source '$WORKTREE/scripts/system-maintenance/bin/shutdown-timer-monitor.sh'; \
|
||||
"source '$WORKTREE/system-maintenance/bin/shutdown-timer-monitor.sh'; \
|
||||
timer_needs_restoration() { return 1; }; \
|
||||
restore_timer() { :; }; \
|
||||
monitor_with_dbus() { printf 'dbus'; }; \
|
||||
@ -164,7 +164,7 @@ run_dbus_throttle_case() {
|
||||
timer_checks=$((timer_checks + 1))
|
||||
done < "$COUNTER_FILE"
|
||||
printf "%s" "$timer_checks"
|
||||
' _ "$WORKTREE/scripts/system-maintenance/bin/shutdown-timer-monitor.sh")
|
||||
' _ "$WORKTREE/system-maintenance/bin/shutdown-timer-monitor.sh")
|
||||
|
||||
assert_equals "$expected_calls" "$calls" 'monitor_with_dbus should throttle repeated relevant events'
|
||||
}
|
||||
@ -183,7 +183,7 @@ run_dbus_throttle_case '100 101 102' '3' '0'
|
||||
|
||||
printf 'Checking wait helper enforces delay even with /dev/null stdin...\n'
|
||||
wait_elapsed=$(env -i PATH="/usr/bin:/bin" SHUTDOWN_TIMER_MONITOR_SKIP_MAIN=1 /bin/bash -c \
|
||||
"source '$WORKTREE/scripts/system-maintenance/bin/shutdown-timer-monitor.sh'; \
|
||||
"source '$WORKTREE/system-maintenance/bin/shutdown-timer-monitor.sh'; \
|
||||
start=\$(printf '%(%s)T' -1); \
|
||||
wait_seconds 1; \
|
||||
end=\$(printf '%(%s)T' -1); \
|
||||
|
||||
@ -173,7 +173,7 @@ repos:
|
||||
(?x)^(
|
||||
Bash/.*|
|
||||
\.venv/.*|
|
||||
linux_configuration/misc/testsAndMisc-bash/tools/.*
|
||||
linux_configuration/misc/tools/.*
|
||||
)$
|
||||
additional_dependencies:
|
||||
- types-requests
|
||||
|
||||
@ -141,7 +141,7 @@ color_output = true
|
||||
exclude = [
|
||||
"Bash/ffmpeg-build/",
|
||||
".venv/",
|
||||
"linux_configuration/misc/testsAndMisc-bash/tools/", # Avoid duplicate module named 'tools'
|
||||
"linux_configuration/misc/tools/", # Avoid duplicate module named 'tools'
|
||||
]
|
||||
|
||||
# Standalone tool scripts outside python_pkg/ are not held to strict mypy rules
|
||||
@ -170,7 +170,7 @@ disallow_untyped_decorators = false
|
||||
# bare name (the same dirs linux_configuration/tests/conftest.py adds to
|
||||
# sys.path at runtime) resolve under static analysis instead of raising E0401.
|
||||
# Paths are relative to the repo root, which is pre-commit's working directory.
|
||||
init-hook = "import sys; sys.path[:0] = ['meta/scripts', 'python_pkg', 'linux_configuration/utils', 'linux_configuration/periodic_background/digital_wellbeing', 'linux_configuration/misc/testsAndMisc-bash/tools']"
|
||||
init-hook = "import sys; sys.path[:0] = ['meta/scripts', 'python_pkg', 'linux_configuration/utils', 'linux_configuration/periodic_background/digital_wellbeing', 'linux_configuration/misc/tools']"
|
||||
# Analyse import fallback blocks
|
||||
analyse-fallback-blocks = true
|
||||
# Pickle collected data for later comparisons
|
||||
|
||||
@ -69,9 +69,9 @@ linux_configuration/fixes/lib/bt_adapter.sh
|
||||
linux_configuration/fixes/lib/pacman_hook_stall_setup.sh
|
||||
linux_configuration/fresh-install/lib/packages.sh
|
||||
linux_configuration/installers/joplin_server.sh
|
||||
linux_configuration/misc/testsAndMisc-bash/lib/clean_audio_filters.sh
|
||||
linux_configuration/misc/testsAndMisc-bash/lib/transcribe_deps.sh
|
||||
linux_configuration/misc/testsAndMisc-bash/lib/transcribe_pkgmgr.sh
|
||||
linux_configuration/misc/lib/clean_audio_filters.sh
|
||||
linux_configuration/misc/lib/transcribe_deps.sh
|
||||
linux_configuration/misc/lib/transcribe_pkgmgr.sh
|
||||
meta/lib/lint_full_tools.sh
|
||||
meta/lib/lint_output.sh
|
||||
meta/scripts/lib/disk_cleanup_common.sh
|
||||
|
||||
Loading…
Reference in New Issue
Block a user