about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/primops.cc5
-rw-r--r--src/libstore/misc.cc76
-rw-r--r--src/libstore/normalise.cc3
-rw-r--r--src/libstore/normalise.hh39
-rw-r--r--src/libstore/store.cc2
-rw-r--r--src/libstore/storeexpr.cc15
-rw-r--r--src/libstore/storeexpr.hh30
-rw-r--r--src/nix-env/main.cc2
-rw-r--r--src/nix-store/help.txt13
-rw-r--r--src/nix-store/main.cc70
10 files changed, 118 insertions, 137 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 28bbd2859ac9..12cc272f7152 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -270,6 +270,9 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args)
                 % *i % drvName);
         }
 
+    /* !!! the name should not end in the derivation extension (.drv).
+       Likewise for sources. */
+
     /* Construct the "masked" derivation store expression, which is
        the final one except that in the list of outputs, the output
        paths are empty, and the corresponding environment variables
@@ -290,7 +293,7 @@ static Expr primDerivation(EvalState & state, const ATermVector & _args)
         DerivationOutput(outPath, outputHashAlgo, outputHash);
 
     /* Write the resulting term into the Nix store directory. */
-    Path drvPath = writeTerm(unparseDerivation(drv), "d-" + drvName);
+    Path drvPath = writeDerivation(drv, drvName);
 
     printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'")
         % drvName % drvPath);
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index 24a522c1ed44..2757a061ece2 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -26,65 +26,39 @@ void computeFSClosure(const Path & storePath,
 }
 
 
-#if 0
-PathSet storeExprRoots(const Path & nePath)
-{
-    PathSet paths;
-
-    StoreExpr ne = storeExprFromPath(nePath);
-
-    if (ne.type == StoreExpr::neClosure)
-        paths.insert(ne.closure.roots.begin(), ne.closure.roots.end());
-    else if (ne.type == StoreExpr::neDerivation)
-        for (DerivationOutputs::iterator i = ne.derivation.outputs.begin();
-             i != ne.derivation.outputs.end(); ++i)
-            paths.insert(i->second.path);
-    else abort();
-
-    return paths;
-}
-
-
-static void requisitesWorker(const Path & nePath,
-    bool includeExprs, bool includeSuccessors,
-    PathSet & paths, PathSet & doneSet)
+void storePathRequisites(const Path & storePath,
+    bool includeOutputs, PathSet & paths)
 {
     checkInterrupt();
     
-    if (doneSet.find(nePath) != doneSet.end()) return;
-    doneSet.insert(nePath);
+    if (paths.find(storePath) != paths.end()) return;
 
-    StoreExpr ne = storeExprFromPath(nePath);
+    if (isDerivation(storePath)) {
 
-    if (ne.type == StoreExpr::neClosure)
-        for (ClosureElems::iterator i = ne.closure.elems.begin();
-             i != ne.closure.elems.end(); ++i)
-            paths.insert(i->first);
-    
-    else if (ne.type == StoreExpr::neDerivation)
-        for (PathSet::iterator i = ne.derivation.inputs.begin();
-             i != ne.derivation.inputs.end(); ++i)
-            requisitesWorker(*i,
-                includeExprs, includeSuccessors, paths, doneSet);
+        paths.insert(storePath);
+        
+        Derivation drv = derivationFromPath(storePath);
 
-    else abort();
+        for (PathSet::iterator i = drv.inputDrvs.begin();
+             i != drv.inputDrvs.end(); ++i)
+            storePathRequisites(*i, includeOutputs, paths);
 
-    if (includeExprs) paths.insert(nePath);
+        for (PathSet::iterator i = drv.inputSrcs.begin();
+             i != drv.inputSrcs.end(); ++i)
+            storePathRequisites(*i, includeOutputs, paths);
 
-    Path nfPath;
-    if (includeSuccessors && querySuccessor(nePath, nfPath))
-        requisitesWorker(nfPath, includeExprs, includeSuccessors,
-            paths, doneSet);
-}
+        if (includeOutputs) {
 
+            for (DerivationOutputs::iterator i = drv.outputs.begin();
+                 i != drv.outputs.end(); ++i)
+                if (isValidPath(i->second.path))
+                    storePathRequisites(i->second.path, includeOutputs, paths);
 
-PathSet storeExprRequisites(const Path & nePath,
-    bool includeExprs, bool includeSuccessors)
-{
-    PathSet paths;
-    PathSet doneSet;
-    requisitesWorker(nePath, includeExprs, includeSuccessors,
-        paths, doneSet);
-    return paths;
+        }
+        
+    }
+
+    else {
+        computeFSClosure(storePath, paths);
+    }
 }
-#endif
diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc
index a01b6d801704..9424bd24abd9 100644
--- a/src/libstore/normalise.cc
+++ b/src/libstore/normalise.cc
@@ -1307,6 +1307,9 @@ void SubstitutionGoal::init()
         return;
     }
 
+    /* !!! build the outgoing references of this path first to
+       maintain the closure invariant! */
+
     /* Otherwise, get the substitutes. */
     subs = querySubstitutes(storePath);
 
diff --git a/src/libstore/normalise.hh b/src/libstore/normalise.hh
index 2a084b7ed467..c5257f9b9dc5 100644
--- a/src/libstore/normalise.hh
+++ b/src/libstore/normalise.hh
@@ -3,7 +3,6 @@
 
 #include "storeexpr.hh"
 
-
 /* Perform the specified derivation, if necessary.  That is, do
    whatever is necessary to create the output paths of the
    derivation.  If the output paths already exists, we're done.  If
@@ -20,29 +19,29 @@ void ensurePath(const Path & storePath);
    through ensurePath(). */
 Derivation derivationFromPath(const Path & drvPath);
 
-
-/* Places in `paths' the set of all store paths in the file system
+/* Place in `paths' the set of all store paths in the file system
    closure of `storePath'; that is, all paths than can be directly or
    indirectly reached from it.  `paths' is not cleared. */
 void computeFSClosure(const Path & storePath,
     PathSet & paths);
 
-
-#if 0
-/* Get the list of root (output) paths of the given store
-   expression. */
-PathSet storeExprRoots(const Path & nePath);
-
-/* Get the list of paths that are required to realise the given store
-   expression.  For a derive expression, this is the union of
-   requisites of the inputs; for a closure expression, it is the path
-   of each element in the closure.  If `includeExprs' is true, include
-   the paths of the store expressions themselves.  If
-   `includeSuccessors' is true, include the requisites of
-   successors. */
-PathSet storeExprRequisites(const Path & nePath,
-    bool includeExprs, bool includeSuccessors);
-#endif
-
+/* Place in `paths' the set of paths that are required to `realise'
+   the given store path, i.e., all paths necessary for valid
+   deployment of the path.  For a derivation, this is the union of
+   requisites of the inputs, plus the derivation; for other store
+   paths, it is the set of paths in the FS closure of the path.  If
+   `includeOutputs' is true, include the requisites of the output
+   paths of derivations as well.
+
+   Note that this function can be used to implement three different
+   deployment policies:
+
+   - Source deployment (when called on a derivation).
+   - Binary deployment (when called on an output path).
+   - Source/binary deployment (when called on a derivation with
+     `includeOutputs' set to true).
+*/
+void storePathRequisites(const Path & storePath,
+    bool includeOutputs, PathSet & paths);
 
 #endif /* !__NORMALISE_H */
diff --git a/src/libstore/store.cc b/src/libstore/store.cc
index 51e2e7e7d2cc..01c724b918ae 100644
--- a/src/libstore/store.cc
+++ b/src/libstore/store.cc
@@ -217,6 +217,8 @@ void setReferences(const Transaction & txn, const Path & storePath,
 void queryReferences(const Path & storePath, PathSet & references)
 {
     Paths references2;
+    if (!isValidPath(storePath))
+        throw Error(format("path `%1%' is not valid") % storePath);
     nixDB.queryStrings(noTxn, dbReferences, storePath, references2);
     references.insert(references2.begin(), references2.end());
 }
diff --git a/src/libstore/storeexpr.cc b/src/libstore/storeexpr.cc
index d7c87bfa151c..a9240130e755 100644
--- a/src/libstore/storeexpr.cc
+++ b/src/libstore/storeexpr.cc
@@ -12,11 +12,10 @@ Hash hashTerm(ATerm t)
 }
 
 
-Path writeTerm(ATerm t, const string & suffix)
+Path writeDerivation(const Derivation & drv, const string & name)
 {
-    char * s = ATwriteToString(t);
-    if (!s) throw Error("cannot print aterm");
-    return addTextToStore(suffix + ".store", string(s));
+    return addTextToStore(name + drvExtension,
+        atPrint(unparseDerivation(drv)));
 }
 
 
@@ -133,3 +132,11 @@ ATerm unparseDerivation(const Derivation & drv)
         ATreverse(args),
         ATreverse(env));
 }
+
+
+bool isDerivation(const string & fileName)
+{
+    return
+        fileName.size() >= drvExtension.size() &&
+        string(fileName, fileName.size() - drvExtension.size()) == drvExtension;
+}
diff --git a/src/libstore/storeexpr.hh b/src/libstore/storeexpr.hh
index 8eb80a19a845..c7b35f8ebe45 100644
--- a/src/libstore/storeexpr.hh
+++ b/src/libstore/storeexpr.hh
@@ -5,23 +5,11 @@
 #include "store.hh"
 
 
-/* Abstract syntax of store expressions. */
+/* Extension of derivations in the Nix store. */
+const string drvExtension = ".drv";
 
-struct ClosureElem
-{
-    PathSet refs;
-};
-
-typedef map<Path, ClosureElem> ClosureElems;
-
-/*
-struct Closure
-{
-    PathSet roots;
-    ClosureElems elems;
-};
-*/
 
+/* Abstract syntax of derivations. */
 
 struct DerivationOutput
 {
@@ -57,14 +45,18 @@ struct Derivation
 /* Hash an aterm. */
 Hash hashTerm(ATerm t);
 
-/* Write an aterm to the Nix store directory, and return its path. */
-Path writeTerm(ATerm t, const string & suffix);
+/* Write a derivation to the Nix store, and return its path. */
+Path writeDerivation(const Derivation & drv, const string & name);
 
-/* Parse a store expression. */
+/* Parse a derivation. */
 Derivation parseDerivation(ATerm t);
 
-/* Parse a store expression. */
+/* Parse a derivation. */
 ATerm unparseDerivation(const Derivation & drv);
 
+/* Check whether a file name ends with the extensions for
+   derivations. */
+bool isDerivation(const string & fileName);
+
 
 #endif /* !__STOREEXPR_H */
diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc
index c9498907d5c6..4d2ad0c8978e 100644
--- a/src/nix-env/main.cc
+++ b/src/nix-env/main.cc
@@ -205,7 +205,7 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
 
     /* Also write a copy of the list of inputs to the store; we need
        it for future modifications of the environment. */
-    Path inputsFile = writeTerm(inputs2, "env-inputs");
+    Path inputsFile = addTextToStore("env-inputs", atPrint(inputs2));
 
     Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3(
         makeBind(toATerm("system"),
diff --git a/src/nix-store/help.txt b/src/nix-store/help.txt
index cbded730e866..1bd752fc11c6 100644
--- a/src/nix-store/help.txt
+++ b/src/nix-store/help.txt
@@ -4,14 +4,12 @@ nix-store [OPTIONS...] [ARGUMENTS...]
 
 Operations:
 
-  --realise / -r: realise a Nix expression
-  --delete / -d: delete paths from the Nix store
+  --build / -b: build a Nix derivation
   --add / -A: copy a path to the Nix store
   --query / -q: query information
 
-  --successor: register a successor expression (dangerous!)
   --substitute: register a substitute expression (dangerous!)
-  --clear-substitute: clear all substitutes
+  --clear-substitutes: clear all substitutes
   --validpath: register path validity (dangerous!)
   --isvalid: check path validity
 
@@ -26,9 +24,10 @@ Operations:
 
 Query flags:
 
-  --list / -l: query the output paths (roots) of a Nix expression (default)
-  --requisites / -R: print all paths necessary to realise expression
-  --predecessors: print predecessors of a Nix expression
+  --outputs: query the output paths of a Nix derivation (default)
+  --requisites / -R: print all paths necessary to realise a path
+  --references: print all paths referenced by the given path
+  --referers: print all paths refering to the given path
   --graph: print a dot graph rooted at given ids
 
 Options:
diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc
index 5a67a6af647d..12b61c76f787 100644
--- a/src/nix-store/main.cc
+++ b/src/nix-store/main.cc
@@ -18,6 +18,15 @@ void printHelp()
 }
 
 
+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);
+}
+
+
 /* Build the given derivations. */
 static void opBuild(Strings opFlags, Strings opArgs)
 {
@@ -25,7 +34,11 @@ static void opBuild(Strings opFlags, Strings opArgs)
 
     for (Strings::iterator i = opArgs.begin();
          i != opArgs.end(); i++)
+    {
         buildDerivation(*i);
+        Derivation drv = derivationFromPath(*i);
+        cout << format("%1%\n") % findOutput(drv, "out");
+    }
 }
 
 
@@ -40,70 +53,59 @@ static void opAdd(Strings opFlags, Strings opArgs)
 }
 
 
-#if 0
-Path maybeNormalise(const Path & ne, bool normalise, bool realise)
+static Path maybeUseOutput(const Path & storePath, bool useOutput)
 {
-    if (realise) {
-        Path ne2 = realiseStoreExpr(ne);
-        return normalise ? ne2 : ne;
-    } else
-        return normalise ? normaliseStoreExpr(ne) : ne;
+    if (useOutput && isDerivation(storePath)) {
+        Derivation drv = derivationFromPath(storePath);
+        return findOutput(drv, "out");
+    }
+    else return storePath;
 }
 
 
 /* Perform various sorts of queries. */
 static void opQuery(Strings opFlags, Strings opArgs)
 {
-    enum { qList, qRequisites, qPredecessors, qGraph 
-    } query = qList;
-    bool normalise = false;
-    bool realise = false;
-    bool includeExprs = true;
-    bool includeSuccessors = false;
+    enum { qOutputs, qRequisites, qPredecessors, qGraph } query = qOutputs;
+    bool useOutput = false;
+    bool includeOutputs = false;
 
     for (Strings::iterator i = opFlags.begin();
          i != opFlags.end(); i++)
-        if (*i == "--list" || *i == "-l") query = qList;
+        if (*i == "--outputs") query = qOutputs;
         else if (*i == "--requisites" || *i == "-R") query = qRequisites;
-        else if (*i == "--predecessors") query = qPredecessors;
         else if (*i == "--graph") query = qGraph;
-        else if (*i == "--normalise" || *i == "-n") normalise = true;
-        else if (*i == "--force-realise" || *i == "-f") realise = true;
-        else if (*i == "--exclude-exprs") includeExprs = false;
-        else if (*i == "--include-successors") includeSuccessors = true;
+        else if (*i == "--use-output" || *i == "-u") useOutput = true;
+        else if (*i == "--include-outputs") includeOutputs = true;
         else throw UsageError(format("unknown flag `%1%'") % *i);
 
     switch (query) {
         
-        case qList: {
+        case qOutputs: {
             for (Strings::iterator i = opArgs.begin();
                  i != opArgs.end(); i++)
             {
-                StringSet paths = storeExprRoots(
-                    maybeNormalise(*i, normalise, realise));
-                for (StringSet::iterator j = paths.begin(); 
-                     j != paths.end(); j++)
-                    cout << format("%s\n") % *j;
+                Derivation drv = derivationFromPath(*i);
+                cout << format("%1%\n") % findOutput(drv, "out");
             }
             break;
         }
 
         case qRequisites: {
-            StringSet paths;
+            PathSet paths;
             for (Strings::iterator i = opArgs.begin();
                  i != opArgs.end(); i++)
             {
-                StringSet paths2 = storeExprRequisites(
-                    maybeNormalise(*i, normalise, realise),
-                    includeExprs, includeSuccessors);
-                paths.insert(paths2.begin(), paths2.end());
+                Path path = maybeUseOutput(*i, useOutput);
+                storePathRequisites(path, includeOutputs, paths);
             }
-            for (StringSet::iterator i = paths.begin(); 
+            for (PathSet::iterator i = paths.begin(); 
                  i != paths.end(); i++)
                 cout << format("%s\n") % *i;
             break;
         }
 
+#if 0            
         case qPredecessors: {
             for (Strings::iterator i = opArgs.begin();
                  i != opArgs.end(); i++)
@@ -124,12 +126,12 @@ static void opQuery(Strings opFlags, Strings opArgs)
 	    printDotGraph(roots);
             break;
         }
+#endif
 
         default:
             abort();
     }
 }
-#endif
 
 
 static void opSubstitute(Strings opFlags, Strings opArgs)
@@ -340,8 +342,8 @@ void run(Strings args)
             op = opBuild;
         else if (arg == "--add" || arg == "-A")
             op = opAdd;
-        //        else if (arg == "--query" || arg == "-q")
-        //            op = opQuery;
+        else if (arg == "--query" || arg == "-q")
+            op = opQuery;
         else if (arg == "--substitute")
             op = opSubstitute;
         else if (arg == "--clear-substitutes")