From c41c8abaa74fd7887dd68b60fbd7bc179ed4dc61 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Fri, 10 Jul 2026 14:13:00 +0100 Subject: [PATCH] fix(cli): lifecycle tools in HM so stale pull can self-heal Extract nomarchy-pull/rebuild/home to pkgs/nomarchy-lifecycle; install via system + home. Home profile wins on PATH so home-manager switch installs the fixed pull (skip git when no upstream) without waiting for a system rebuild that needed a working pull first. V0: flake check --no-build green. --- flake.nix | 3 + modules/home/default.nix | 4 + modules/nixos/default.nix | 123 ++----------------------- pkgs/nomarchy-lifecycle/default.nix | 133 ++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 118 deletions(-) create mode 100644 pkgs/nomarchy-lifecycle/default.nix diff --git a/flake.nix b/flake.nix index 7747322..69013b5 100644 --- a/flake.nix +++ b/flake.nix @@ -87,6 +87,9 @@ nomarchy-control-center = final.callPackage ./pkgs/nomarchy-control-center { }; nomarchy-battery-notify = final.callPackage ./pkgs/nomarchy-battery-notify { }; nomarchy-detect-hw = final.callPackage ./pkgs/nomarchy-detect-hw { }; + # pull / rebuild / home (+ legacy aliases) — also on HM so a home + # switch can refresh a broken system-package nomarchy-pull. + nomarchy-lifecycle = final.callPackage ./pkgs/nomarchy-lifecycle { }; }; nixosModules.nomarchy = { diff --git a/modules/home/default.nix b/modules/home/default.nix index ab70b88..2159a37 100644 --- a/modules/home/default.nix +++ b/modules/home/default.nix @@ -61,6 +61,10 @@ awww # wallpaper daemon with animated transitions (the swww fork) libnotify hyprpicker + # Lifecycle CLIs (pull/rebuild/home). HM profile usually precedes + # /run/current-system on PATH, so nomarchy-home can replace a broken + # system-generation nomarchy-pull without a full sys rebuild. + nomarchy-lifecycle ]; home.sessionVariables = { diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 160463a..f42a5a3 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -333,124 +333,11 @@ in nomarchy-control-center # TUI control center nomarchy-detect-hw # post-install hardware re-probe (HARDWARE.md §8) - # Day-to-day lifecycle (README §3). Always run as your user — - # `nix flake update` / git must not run as root (libgit2 refuses a - # user-owned flake); sudo is only for the system switch. - # - # nomarchy-pull git pull (if checkout) + flake.lock update - # nomarchy-rebuild system switch against the *current* lock - # nomarchy-home Home Manager switch (desktop layer) - # - # Full distro upgrade: nomarchy-pull && nomarchy-rebuild && nomarchy-home - # Config-only system: nomarchy-rebuild - # Theme/desktop only: nomarchy-home - # - # Legacy names (sys-update / sys-rebuild / home-update) stay as - # thin wrappers so old docs and muscle memory keep working. - (pkgs.writeShellScriptBin "nomarchy-pull" '' - set -euo pipefail - if [ "$(id -u)" -eq 0 ]; then - echo "nomarchy-pull: run as your normal user" >&2 - exit 1 - fi - flake="''${NOMARCHY_PATH:-$HOME/.nomarchy}" - if [ ! -d "$flake" ]; then - echo "nomarchy-pull: flake path not found: $flake" >&2 - echo " Set NOMARCHY_PATH or clone/symlink your flake to ~/.nomarchy." >&2 - exit 1 - fi - # 1) Your checkout (system.nix / home.nix / local edits). - if [ -d "$flake/.git" ]; then - echo "nomarchy-pull: git pull --ff-only in $flake" - git -C "$flake" pull --ff-only - else - echo "nomarchy-pull: $flake is not a git checkout — skipping git pull" - fi - # 2) Flake inputs (nixpkgs, nomarchy, home-manager, …). - echo "nomarchy-pull: nix flake update in $flake" - nix flake update --flake "$flake" - echo "nomarchy-pull: done — next: nomarchy-rebuild then nomarchy-home" - '') - (pkgs.writeShellScriptBin "nomarchy-rebuild" '' - set -euo pipefail - if [ "$(id -u)" -eq 0 ]; then - echo "nomarchy-rebuild: run as your normal user (it sudos the rebuild itself)" >&2 - exit 1 - fi - flake="''${NOMARCHY_PATH:-$HOME/.nomarchy}" - if [ ! -d "$flake" ]; then - echo "nomarchy-rebuild: flake path not found: $flake" >&2 - exit 1 - fi - before=$(readlink -f /run/current-system) - log=$(mktemp) - trap 'rm -f "$log"' EXIT - set +e - # Snapshot-first when snapper is on; pass flake path through sudo - # (nixos-rebuild-snap used to hardcode /etc/nixos). - if command -v nixos-rebuild-snap >/dev/null 2>&1; then - sudo env NOMARCHY_PATH="$flake" nixos-rebuild-snap "$@" 2>&1 | tee "$log" - else - sudo nixos-rebuild switch --flake "$flake#default" "$@" 2>&1 | tee "$log" - fi - rc=''${PIPESTATUS[0]} - set -e - if [ "$rc" -ne 0 ]; then - echo - echo "nomarchy-rebuild: FAILED (exit $rc). Last lines:" - tail -n 40 "$log" || true - echo - echo "Diagnose: nomarchy-doctor" - echo "Recovery: docs/RECOVERY.md (boot menu generations / snapper)" - exit "$rc" - fi - after=$(readlink -f /run/current-system) - if [ "$before" = "$after" ]; then - echo "nomarchy-rebuild: no changes — the system is identical." - else - echo "nomarchy-rebuild: what changed:" - ${pkgs.nvd}/bin/nvd diff "$before" "$after" || true - fi - '') - (pkgs.writeShellScriptBin "nomarchy-home" '' - set -euo pipefail - if [ "$(id -u)" -eq 0 ]; then - echo "nomarchy-home: run as your normal user" >&2 - exit 1 - fi - flake="''${NOMARCHY_PATH:-$HOME/.nomarchy}" - if [ ! -d "$flake" ]; then - echo "nomarchy-home: flake path not found: $flake" >&2 - exit 1 - fi - log=$(mktemp) - trap 'rm -f "$log"' EXIT - set +e - home-manager switch --flake "$flake" "$@" 2>&1 | tee "$log" - rc=''${PIPESTATUS[0]} - set -e - if [ "$rc" -ne 0 ]; then - echo - echo "nomarchy-home: FAILED (exit $rc). Last lines:" - tail -n 40 "$log" || true - echo - echo "Diagnose: nomarchy-doctor" - echo "Recovery: home-manager generations (or docs/RECOVERY.md)" - exit "$rc" - fi - echo "nomarchy-home: desktop applied." - '') - # Legacy aliases — same behaviour, old names. - (pkgs.writeShellScriptBin "sys-update" '' - # Was: flake update + system rebuild. Now the two explicit steps. - nomarchy-pull && nomarchy-rebuild "$@" - '') - (pkgs.writeShellScriptBin "sys-rebuild" '' - exec nomarchy-rebuild "$@" - '') - (pkgs.writeShellScriptBin "home-update" '' - exec nomarchy-home "$@" - '') + # Day-to-day lifecycle (README §3): nomarchy-pull / -rebuild / -home + # (+ legacy sys-update / sys-rebuild / home-update). Defined once in + # pkgs/nomarchy-lifecycle; also installed via HM so a home switch can + # refresh a stale system-package pull script. + pkgs.nomarchy-lifecycle git vim diff --git a/pkgs/nomarchy-lifecycle/default.nix b/pkgs/nomarchy-lifecycle/default.nix new file mode 100644 index 0000000..b0f7c1d --- /dev/null +++ b/pkgs/nomarchy-lifecycle/default.nix @@ -0,0 +1,133 @@ +# Day-to-day lifecycle CLIs for a Nomarchy machine flake (~/.nomarchy). +# Installed on both NixOS (systemPackages) and Home Manager so a home +# switch can refresh them without waiting for a full system rebuild — +# otherwise a broken nomarchy-pull can never update itself. +{ lib, writeShellScriptBin, nvd, jq, symlinkJoin }: + +let + # Shared preamble: refuse root, resolve flake path. + preamble = name: '' + set -euo pipefail + if [ "$(id -u)" -eq 0 ]; then + echo "${name}: run as your normal user" >&2 + exit 1 + fi + flake="''${NOMARCHY_PATH:-$HOME/.nomarchy}" + ''; + + nomarchy-pull = writeShellScriptBin "nomarchy-pull" '' + ${preamble "nomarchy-pull"} + if [ ! -e "$flake/flake.nix" ]; then + echo "nomarchy-pull: no flake.nix at $flake" >&2 + echo " Set NOMARCHY_PATH or put your machine flake in ~/.nomarchy." >&2 + exit 1 + fi + # Optional: pull *your* machine config only if this checkout tracks a + # remote. Distro updates come from the nomarchy flake *input* below — + # many installs have no upstream on ~/.nomarchy (local auto-commits). + if [ -d "$flake/.git" ] \ + && git -C "$flake" rev-parse --abbrev-ref '@{u}' >/dev/null 2>&1; then + echo "nomarchy-pull: git pull --ff-only (machine flake tracks upstream)" + git -C "$flake" pull --ff-only + elif [ -d "$flake/.git" ]; then + echo "nomarchy-pull: machine flake has no upstream branch — skipping git pull" + echo " (normal for a local-only ~/.nomarchy; distro updates use flake inputs)" + fi + echo "nomarchy-pull: nix flake update in $flake" + nix flake update --flake "$flake" + nom=$(nix flake metadata "$flake" --json 2>/dev/null \ + | ${jq}/bin/jq -r ' + .locks.nodes.nomarchy.locked + | if . == null then empty + elif .rev then "nomarchy @ \(.rev[0:12])" + else empty end + ' 2>/dev/null || true) + [ -n "''${nom:-}" ] && echo "nomarchy-pull: $nom" + echo "nomarchy-pull: done — next: nomarchy-rebuild then nomarchy-home" + ''; + + nomarchy-rebuild = writeShellScriptBin "nomarchy-rebuild" '' + ${preamble "nomarchy-rebuild"} + if [ ! -e "$flake/flake.nix" ]; then + echo "nomarchy-rebuild: no flake.nix at $flake" >&2 + exit 1 + fi + before=$(readlink -f /run/current-system) + log=$(mktemp) + trap 'rm -f "$log"' EXIT + set +e + if command -v nixos-rebuild-snap >/dev/null 2>&1; then + sudo env NOMARCHY_PATH="$flake" nixos-rebuild-snap "$@" 2>&1 | tee "$log" + else + sudo nixos-rebuild switch --flake "$flake#default" "$@" 2>&1 | tee "$log" + fi + rc=''${PIPESTATUS[0]} + set -e + if [ "$rc" -ne 0 ]; then + echo + echo "nomarchy-rebuild: FAILED (exit $rc). Last lines:" + tail -n 40 "$log" || true + echo + echo "Diagnose: nomarchy-doctor" + echo "Recovery: docs/RECOVERY.md (boot menu generations / snapper)" + exit "$rc" + fi + after=$(readlink -f /run/current-system) + if [ "$before" = "$after" ]; then + echo "nomarchy-rebuild: no changes — the system is identical." + else + echo "nomarchy-rebuild: what changed:" + ${nvd}/bin/nvd diff "$before" "$after" || true + fi + ''; + + nomarchy-home = writeShellScriptBin "nomarchy-home" '' + ${preamble "nomarchy-home"} + if [ ! -e "$flake/flake.nix" ]; then + echo "nomarchy-home: no flake.nix at $flake" >&2 + exit 1 + fi + log=$(mktemp) + trap 'rm -f "$log"' EXIT + set +e + home-manager switch --flake "$flake" "$@" 2>&1 | tee "$log" + rc=''${PIPESTATUS[0]} + set -e + if [ "$rc" -ne 0 ]; then + echo + echo "nomarchy-home: FAILED (exit $rc). Last lines:" + tail -n 40 "$log" || true + echo + echo "Diagnose: nomarchy-doctor" + echo "Recovery: home-manager generations (or docs/RECOVERY.md)" + exit "$rc" + fi + echo "nomarchy-home: desktop applied." + ''; + + # Legacy aliases + sys-update = writeShellScriptBin "sys-update" '' + nomarchy-pull && nomarchy-rebuild "$@" + ''; + sys-rebuild = writeShellScriptBin "sys-rebuild" '' + exec nomarchy-rebuild "$@" + ''; + home-update = writeShellScriptBin "home-update" '' + exec nomarchy-home "$@" + ''; +in +symlinkJoin { + name = "nomarchy-lifecycle"; + paths = [ + nomarchy-pull + nomarchy-rebuild + nomarchy-home + sys-update + sys-rebuild + home-update + ]; + meta = { + description = "Nomarchy machine-flake lifecycle: pull, rebuild, home"; + mainProgram = "nomarchy-pull"; + }; +}