From ec326276217ad5b7761327da567f79bb5cc17f32 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 24 Jun 2004 13:40:38 +0000 Subject: [PATCH] * Multiple and/or failing substitutes now work. --- src/libstore/normalise.cc | 54 ++++++++++++++++++++++++++++++--------- tests/Makefile.am | 9 +++---- tests/substitutes2.nix.in | 6 +++++ tests/substitutes2.sh | 4 +-- 4 files changed, 54 insertions(+), 19 deletions(-) create mode 100644 tests/substitutes2.nix.in diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc index a89426cdf..cbb0e2f75 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 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(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 Error(format("substitute did not produce path `%1%'") % storePath); + if (!pathExists(storePath)) + throw SubstError( + format("substitute did not produce path `%1%'") + % storePath); + + } catch (SubstError & e) { + + 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 dad3f8791..a42033414 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 000000000..8ade1ba11 --- /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 33bae3238..76ff74b3e 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