Skip to content

Commit

Permalink
Fix nix upgrade-nix profile search
Browse files Browse the repository at this point in the history
Commit cfe66db updated `nix upgrade-nix` to use
`ExecutablePath::load().find`, which broke the logic for finding the
profile associated with the nix executable. The error looks something
like:

```
$ sudo -i nix upgrade-nix --debug
found Nix in '"/nix/store/46p1z0w9ad605kky62dr53z4h24k2a5r-nix-2.25.2/bin/nix"'
found profile '/nix/store/46p1z0w9ad605kky62dr53z4h24k2a5r-nix-2.25.2/bin'
error: directory '"/nix/store/46p1z0w9ad605kky62dr53z4h24k2a5r-nix-2.25.2/bin/nix"' does not appear to be part of a Nix profile
```

This seems to happen for two reasons:

1. The original PATH search resulted in a directory, but `find` returns
   the path to the executable. Fixed by getting the path's parent.
2. The profile symlink cannot be found because
   `ExecutablePath::load().find` canonicalizes the executable path. I
   updated find to normalize the path instead, which seems more in line
   with how other programs resolve paths. I'm not sure if this affects
   other callers though.

I manually tested this on macOS and Linux, and it seemed to fix
upgrading from 2.25.2 to 2.25.3.
  • Loading branch information
gcurtis committed Dec 13, 2024
1 parent f1187cb commit 2452621
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/libutil/executable-path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ ExecutablePath::findName(const OsString & exe, std::function<bool(const fs::path
for (auto & dir : directories) {
auto candidate = dir / exe;
if (isExecutable(candidate))
return std::filesystem::canonical(candidate);
return candidate.lexically_normal();
}

return std::nullopt;
Expand Down
2 changes: 1 addition & 1 deletion src/nix/upgrade-nix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand
auto whereOpt = ExecutablePath::load().findName(OS_STR("nix-env"));
if (!whereOpt)
throw Error("couldn't figure out how Nix is installed, so I can't upgrade it");
auto & where = *whereOpt;
const auto & where = whereOpt->parent_path();

printInfo("found Nix in '%s'", where);

Expand Down

0 comments on commit 2452621

Please sign in to comment.