diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-08-23T15·11+0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-08-23T15·11+0200 |
commit | d74236d1f2c3bca4fcc8cb1574fb962e813f69d3 (patch) | |
tree | 0ec4d387e04e9a79835efebd85753aeb5a00d251 | |
parent | 22d6e31fc6a9de2ee424984e629ccd2e394ba512 (diff) |
nix build: Use Nix search path
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.
-rw-r--r-- | src/libexpr/eval.cc | 7 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 6 | ||||
-rw-r--r-- | src/nix-env/nix-env.cc | 3 | ||||
-rw-r--r-- | src/nix/installables.cc | 42 | ||||
-rw-r--r-- | src/nix/installables.hh | 12 |
5 files changed, 57 insertions, 13 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 0833603b2a9e..625888b19fcb 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -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; } diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 80e369f2d68f..47e4d99bf6ed 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -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: diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 3f0486bb6541..955a2466102f 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -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); diff --git a/src/nix/installables.cc b/src/nix/installables.cc index 6257c7679af9..8341bbc5a3a4 100644 --- a/src/nix/installables.cc +++ b/src/nix/installables.cc @@ -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; diff --git a/src/nix/installables.hh b/src/nix/installables.hh index 5eb897d46148..a58f7dc59bb4 100644 --- a/src/nix/installables.hh +++ b/src/nix/installables.hh @@ -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); + }; } |