diff --git a/src/libstore/build.hh b/src/libstore/build.hh index 2c6bcf9f2d..45997ebb24 100644 --- a/src/libstore/build.hh +++ b/src/libstore/build.hh @@ -28,4 +28,9 @@ Derivation derivationFromPath(const Path & drvPath); void computeFSClosure(const Path & storePath, PathSet & paths, bool flipDirection = false); +/* Return the path corresponding to the output identifier `id' in the + given derivation. */ +Path findOutput(const Derivation & drv, string id); + + #endif /* !__BUILD_H */ diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index 5f20ee2775..f3cc98bf4e 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -27,3 +27,12 @@ void computeFSClosure(const Path & storePath, i != references.end(); ++i) computeFSClosure(*i, paths, flipDirection); } + + + Path findOutput(const Derivation & drv, string id) +{ + for (DerivationOutputs::const_iterator i = drv.outputs.begin(); + i != drv.outputs.end(); ++i) + if (i->first == id) return i->second.path; + throw Error(format("derivation has no output `%1%'") % id); +} diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc index a250413ab1..bab1f7fe14 100644 --- a/src/nix-env/main.cc +++ b/src/nix-env/main.cc @@ -2,6 +2,7 @@ #include "names.hh" #include "globals.hh" #include "build.hh" +#include "gc.hh" #include "shared.hh" #include "parser.hh" #include "eval.hh" @@ -226,6 +227,12 @@ static void createUserEnv(EvalState & state, const UserEnvElems & elems, )); manifest = ATinsert(manifest, t); inputs = ATinsert(inputs, makeStr(toATerm(i->second.outPath))); + + /* This is only necessary when installing store paths, e.g., + `nix-env -i /nix/store/abcd...-foo'. */ + addTempRoot(i->second.outPath); + ensurePath(i->second.outPath); + references.insert(i->second.outPath); if (drvPath != "") references.insert(drvPath); } @@ -270,7 +277,11 @@ static void queryInstSources(EvalState & state, const InstallSourceInfo & instSource, const Strings & args, UserEnvElems & elems) { - switch (instSource.type) { + InstallSourceType type = instSource.type; + if (type == srcUnknown && args.size() > 0 && args.front()[0] == '/') + type = srcStorePaths; + + switch (type) { /* Get the available user environment elements from the derivations specified in a Nix expression, including only @@ -333,6 +344,32 @@ static void queryInstSources(EvalState & state, break; case srcStorePaths: + + for (Strings::const_iterator i = args.begin(); + i != args.end(); ++i) + { + assertStorePath(*i); + + UserEnvElem elem; + string name = baseNameOf(*i); + unsigned int dash = name.find('-'); + if (dash != string::npos) + name = string(name, dash + 1); + + if (isDerivation(*i)) { + elem.drvPath = *i; + elem.outPath = findOutput(derivationFromPath(*i), "out"); + if (name.size() >= drvExtension.size() && + string(name, name.size() - drvExtension.size()) == drvExtension) + name = string(name, 0, name.size() - drvExtension.size()); + } + else elem.outPath = *i; + + elem.name = name; + + elems[elem.outPath] = elem; + } + break; case srcProfile: diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc index fa7960c382..a93956ab7a 100644 --- a/src/nix-store/main.cc +++ b/src/nix-store/main.cc @@ -23,15 +23,6 @@ static int rootNr = 0; static bool indirectRoot = false; -static Path findOutput(const Derivation & drv, string id) -{ - for (DerivationOutputs::const_iterator i = drv.outputs.begin(); - i != drv.outputs.end(); ++i) - if (i->first == id) return i->second.path; - throw Error(format("derivation has no output `%1%'") % id); -} - - static Path fixPath(Path path) { path = absPath(path);