2024-05-30 18:22:11 +02:00
|
|
|
#include "command.hh"
|
|
|
|
#include "run.hh"
|
|
|
|
#include <queue>
|
|
|
|
|
|
|
|
using namespace nix;
|
|
|
|
|
|
|
|
struct CmdEnv : NixMultiCommand
|
|
|
|
{
|
2024-05-30 18:40:53 +02:00
|
|
|
CmdEnv()
|
|
|
|
: NixMultiCommand("env", RegisterCommand::getCommandsFor({"env"}))
|
|
|
|
{
|
|
|
|
}
|
2024-05-30 18:22:11 +02:00
|
|
|
|
|
|
|
std::string description() override
|
|
|
|
{
|
|
|
|
return "manipulate the process environment";
|
|
|
|
}
|
|
|
|
|
2024-05-30 18:40:53 +02:00
|
|
|
Category category() override
|
|
|
|
{
|
|
|
|
return catUtility;
|
|
|
|
}
|
2024-05-30 18:22:11 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static auto rCmdEnv = registerCommand<CmdEnv>("env");
|
|
|
|
|
|
|
|
struct CmdShell : InstallablesCommand, MixEnvironment
|
|
|
|
{
|
|
|
|
|
|
|
|
using InstallablesCommand::run;
|
|
|
|
|
2024-05-30 18:40:53 +02:00
|
|
|
std::vector<std::string> command = {getEnv("SHELL").value_or("bash")};
|
2024-05-30 18:22:11 +02:00
|
|
|
|
|
|
|
CmdShell()
|
|
|
|
{
|
2024-05-30 18:40:53 +02:00
|
|
|
addFlag(
|
|
|
|
{.longName = "command",
|
|
|
|
.shortName = 'c',
|
|
|
|
.description = "Command and arguments to be executed, defaulting to `$SHELL`",
|
|
|
|
.labels = {"command", "args"},
|
|
|
|
.handler = {[&](std::vector<std::string> ss) {
|
|
|
|
if (ss.empty())
|
|
|
|
throw UsageError("--command requires at least one argument");
|
|
|
|
command = ss;
|
|
|
|
}}});
|
2024-05-30 18:22:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string description() override
|
|
|
|
{
|
|
|
|
return "run a shell in which the specified packages are available";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string doc() override
|
|
|
|
{
|
|
|
|
return
|
2024-05-30 18:40:53 +02:00
|
|
|
#include "shell.md"
|
|
|
|
;
|
2024-05-30 18:22:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void run(ref<Store> store, Installables && installables) override
|
|
|
|
{
|
2024-05-30 18:40:53 +02:00
|
|
|
auto outPaths =
|
|
|
|
Installable::toStorePaths(getEvalStore(), store, Realise::Outputs, OperateOn::Output, installables);
|
2024-05-30 18:22:11 +02:00
|
|
|
|
|
|
|
auto accessor = store->getFSAccessor();
|
|
|
|
|
|
|
|
std::unordered_set<StorePath> done;
|
|
|
|
std::queue<StorePath> todo;
|
2024-05-30 18:40:53 +02:00
|
|
|
for (auto & path : outPaths)
|
|
|
|
todo.push(path);
|
2024-05-30 18:22:11 +02:00
|
|
|
|
|
|
|
setEnviron();
|
|
|
|
|
|
|
|
std::vector<std::string> pathAdditions;
|
|
|
|
|
|
|
|
while (!todo.empty()) {
|
|
|
|
auto path = todo.front();
|
|
|
|
todo.pop();
|
2024-05-30 18:40:53 +02:00
|
|
|
if (!done.insert(path).second)
|
|
|
|
continue;
|
2024-05-30 18:22:11 +02:00
|
|
|
|
|
|
|
if (true)
|
|
|
|
pathAdditions.push_back(store->printStorePath(path) + "/bin");
|
|
|
|
|
|
|
|
auto propPath = accessor->resolveSymlinks(
|
|
|
|
CanonPath(store->printStorePath(path)) / "nix-support" / "propagated-user-env-packages");
|
|
|
|
if (auto st = accessor->maybeLstat(propPath); st && st->type == SourceAccessor::tRegular) {
|
|
|
|
for (auto & p : tokenizeString<Paths>(accessor->readFile(propPath)))
|
|
|
|
todo.push(store->parseStorePath(p));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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());
|
|
|
|
|
|
|
|
Strings args;
|
2024-05-30 18:40:53 +02:00
|
|
|
for (auto & arg : command)
|
|
|
|
args.push_back(arg);
|
2024-05-30 18:22:11 +02:00
|
|
|
|
|
|
|
runProgramInStore(store, UseLookupPath::Use, *command.begin(), args);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static auto rCmdShell = registerCommand2<CmdShell>({"env", "shell"});
|