Skip to content

Commit

Permalink
Add support for narHash in builtins.fetchGit
Browse files Browse the repository at this point in the history
Replacement for NixOS#3216 which became obsolete after the fetchers-API was
introduced which provides a `narHash`-argument for each fetcher
which is a SRI-hash of a content-addressable path. However, the
`fetchGit`-primop required some changes to work with it.

To summarize, the following things changed:

* The hash-mismatch error in `libfetchers` now returns `102` as exit
  code which is the default for those errors.

* The `git`-fetcher computes an SRI-hash of the result for the
  hash-validation.

* It's possible to specify an SRI-hash using the `narHash`-attribute in
  `builtins.fetchGit`. This is only allowed if a revision is specified.
  • Loading branch information
Ma27 committed Apr 29, 2020
1 parent 06849c3 commit 4a0a6c1
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/libexpr/primops/fetchGit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Va
std::string url;
std::optional<std::string> ref;
std::optional<Hash> rev;
std::optional<std::string> narHash;

std::string name = "source";
bool fetchSubmodules = false;
PathSet context;
Expand All @@ -34,12 +36,18 @@ static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Va
name = state.forceStringNoCtx(*attr.value, *attr.pos);
else if (n == "submodules")
fetchSubmodules = state.forceBool(*attr.value, *attr.pos);
else if (n == "narHash")
narHash = state.forceStringNoCtx(*attr.value, *attr.pos);
else
throw EvalError("unsupported argument '%s' to 'fetchGit', at %s", attr.name, *attr.pos);
}

if (url.empty())
throw EvalError(format("'url' argument required, at %1%") % pos);
if (narHash && !rev)
throw EvalError(
format("'narHash' can only be used for 'fetchGit' if 'rev' is set, at %1%") % pos
);

} else
url = state.coerceToString(pos, *args[0], context, false, false);
Expand All @@ -57,6 +65,7 @@ static void prim_fetchGit(EvalState & state, const Pos & pos, Value * * args, Va
if (ref) attrs.insert_or_assign("ref", *ref);
if (rev) attrs.insert_or_assign("rev", rev->gitRev());
if (fetchSubmodules) attrs.insert_or_assign("submodules", true);
if (narHash) attrs.emplace("narHash", *narHash);
auto input = fetchers::inputFromAttrs(attrs);

// FIXME: use name?
Expand Down
2 changes: 1 addition & 1 deletion src/libfetchers/fetchers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ std::pair<Tree, std::shared_ptr<const Input>> Input::fetchTree(ref<Store> store)
assert(input->narHash == tree.info.narHash);

if (narHash && narHash != input->narHash)
throw Error("NAR hash mismatch in input '%s' (%s), expected '%s', got '%s'",
throw Error((unsigned int) 102, "NAR hash mismatch in input '%s' (%s), expected '%s', got '%s'",
to_string(), tree.actualPath, narHash->to_string(SRI), input->narHash->to_string(SRI));

return {std::move(tree), input};
Expand Down
1 change: 1 addition & 0 deletions src/libfetchers/git.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ struct GitInput : Input
{
assert(input->rev);
assert(!rev || rev == input->rev);
input->narHash = store->queryPathInfo(storePath)->narHash;
return {
Tree {
.actualPath = store->toRealPath(storePath),
Expand Down
8 changes: 8 additions & 0 deletions tests/fetchGit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ git -C $repo commit -m 'Bla3' -a
path4=$(nix eval --tarball-ttl 0 --raw "(builtins.fetchGit file://$repo).outPath")
[[ $path2 = $path4 ]]

nix eval --raw "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-B5yIPHhEm0eysJKEsO7nqxprh9vcblFxpJG11gXJus1=\"; }).outPath" || status=$?
[[ "$status" = "102" ]]

nix eval --raw "(builtins.fetchGit { url = $repo; narHash = \"sha256-B5yIPHhEm0eysJKEsO7nqxprh9vcblFxpJG11gXJus1=\"; }).outPath" 2>&1 | grep "'narHash' can only be used for 'fetchGit' if 'rev' is set"

path5=$(nix eval --raw "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-Hr8g6AqANb3xqX28eu1XnjK/3ab8Gv6TJSnkb1LezG9=\"; }).outPath")
[[ $path = $path5 ]]

# tarball-ttl should be ignored if we specify a rev
echo delft > $repo/hello
git -C $repo add hello
Expand Down

0 comments on commit 4a0a6c1

Please sign in to comment.