Skip to content

Commit

Permalink
nix shell: reflect command line order in PATH order
Browse files Browse the repository at this point in the history
Prior to this change, Nix would prepend every installable to the PATH
list in order to ensure that installables appeared before the current
PATH from the ambient environment.

With this change, all the installables are still prepended to the PATH,
but in the same order as they appear on the command line. This means
that the first of two packages that expose an executable `hello` would
appear in the PATH first, and thus be executed first.

See the test in the prior commit for a more concrete example.
  • Loading branch information
cole-h committed Dec 21, 2023
1 parent 1fb43d1 commit f4454aa
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
14 changes: 14 additions & 0 deletions src/libcmd/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,20 @@ StorePathSet Installable::toStorePathSet(
return outPaths;
}

StorePaths Installable::toStorePaths(
ref<Store> evalStore,
ref<Store> store,
Realise mode, OperateOn operateOn,
const Installables & installables)
{
StorePaths outPaths;
for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) {
auto thisOutPaths = path.outPaths();
outPaths.insert(outPaths.end(), thisOutPaths.begin(), thisOutPaths.end());
}
return outPaths;
}

StorePath Installable::toStorePath(
ref<Store> evalStore,
ref<Store> store,
Expand Down
7 changes: 7 additions & 0 deletions src/libcmd/installables.hh
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ struct Installable
OperateOn operateOn,
const Installables & installables);

static std::vector<StorePath> toStorePaths(
ref<Store> evalStore,
ref<Store> store,
Realise mode,
OperateOn operateOn,
const Installables & installables);

static StorePath toStorePath(
ref<Store> evalStore,
ref<Store> store,
Expand Down
9 changes: 6 additions & 3 deletions src/nix/run.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,15 @@ struct CmdShell : InstallablesCommand, MixEnvironment

setEnviron();

auto unixPath = tokenizeString<Strings>(getEnv("PATH").value_or(""), ":");
std::vector<std::string> pathAdditions;

while (!todo.empty()) {
auto path = todo.front();
todo.pop();
if (!done.insert(path).second) continue;

if (true)
unixPath.push_front(store->printStorePath(path) + "/bin");
pathAdditions.push_back(store->printStorePath(path) + "/bin");

auto propPath = CanonPath(store->printStorePath(path)) + "nix-support" + "propagated-user-env-packages";
if (auto st = accessor->maybeLstat(propPath); st && st->type == SourceAccessor::tRegular) {
Expand All @@ -131,7 +131,10 @@ struct CmdShell : InstallablesCommand, MixEnvironment
}
}

setenv("PATH", concatStringsSep(":", unixPath).c_str(), 1);
auto unixPath = tokenizeString<Strings>(getEnv("PATH").value_or(""), ":");
unixPath.insert(unixPath.begin(), pathAdditions.begin(), pathAdditions.end());
auto unixPathString = concatStringsSep(":", unixPath);
setenv("PATH", unixPathString.c_str(), 1);

Strings args;
for (auto & arg : command) args.push_back(arg);
Expand Down

0 comments on commit f4454aa

Please sign in to comment.