mirror of
https://github.com/NixOS/nix
synced 2024-09-19 10:50:24 -04:00
feat: add flag add
to MixEnvironment
This commit is contained in:
parent
11452ce674
commit
0d52f4b61f
|
@ -1,3 +1,4 @@
|
||||||
|
#include <algorithm>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include "command.hh"
|
#include "command.hh"
|
||||||
|
@ -9,8 +10,7 @@
|
||||||
#include "profiles.hh"
|
#include "profiles.hh"
|
||||||
#include "repl.hh"
|
#include "repl.hh"
|
||||||
#include "strings.hh"
|
#include "strings.hh"
|
||||||
|
#include "environment-variables.hh"
|
||||||
extern char * * environ __attribute__((weak));
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -290,48 +290,63 @@ MixDefaultProfile::MixDefaultProfile()
|
||||||
MixEnvironment::MixEnvironment() : ignoreEnvironment(false)
|
MixEnvironment::MixEnvironment() : ignoreEnvironment(false)
|
||||||
{
|
{
|
||||||
addFlag({
|
addFlag({
|
||||||
.longName = "ignore-environment",
|
.longName = "ignore-env",
|
||||||
.shortName = 'i',
|
.shortName = 'i',
|
||||||
.description = "Clear the entire environment (except those specified with `--keep`).",
|
.description = "Clear the entire environment, except for those specified with `--keep-env-var`.",
|
||||||
.handler = {&ignoreEnvironment, true},
|
.handler = {&ignoreEnvironment, true},
|
||||||
});
|
});
|
||||||
|
|
||||||
addFlag({
|
addFlag({
|
||||||
.longName = "keep",
|
.longName = "keep-env-var",
|
||||||
.shortName = 'k',
|
.shortName = 'k',
|
||||||
.description = "Keep the environment variable *name*.",
|
.description = "Keep the environment variable *name*.",
|
||||||
.labels = {"name"},
|
.labels = {"name"},
|
||||||
.handler = {[&](std::string s) { keep.insert(s); }},
|
.handler = {[&](std::string s) { keepVars.insert(s); }},
|
||||||
});
|
});
|
||||||
|
|
||||||
addFlag({
|
addFlag({
|
||||||
.longName = "unset",
|
.longName = "unset-env-var",
|
||||||
.shortName = 'u',
|
.shortName = 'u',
|
||||||
.description = "Unset the environment variable *name*.",
|
.description = "Unset the environment variable *name*.",
|
||||||
.labels = {"name"},
|
.labels = {"name"},
|
||||||
.handler = {[&](std::string s) { unset.insert(s); }},
|
.handler = {[&](std::string s) { unsetVars.insert(s); }},
|
||||||
|
});
|
||||||
|
|
||||||
|
addFlag({
|
||||||
|
.longName = "set-env-var",
|
||||||
|
.shortName = 's',
|
||||||
|
.description = "Add/override an environment variable *name* with *value*.",
|
||||||
|
.labels = {"name", "value"},
|
||||||
|
.handler = {[&](std::string name, std::string value) { setVars.insert_or_assign(name, value); }},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MixEnvironment::setEnviron() {
|
void MixEnvironment::setEnviron() {
|
||||||
if (ignoreEnvironment) {
|
if (ignoreEnvironment && !unsetVars.empty())
|
||||||
if (!unset.empty())
|
throw UsageError("--unset-env-var does not make sense with --ignore-env");
|
||||||
throw UsageError("--unset does not make sense with --ignore-environment");
|
|
||||||
|
|
||||||
for (const auto & var : keep) {
|
if (!ignoreEnvironment && !keepVars.empty())
|
||||||
auto val = getenv(var.c_str());
|
throw UsageError("--keep-env-var does not make sense without --ignore-env");
|
||||||
if (val) stringsEnv.emplace_back(fmt("%s=%s", var.c_str(), val));
|
|
||||||
}
|
|
||||||
|
|
||||||
vectorEnv = stringsToCharPtrs(stringsEnv);
|
auto env = getEnv();
|
||||||
environ = vectorEnv.data();
|
|
||||||
} else {
|
|
||||||
if (!keep.empty())
|
|
||||||
throw UsageError("--keep does not make sense without --ignore-environment");
|
|
||||||
|
|
||||||
for (const auto & var : unset)
|
if (ignoreEnvironment)
|
||||||
unsetenv(var.c_str());
|
std::erase_if(env, [&](const auto & var) {
|
||||||
}
|
return !keepVars.contains(var.first);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!unsetVars.empty())
|
||||||
|
std::erase_if(env, [&](const auto & var) {
|
||||||
|
return unsetVars.contains(var.first);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!setVars.empty())
|
||||||
|
for (const auto & [name, value] : setVars)
|
||||||
|
env[name] = value;
|
||||||
|
|
||||||
|
replaceEnv(std::move(env));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,17 +315,18 @@ struct MixDefaultProfile : MixProfile
|
||||||
|
|
||||||
struct MixEnvironment : virtual Args {
|
struct MixEnvironment : virtual Args {
|
||||||
|
|
||||||
StringSet keep, unset;
|
StringSet keepVars;
|
||||||
Strings stringsEnv;
|
StringSet unsetVars;
|
||||||
std::vector<char*> vectorEnv;
|
std::map<std::string, std::string> setVars;
|
||||||
bool ignoreEnvironment;
|
bool ignoreEnvironment;
|
||||||
|
|
||||||
MixEnvironment();
|
MixEnvironment();
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Modify global environ based on `ignoreEnvironment`, `keep`, and
|
* Modify global environ based on `ignoreEnvironment`, `keep`,
|
||||||
* `unset`. It's expected that exec will be called before this class
|
* `unset`, and `added`. It's expected that exec will be called
|
||||||
* goes out of scope, otherwise `environ` will become invalid.
|
* before this class goes out of scope, otherwise `environ` will
|
||||||
|
* become invalid.
|
||||||
*/
|
*/
|
||||||
void setEnviron();
|
void setEnviron();
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,9 +43,9 @@ echo "\$ENVVAR"
|
||||||
EOF
|
EOF
|
||||||
)" = "a" ]]
|
)" = "a" ]]
|
||||||
|
|
||||||
# Test whether `nix develop --ignore-environment` does _not_ pass through environment variables.
|
# Test whether `nix develop --ignore-env` does _not_ pass through environment variables.
|
||||||
[[ -z "$(
|
[[ -z "$(
|
||||||
ENVVAR=a nix develop --ignore-environment --no-write-lock-file .#hello <<EOF
|
ENVVAR=a nix develop --ignore-env --no-write-lock-file .#hello <<EOF
|
||||||
echo "\$ENVVAR"
|
echo "\$ENVVAR"
|
||||||
EOF
|
EOF
|
||||||
)" ]]
|
)" ]]
|
||||||
|
@ -63,7 +63,7 @@ EOF
|
||||||
|
|
||||||
# Test whether `nix develop` with ignore environment sets `SHELL` to nixpkgs#bashInteractive shell.
|
# Test whether `nix develop` with ignore environment sets `SHELL` to nixpkgs#bashInteractive shell.
|
||||||
[[ "$(
|
[[ "$(
|
||||||
SHELL=custom nix develop --ignore-environment --no-write-lock-file .#hello <<EOF
|
SHELL=custom nix develop --ignore-env --no-write-lock-file .#hello <<EOF
|
||||||
echo "\$SHELL"
|
echo "\$SHELL"
|
||||||
EOF
|
EOF
|
||||||
)" -ef "$BASH_INTERACTIVE_EXECUTABLE" ]]
|
)" -ef "$BASH_INTERACTIVE_EXECUTABLE" ]]
|
||||||
|
|
Loading…
Reference in a new issue