nix: add support for nix profile

PR #2833

Co-authored-by: David Arnold <dar@xoe.solutions>
Co-authored-by: Florian Franzen <Florian.Franzen@gmail.com>

(cherry picked from commit 2f58d0a3de)
This commit is contained in:
Moises Nessim 2021-11-10 13:23:33 -05:00 committed by Robert Helgesson
parent ef6799c1ce
commit 7049cf37a9
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
4 changed files with 58 additions and 9 deletions

View file

@ -10,6 +10,23 @@ function errorEcho() {
echo $* >&2 echo $* >&2
} }
function removeByName() {
nix profile list \
| { grep "$1" || test $? = 1; } \
| cut -d ' ' -f 4 \
| xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG
}
function setNixProfileCommands() {
if [[ -e ~/.nix-profile/manifest.json ]] ; then
LIST_OUTPATH_CMD="nix profile list"
REMOVE_CMD="removeByName"
else
LIST_OUTPATH_CMD="nix-env -q --outpath"
REMOVE_CMD="nix-env -q"
fi
}
function setVerboseAndDryRun() { function setVerboseAndDryRun() {
if [[ -v VERBOSE ]]; then if [[ -v VERBOSE ]]; then
export VERBOSE_ARG="--verbose" export VERBOSE_ARG="--verbose"
@ -371,8 +388,9 @@ function doExpireGenerations() {
} }
function doListPackages() { function doListPackages() {
setNixProfileCommands
local outPath local outPath
outPath="$(nix-env -q --out-path | grep -o '/.*home-manager-path$')" outPath="$($LIST_OUTPATH_CMD | grep -o '/.*home-manager-path$')"
if [[ -n "$outPath" ]] ; then if [[ -n "$outPath" ]] ; then
nix-store -q --references "$outPath" | sed 's/[^-]*-//' nix-store -q --references "$outPath" | sed 's/[^-]*-//'
else else
@ -447,6 +465,7 @@ function doShowNews() {
function doUninstall() { function doUninstall() {
setVerboseAndDryRun setVerboseAndDryRun
setNixProfileCommands
echo "This will remove Home Manager from your system." echo "This will remove Home Manager from your system."
@ -464,7 +483,7 @@ function doUninstall() {
HOME_MANAGER_CONFIG="$(mktemp --tmpdir home-manager.XXXXXXXXXX)" HOME_MANAGER_CONFIG="$(mktemp --tmpdir home-manager.XXXXXXXXXX)"
echo "{ lib, ... }: { home.file = lib.mkForce {}; }" > "$HOME_MANAGER_CONFIG" echo "{ lib, ... }: { home.file = lib.mkForce {}; }" > "$HOME_MANAGER_CONFIG"
doSwitch doSwitch
$DRY_RUN_CMD nix-env -e home-manager-path || true $DRY_RUN_CMD $REMOVE_CMD home-manager-path || true
rm "$HOME_MANAGER_CONFIG" rm "$HOME_MANAGER_CONFIG"
$DRY_RUN_CMD rm $VERBOSE_ARG -r \ $DRY_RUN_CMD rm $VERBOSE_ARG -r \
"${XDG_DATA_HOME:-$HOME/.local/share}/home-manager" "${XDG_DATA_HOME:-$HOME/.local/share}/home-manager"

View file

@ -260,7 +260,17 @@ in
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
echo "Creating profile generation $newGenNum" echo "Creating profile generation $newGenNum"
$DRY_RUN_CMD nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath" if [[ -e "$genProfilePath"/manifest.json ]] ; then
# Remove all packages from "$genProfilePath"
# `nix profile remove '.*' --profile "$genProfilePath"` was not working, so here is a workaround:
nix profile list --profile "$genProfilePath" \
| cut -d ' ' -f 4 \
| xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG --profile "$genProfilePath"
$DRY_RUN_CMD nix profile install $VERBOSE_ARG --profile "$genProfilePath" "$newGenPath"
else
$DRY_RUN_CMD nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath"
fi
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath" $DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath"
else else
echo "No change so reusing latest profile generation $oldGenNum" echo "No change so reusing latest profile generation $oldGenNum"

View file

@ -578,30 +578,49 @@ in
if config.submoduleSupport.externalPackageInstall if config.submoduleSupport.externalPackageInstall
then then
'' ''
if nix-env -q | grep '^home-manager-path$'; then if [[ -e "$nixProfilePath"/manifest.json ]] ; then
$DRY_RUN_CMD nix-env -e home-manager-path nix profile list \
| { grep 'home-manager-path$' || test $? = 1; } \
| awk -F ' ' '{ print $4 }' \
| cut -d ' ' -f 4 \
| xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG
else
if nix-env -q | grep '^home-manager-path$'; then
$DRY_RUN_CMD nix-env -e home-manager-path
fi
fi fi
'' ''
else else
'' ''
if ! $DRY_RUN_CMD nix-env -i ${cfg.path} ; then if [[ -e "$nixProfilePath"/manifest.json ]] ; then
INSTALL_CMD="nix profile install"
LIST_CMD="nix profile list"
REMOVE_CMD_SYNTAX='nix profile remove {number | store path}'
else
INSTALL_CMD="nix-env -i"
LIST_CMD="nix-env -q"
REMOVE_CMD_SYNTAX='nix-env -e {package name}'
fi
if ! $DRY_RUN_CMD $INSTALL_CMD ${cfg.path} ; then
cat <<EOF cat <<EOF
Oops, nix-env failed to install your new Home Manager profile! Oops, nix-env failed to install your new Home Manager profile!
Perhaps there is a conflict with a package that was installed using Perhaps there is a conflict with a package that was installed using
'nix-env -i'? Try running '$INSTALL_CMD'? Try running
nix-env -q $LIST_COMMAND
and if there is a conflicting package you can remove it with and if there is a conflicting package you can remove it with
nix-env -e {package name} $REMOVE_CMD_SYNTAX
Then try activating your Home Manager configuration again. Then try activating your Home Manager configuration again.
EOF EOF
exit 1 exit 1
fi fi
unset INSTALL_CMD LIST_CMD REMOVE_CMD_SYNTAX
'' ''
); );

View file

@ -5,6 +5,7 @@ function setupVars() {
local profilesPath="$nixStateDir/profiles/per-user/$USER" local profilesPath="$nixStateDir/profiles/per-user/$USER"
local gcPath="$nixStateDir/gcroots/per-user/$USER" local gcPath="$nixStateDir/gcroots/per-user/$USER"
declare -gr nixProfilePath="$profilesPath/profile"
declare -gr genProfilePath="$profilesPath/home-manager" declare -gr genProfilePath="$profilesPath/home-manager"
declare -gr newGenPath="@GENERATION_DIR@"; declare -gr newGenPath="@GENERATION_DIR@";
declare -gr newGenGcPath="$gcPath/current-home" declare -gr newGenGcPath="$gcPath/current-home"