Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the NIX_PATH environment variable take precedence over config files #8902

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 0 additions & 44 deletions src/libexpr/eval-settings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,6 @@

namespace nix {

/* Very hacky way to parse $NIX_PATH, which is colon-separated, but
can contain URLs (e.g. "nixpkgs=https://bla...:foo=https://"). */
static Strings parseNixPath(const std::string & s)
{
Strings res;

auto p = s.begin();

while (p != s.end()) {
auto start = p;
auto start2 = p;

while (p != s.end() && *p != ':') {
if (*p == '=') start2 = p + 1;
++p;
}

if (p == s.end()) {
if (p != start) res.push_back(std::string(start, p));
break;
}

if (*p == ':') {
auto prefix = std::string(start2, s.end());
if (EvalSettings::isPseudoUrl(prefix) || hasPrefix(prefix, "flake:")) {
++p;
while (p != s.end() && *p != ':') ++p;
}
res.push_back(std::string(start, p));
if (p == s.end()) break;
}

++p;
}

return res;
}

EvalSettings::EvalSettings()
{
auto var = getEnv("NIX_PATH");
if (var) nixPath = parseNixPath(*var);
}

Strings EvalSettings::getDefaultNixPath()
{
Strings res;
Expand Down
2 changes: 0 additions & 2 deletions src/libexpr/eval-settings.hh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ namespace nix {

struct EvalSettings : Config
{
EvalSettings();

static Strings getDefaultNixPath();

static bool isPseudoUrl(std::string_view s);
Expand Down
44 changes: 44 additions & 0 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,43 @@ void initGC()
gcInitialised = true;
}

/* Very hacky way to parse $NIX_PATH, which is colon-separated, but
can contain URLs (e.g. "nixpkgs=https://bla...:foo=https://"). */
static Strings parseNixPath(const std::string & s)
{
Strings res;

auto p = s.begin();

while (p != s.end()) {
auto start = p;
auto start2 = p;

while (p != s.end() && *p != ':') {
if (*p == '=') start2 = p + 1;
++p;
}

if (p == s.end()) {
if (p != start) res.push_back(std::string(start, p));
break;
}

if (*p == ':') {
auto prefix = std::string(start2, s.end());
if (EvalSettings::isPseudoUrl(prefix) || hasPrefix(prefix, "flake:")) {
++p;
while (p != s.end() && *p != ':') ++p;
}
res.push_back(std::string(start, p));
if (p == s.end()) break;
}

++p;
}

return res;
}

ErrorBuilder & ErrorBuilder::atPos(PosIdx pos)
{
Expand Down Expand Up @@ -526,8 +563,15 @@ EvalState::EvalState(

/* Initialise the Nix expression search path. */
if (!evalSettings.pureEval) {
// Command line specification
for (auto & i : _searchPath.elements)
searchPath.elements.emplace_back(SearchPath::Elem {i});
// Environment variable
auto environment = getEnv("NIX_PATH");
if (environment)
for (auto & i : parseNixPath(*environment))
searchPath.elements.emplace_back(SearchPath::Elem::parse(i));
// Config files and defaults
for (auto & i : evalSettings.nixPath.get())
searchPath.elements.emplace_back(SearchPath::Elem::parse(i));
}
Expand Down
9 changes: 9 additions & 0 deletions tests/nix_path.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ export NIX_PATH=non-existent=/non-existent/but-unused-anyways:by-absolute-path=$
nix-instantiate --eval -E '<by-absolute-path/simple.nix>' --restrict-eval
nix-instantiate --eval -E '<by-relative-path/simple.nix>' --restrict-eval

tmpfile=$(mktemp)
echo "nix-path = " > "$tmpfile"
export NIX_USER_CONF_FILES="$tmpfile"

# This should still work because the NIX_PATH environment variable will take
# precedence over the empty nix path set by the configuration file
nix-instantiate --eval -E '<by-relative-path/simple.nix>' --restrict-eval


# Should ideally also test this, but there’s no pure way to do it, so just trust me that it works
# nix-instantiate --eval -E '<nixpkgs>' -I nixpkgs=channel:nixos-unstable --restrict-eval

Expand Down