buildGoModule: add vendorHash

the _unset hack is kind of ugly, but it needs to default to something
and it can't be null, because that already has special meaning
This commit is contained in:
ajs124 2022-07-29 00:46:48 +02:00 committed by zowoq
parent 6f435e54b5
commit 0d5c464ad6
2 changed files with 33 additions and 13 deletions

View file

@ -11,8 +11,8 @@ The function `buildGoModule` builds Go programs managed with Go modules. It buil
In the following is an example expression using `buildGoModule`, the following arguments are of special significance to the function:
- `vendorSha256`: is the hash of the output of the intermediate fetcher derivation. `vendorSha256` can also take `null` as an input. When `null` is used as a value, rather than fetching the dependencies and vendoring them, we use the vendoring included within the source repo. If you'd like to not have to update this field on dependency changes, run `go mod vendor` in your source repo and set `vendorSha256 = null;`
- `proxyVendor`: Fetches (go mod download) and proxies the vendor directory. This is useful if your code depends on c code and go mod tidy does not include the needed sources to build or if any dependency has case-insensitive conflicts which will produce platform dependant `vendorSha256` checksums.
- `vendorHash`: is the hash of the output of the intermediate fetcher derivation. `vendorHash` can also take `null` as an input. When `null` is used as a value, rather than fetching the dependencies and vendoring them, we use the vendoring included within the source repo. If you'd like to not have to update this field on dependency changes, run `go mod vendor` in your source repo and set `vendorHash = null;`
- `proxyVendor`: Fetches (go mod download) and proxies the vendor directory. This is useful if your code depends on c code and go mod tidy does not include the needed sources to build or if any dependency has case-insensitive conflicts which will produce platform dependant `vendorHash` checksums.
```nix
pet = buildGoModule rec {
@ -26,7 +26,7 @@ pet = buildGoModule rec {
sha256 = "0m2fzpqxk7hrbxsgqplkg7h2p7gv6s1miymv3gvw0cz039skag0s";
};
vendorSha256 = "1879j77k96684wi554rkjxydrj8g3hpp0kvxz03sd8dmwr3lh83j";
vendorHash = "sha256-ciBIR+a1oaYH+H1PcC8cD8ncfJczk1IiJ8iYNM+R6aA=";
meta = with lib; {
description = "Simple command-line snippet manager, written in Go";

View file

@ -19,17 +19,20 @@
# path to go.mod and go.sum directory
, modRoot ? "./"
# vendorSha256 is the sha256 of the vendored dependencies
# vendorHash is the SRI hash of the vendored dependencies
#
# if vendorSha256 is null, then we won't fetch any dependencies and
# if vendorHash is null, then we won't fetch any dependencies and
# rely on the vendor folder within the source.
, vendorSha256
, vendorHash ? "_unset"
# same as vendorHash, but outputHashAlgo is hardcoded to sha256
# so regular base32 sha256 hashes work
, vendorSha256 ? "_unset"
# Whether to delete the vendor folder supplied with the source.
, deleteVendor ? false
# Whether to fetch (go mod download) and proxy the vendor directory.
# This is useful if your code depends on c code and go mod tidy does not
# include the needed sources to build or if any dependency has case-insensitive
# conflicts which will produce platform dependant `vendorSha256` checksums.
# conflicts which will produce platform dependant `vendorHash` checksums.
, proxyVendor ? false
# We want parallel builds by default
@ -55,11 +58,23 @@
with builtins;
assert goPackagePath != "" -> throw "`goPackagePath` is not needed with `buildGoModule`";
assert (vendorSha256 == "_unset" && vendorHash == "_unset") -> throw "either `vendorHash` or `vendorSha256` is required";
assert (vendorSha256 != "_unset" && vendorHash != "_unset") -> throw "both `vendorHash` and `vendorSha256` set. only one can be set.";
let
args = removeAttrs args' [ "overrideModAttrs" "vendorSha256" ];
hasAnyVendorHash = (vendorSha256 != null && vendorSha256 != "_unset") || (vendorHash != null && vendorHash != "_unset");
vendorHashType =
if hasAnyVendorHash then
if vendorSha256 != null && vendorSha256 != "_unset" then
"sha256"
else
"sri"
else
null;
go-modules = if vendorSha256 != null then stdenv.mkDerivation (let modArgs = {
args = removeAttrs args' [ "overrideModAttrs" "vendorSha256" "vendorHash" ];
go-modules = if hasAnyVendorHash then stdenv.mkDerivation (let modArgs = {
name = "${name}-go-modules";
@ -98,7 +113,7 @@ let
fi
'' + ''
if [ -d vendor ]; then
echo "vendor folder exists, please set 'vendorSha256 = null;' in your expression"
echo "vendor folder exists, please set 'vendorHash = null;' or 'vendorSha256 = null;' in your expression"
exit 10
fi
@ -134,9 +149,14 @@ let
}; in modArgs // (
{
outputHashMode = "recursive";
} // (if (vendorHashType == "sha256") then {
outputHashAlgo = "sha256";
outputHash = vendorSha256;
}
} else {
outputHash = vendorHash;
}) // (lib.optionalAttrs (vendorHashType == "sri" && vendorHash == "") {
outputHashAlgo = "sha256";
})
) // overrideModAttrs modArgs) else "";
package = stdenv.mkDerivation (args // {
@ -156,7 +176,7 @@ let
export GOPROXY=off
export GOSUMDB=off
cd "$modRoot"
'' + lib.optionalString (vendorSha256 != null) ''
'' + lib.optionalString hasAnyVendorHash ''
${if proxyVendor then ''
export GOPROXY=file://${go-modules}
'' else ''
@ -274,7 +294,7 @@ let
disallowedReferences = lib.optional (!allowGoReference) go;
passthru = passthru // { inherit go go-modules vendorSha256 ; };
passthru = passthru // { inherit go go-modules vendorSha256 vendorHash; };
enableParallelBuilding = enableParallelBuilding;