diff --git a/doc/languages-frameworks/go.section.md b/doc/languages-frameworks/go.section.md index 9c67a514335e..8616d64e7c4e 100644 --- a/doc/languages-frameworks/go.section.md +++ b/doc/languages-frameworks/go.section.md @@ -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"; diff --git a/pkgs/development/go-modules/generic/default.nix b/pkgs/development/go-modules/generic/default.nix index b6af52d0efb8..0ca16f80b413 100644 --- a/pkgs/development/go-modules/generic/default.nix +++ b/pkgs/development/go-modules/generic/default.nix @@ -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;