Skip to content

Commit

Permalink
nix build: Use Nix search path
Browse files Browse the repository at this point in the history
That is, unless --file is specified, the Nix search path is
synthesized into an attribute set. Thus you can say

  $ nix build nixpkgs.hello

assuming $NIX_PATH contains an entry of the form "nixpkgs=...". This
is more verbose than

  $ nix build hello

but is less ambiguous.
edolstra committed Aug 23, 2016

Partially verified

This commit is signed with the committer’s verified signature.
spydon’s contribution has been verified via GPG key.
We cannot verify signatures from co-authors, and some of the co-authors attributed to this commit require their commits to be signed.
1 parent 22d6e31 commit d74236d
Showing 5 changed files with 57 additions and 13 deletions.
7 changes: 4 additions & 3 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
@@ -379,9 +379,9 @@ void EvalState::addPrimOp(const string & name,
}


void EvalState::getBuiltin(const string & name, Value & v)
Value & EvalState::getBuiltin(const string & name)
{
v = *baseEnv.values[0]->attrs->find(symbols.create(name))->value;
return *baseEnv.values[0]->attrs->find(symbols.create(name))->value;
}


@@ -462,7 +462,7 @@ void mkString(Value & v, const char * s)
}


void mkString(Value & v, const string & s, const PathSet & context)
Value & mkString(Value & v, const string & s, const PathSet & context)
{
mkString(v, s.c_str());
if (!context.empty()) {
@@ -473,6 +473,7 @@ void mkString(Value & v, const string & s, const PathSet & context)
v.string.context[n++] = dupString(i.c_str());
v.string.context[n] = 0;
}
return v;
}


6 changes: 4 additions & 2 deletions src/libexpr/eval.hh
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ struct Env
};


void mkString(Value & v, const string & s, const PathSet & context = PathSet());
Value & mkString(Value & v, const string & s, const PathSet & context = PathSet());

void copyContext(const Value & v, PathSet & context);

@@ -108,6 +108,8 @@ public:

void addToSearchPath(const string & s);

SearchPath getSearchPath() { return searchPath; }

Path checkSourcePath(const Path & path);

/* Parse a Nix expression from the specified file. */
@@ -204,7 +206,7 @@ private:

public:

void getBuiltin(const string & name, Value & v);
Value & getBuiltin(const string & name);

private:

3 changes: 1 addition & 2 deletions src/nix-env/nix-env.cc
Original file line number Diff line number Diff line change
@@ -128,9 +128,8 @@ static void getAllExprs(EvalState & state,
}
attrs.insert(attrName);
/* Load the expression on demand. */
Value & vFun(*state.allocValue());
Value & vFun = state.getBuiltin("import");
Value & vArg(*state.allocValue());
state.getBuiltin("import", vFun);
mkString(vArg, path2);
if (v.attrs->size() == v.attrs->capacity())
throw Error(format("too many Nix expressions in directory ‘%1%’") % path);
42 changes: 37 additions & 5 deletions src/nix/installables.cc
Original file line number Diff line number Diff line change
@@ -9,6 +9,41 @@

namespace nix {

Value * MixInstallables::buildSourceExpr(EvalState & state)
{
Value * vRoot = state.allocValue();

if (file != "") {
Expr * e = state.parseExprFromFile(resolveExprPath(lookupFileArg(state, file)));
state.eval(e, *vRoot);
}

else {

/* Construct the installation source from $NIX_PATH. */

auto searchPath = state.getSearchPath();

state.mkAttrs(*vRoot, searchPath.size());

std::unordered_set<std::string> seen;

for (auto & i : searchPath) {
if (i.first == "") continue;
if (seen.count(i.first)) continue;
seen.insert(i.first);
if (!pathExists(i.second)) continue;
mkApp(*state.allocAttr(*vRoot, state.symbols.create(i.first)),
state.getBuiltin("import"),
mkString(*state.allocValue(), i.second));
}

vRoot->attrs->sort();
}

return vRoot;
}

UserEnvElems MixInstallables::evalInstallables(ref<Store> store)
{
UserEnvElems res;
@@ -46,15 +81,12 @@ UserEnvElems MixInstallables::evalInstallables(ref<Store> store)

EvalState state({}, store);

Expr * e = state.parseExprFromFile(resolveExprPath(lookupFileArg(state, file)));

Value vRoot;
state.eval(e, vRoot);
auto vRoot = buildSourceExpr(state);

std::map<string, string> autoArgs_;
Bindings & autoArgs(*evalAutoArgs(state, autoArgs_));

Value & v(*findAlongAttrPath(state, installable, autoArgs, vRoot));
Value & v(*findAlongAttrPath(state, installable, autoArgs, *vRoot));
state.forceValue(v);

DrvInfos drvs;
12 changes: 11 additions & 1 deletion src/nix/installables.hh
Original file line number Diff line number Diff line change
@@ -21,10 +21,13 @@ struct UserEnvElem

typedef std::vector<UserEnvElem> UserEnvElems;

struct Value;
class EvalState;

struct MixInstallables : virtual Args
{
Strings installables;
Path file = "<nixpkgs>";
Path file;

MixInstallables()
{
@@ -33,6 +36,13 @@ struct MixInstallables : virtual Args
}

UserEnvElems evalInstallables(ref<Store> store);

/* Return a value representing the Nix expression from which we
are installing. This is either the file specified by ‘--file’,
or an attribute set constructed from $NIX_PATH, e.g. ‘{ nixpkgs
= import ...; bla = import ...; }’. */
Value * buildSourceExpr(EvalState & state);

};

}

0 comments on commit d74236d

Please sign in to comment.