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.
This commit is contained in:
parent
c1ae18941a
commit
65b5f177b5
2 changed files with 18 additions and 11 deletions
|
@ -8,10 +8,13 @@
|
||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
Path exportGit(ref<Store> store, const std::string & uri,
|
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 != "") {
|
if (rev != "") {
|
||||||
std::regex revRegex("^[0-9a-fA-F]{40}$");
|
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.
|
// FIXME: check whether rev is an ancestor of ref.
|
||||||
std::string commitHash =
|
std::string commitHash = rev != "" ? rev : chomp(readFile(localRefFile));
|
||||||
rev != "" ? rev : chomp(readFile(localRefFile));
|
|
||||||
|
|
||||||
printTalkative("using revision %s of repo '%s'", uri, commitHash);
|
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));
|
PathLocks storeLinkLock({storeLink}, fmt("waiting for lock on '%1%'...", storeLink));
|
||||||
|
|
||||||
if (pathExists(storeLink)) {
|
if (pathExists(storeLink)) {
|
||||||
|
@ -76,7 +79,7 @@ Path exportGit(ref<Store> store, const std::string & uri,
|
||||||
|
|
||||||
runProgram("tar", true, { "x", "-C", tmpDir }, tar);
|
runProgram("tar", true, { "x", "-C", tmpDir }, tar);
|
||||||
|
|
||||||
auto storePath = store->addToStore("git-export", tmpDir);
|
auto storePath = store->addToStore(name, tmpDir);
|
||||||
|
|
||||||
replaceSymlink(storePath, storeLink);
|
replaceSymlink(storePath, storeLink);
|
||||||
|
|
||||||
|
@ -91,6 +94,7 @@ static void prim_fetchgit(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
std::string url;
|
std::string url;
|
||||||
std::string ref = "master";
|
std::string ref = "master";
|
||||||
std::string rev;
|
std::string rev;
|
||||||
|
std::string name = "source";
|
||||||
|
|
||||||
state.forceValue(*args[0]);
|
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);
|
state.forceAttrs(*args[0], pos);
|
||||||
|
|
||||||
for (auto & attr : *args[0]->attrs) {
|
for (auto & attr : *args[0]->attrs) {
|
||||||
string name(attr.name);
|
string n(attr.name);
|
||||||
if (name == "url") {
|
if (n == "url") {
|
||||||
PathSet context;
|
PathSet context;
|
||||||
url = state.coerceToString(*attr.pos, *attr.value, context, false, false);
|
url = state.coerceToString(*attr.pos, *attr.value, context, false, false);
|
||||||
if (hasPrefix(url, "/")) url = "file://" + url;
|
if (hasPrefix(url, "/")) url = "file://" + url;
|
||||||
}
|
}
|
||||||
else if (name == "ref")
|
else if (n == "ref")
|
||||||
ref = state.forceStringNoCtx(*attr.value, *attr.pos);
|
ref = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||||
else if (name == "rev")
|
else if (n == "rev")
|
||||||
rev = state.forceStringNoCtx(*attr.value, *attr.pos);
|
rev = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||||
|
else if (n == "name")
|
||||||
|
name = state.forceStringNoCtx(*attr.value, *attr.pos);
|
||||||
else
|
else
|
||||||
throw EvalError("unsupported argument '%s' to 'fetchgit', at %s", attr.name, *attr.pos);
|
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
|
} else
|
||||||
url = state.forceStringNoCtx(*args[0], pos);
|
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}));
|
mkString(v, storePath, PathSet({storePath}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace nix {
|
||||||
class Store;
|
class Store;
|
||||||
|
|
||||||
Path exportGit(ref<Store> store, const std::string & uri,
|
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 = "");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue