about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/normalise.cc54
-rw-r--r--tests/Makefile.am9
-rw-r--r--tests/substitutes2.nix.in6
-rw-r--r--tests/substitutes2.sh4
4 files changed, 54 insertions, 19 deletions
diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc
index a89426cdf22c..cbb0e2f75825 100644
--- a/src/libstore/normalise.cc
+++ b/src/libstore/normalise.cc
@@ -153,6 +153,13 @@ public:
 };
 
 
+class SubstError : public Error
+{
+public:
+    SubstError(const format & f) : Error(f) { };
+};
+
+
 
 //////////////////////////////////////////////////////////////////////
 
@@ -209,6 +216,8 @@ void commonChildInit(Pipe & logPipe)
 }
 
 
+/* Convert a string list to an array of char pointers.  Careful: the
+   string list should outlive the array. */
 const char * * strings2CharPtrs(const Strings & ss)
 {
     const char * * arr = new const char * [ss.size() + 1];
@@ -1202,7 +1211,7 @@ private:
     Pid pid;
 
     /* Lock on the store path. */
-    PathLocks outputLock;
+    shared_ptr<PathLocks> outputLock;
     
     typedef void (SubstitutionGoal::*GoalState)();
     GoalState state;
@@ -1310,18 +1319,20 @@ void SubstitutionGoal::tryToRun()
     /* Acquire a lock on the output path. */
     PathSet lockPath;
     lockPath.insert(storePath);
-    outputLock.lockPaths(lockPath);
+    outputLock = shared_ptr<PathLocks>(new PathLocks);
+    outputLock->lockPaths(lockPath);
 
     /* Check again whether the path is invalid. */
     if (isValidPath(storePath)) {
         debug(format("store path `%1%' has become valid") % storePath);
-        outputLock.setDeletion(true);
+        outputLock->setDeletion(true);
         amDone();
         return;
     }
 
-    startNest(nest, lvlInfo,
-        format("substituting path `%1%'") % storePath);
+    printMsg(lvlInfo,
+        format("substituting path `%1%' using substituter `%2%'")
+        % storePath % sub.storeExpr);
     
     /* What's the substitute program? */
     StoreExpr expr = storeExprFromPath(nfSub);
@@ -1396,21 +1407,40 @@ void SubstitutionGoal::finished()
 
     debug(format("substitute for `%1%' finished") % storePath);
 
-    /* Check the exit status. */
-    if (!statusOk(status))
-        throw Error(format("builder for `%1%' %2%")
-            % storePath % statusToString(status));
+    /* Check the exit status and the build result. */
+    try {
+        
+        if (!statusOk(status))
+            throw SubstError(format("builder for `%1%' %2%")
+                % storePath % statusToString(status));
+
+        if (!pathExists(storePath))
+            throw SubstError(
+                format("substitute did not produce path `%1%'")
+                % storePath);
+        
+    } catch (SubstError & e) {
 
-    if (!pathExists(storePath))
-        throw Error(format("substitute did not produce path `%1%'") % storePath);
+        printMsg(lvlInfo,
+            format("substitution of path `%1%' using substituter `%2%' failed: %3%")
+            % storePath % sub.storeExpr % e.msg());
+        
+        /* Try the next substitute. */
+        state = &SubstitutionGoal::tryNext;
+        worker.wakeUp(shared_from_this());
+        return;
+    }
 
     Transaction txn;
     createStoreTransaction(txn);
     registerValidPath(txn, storePath);
     txn.commit();
 
-    outputLock.setDeletion(true);
+    outputLock->setDeletion(true);
     
+    printMsg(lvlChatty,
+        format("substitution of path `%1%' succeeded") % storePath);
+
     amDone();
 }
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index dad3f8791368..a420334147fc 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -18,11 +18,10 @@ locking.sh: locking.nix
 parallel.sh: parallel.nix
 build-hook.sh: build-hook.nix
 substitutes.sh: substitutes.nix substituter.nix
-substitutes2.sh: substitutes.nix substituter.nix substituter2.nix
+substitutes2.sh: substitutes2.nix substituter.nix substituter2.nix
 
-#TESTS = init.sh simple.sh dependencies.sh locking.sh parallel.sh \
-#  build-hook.sh substitutes.sh substitutes2.sh
-TESTS = init.sh substitutes2.sh
+TESTS = init.sh simple.sh dependencies.sh locking.sh parallel.sh \
+  build-hook.sh substitutes.sh substitutes2.sh
 
 XFAIL_TESTS =
 
@@ -35,4 +34,4 @@ EXTRA_DIST = $(TESTS) \
   parallel.nix.in parallel.builder.sh \
   build-hook.nix.in build-hook.hook.sh \
   substitutes.nix.in substituter.nix.in substituter.builder.sh \
-  substituter2.nix.in substituter2.builder.sh
+  substitutes2.nix.in substituter2.nix.in substituter2.builder.sh
diff --git a/tests/substitutes2.nix.in b/tests/substitutes2.nix.in
new file mode 100644
index 000000000000..8ade1ba11674
--- /dev/null
+++ b/tests/substitutes2.nix.in
@@ -0,0 +1,6 @@
+derivation {
+  name = "substitutes-2";
+  system = "@system@";
+  builder = "@shell@";
+  args = ["-e" "-x" ./simple.builder.sh];
+}
\ No newline at end of file
diff --git a/tests/substitutes2.sh b/tests/substitutes2.sh
index 33bae3238fb8..76ff74b3ed29 100644
--- a/tests/substitutes2.sh
+++ b/tests/substitutes2.sh
@@ -1,5 +1,5 @@
 # Instantiate.
-storeExpr=$($TOP/src/nix-instantiate/nix-instantiate substitutes.nix)
+storeExpr=$($TOP/src/nix-instantiate/nix-instantiate substitutes2.nix)
 echo "store expr is $storeExpr"
 
 # Find the output path.
@@ -19,7 +19,7 @@ regSub() {
 }
 
 # Register a fake successor, and a substitute for it.
-suc=$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-s.store
+suc=$NIX_STORE_DIR/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab-s.store
 regSub $suc $subExpr
 $TOP/src/nix-store/nix-store --successor $storeExpr $suc