about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2012-10-03T19·09-0400
committerEelco Dolstra <eelco.dolstra@logicblox.com>2012-10-03T19·09-0400
commit0a7084567fc4e7d077863075a7ea1bb82d843341 (patch)
tree4868d450da1e153b0660eede85105cb2b14d0859
parenta807edfae8428bf426ee6ae849a7a24d74d39202 (diff)
Add a ‘--repair’ flag to nix-instantiate
This allows repairing corrupted derivations and other source files.
-rw-r--r--src/libexpr/eval.cc3
-rw-r--r--src/libexpr/eval.hh4
-rw-r--r--src/libexpr/primops.cc6
-rw-r--r--src/libstore/derivations.cc4
-rw-r--r--src/libstore/derivations.hh2
-rw-r--r--src/libstore/local-store.cc16
-rw-r--r--src/libstore/local-store.hh6
-rw-r--r--src/libstore/remote-store.cc10
-rw-r--r--src/libstore/remote-store.hh4
-rw-r--r--src/libstore/store-api.hh4
-rw-r--r--src/nix-instantiate/nix-instantiate.cc2
11 files changed, 36 insertions, 25 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 9e5be908f089..2f9601ec550f 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -141,6 +141,7 @@ EvalState::EvalState()
     , baseEnv(allocEnv(128))
     , baseEnvDispl(0)
     , staticBaseEnv(false, 0)
+    , repair(false)
 {
     nrEnvs = nrValuesInEnvs = nrValues = nrListElems = 0;
     nrAttrsets = nrOpUpdates = nrOpUpdateValuesCopied = 0;
@@ -1093,7 +1094,7 @@ string EvalState::coerceToString(Value & v, PathSet & context,
         else {
             dstPath = settings.readOnlyMode
                 ? computeStorePathForPath(path).first
-                : store->addToStore(path);
+                : store->addToStore(path, true, htSHA256, defaultPathFilter, repair);
             srcToStore[path] = dstPath;
             printMsg(lvlChatty, format("copied source `%1%' -> `%2%'")
                 % path % dstPath);
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index a1f26a0566d1..a3c55a38860f 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -95,6 +95,10 @@ public:
     const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName,
         sSystem, sOverrides;
 
+    /* If set, force copying files to the Nix store even if they
+       already exist there. */
+    bool repair;
+
 private:
     SrcToStore srcToStore; 
 
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index bbe89c5f55be..509297003f6e 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -487,7 +487,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
     }
 
     /* Write the resulting term into the Nix store directory. */
-    Path drvPath = writeDerivation(*store, drv, drvName);
+    Path drvPath = writeDerivation(*store, drv, drvName, state.repair);
 
     printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'")
         % drvName % drvPath);
@@ -625,7 +625,7 @@ static void prim_toFile(EvalState & state, Value * * args, Value & v)
     
     Path storePath = settings.readOnlyMode
         ? computeStorePathForText(name, contents, refs)
-        : store->addTextToStore(name, contents, refs);
+        : store->addTextToStore(name, contents, refs, state.repair);
 
     /* Note: we don't need to add `context' to the context of the
        result, since `storePath' itself has references to the paths
@@ -689,7 +689,7 @@ static void prim_filterSource(EvalState & state, Value * * args, Value & v)
 
     Path dstPath = settings.readOnlyMode
         ? computeStorePathForPath(path, true, htSHA256, filter).first
-        : store->addToStore(path, true, htSHA256, filter);
+        : store->addToStore(path, true, htSHA256, filter, state.repair);
 
     mkString(v, dstPath, singleton<PathSet>(dstPath));
 }
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
index 73047c7538a0..e0a4f43c0bb8 100644
--- a/src/libstore/derivations.cc
+++ b/src/libstore/derivations.cc
@@ -27,7 +27,7 @@ void DerivationOutput::parseHashInfo(bool & recursive, HashType & hashType, Hash
 
 
 Path writeDerivation(StoreAPI & store,
-    const Derivation & drv, const string & name)
+    const Derivation & drv, const string & name, bool repair)
 {
     PathSet references;
     references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end());
@@ -40,7 +40,7 @@ Path writeDerivation(StoreAPI & store,
     string contents = unparseDerivation(drv);
     return settings.readOnlyMode
         ? computeStorePathForText(suffix, contents, references)
-        : store.addTextToStore(suffix, contents, references);
+        : store.addTextToStore(suffix, contents, references, repair);
 }
 
 
diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh
index a5ffc2252064..7d38e60c0fe6 100644
--- a/src/libstore/derivations.hh
+++ b/src/libstore/derivations.hh
@@ -57,7 +57,7 @@ class StoreAPI;
 
 /* Write a derivation to the Nix store, and return its path. */
 Path writeDerivation(StoreAPI & store,
-    const Derivation & drv, const string & name);
+    const Derivation & drv, const string & name, bool repair = false);
 
 /* Parse a derivation. */
 Derivation parseDerivation(const string & s);
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index b55ab428421f..982644af7154 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -1158,7 +1158,7 @@ void LocalStore::invalidatePath(const Path & path)
 
 
 Path LocalStore::addToStoreFromDump(const string & dump, const string & name,
-    bool recursive, HashType hashAlgo)
+    bool recursive, HashType hashAlgo, bool repair)
 {
     Hash h = hashString(hashAlgo, dump);
 
@@ -1166,14 +1166,14 @@ Path LocalStore::addToStoreFromDump(const string & dump, const string & name,
 
     addTempRoot(dstPath);
 
-    if (!isValidPath(dstPath)) {
+    if (repair || !isValidPath(dstPath)) {
 
         /* The first check above is an optimisation to prevent
            unnecessary lock acquisition. */
 
         PathLocks outputLock(singleton<PathSet, Path>(dstPath));
 
-        if (!isValidPath(dstPath)) {
+        if (repair || !isValidPath(dstPath)) {
 
             if (pathExists(dstPath)) deletePathWrapped(dstPath);
 
@@ -1213,7 +1213,7 @@ Path LocalStore::addToStoreFromDump(const string & dump, const string & name,
 
 
 Path LocalStore::addToStore(const Path & _srcPath,
-    bool recursive, HashType hashAlgo, PathFilter & filter)
+    bool recursive, HashType hashAlgo, PathFilter & filter, bool repair)
 {
     Path srcPath(absPath(_srcPath));
     debug(format("adding `%1%' to the store") % srcPath);
@@ -1227,22 +1227,22 @@ Path LocalStore::addToStore(const Path & _srcPath,
     else
         sink.s = readFile(srcPath);
 
-    return addToStoreFromDump(sink.s, baseNameOf(srcPath), recursive, hashAlgo);
+    return addToStoreFromDump(sink.s, baseNameOf(srcPath), recursive, hashAlgo, repair);
 }
 
 
 Path LocalStore::addTextToStore(const string & name, const string & s,
-    const PathSet & references)
+    const PathSet & references, bool repair)
 {
     Path dstPath = computeStorePathForText(name, s, references);
 
     addTempRoot(dstPath);
 
-    if (!isValidPath(dstPath)) {
+    if (repair || !isValidPath(dstPath)) {
 
         PathLocks outputLock(singleton<PathSet, Path>(dstPath));
 
-        if (!isValidPath(dstPath)) {
+        if (repair || !isValidPath(dstPath)) {
 
             if (pathExists(dstPath)) deletePathWrapped(dstPath);
 
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index b2f06d8118ca..8d745cfb835e 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -133,17 +133,17 @@ public:
 
     Path addToStore(const Path & srcPath,
         bool recursive = true, HashType hashAlgo = htSHA256,
-        PathFilter & filter = defaultPathFilter);
+        PathFilter & filter = defaultPathFilter, bool repair = false);
 
     /* Like addToStore(), but the contents of the path are contained
        in `dump', which is either a NAR serialisation (if recursive ==
        true) or simply the contents of a regular file (if recursive ==
        false). */
     Path addToStoreFromDump(const string & dump, const string & name,
-        bool recursive = true, HashType hashAlgo = htSHA256);
+        bool recursive = true, HashType hashAlgo = htSHA256, bool repair = false);
 
     Path addTextToStore(const string & name, const string & s,
-        const PathSet & references);
+        const PathSet & references, bool repair = false);
 
     void exportPath(const Path & path, bool sign,
         Sink & sink);
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index 2a895593b25c..08e409d3f058 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -419,8 +419,10 @@ Path RemoteStore::queryPathFromHashPart(const string & hashPart)
 
 
 Path RemoteStore::addToStore(const Path & _srcPath,
-    bool recursive, HashType hashAlgo, PathFilter & filter)
+    bool recursive, HashType hashAlgo, PathFilter & filter, bool repair)
 {
+    if (repair) throw Error("repairing is not supported when building through the Nix daemon");
+
     openConnection();
 
     Path srcPath(absPath(_srcPath));
@@ -438,8 +440,10 @@ Path RemoteStore::addToStore(const Path & _srcPath,
 
 
 Path RemoteStore::addTextToStore(const string & name, const string & s,
-    const PathSet & references)
+    const PathSet & references, bool repair)
 {
+    if (repair) throw Error("repairing is not supported when building through the Nix daemon");
+
     openConnection();
     writeInt(wopAddTextToStore, to);
     writeString(name, to);
@@ -476,7 +480,7 @@ Paths RemoteStore::importPaths(bool requireSignature, Source & source)
 
 void RemoteStore::buildPaths(const PathSet & drvPaths, bool repair)
 {
-    if (repair) throw Error("`--repair' is not supported when building through the Nix daemon");
+    if (repair) throw Error("repairing is not supported when building through the Nix daemon");
     openConnection();
     writeInt(wopBuildPaths, to);
     writeStrings(drvPaths, to);
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
index fe60ccb399d6..d23b0717663a 100644
--- a/src/libstore/remote-store.hh
+++ b/src/libstore/remote-store.hh
@@ -53,10 +53,10 @@ public:
     
     Path addToStore(const Path & srcPath,
         bool recursive = true, HashType hashAlgo = htSHA256,
-        PathFilter & filter = defaultPathFilter);
+        PathFilter & filter = defaultPathFilter, bool repair = false);
 
     Path addTextToStore(const string & name, const string & s,
-        const PathSet & references);
+        const PathSet & references, bool repair = false);
 
     void exportPath(const Path & path, bool sign,
         Sink & sink);
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 800645fa44df..cbbacc12c92a 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -158,12 +158,12 @@ public:
        libutil/archive.hh). */
     virtual Path addToStore(const Path & srcPath,
         bool recursive = true, HashType hashAlgo = htSHA256,
-        PathFilter & filter = defaultPathFilter) = 0;
+        PathFilter & filter = defaultPathFilter, bool repair = false) = 0;
 
     /* Like addToStore, but the contents written to the output path is
        a regular file containing the given string. */
     virtual Path addTextToStore(const string & name, const string & s,
-        const PathSet & references) = 0;
+        const PathSet & references, bool repair = false) = 0;
 
     /* Export a store path, that is, create a NAR dump of the store
        path and append its references and its deriver.  Optionally, a
diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc
index 6ddf9f069ef3..34f81b14a286 100644
--- a/src/nix-instantiate/nix-instantiate.cc
+++ b/src/nix-instantiate/nix-instantiate.cc
@@ -125,6 +125,8 @@ void run(Strings args)
             xmlOutputSourceLocation = false;
         else if (arg == "--strict")
             strict = true;
+        else if (arg == "--repair")
+            state.repair = true;
         else if (arg[0] == '-')
             throw UsageError(format("unknown flag `%1%'") % arg);
         else