diff --git a/home/console/nix-flake.nix b/home/console/nix-flake.nix index 8b1c33c..767341b 100644 --- a/home/console/nix-flake.nix +++ b/home/console/nix-flake.nix @@ -19,106 +19,35 @@ }; config = lib.mkIf config.modules.terminal.flakeManagement.enable { - # statix/deadnix are only ever invoked from this module, so they're - # pulled in here rather than via a separate linting module. - home.packages = with pkgs; [statix deadnix sops alejandra]; + home.packages = with pkgs; [statix deadnix sops alejandra flake-runner]; + programs = { - # Installs nh and sets NH_FLAKE so ad-hoc `nh os switch` etc. also - # work correctly for this repo outside of the wrapper functions below. nh = { enable = true; flake = config.modules.terminal.flakeManagement.repoPath; }; + nushell.extraConfig = let repo = config.modules.terminal.flakeManagement.repoPath; - # pedantix wraps alejandra with extra checks per-file; if it's not - # enabled, fall back to running plain alejandra over the whole tree. - formatCmd = - if config.modules.terminal.pedantix.enable - then ''fd ".nix" $"${repo}/" | split row "\n" | each {pedantix $in} | ignore'' - else ''alejandra $"${repo}"''; - in '' - def progress-bar [step: int, total: int, --width: int = 12] { - let filled = (($step | into float) * $width / $total | math round | into int) - let bar = (1..$width | each { |i| if $i <= $filled { "█" } else { "░" } } | str join) - $"[($bar)] ($step)/($total)" - } - - # Unified flake management command. Flags select which stages run, but - # execution order is always pull -> update -> format/lint -> rebuild, - # regardless of flag order, since anything else risks flake.lock conflicts. - def flake [ - --pull (-p) # jj git pull, hard gate on unresolved conflicts - --update (-u) # nix flake update --flake ${repo} - --format (-f) # format + statix + deadnix (hard gates) - --rebuild (-r) # nh os switch, prints resulting generation - --help (-h) # show usage - ] { - if $help { - print "Usage: flake [-p|--pull] [-u|--update] [-f|--format] [-r|--rebuild]" - print "" - print " -p, --pull jj git pull (aborts on unresolved conflicts)" - print " -u, --update nix flake update" - print " -f, --format format .nix files, then statix + deadnix (hard gates)" - print " -r, --rebuild nh os switch" - print "" - print "Shortcuts:" - print ("nixfm = -f | rebuild = -pfr | upflake = -pfru" | split row "|" | split column "=" | str trim | rename Command Flags) - return - } - - let total = ([$pull $update $format $rebuild] | where { $in } | length) - if $total == 0 { - print "⚠️ No stage flags given — nothing to do. Try `flake --help`." - return - } - mut step = 0 - - if $pull { - $step += 1 - print $"⚠️ (progress-bar $step $total) Pulling latest changes..." - jj -R $"${repo}" git fetch - let conflicted = (jj -R $"${repo}" log -r "conflicts()" --no-graph -T "change_id ++ \"\n\"" | lines) - if ($conflicted | is-not-empty) { - error make { msg: $"jj pull produced conflicts, resolve before continuing:\n($conflicted | str join "\n")" } - } - print $"☑️ (progress-bar $step $total) Pulled cleanly." - } - - if $update { - $step += 1 - print $"⚠️ (progress-bar $step $total) Updating flake.lock..." - nix flake update --flake $"${repo}" - print $"☑️ (progress-bar $step $total) Updated flake.lock." - } - - if $format { - $step += 1 - print $"⚠️ (progress-bar $step $total) Formatting + linting..." - ${formatCmd} - statix check $"${repo}" - deadnix --fail $"${repo}" - print $"☑️ (progress-bar $step $total) Formatting + linting clean." - } - - if $rebuild { - $step += 1 - print $"⚠️ (progress-bar $step $total) Rebuilding & switching..." - nh os switch $"${repo}" -H ${hostName} --quiet --elevation-strategy sudo - nixos-rebuild list-generations | split row "\n" | split column " " | headers | get "Generation" | get 0 | $"✅ (progress-bar $step $total) Successfully built Generation ($in)" - } - } + runnerArgs = lib.concatStringsSep " " ( + [ + "--repo ${repo}" + "--host ${hostName}" + ] + ++ lib.optional config.modules.terminal.pedantix.enable "--pedantix" + ); + in '' # Format every .nix file, then lint. statix and deadnix are both # hard gates now: any non-zero exit from either aborts before a # broken/dead-code-laden commit can happen. - def nixfm [] { flake --format } + def nixfm [] { flake-runner --format ${runnerArgs} } # Format + lint, then rebuild and switch via nh. - def rebuild [] { flake --pull --format --rebuild } + def rebuild [] { flake-runner --pull --format --rebuild ${runnerArgs} } # Update the flake's inputs, then rebuild. - def upflake [] { flake --pull --update --format --rebuild } + def upflake [] { flake-runner --pull --update --format --rebuild ${runnerArgs} } # Pull a live NetworkManager connection profile out of # /etc/NetworkManager/system-connections, sops-encrypt it as a diff --git a/pkgs/flake-runner/default.nix b/pkgs/flake-runner/default.nix new file mode 100644 index 0000000..e85012b --- /dev/null +++ b/pkgs/flake-runner/default.nix @@ -0,0 +1,17 @@ +{ + lib, + rustPlatform, +}: +rustPlatform.buildRustPackage { + cargoLock = { + lockFile = ./Cargo.lock; + }; + pname = "flake-runner"; + src = ./.; + version = "0.1.0"; + meta = { + description = "Pull/update/format/rebuild pipeline for nixos-cfg, with a pinned progress bar"; + mainProgram = "flake-runner"; + platforms = lib.platforms.linux; + }; +}