Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
fricklerhandwerk committed Jul 11, 2024
1 parent 4e2ee47 commit d41543a
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 43 deletions.
38 changes: 0 additions & 38 deletions src/libexpr/eval-settings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,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(bool & readOnlyMode, EvalSettings::LookupPathHooks lookupPathHooks)
: readOnlyMode{readOnlyMode}
, lookupPathHooks{lookupPathHooks}
Expand Down
73 changes: 68 additions & 5 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,48 @@ static Symbol getName(const AttrName & name, EvalState & state, Env & env)
}
}

/* 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;
}

static constexpr size_t BASE_ENV_SIZE = 128;

EvalState::EvalState(
const LookupPath & _lookupPath,
const LookupPath & lookupPathFromArguments,
ref<Store> store,
const EvalSettings & settings,
std::shared_ptr<Store> buildStore)
Expand Down Expand Up @@ -329,12 +367,37 @@ EvalState::EvalState(
vStringSymlink.mkString("symlink");
vStringUnknown.mkString("unknown");

/* Initialise the Nix expression search path. */
/*
* Initialise the Nix expression search path.
*
* We're implementing the logic of command-line arguments overriding
* environment variables here, because the settings mechanism doesn't
* have a way to deal with that.
* It needs to be cleaned up, but that would be a bigger endeavor.
* As a first step, the following should be a separate function.
*/
//assert(lookupPath.empty());
if (!settings.pureEval) {
for (auto & i : _lookupPath.elements)
/* Add elements from `-I` arguments first */
for (auto & i : lookupPathFromArguments.elements) {
lookupPath.elements.emplace_back(LookupPath::Elem {i});
for (auto & i : settings.nixPath.get())
lookupPath.elements.emplace_back(LookupPath::Elem::parse(i));
}
/* The environment variable takes lower priority by appending */
if (auto var = getEnv("NIX_PATH")) {
for (auto & i : parseNixPath(*var))
lookupPath.elements.emplace_back(LookupPath::Elem {i});
}

/* Configuration values take lowest precedence.
* FIXME: Currently one can't override `NIX_PATH` with `--nix-path`
* because that's indistiguishable from `nix-path` in the
* configurationf file. We could add hack in the argument parsing logic
* that checks if `NIX_PATH` is set.
*/
if (!settings.restrictEval) {
for (auto & i : settings.nixPath.get())
lookupPath.elements.emplace_back(LookupPath::Elem {i});
}
}

/* Allow access to all paths in the search path. */
Expand Down
2 changes: 2 additions & 0 deletions src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ namespace eval_cache {
class EvalCache;
}

static Strings parseNixPath(const std::string &);

/**
* Function that implements a primop.
*/
Expand Down
1 change: 1 addition & 0 deletions tests/functional/nix_path.sh
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ echo "nix-path = foo=$TEST_ROOT/from-nix-path-file" >> $NIX_CONF_DIR/nix.conf
[[ $(NIX_PATH=$TEST_ROOT/from-NIX_PATH nix-instantiate --extra-nix-path foo=$TEST_ROOT --find-file foo/bar.nix) = $TEST_ROOT/from-NIX_PATH/bar.nix ]]

# --nix-path overrides NIX_PATH
# TODO: this will likely fail
[[ $(NIX_PATH=foo=$TEST_ROOT/from-NIX_PATH nix-instantiate --nix-path foo=$TEST_ROOT/from-nix-path --find-file foo/bar.nix) = $TEST_ROOT/from-nix-path/bar.nix ]]
# if --nix-path does not have the desired entry, it fails
(! NIX_PATH=$TEST_ROOT/from-NIX_PATH nix-instantiate --nix-path foo=$TEST_ROOT --find-file foo/bar.nix)
Expand Down

0 comments on commit d41543a

Please sign in to comment.