From 65b5f177b5fbb1b0778ede047a13a3cee9c59cfe Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 30 Oct 2017 09:57:38 +0100 Subject: 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. --- src/libexpr/primops/fetchgit.cc | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'src/libexpr/primops/fetchgit.cc') 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 +using namespace std::string_literals; + namespace nix { Path exportGit(ref 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, 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, 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})); } -- cgit 1.4.1