{ git, jq, lib, nix, nvd, openssh, symlinkJoin, writeShellApplication, writeTextDir, xdg-utils, }: let bin = writeShellApplication { name = "nixfiles"; runtimeInputs = [ git jq nix nvd openssh xdg-utils ]; # Shamelessly appropriated from https://github.com/ncfavier/config. # Hopefully Naïm will not sue me for copyright infrigment. text = '' nixfiles="''${NIXFILES:-.}" rebuild="nixos-rebuild" rebuild_opts=(--fast --use-remote-sudo) cmd=$1 shift case $cmd in repl|eval|nix-build|rev) args=() flakeArgs=() for arg do case $arg in -w|--wip) flakeArgs+=(--override-flake nixfiles "$nixfiles") ;; *) args+=("$arg") ;; esac done set -- "''${args[@]}" ;;& compare) if command -v xdg-open >/dev/null; then open="xdg-open" else open="open" fi input=$1 # shellcheck disable=SC1090 . <(nix flake metadata --json nixfiles | jq -r --arg open "$open" --arg input "$input" ' def browse($url): @sh "$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 . ;; nix-build) # https://github.com/NixOS/nix/issues/6661 exec nix-build --log-format bar-with-logs "''${flakeArgs[@]}" ~/.nix-defexpr -A "$@" ;; specialise) name=$1 shift # Assumes that sudo is already configured. Has setuid baked in if needed and etc. 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 ;; diff) exec nvd diff /run/current-system "$nixfiles/result" ;; @*) # Assumes that hosts are configured in the OpenSSH configuration. host=''${cmd#@} hostname=$(ssh -q "$host" 'echo "$HOSTNAME"') exec "$rebuild" -v --flake "$nixfiles#$hostname" --target-host "$host" "''${rebuild_opts[@]}" --show-trace "$@" ;; *) exec "$rebuild" -v --flake "$nixfiles" "''${rebuild_opts[@]}" --show-trace "$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:-.}" _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 nix-build specialise revert home boot build build-vm build-vm-with-bootloader dry-activate dry-build edit switch test' fi else case ''${words[1]} in compare|update|rev) __complete_nix_cmd "$cword" nix flake lock "$nixfiles" --update-input ;; repl|eval|nix-build) __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" ;; switch) __complete_nix_cmd 2 nix build "$nixfiles" ;; esac fi } complete -F _nixfiles nixfiles ''; in symlinkJoin { name = "nixfiles"; paths = [ bin bashCompletion ]; meta = with lib; { description = "A helper utility to manage NixOS configurations with Nix flakes"; homepage = "https://git.azahi.cc/nixfiles"; license = licenses.wtfpl; platforms = platforms.unix; maintainers = with maintainers; [ azahi ]; mainProgram = "nixfiles"; }; }