about summary refs log tree commit diff
path: root/packages
diff options
context:
space:
mode:
authorAzat Bahawi <azat@bahawi.net>2023-09-28 03:41:22 +0300
committerAzat Bahawi <azat@bahawi.net>2023-09-28 03:41:22 +0300
commitfa40015d45d721eba1b363fbca3e55881f296b87 (patch)
tree2377044fdc99870678b3752ae05ee037e8cb14ca /packages
parent2023-09-20 (diff)
2023-09-28
Diffstat (limited to '')
-rw-r--r--packages/nixfiles.nix213
1 files changed, 148 insertions, 65 deletions
diff --git a/packages/nixfiles.nix b/packages/nixfiles.nix
index 47b2c49..3f17edc 100644
--- a/packages/nixfiles.nix
+++ b/packages/nixfiles.nix
@@ -3,71 +3,154 @@
   jq,
   nix,
   openssh,
+  symlinkJoin,
   writeShellApplication,
-}:
-writeShellApplication {
-  name = "nixfiles";
-  runtimeInputs = [git jq nix openssh];
-  text = ''
-    cmd="$1"
-    shift
-    case "$cmd" in
-    update)
-      if (( $# )); then
-        args=()
-        for input do args+=(--update-input "$input"); done
-        exec nix flake lock "." "''${args[@]}"
-      else
-        exec nix flake update -v "."
-      fi
-      ;;
-    rev)
-      nix flake metadata --json nixfiles |
-        if (( $# )); then
-          jq -r --arg input "$1" '.locks.nodes[$input].locked.rev'
-        else
-          jq -r '.revision // "dirty"'
-        fi
-      ;;
-    repl|eval|build)
-      args=()
-      for arg do case $arg in
-        -w|--wip) args+=(--override-flake config ".")
-        ;;
-        *) args+=("$arg")
-      esac done
-      set -- "''${args[@]}"
-      ;;&
-    repl)
-      exec nix repl ~/.nix-defexpr "$@"
-      ;;
-    eval)
-      exec nix eval -f ~/.nix-defexpr --json "$@" | jq -r .
-      ;;
-    build)
-      exec nix build -f ~/.nix-defexpr --json "$@" | jq -r .
-      ;;
-    home)
-      attr="nixosConfigurations.$HOSTNAME.config.hm.home.activationPackage"
-      export VERBOSE=1
-      exec nix shell --verbose ".#$attr" "$@" --command home-manager-generation
-      ;;
-    specialise)
-      name="$1"
+  writeTextDir,
+  xdg-utils,
+}: let
+  bin = writeShellApplication {
+    name = "nixfiles";
+
+    runtimeInputs = [
+      git
+      jq
+      nix
+      openssh
+      xdg-utils
+    ];
+
+    # Shamelessly appropriated from https://github.com/ncfavier/config.
+    # Hopefully Naïm will not sue me for copyright infrigment.
+    text = ''
+      nixfiles="''${NIXFILES:-$HOME/src/nixfiles}"
+      cmd=$1
       shift
-      exec sudo /run/current-system/specialisation/"$name"/bin/switch-to-configuration switch
-      ;;
-    revert)
-      exec sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch
-      ;;
-    @*)
-      host="''${cmd#@}"
-      hostname="$(ssh -q "$host" 'echo "$HOSTNAME"')"
-      exec nixos-rebuild -v --flake ".#$hostname" --target-host "$host" --use-remote-sudo "$@"
-      ;;
-    *)
-      exec nixos-rebuild -v --flake . --use-remote-sudo "$cmd" "$@"
-      ;;
-    esac
+      case $cmd in
+        repl|eval|build|rev)
+          args=() flakeArgs=()
+          for arg do case $arg in
+            -w|--wip) flakeArgs+=(--override-flake nixfiles "$nixfiles");;
+            *) args+=("$arg")
+          esac done
+          set -- "''${args[@]}"
+          ;;&
+
+        compare)
+          input=$1
+          # shellcheck disable=SC1090
+          . <(nix flake metadata --json nixfiles | jq -r --arg input "$input" '
+            def browse($url): @sh "xdg-open \($url)";
+            .locks.nodes[$input] |
+            if .locked.type == "github" then
+              browse("https://github.com/\(.locked.owner)/\(.locked.repo)/compare/\(.locked.rev)...\(.original.ref // "master")")
+            elif .locked.type == "gitlab" then
+              browse("https://gitlab.com/\(.locked.owner)/\(.locked.repo)/-/compare/\(.locked.rev)...\(.original.ref // "master")")
+            else
+              "echo unsupported input type \(.locked.type) (supported: github, gitlab)"
+            end
+          ')
+          ;;
+        update)
+          if (( $# )); then
+            args=()
+            for input do args+=(--update-input "$input"); done
+            exec nix flake lock --refresh "''${args[@]}" "$nixfiles"
+          else
+            # https://github.com/NixOS/nix/issues/6095
+            exec nix flake update -v --refresh "$nixfiles"
+          fi
+          ;;
+        rev)
+          if (( $# )); then
+            expr=inputs.''${1//'/'/.inputs.}.rev
+          else
+            expr=self.revision
+          fi
+          nix eval "''${flakeArgs[@]}" -f ~/.nix-defexpr --raw "$expr"
+          echo
+          ;;
+
+        repl)
+          exec nix repl "''${flakeArgs[@]}" -f ~/.nix-defexpr "$@";;
+        eval)
+          exec nix eval "''${flakeArgs[@]}" -f ~/.nix-defexpr --json "$@" | jq -r .;;
+        build)
+          # https://github.com/NixOS/nix/issues/6661
+          exec nix-build --log-format bar-with-logs "''${flakeArgs[@]}" ~/.nix-defexpr -A "$@";;
+
+        specialise)
+          name=$1
+          shift
+          exec sudo /run/current-system/specialisation/"$name"/bin/switch-to-configuration switch;;
+        revert)
+          exec sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch;;
+
+        home)
+          attr=nixosConfigurations."$HOSTNAME".config.hm.home.activationPackage
+          export VERBOSE=1
+          exec nix shell -v ".#$attr" "$@" -c home-manager-generation;;
+        @*)
+          host=''${cmd#@}
+          hostname=$(ssh -q "$host" 'echo "$HOSTNAME"')
+          exec nixos-rebuild -v --flake ".#$hostname" --target-host "$host" --use-remote-sudo "$@";;
+        *)
+          exec nixos-rebuild -v --fast --flake "." --use-remote-sudo "$cmd" "$@";;
+      esac
+    '';
+  };
+
+  bashCompletion = writeTextDir "/share/bash-completion/completions/nixfiles" ''
+    __compreply() {
+        local completion
+        while IFS= read -r completion; do
+        COMPREPLY+=("$completion")
+        done < <(compgen "$@" -- "$cur")
+    }
+    __complete_nix_cmd() {
+        local skip=$1; shift
+        COMP_WORDS=("$@" "''${COMP_WORDS[@]:skip}")
+        (( COMP_CWORD += $# - skip ))
+        _completion_loader nix
+        _complete_nix
+    }
+    _nixfiles() {
+        local cur prev words cword
+        local nixfiles="''${NIXFILES:-$HOME/src/nixfiles}"
+        _init_completion -n ':=&'
+        if [[ "$cword" == 1 ]] || [[ "$cword" == 2 && "$prev" == @* ]]; then
+            if [[ $cur == @* ]]; then
+                _known_hosts_real -a -- "$cur"
+            else
+                __compreply -W 'compare update repl eval bld specialise revert home build build-vm test switch boot'
+            fi
+        else case ''${words[1]} in
+            compare|update|rev)
+                __complete_nix_cmd "$cword" nix flake lock "$nixfiles" --update-input
+                ;;
+            repl|eval|bld)
+                compreply -W '-w --wip'
+                ;;&
+            repl)
+                __complete_nix_cmd 2 nix repl ~/.nix-defexpr
+                ;;
+            eval)
+                __complete_nix_cmd 2 nix eval -f ~/.nix-defexpr --json
+                ;;
+            build)
+                __complete_nix_cmd 2 nix build -f ~/.nix-defexpr --json
+                ;;
+            home)
+                __complete_nix_cmd 2 nix shell "$nixfiles"
+                ;;
+            build|switch)
+                __complete_nix_cmd 2 nix build "$nixfiles"
+                ;;
+        esac fi
+    }
+    complete -F _nixfiles nixfiles
   '';
-}
+in
+  symlinkJoin {
+    name = "nixfiles";
+    paths = [bin bashCompletion];
+  }

Consider giving Nix/NixOS a try! <3