about summary refs log tree commit diff
path: root/src/libexpr/primops
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-10-30T08·57+0100
committerEelco Dolstra <edolstra@gmail.com>2017-10-30T09·22+0100
commit65b5f177b5fbb1b0778ede047a13a3cee9c59cfe (patch)
treecc5ba83c50ae5d528cd1c4c4770b9b66f3e1878a /src/libexpr/primops
parentc1ae18941a222d51a47d4971f4bc4cbc5dea449a (diff)
builtins.fetchgit: Support a "name" attribute
The "name" attribute defaults to "source", which we should use for all
similar functions (e.g. fetchTarball and in Hydra) to ensure that we
get a consistent store path regardless of how the tree is fetched.

"source" is not necessarily a correct label, but using an empty name
is problematic: you get an ugly store path ending in a dash, and it's
impossible to have a fixed-output derivation that produces that path
because ".drv" is not a valid store name.

Fixes #904.
Diffstat (limited to 'src/libexpr/primops')
-rw-r--r--src/libexpr/primops/fetchgit.cc26
-rw-r--r--src/libexpr/primops/fetchgit.hh3
2 files changed, 18 insertions, 11 deletions
diff --git a/src/libexpr/primops/fetchgit.cc b/src/libexpr/primops/fetchgit.cc
index 9db4adbc9da2..adc58770233b 100644
--- a/src/libexpr/primops/fetchgit.cc
+++ b/src/libexpr/primops/fetchgit.cc
@@ -8,10 +8,13 @@
 
 #include <regex>
 
+using namespace std::string_literals;
+
 namespace nix {
 
 Path exportGit(ref<Store> store, const std::string & uri,
-    const std::string & ref, const std::string & rev)
+    const std::string & ref, const std::string & rev,
+    const std::string & name)
 {
     if (rev != "") {
         std::regex revRegex("^[0-9a-fA-F]{40}$");
@@ -51,12 +54,12 @@ Path exportGit(ref<Store> store, const std::string & uri,
     }
 
     // FIXME: check whether rev is an ancestor of ref.
-    std::string commitHash =
-        rev != "" ? rev : chomp(readFile(localRefFile));
+    std::string commitHash = rev != "" ? rev : chomp(readFile(localRefFile));
 
     printTalkative("using revision %s of repo '%s'", uri, commitHash);
 
-    Path storeLink = cacheDir + "/" + commitHash + ".link";
+    std::string storeLinkName = hashString(htSHA512, name + std::string("\0"s) + commitHash).to_string(Base32, false);
+    Path storeLink = cacheDir + "/" + storeLinkName + ".link";
     PathLocks storeLinkLock({storeLink}, fmt("waiting for lock on '%1%'...", storeLink));
 
     if (pathExists(storeLink)) {
@@ -76,7 +79,7 @@ Path exportGit(ref<Store> store, const std::string & uri,
 
     runProgram("tar", true, { "x", "-C", tmpDir }, tar);
 
-    auto storePath = store->addToStore("git-export", tmpDir);
+    auto storePath = store->addToStore(name, tmpDir);
 
     replaceSymlink(storePath, storeLink);
 
@@ -91,6 +94,7 @@ static void prim_fetchgit(EvalState & state, const Pos & pos, Value * * args, Va
     std::string url;
     std::string ref = "master";
     std::string rev;
+    std::string name = "source";
 
     state.forceValue(*args[0]);
 
@@ -99,16 +103,18 @@ static void prim_fetchgit(EvalState & state, const Pos & pos, Value * * args, Va
         state.forceAttrs(*args[0], pos);
 
         for (auto & attr : *args[0]->attrs) {
-            string name(attr.name);
-            if (name == "url") {
+            string n(attr.name);
+            if (n == "url") {
                 PathSet context;
                 url = state.coerceToString(*attr.pos, *attr.value, context, false, false);
                 if (hasPrefix(url, "/")) url = "file://" + url;
             }
-            else if (name == "ref")
+            else if (n == "ref")
                 ref = state.forceStringNoCtx(*attr.value, *attr.pos);
-            else if (name == "rev")
+            else if (n == "rev")
                 rev = state.forceStringNoCtx(*attr.value, *attr.pos);
+            else if (n == "name")
+                name = state.forceStringNoCtx(*attr.value, *attr.pos);
             else
                 throw EvalError("unsupported argument '%s' to 'fetchgit', at %s", attr.name, *attr.pos);
         }
@@ -119,7 +125,7 @@ static void prim_fetchgit(EvalState & state, const Pos & pos, Value * * args, Va
     } else
         url = state.forceStringNoCtx(*args[0], pos);
 
-    Path storePath = exportGit(state.store, url, ref, rev);
+    Path storePath = exportGit(state.store, url, ref, rev, name);
 
     mkString(v, storePath, PathSet({storePath}));
 }
diff --git a/src/libexpr/primops/fetchgit.hh b/src/libexpr/primops/fetchgit.hh
index ff228f3b3c6a..4bf34b76f8dc 100644
--- a/src/libexpr/primops/fetchgit.hh
+++ b/src/libexpr/primops/fetchgit.hh
@@ -9,6 +9,7 @@ namespace nix {
 class Store;
 
 Path exportGit(ref<Store> store, const std::string & uri,
-    const std::string & ref, const std::string & rev = "");
+    const std::string & ref, const std::string & rev = "",
+    const std::string & name = "");
 
 }