From 785cb3a75476033ba6eec2fef334d47d8e64388a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 22 Nov 2019 16:06:44 +0100 Subject: [PATCH] refactor(tvix): getEnv(): Return std::optional This allows distinguishing between an empty value and no value. Patch ported from upstream at https://github.com/NixOS/nix/commit/ba87b08f8529e4d9f8c58d8c625152058ceadb75 Change-Id: I061cc8e16b1a7a0341adfc3b0edca1c0c51d5c97 Reviewed-on: https://cl.tvl.fyi/c/depot/+/1884 Tested-by: BuildkiteCI Reviewed-by: kanepyork --- third_party/nix/src/libexpr/eval.cc | 8 ++-- third_party/nix/src/libexpr/primops.cc | 2 +- third_party/nix/src/libstore/build.cc | 2 +- third_party/nix/src/libstore/gc.cc | 3 +- third_party/nix/src/libstore/globals.cc | 25 ++++++----- third_party/nix/src/libstore/globals.hh | 4 +- third_party/nix/src/libstore/local-store.hh | 5 ++- third_party/nix/src/libstore/ssh.cc | 4 +- third_party/nix/src/libutil/util.cc | 45 ++++++++----------- third_party/nix/src/libutil/util.hh | 2 +- third_party/nix/src/nix-build/nix-build.cc | 10 +++-- third_party/nix/src/nix-env/nix-env.cc | 2 +- .../src/nix-prefetch-url/nix-prefetch-url.cc | 2 +- third_party/nix/src/nix/doctor.cc | 8 ++-- third_party/nix/src/nix/edit.cc | 2 +- third_party/nix/src/nix/run.cc | 4 +- third_party/nix/src/nix/upgrade-nix.cc | 4 +- 17 files changed, 66 insertions(+), 66 deletions(-) diff --git a/third_party/nix/src/libexpr/eval.cc b/third_party/nix/src/libexpr/eval.cc index b735495f2..28ae46bdf 100644 --- a/third_party/nix/src/libexpr/eval.cc +++ b/third_party/nix/src/libexpr/eval.cc @@ -287,11 +287,11 @@ EvalState::EvalState(const Strings& _searchPath, const ref& store) staticBaseEnv(false, nullptr) { expr::InitGC(); - countCalls = getEnv("NIX_COUNT_CALLS", "0") != "0"; + countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0"; /* Initialise the Nix expression search path. */ if (!evalSettings.pureEval) { - Strings paths = parseNixPath(getEnv("NIX_PATH", "")); + Strings paths = parseNixPath(getEnv("NIX_PATH").value_or("")); for (auto& i : _searchPath) { addToSearchPath(i); } @@ -1644,7 +1644,7 @@ bool EvalState::eqValues(Value& v1, Value& v2) { } void EvalState::printStats() { - bool showStats = getEnv("NIX_SHOW_STATS", "0") != "0"; + bool showStats = getEnv("NIX_SHOW_STATS").value_or("0") != "0"; struct rusage buf; getrusage(RUSAGE_SELF, &buf); @@ -1658,7 +1658,7 @@ void EvalState::printStats() { nrAttrsets * sizeof(Bindings) + nrAttrsInAttrsets * sizeof(Attr); if (showStats) { - auto outPath = getEnv("NIX_SHOW_STATS_PATH", "-"); + auto outPath = getEnv("NIX_SHOW_STATS_PATH").value_or("-"); std::fstream fs; if (outPath != "-") { fs.open(outPath, std::fstream::out); diff --git a/third_party/nix/src/libexpr/primops.cc b/third_party/nix/src/libexpr/primops.cc index 04a44311a..dd8a509df 100644 --- a/third_party/nix/src/libexpr/primops.cc +++ b/third_party/nix/src/libexpr/primops.cc @@ -413,7 +413,7 @@ static void prim_getEnv(EvalState& state, const Pos& pos, Value** args, std::string name = state.forceStringNoCtx(*args[0], pos); mkString(v, evalSettings.restrictEval || evalSettings.pureEval ? "" - : getEnv(name)); + : getEnv(name).value_or("")); } /* Evaluate the first argument, then return the second argument. */ diff --git a/third_party/nix/src/libstore/build.cc b/third_party/nix/src/libstore/build.cc index 3dce15665..6e4ca99b1 100644 --- a/third_party/nix/src/libstore/build.cc +++ b/third_party/nix/src/libstore/build.cc @@ -2582,7 +2582,7 @@ void DerivationGoal::initEnv() { if (fixedOutput) { for (auto& i : parsedDrv->getStringsAttr("impureEnvVars").value_or(Strings())) { - env[i] = getEnv(i); + env[i] = getEnv(i).value_or(""); } } diff --git a/third_party/nix/src/libstore/gc.cc b/third_party/nix/src/libstore/gc.cc index 4f04e09a7..50c52bb00 100644 --- a/third_party/nix/src/libstore/gc.cc +++ b/third_party/nix/src/libstore/gc.cc @@ -906,7 +906,8 @@ void LocalStore::collectGarbage(const GCOptions& options, GCResults& results) { } void LocalStore::autoGC(bool sync) { - static auto fakeFreeSpaceFile = getEnv("_NIX_TEST_FREE_SPACE_FILE", ""); + static auto fakeFreeSpaceFile = + getEnv("_NIX_TEST_FREE_SPACE_FILE").value_or(""); auto getAvail = [this]() -> uint64_t { if (!fakeFreeSpaceFile.empty()) { diff --git a/third_party/nix/src/libstore/globals.cc b/third_party/nix/src/libstore/globals.cc index 34f5d4605..6babb4589 100644 --- a/third_party/nix/src/libstore/globals.cc +++ b/third_party/nix/src/libstore/globals.cc @@ -31,19 +31,22 @@ static GlobalConfig::Register r1(&settings); Settings::Settings() : nixPrefix(NIX_PREFIX), nixStore(canonPath( - getEnv("NIX_STORE_DIR", getEnv("NIX_STORE", NIX_STORE_DIR)))), - nixDataDir(canonPath(getEnv("NIX_DATA_DIR", NIX_DATA_DIR))), - nixLogDir(canonPath(getEnv("NIX_LOG_DIR", NIX_LOG_DIR))), - nixStateDir(canonPath(getEnv("NIX_STATE_DIR", NIX_STATE_DIR))), - nixConfDir(canonPath(getEnv("NIX_CONF_DIR", NIX_CONF_DIR))), - nixLibexecDir(canonPath(getEnv("NIX_LIBEXEC_DIR", NIX_LIBEXEC_DIR))), - nixBinDir(canonPath(getEnv("NIX_BIN_DIR", NIX_BIN_DIR))), + getEnv("NIX_STORE_DIR") + .value_or(getEnv("NIX_STORE").value_or(NIX_STORE_DIR)))), + nixDataDir(canonPath(getEnv("NIX_DATA_DIR").value_or(NIX_DATA_DIR))), + nixLogDir(canonPath(getEnv("NIX_LOG_DIR").value_or(NIX_LOG_DIR))), + nixStateDir(canonPath(getEnv("NIX_STATE_DIR").value_or(NIX_STATE_DIR))), + nixConfDir(canonPath(getEnv("NIX_CONF_DIR").value_or(NIX_CONF_DIR))), + nixLibexecDir( + canonPath(getEnv("NIX_LIBEXEC_DIR").value_or(NIX_LIBEXEC_DIR))), + nixBinDir(canonPath(getEnv("NIX_BIN_DIR").value_or(NIX_BIN_DIR))), nixManDir(canonPath(NIX_MAN_DIR)), nixDaemonSocketFile(canonPath(nixStateDir + DEFAULT_SOCKET_PATH)) { buildUsersGroup = getuid() == 0 ? "nixbld" : ""; - lockCPU = getEnv("NIX_AFFINITY_HACK", "1") == "1"; + lockCPU = getEnv("NIX_AFFINITY_HACK").value_or("1") == "1"; - caFile = getEnv("NIX_SSL_CERT_FILE", getEnv("SSL_CERT_FILE", "")); + caFile = getEnv("NIX_SSL_CERT_FILE") + .value_or(getEnv("SSL_CERT_FILE").value_or("")); if (caFile.empty()) { for (auto& fn : {"/etc/ssl/certs/ca-certificates.crt", @@ -58,9 +61,9 @@ Settings::Settings() /* Backwards compatibility. */ // TODO(tazjin): still? auto s = getEnv("NIX_REMOTE_SYSTEMS"); - if (!s.empty()) { + if (s) { Strings ss; - for (auto p : absl::StrSplit(s, absl::ByChar(':'), absl::SkipEmpty())) { + for (auto p : absl::StrSplit(*s, absl::ByChar(':'), absl::SkipEmpty())) { ss.push_back(absl::StrCat("@", p)); } builders = concatStringsSep(" ", ss); diff --git a/third_party/nix/src/libstore/globals.hh b/third_party/nix/src/libstore/globals.hh index 54defff06..29848fbb4 100644 --- a/third_party/nix/src/libstore/globals.hh +++ b/third_party/nix/src/libstore/globals.hh @@ -61,8 +61,8 @@ class Settings : public Config { /* File name of the socket the daemon listens to. */ Path nixDaemonSocketFile; - Setting storeUri{this, getEnv("NIX_REMOTE", "auto"), "store", - "The default Nix store to use."}; + Setting storeUri{this, getEnv("NIX_REMOTE").value_or("auto"), + "store", "The default Nix store to use."}; Setting keepFailed{ this, false, "keep-failed", diff --git a/third_party/nix/src/libstore/local-store.hh b/third_party/nix/src/libstore/local-store.hh index 193050e53..cfcfb35cc 100644 --- a/third_party/nix/src/libstore/local-store.hh +++ b/third_party/nix/src/libstore/local-store.hh @@ -98,8 +98,9 @@ class LocalStore : public LocalFSStore { public: // Hack for build-remote.cc. // TODO(tazjin): remove this when we've got gRPC - PathSet locksHeld = absl::StrSplit( - getEnv("NIX_HELD_LOCKS"), absl::ByAnyChar(" \t\n\r"), absl::SkipEmpty()); + PathSet locksHeld = + absl::StrSplit(getEnv("NIX_HELD_LOCKS").value_or(""), + absl::ByAnyChar(" \t\n\r"), absl::SkipEmpty()); /* Initialise the local store, upgrading the schema if necessary. */ diff --git a/third_party/nix/src/libstore/ssh.cc b/third_party/nix/src/libstore/ssh.cc index 7d5fe6d10..6043e584d 100644 --- a/third_party/nix/src/libstore/ssh.cc +++ b/third_party/nix/src/libstore/ssh.cc @@ -22,8 +22,8 @@ SSHMaster::SSHMaster(const std::string& host, std::string keyFile, void SSHMaster::addCommonSSHOpts(Strings& args) { for (auto& i : - absl::StrSplit(getEnv("NIX_SSHOPTS"), absl::ByAnyChar(" \t\n\r"), - absl::SkipEmpty())) { + absl::StrSplit(getEnv("NIX_SSHOPTS").value_or(""), + absl::ByAnyChar(" \t\n\r"), absl::SkipEmpty())) { args.push_back(std::string(i)); } if (!keyFile.empty()) { diff --git a/third_party/nix/src/libutil/util.cc b/third_party/nix/src/libutil/util.cc index 939b6361d..aea1e68e3 100644 --- a/third_party/nix/src/libutil/util.cc +++ b/third_party/nix/src/libutil/util.cc @@ -45,9 +45,10 @@ std::string SysError::addErrno(const std::string& s) { return s + ": " + strerror(errNo); } -std::string getEnv(const std::string& key, const std::string& def) { +std::optional getEnv(const std::string& key) { char* value = getenv(key.c_str()); - return value != nullptr ? std::string(value) : def; + if (value == nullptr) return {}; + return std::string(value); } std::map getEnv() { @@ -466,8 +467,9 @@ void deletePath(const Path& path, unsigned long long& bytesFreed) { static Path tempName(Path tmpRoot, const Path& prefix, bool includePid, int& counter) { - tmpRoot = - canonPath(tmpRoot.empty() ? getEnv("TMPDIR", "/tmp") : tmpRoot, true); + tmpRoot = canonPath( + tmpRoot.empty() ? getEnv("TMPDIR").value_or("/tmp") : tmpRoot, true); + if (includePid) { return (format("%1%/%2%-%3%-%4%") % tmpRoot % prefix % getpid() % counter++) .str(); @@ -507,16 +509,17 @@ Path createTempDir(const Path& tmpRoot, const Path& prefix, bool includePid, std::string getUserName() { auto pw = getpwuid(geteuid()); - std::string name = pw != nullptr ? pw->pw_name : getEnv("USER", ""); - if (name.empty()) { + std::optional name = + pw != nullptr ? pw->pw_name : getEnv("USER"); + if (!name.has_value()) { throw Error("cannot figure out user name"); } - return name; + return *name; } static Lazy getHome2([]() { - Path homeDir = getEnv("HOME"); - if (homeDir.empty()) { + std::optional homeDir = getEnv("HOME"); + if (!homeDir) { std::vector buf(16384); struct passwd pwbuf; struct passwd* pw; @@ -524,32 +527,24 @@ static Lazy getHome2([]() { (pw == nullptr) || (pw->pw_dir == nullptr) || (pw->pw_dir[0] == 0)) { throw Error("cannot determine user's home directory"); } - homeDir = pw->pw_dir; + return std::string(pw->pw_dir); } - return homeDir; + return homeDir.value(); }); Path getHome() { return getHome2(); } Path getCacheDir() { - Path cacheDir = getEnv("XDG_CACHE_HOME"); - if (cacheDir.empty()) { - cacheDir = getHome() + "/.cache"; - } - return cacheDir; + return getEnv("XDG_CACHE_HOME").value_or(getHome() + "/.cache"); } Path getConfigDir() { - Path configDir = getEnv("XDG_CONFIG_HOME"); - if (configDir.empty()) { - configDir = getHome() + "/.config"; - } - return configDir; + return getEnv("XDG_CONFIG_HOME").value_or(getHome() + "/.config"); } std::vector getConfigDirs() { Path configHome = getConfigDir(); - std::string configDirs = getEnv("XDG_CONFIG_DIRS"); + std::string configDirs = getEnv("XDG_CONFIG_DIRS").value_or(""); std::vector result = absl::StrSplit(configDirs, absl::ByChar(':'), absl::SkipEmpty()); result.insert(result.begin(), configHome); @@ -557,11 +552,7 @@ std::vector getConfigDirs() { } Path getDataDir() { - Path dataDir = getEnv("XDG_DATA_HOME"); - if (dataDir.empty()) { - dataDir = getHome() + "/.local/share"; - } - return dataDir; + return getEnv("XDG_DATA_HOME").value_or(getHome() + "/.local/share"); } // TODO(grfn): Remove in favor of std::filesystem::create_directories diff --git a/third_party/nix/src/libutil/util.hh b/third_party/nix/src/libutil/util.hh index b6d726b46..b3349c4f3 100644 --- a/third_party/nix/src/libutil/util.hh +++ b/third_party/nix/src/libutil/util.hh @@ -26,7 +26,7 @@ struct Source; extern const std::string nativeSystem; /* Return an environment variable. */ -std::string getEnv(const std::string& key, const std::string& def = ""); +std::optional getEnv(const std::string& key); /* Get the entire environment. */ std::map getEnv(); diff --git a/third_party/nix/src/nix-build/nix-build.cc b/third_party/nix/src/nix-build/nix-build.cc index 30ab2a813..26c308967 100644 --- a/third_party/nix/src/nix-build/nix-build.cc +++ b/third_party/nix/src/nix-build/nix-build.cc @@ -377,9 +377,12 @@ static void _main(int argc, char** argv) { /* Figure out what bash shell to use. If $NIX_BUILD_SHELL is not set, then build bashInteractive from . */ - auto shell = getEnv("NIX_BUILD_SHELL", ""); + auto opt_shell = getEnv("NIX_BUILD_SHELL"); + std::string shell; - if (shell.empty()) { + if (opt_shell.has_value()) { + shell = opt_shell.value(); + } else { try { auto expr = state->parseExprFromString( "(import {}).bashInteractive", absPath(".")); @@ -427,7 +430,8 @@ static void _main(int argc, char** argv) { // Set the environment. auto env = getEnv(); - auto tmp = getEnv("TMPDIR", getEnv("XDG_RUNTIME_DIR", "/tmp")); + auto tmp = + getEnv("TMPDIR").value_or(getEnv("XDG_RUNTIME_DIR").value_or("/tmp")); if (pure) { decltype(env) newEnv; diff --git a/third_party/nix/src/nix-env/nix-env.cc b/third_party/nix/src/nix-env/nix-env.cc index 830bd514d..ee36510f0 100644 --- a/third_party/nix/src/nix-env/nix-env.cc +++ b/third_party/nix/src/nix-env/nix-env.cc @@ -1516,7 +1516,7 @@ static int _main(int argc, char** argv) { globals.instSource.autoArgs = myArgs.getAutoArgs(*globals.state); if (globals.profile.empty()) { - globals.profile = getEnv("NIX_PROFILE", ""); + globals.profile = getEnv("NIX_PROFILE").value_or(""); } if (globals.profile.empty()) { diff --git a/third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc b/third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc index c718ef5f4..b61a38a7f 100644 --- a/third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc +++ b/third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc @@ -59,7 +59,7 @@ static int _main(int argc, char** argv) { { HashType ht = htSHA256; std::vector args; - bool printPath = !getEnv("PRINT_PATH").empty(); + bool printPath = getEnv("PRINT_PATH").has_value(); bool fromExpr = false; std::string attrPath; bool unpack = false; diff --git a/third_party/nix/src/nix/doctor.cc b/third_party/nix/src/nix/doctor.cc index 0105b05e9..e65ca69f6 100644 --- a/third_party/nix/src/nix/doctor.cc +++ b/third_party/nix/src/nix/doctor.cc @@ -48,8 +48,8 @@ struct CmdDoctor final : StoreCommand { static bool checkNixInPath() { PathSet dirs; - for (auto& dir : - absl::StrSplit(getEnv("PATH"), absl::ByChar(':'), absl::SkipEmpty())) { + for (auto& dir : absl::StrSplit(getEnv("PATH").value_or(""), + absl::ByChar(':'), absl::SkipEmpty())) { if (pathExists(absl::StrCat(dir, "/nix-env"))) { dirs.insert(dirOf(canonPath(absl::StrCat(dir, "/nix-env"), true))); } @@ -72,8 +72,8 @@ struct CmdDoctor final : StoreCommand { static bool checkProfileRoots(const ref& store) { PathSet dirs; - for (auto dir : - absl::StrSplit(getEnv("PATH"), absl::ByChar(':'), absl::SkipEmpty())) { + for (auto dir : absl::StrSplit(getEnv("PATH").value_or(""), + absl::ByChar(':'), absl::SkipEmpty())) { Path profileDir = dirOf(dir); try { Path userEnv = canonPath(profileDir, true); diff --git a/third_party/nix/src/nix/edit.cc b/third_party/nix/src/nix/edit.cc index 644caa7cb..b5369e4a8 100644 --- a/third_party/nix/src/nix/edit.cc +++ b/third_party/nix/src/nix/edit.cc @@ -53,7 +53,7 @@ struct CmdEdit final : InstallableCommand { throw Error("cannot parse line number '%s'", pos); } - auto editor = getEnv("EDITOR", "cat"); + auto editor = getEnv("EDITOR").value_or("cat"); Strings args = absl::StrSplit(editor, absl::ByAnyChar(" \t\n\r"), absl::SkipEmpty()); diff --git a/third_party/nix/src/nix/run.cc b/third_party/nix/src/nix/run.cc index e76f8834c..06c95f856 100644 --- a/third_party/nix/src/nix/run.cc +++ b/third_party/nix/src/nix/run.cc @@ -123,8 +123,8 @@ struct CmdRun final : InstallablesCommand { todo.push(path); } - Strings unixPath = - absl::StrSplit(getEnv("PATH"), absl::ByChar(':'), absl::SkipEmpty()); + Strings unixPath = absl::StrSplit(getEnv("PATH").value_or(""), + absl::ByChar(':'), absl::SkipEmpty()); while (!todo.empty()) { Path path = todo.front(); diff --git a/third_party/nix/src/nix/upgrade-nix.cc b/third_party/nix/src/nix/upgrade-nix.cc index eff51ba15..77e284afb 100644 --- a/third_party/nix/src/nix/upgrade-nix.cc +++ b/third_party/nix/src/nix/upgrade-nix.cc @@ -103,8 +103,8 @@ struct CmdUpgradeNix final : MixDryRun, StoreCommand { static Path getProfileDir(const ref& store) { Path where; - for (auto& dir : - absl::StrSplit(getEnv("PATH"), absl::ByChar(':'), absl::SkipEmpty())) { + for (auto& dir : absl::StrSplit(getEnv("PATH").value_or(""), + absl::ByChar(':'), absl::SkipEmpty())) { if (pathExists(absl::StrCat(dir, "/nix-env"))) { where = dir; break;