From 7f351e2993ed170dd9b8521a9e41f4d91d9b9c5d Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Tue, 8 Aug 2023 12:19:01 +0200 Subject: [PATCH] home-manager: handle profile list in Nix >2.17 Nix 2.17 changed the format of the `nix profile list` output. This commit adds support for parsing the new JSON profile list format. Fixes #4298 (cherry picked from commit c3ab5ea047e6dc73df530948f7367455749d8906) --- home-manager/default.nix | 3 ++- home-manager/home-manager | 18 ++++++++++++++---- modules/home-environment.nix | 25 ++++++++++++++++++++----- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/home-manager/default.nix b/home-manager/default.nix index 3589acb8..f1d654cc 100644 --- a/home-manager/default.nix +++ b/home-manager/default.nix @@ -1,4 +1,4 @@ -{ runCommand, lib, bash, callPackage, coreutils, findutils, gettext, gnused +{ runCommand, lib, bash, callPackage, coreutils, findutils, gettext, gnused, jq , less, ncurses, unixtools # used for pkgs.path for nixos-option , pkgs @@ -36,6 +36,7 @@ in runCommand "home-manager" { findutils gettext gnused + jq less ncurses nixos-option diff --git a/home-manager/home-manager b/home-manager/home-manager index 6d670fda..e2a84e42 100644 --- a/home-manager/home-manager +++ b/home-manager/home-manager @@ -11,11 +11,21 @@ export TEXTDOMAINDIR=@OUT@/share/locale # shellcheck disable=1091 source @HOME_MANAGER_LIB@ +function nixProfileList() { + # We attempt to use `--json` first (added in Nix 2.17). Otherwise attempt to + # parse the legacy output format. + { + nix profile list --json 2>/dev/null \ + | jq -r --arg name "$1" '.elements[].storePaths[] | select(endswith($name))' + } || { + nix profile list \ + | { grep "$1\$" || test $? = 1; } \ + | cut -d ' ' -f 4 + } +} + function removeByName() { - nix profile list \ - | { grep "$1" || test $? = 1; } \ - | cut -d ' ' -f 4 \ - | xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG + nixProfileList "$1" | xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG } function setNixProfileCommands() { diff --git a/modules/home-environment.nix b/modules/home-environment.nix index 9abf223b..78d4e7eb 100644 --- a/modules/home-environment.nix +++ b/modules/home-environment.nix @@ -599,13 +599,27 @@ in '' else '' + function nixProfileList() { + # We attempt to use `--json` first (added in Nix 2.17). Otherwise attempt to + # parse the legacy output format. + { + nix profile list --json 2>/dev/null \ + | jq -r --arg name "$1" '.elements[].storePaths[] | select(endswith($name))' + } || { + nix profile list \ + | { grep "$1\$" || test $? = 1; } \ + | cut -d ' ' -f 4 + } + } + + function nixRemoveProfileByName() { + nixProfileList "$1" | xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG + } + function nixReplaceProfile() { local oldNix="$(command -v nix)" - nix profile list \ - | { grep 'home-manager-path$' || test $? = 1; } \ - | cut -d ' ' -f 4 \ - | xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG + nixRemoveProfileByName 'home-manager-path' $DRY_RUN_CMD $oldNix profile install $1 } @@ -627,7 +641,7 @@ in _iError $'Oops, Nix failed to install your new Home Manager profile!\n\nPerhaps there is a conflict with a package that was installed using\n"%s"? Try running\n\n %s\n\nand if there is a conflicting package you can remove it with\n\n %s\n\nThen try activating your Home Manager configuration again.' "$INSTALL_CMD" "$LIST_CMD" "$REMOVE_CMD_SYNTAX" exit 1 fi - unset -f nixReplaceProfile + unset -f nixProfileList nixRemoveProfileByName nixReplaceProfile unset INSTALL_CMD INSTALL_CMD_ACTUAL LIST_CMD REMOVE_CMD_SYNTAX '' ); @@ -679,6 +693,7 @@ in gettext gnugrep gnused + jq ncurses # For `tput`. ] ++ config.home.extraActivationPath