diff --git a/pkgs/build-support/fetchgit/default.nix b/pkgs/build-support/fetchgit/default.nix index 0efeed065589..4ffb998ee205 100644 --- a/pkgs/build-support/fetchgit/default.nix +++ b/pkgs/build-support/fetchgit/default.nix @@ -38,183 +38,183 @@ lib.makeOverridable ( extendDrvArgs = finalAttrs: - lib.fetchers.withNormalizedHash { } ( - # NOTE Please document parameter additions or changes in - # ../../../doc/build-helpers/fetchers.chapter.md - { - url, - tag ? null, - rev ? null, - name ? urlToName { - inherit url; - rev = lib.revOrTag rev tag; - # when rootDir is specified, avoid invalidating the result when rev changes - append = if rootDir != "" then "-${lib.strings.sanitizeDerivationName rootDir}" else ""; - }, - leaveDotGit ? deepClone || fetchTags, - outputHash ? lib.fakeHash, - outputHashAlgo ? null, - fetchSubmodules ? true, - deepClone ? false, - branchName ? null, - sparseCheckout ? lib.optional (rootDir != "") rootDir, - nonConeMode ? rootDir != "", - nativeBuildInputs ? [ ], - # Shell code executed before the file has been fetched. This, in - # particular, can do things like set NIX_PREFETCH_GIT_CHECKOUT_HOOK to - # run operations between the checkout completing and deleting the .git - # directory. - preFetch ? "", - # Shell code executed after the file has been fetched - # successfully. This can do things like check or transform the file. - postFetch ? "", - preferLocalBuild ? true, - fetchLFS ? false, - # Shell code to build a netrc file for BASIC auth - netrcPhase ? null, - # Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes) - # needed for netrcPhase - netrcImpureEnvVars ? [ ], - passthru ? { }, - meta ? { }, - allowedRequisites ? null, - # fetch all tags after tree (useful for git describe) - fetchTags ? false, - # make this subdirectory the root of the result - rootDir ? "", - # GIT_CONFIG_GLOBAL (as a file) - gitConfigFile ? config.gitConfigFile, - }: + lib.fetchers.withNormalizedHash { } ( + # NOTE Please document parameter additions or changes in + # ../../../doc/build-helpers/fetchers.chapter.md + { + url, + tag ? null, + rev ? null, + name ? urlToName { + inherit url; + rev = lib.revOrTag rev tag; + # when rootDir is specified, avoid invalidating the result when rev changes + append = if rootDir != "" then "-${lib.strings.sanitizeDerivationName rootDir}" else ""; + }, + leaveDotGit ? deepClone || fetchTags, + outputHash ? lib.fakeHash, + outputHashAlgo ? null, + fetchSubmodules ? true, + deepClone ? false, + branchName ? null, + sparseCheckout ? lib.optional (rootDir != "") rootDir, + nonConeMode ? rootDir != "", + nativeBuildInputs ? [ ], + # Shell code executed before the file has been fetched. This, in + # particular, can do things like set NIX_PREFETCH_GIT_CHECKOUT_HOOK to + # run operations between the checkout completing and deleting the .git + # directory. + preFetch ? "", + # Shell code executed after the file has been fetched + # successfully. This can do things like check or transform the file. + postFetch ? "", + preferLocalBuild ? true, + fetchLFS ? false, + # Shell code to build a netrc file for BASIC auth + netrcPhase ? null, + # Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes) + # needed for netrcPhase + netrcImpureEnvVars ? [ ], + passthru ? { }, + meta ? { }, + allowedRequisites ? null, + # fetch all tags after tree (useful for git describe) + fetchTags ? false, + # make this subdirectory the root of the result + rootDir ? "", + # GIT_CONFIG_GLOBAL (as a file) + gitConfigFile ? config.gitConfigFile, + }: - /* - NOTE: - fetchgit has one problem: git fetch only works for refs. - This is because fetching arbitrary (maybe dangling) commits creates garbage collection risks - and checking whether a commit belongs to a ref is expensive. This may - change in the future when some caching is added to git (?) - Usually refs are either tags (refs/tags/*) or branches (refs/heads/*) - Cloning branches will make the hash check fail when there is an update. - But not all patches we want can be accessed by tags. + /* + NOTE: + fetchgit has one problem: git fetch only works for refs. + This is because fetching arbitrary (maybe dangling) commits creates garbage collection risks + and checking whether a commit belongs to a ref is expensive. This may + change in the future when some caching is added to git (?) + Usually refs are either tags (refs/tags/*) or branches (refs/heads/*) + Cloning branches will make the hash check fail when there is an update. + But not all patches we want can be accessed by tags. - The workaround is getting the last n commits so that it's likely that they - still contain the hash we want. + The workaround is getting the last n commits so that it's likely that they + still contain the hash we want. - for now : increase depth iteratively (TODO) + for now : increase depth iteratively (TODO) - real fix: ask git folks to add a - git fetch $HASH contained in $BRANCH - facility because checking that $HASH is contained in $BRANCH is less - expensive than fetching --depth $N. - Even if git folks implemented this feature soon it may take years until - server admins start using the new version? - */ + real fix: ask git folks to add a + git fetch $HASH contained in $BRANCH + facility because checking that $HASH is contained in $BRANCH is less + expensive than fetching --depth $N. + Even if git folks implemented this feature soon it may take years until + server admins start using the new version? + */ - assert nonConeMode -> (sparseCheckout != [ ]); - assert fetchTags -> leaveDotGit; - assert rootDir != "" -> !leaveDotGit; + assert nonConeMode -> (sparseCheckout != [ ]); + assert fetchTags -> leaveDotGit; + assert rootDir != "" -> !leaveDotGit; - let - revWithTag = let - warningMsg = "fetchgit requires one of either `rev` or `tag` to be provided (not both)."; - otherIsNull = other: lib.assertMsg (other == null) warningMsg; + revWithTag = + let + warningMsg = "fetchgit requires one of either `rev` or `tag` to be provided (not both)."; + otherIsNull = other: lib.assertMsg (other == null) warningMsg; + in + if tag != null then + assert (otherIsNull rev); + "refs/tags/${tag}" + else if rev != null then + assert (otherIsNull tag); + rev + else + # FIXME fetching HEAD if no rev or tag is provided is problematic at best + "HEAD"; in - if tag != null then - assert (otherIsNull rev); - "refs/tags/${tag}" - else if rev != null then - assert (otherIsNull tag); - rev + + if builtins.isString sparseCheckout then + # Changed to throw on 2023-06-04 + throw + "Please provide directories/patterns for sparse checkout as a list of strings. Passing a (multi-line) string is not supported any more." else - # FIXME fetching HEAD if no rev or tag is provided is problematic at best - "HEAD"; - in + { + inherit name; - if builtins.isString sparseCheckout then - # Changed to throw on 2023-06-04 - throw - "Please provide directories/patterns for sparse checkout as a list of strings. Passing a (multi-line) string is not supported any more." - else - { - inherit name; + builder = ./builder.sh; + fetcher = ./nix-prefetch-git; - builder = ./builder.sh; - fetcher = ./nix-prefetch-git; + nativeBuildInputs = [ + git + cacert + ] + ++ lib.optionals fetchLFS [ git-lfs ] + ++ nativeBuildInputs; - nativeBuildInputs = [ - git - cacert - ] - ++ lib.optionals fetchLFS [ git-lfs ] - ++ nativeBuildInputs; + inherit outputHash outputHashAlgo; + outputHashMode = "recursive"; - inherit outputHash outputHashAlgo; - outputHashMode = "recursive"; + # git-sparse-checkout(1) says: + # > When the --stdin option is provided, the directories or patterns are read + # > from standard in as a newline-delimited list instead of from the arguments. + sparseCheckout = builtins.concatStringsSep "\n" sparseCheckout; - # git-sparse-checkout(1) says: - # > When the --stdin option is provided, the directories or patterns are read - # > from standard in as a newline-delimited list instead of from the arguments. - sparseCheckout = builtins.concatStringsSep "\n" sparseCheckout; + inherit + url + leaveDotGit + fetchLFS + fetchSubmodules + deepClone + branchName + nonConeMode + preFetch + postFetch + fetchTags + rootDir + gitConfigFile + ; + rev = revWithTag; - inherit - url - leaveDotGit - fetchLFS - fetchSubmodules - deepClone - branchName - nonConeMode - preFetch - postFetch - fetchTags - rootDir - gitConfigFile - ; - rev = revWithTag; + postHook = + if netrcPhase == null then + null + else + '' + ${netrcPhase} + # required that git uses the netrc file + mv {,.}netrc + export NETRC=$PWD/.netrc + export HOME=$PWD + ''; - postHook = - if netrcPhase == null then - null - else - '' - ${netrcPhase} - # required that git uses the netrc file - mv {,.}netrc - export NETRC=$PWD/.netrc - export HOME=$PWD - ''; + impureEnvVars = + lib.fetchers.proxyImpureEnvVars + ++ netrcImpureEnvVars + ++ [ + "GIT_PROXY_COMMAND" + "NIX_GIT_SSL_CAINFO" + "SOCKS_SERVER" - impureEnvVars = - lib.fetchers.proxyImpureEnvVars - ++ netrcImpureEnvVars - ++ [ - "GIT_PROXY_COMMAND" - "NIX_GIT_SSL_CAINFO" - "SOCKS_SERVER" + # This is a parameter intended to be set by setup hooks or preFetch + # scripts that want per-URL control over HTTP proxies used by Git + # (if per-URL control isn't needed, `http_proxy` etc. will + # suffice). It must be a whitespace-separated (with backslash as an + # escape character) list of pairs like this: + # + # http://domain1/path1 proxy1 https://domain2/path2 proxy2 + # + # where the URLs are as documented in the `git-config` manual page + # under `http..*`, and the proxies are as documented on the + # same page under `http.proxy`. + "FETCHGIT_HTTP_PROXIES" + ]; - # This is a parameter intended to be set by setup hooks or preFetch - # scripts that want per-URL control over HTTP proxies used by Git - # (if per-URL control isn't needed, `http_proxy` etc. will - # suffice). It must be a whitespace-separated (with backslash as an - # escape character) list of pairs like this: - # - # http://domain1/path1 proxy1 https://domain2/path2 proxy2 - # - # where the URLs are as documented in the `git-config` manual page - # under `http..*`, and the proxies are as documented on the - # same page under `http.proxy`. - "FETCHGIT_HTTP_PROXIES" - ]; + inherit preferLocalBuild meta allowedRequisites; - inherit preferLocalBuild meta allowedRequisites; - - passthru = { - gitRepoUrl = url; - inherit tag; - } - // passthru; - } - ); + passthru = { + gitRepoUrl = url; + inherit tag; + } + // passthru; + } + ); # No ellipsis. inheritFunctionArgs = false; diff --git a/pkgs/build-support/fetchurl/default.nix b/pkgs/build-support/fetchurl/default.nix index 189b22413d93..e528b70eb7a7 100644 --- a/pkgs/build-support/fetchurl/default.nix +++ b/pkgs/build-support/fetchurl/default.nix @@ -75,260 +75,260 @@ lib.extendMkDerivation { extendDrvArgs = finalAttrs: -{ - # URL to fetch. - url ? "", + { + # URL to fetch. + url ? "", - # Alternatively, a list of URLs specifying alternative download - # locations. They are tried in order. - urls ? [ ], + # Alternatively, a list of URLs specifying alternative download + # locations. They are tried in order. + urls ? [ ], - # Additional curl options needed for the download to succeed. - # Warning: Each space (no matter the escaping) will start a new argument. - # If you wish to pass arguments with spaces, use `curlOptsList` - curlOpts ? "", + # Additional curl options needed for the download to succeed. + # Warning: Each space (no matter the escaping) will start a new argument. + # If you wish to pass arguments with spaces, use `curlOptsList` + curlOpts ? "", - # Additional curl options needed for the download to succeed. - curlOptsList ? [ ], + # Additional curl options needed for the download to succeed. + curlOptsList ? [ ], - # Name of the file. If empty, use the basename of `url' (or of the - # first element of `urls'). - name ? "", + # Name of the file. If empty, use the basename of `url' (or of the + # first element of `urls'). + name ? "", - # for versioned downloads optionally take pname + version. - pname ? "", - version ? "", + # for versioned downloads optionally take pname + version. + pname ? "", + version ? "", - # SRI hash. - hash ? "", + # SRI hash. + hash ? "", - # Legacy ways of specifying the hash. - outputHash ? "", - outputHashAlgo ? "", - sha1 ? "", - sha256 ? "", - sha512 ? "", + # Legacy ways of specifying the hash. + outputHash ? "", + outputHashAlgo ? "", + sha1 ? "", + sha256 ? "", + sha512 ? "", - recursiveHash ? false, + recursiveHash ? false, - # Shell code to build a netrc file for BASIC auth - netrcPhase ? null, + # Shell code to build a netrc file for BASIC auth + netrcPhase ? null, - # Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes) - # needed for netrcPhase - netrcImpureEnvVars ? [ ], + # Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes) + # needed for netrcPhase + netrcImpureEnvVars ? [ ], - # Shell code executed after the file has been fetched - # successfully. This can do things like check or transform the file. - postFetch ? "", + # Shell code executed after the file has been fetched + # successfully. This can do things like check or transform the file. + postFetch ? "", - # Whether to download to a temporary path rather than $out. Useful - # in conjunction with postFetch. The location of the temporary file - # is communicated to postFetch via $downloadedFile. - downloadToTemp ? false, + # Whether to download to a temporary path rather than $out. Useful + # in conjunction with postFetch. The location of the temporary file + # is communicated to postFetch via $downloadedFile. + downloadToTemp ? false, - # If true, set executable bit on downloaded file - executable ? false, + # If true, set executable bit on downloaded file + executable ? false, - # If set, don't download the file, but write a list of all possible - # URLs (resulting from resolving mirror:// URLs) to $out. - showURLs ? false, + # If set, don't download the file, but write a list of all possible + # URLs (resulting from resolving mirror:// URLs) to $out. + showURLs ? false, - # Meta information, if any. - meta ? { }, + # Meta information, if any. + meta ? { }, - # Passthru information, if any. - passthru ? { }, - # Doing the download on a remote machine just duplicates network - # traffic, so don't do that by default - preferLocalBuild ? true, + # Passthru information, if any. + passthru ? { }, + # Doing the download on a remote machine just duplicates network + # traffic, so don't do that by default + preferLocalBuild ? true, - # Additional packages needed as part of a fetch - nativeBuildInputs ? [ ], -}@args: + # Additional packages needed as part of a fetch + nativeBuildInputs ? [ ], + }@args: -let - preRewriteUrls = - if urls != [ ] && url == "" then - ( - if lib.isList urls then urls else throw "`urls` is not a list: ${lib.generators.toPretty { } urls}" - ) - else if urls == [ ] && url != "" then - ( - if lib.isString url then - [ url ] - else - throw "`url` is not a string: ${lib.generators.toPretty { } urls}" - ) - else - throw "fetchurl requires either `url` or `urls` to be set: ${lib.generators.toPretty { } args}"; - - urls_ = let - u = lib.lists.filter (url: lib.isString url) (map rewriteURL preRewriteUrls); - in - if u == [ ] then throw "urls is empty after rewriteURL (was ${toString preRewriteUrls})" else u; - - hash_ = - if - with lib.lists; - length ( - filter (s: s != "") [ - hash - outputHash - sha1 - sha256 - sha512 - ] - ) > 1 - then - throw "multiple hashes passed to fetchurl: ${lib.generators.toPretty { } urls_}" - else - - if hash != "" then - { - outputHashAlgo = null; - outputHash = hash; - } - else if outputHash != "" then - if outputHashAlgo != "" then - { inherit outputHashAlgo outputHash; } - else - throw "fetchurl was passed outputHash without outputHashAlgo: ${lib.generators.toPretty { } urls_}" - else if sha512 != "" then - { - outputHashAlgo = "sha512"; - outputHash = sha512; - } - else if sha256 != "" then - { - outputHashAlgo = "sha256"; - outputHash = sha256; - } - else if sha1 != "" then - { - outputHashAlgo = "sha1"; - outputHash = sha1; - } - else if cacert != null then - { - outputHashAlgo = "sha256"; - outputHash = ""; - } - else - throw "fetchurl requires a hash for fixed-output derivation: ${lib.generators.toPretty { } urls_}"; - - resolvedUrl = - let - mirrorSplit = lib.match "mirror://([[:alpha:]]+)/(.+)" url; - mirrorName = lib.head mirrorSplit; - mirrorList = - if lib.hasAttr mirrorName mirrors then - mirrors."${mirrorName}" + preRewriteUrls = + if urls != [ ] && url == "" then + ( + if lib.isList urls then urls else throw "`urls` is not a list: ${lib.generators.toPretty { } urls}" + ) + else if urls == [ ] && url != "" then + ( + if lib.isString url then + [ url ] + else + throw "`url` is not a string: ${lib.generators.toPretty { } urls}" + ) else - throw "unknown mirror:// site ${mirrorName}"; - in - if mirrorSplit == null || mirrorName == null then - url - else - "${lib.head mirrorList}${lib.elemAt mirrorSplit 1}"; -in + throw "fetchurl requires either `url` or `urls` to be set: ${lib.generators.toPretty { } args}"; - ( - if (pname != "" && version != "") then - { inherit pname version; } - else - { - name = - if showURLs then - "urls" - else if name != "" then - name + urls_ = + let + u = lib.lists.filter (url: lib.isString url) (map rewriteURL preRewriteUrls); + in + if u == [ ] then throw "urls is empty after rewriteURL (was ${toString preRewriteUrls})" else u; + + hash_ = + if + with lib.lists; + length ( + filter (s: s != "") [ + hash + outputHash + sha1 + sha256 + sha512 + ] + ) > 1 + then + throw "multiple hashes passed to fetchurl: ${lib.generators.toPretty { } urls_}" + else + + if hash != "" then + { + outputHashAlgo = null; + outputHash = hash; + } + else if outputHash != "" then + if outputHashAlgo != "" then + { inherit outputHashAlgo outputHash; } else - baseNameOf (toString (builtins.head urls_)); - } - ) - // { - builder = ./builder.sh; + throw "fetchurl was passed outputHash without outputHashAlgo: ${lib.generators.toPretty { } urls_}" + else if sha512 != "" then + { + outputHashAlgo = "sha512"; + outputHash = sha512; + } + else if sha256 != "" then + { + outputHashAlgo = "sha256"; + outputHash = sha256; + } + else if sha1 != "" then + { + outputHashAlgo = "sha1"; + outputHash = sha1; + } + else if cacert != null then + { + outputHashAlgo = "sha256"; + outputHash = ""; + } + else + throw "fetchurl requires a hash for fixed-output derivation: ${lib.generators.toPretty { } urls_}"; - nativeBuildInputs = [ curl ] ++ nativeBuildInputs; + resolvedUrl = + let + mirrorSplit = lib.match "mirror://([[:alpha:]]+)/(.+)" url; + mirrorName = lib.head mirrorSplit; + mirrorList = + if lib.hasAttr mirrorName mirrors then + mirrors."${mirrorName}" + else + throw "unknown mirror:// site ${mirrorName}"; + in + if mirrorSplit == null || mirrorName == null then + url + else + "${lib.head mirrorList}${lib.elemAt mirrorSplit 1}"; + in - urls = urls_; - - # If set, prefer the content-addressable mirrors - # (http://tarballs.nixos.org) over the original URLs. - preferHashedMirrors = false; - - # New-style output content requirements. - inherit (hash_) outputHashAlgo outputHash; - - # Disable TLS verification only when we know the hash and no credentials are - # needed to access the resource - SSL_CERT_FILE = - if - ( - hash_.outputHash == "" - || hash_.outputHash == lib.fakeSha256 - || hash_.outputHash == lib.fakeSha512 - || hash_.outputHash == lib.fakeHash - || netrcPhase != null - ) - then - "${cacert}/etc/ssl/certs/ca-bundle.crt" + ( + if (pname != "" && version != "") then + { inherit pname version; } else - "/no-cert-file.crt"; + { + name = + if showURLs then + "urls" + else if name != "" then + name + else + baseNameOf (toString (builtins.head urls_)); + } + ) + // { + builder = ./builder.sh; - outputHashMode = if (recursiveHash || executable) then "recursive" else "flat"; + nativeBuildInputs = [ curl ] ++ nativeBuildInputs; - curlOpts = lib.warnIf (lib.isList curlOpts) ( - let - url = toString (builtins.head urls_); - curlOptsRepresentation = lib.generators.toPretty { multiline = false; } curlOpts; - curlOptsAsStringRepresentation = lib.strings.escapeNixString (toString curlOpts); - curlOptsListElementsRepresentation = - lib.concatMapStringsSep " " lib.strings.escapeNixString - curlOpts; - in - '' - fetchurl for ${url}: curlOpts is a list (${curlOptsRepresentation}), which is not supported anymore. - - If you wish to get the same effect as before, for elements with spaces (even if escaped) to expand to multiple curl arguments, use a string argument instead: - curlOpts = ${curlOptsAsStringRepresentation}; - - If you wish for each list element to be passed as a separate curl argument, allowing arguments to contain spaces, use curlOptsList instead: - curlOptsList = [ ${curlOptsListElementsRepresentation} ]; - '' - ) curlOpts; + urls = urls_; - curlOptsList = lib.escapeShellArgs curlOptsList; + # If set, prefer the content-addressable mirrors + # (http://tarballs.nixos.org) over the original URLs. + preferHashedMirrors = false; - inherit - showURLs - mirrorsFile - postFetch - downloadToTemp - executable - ; + # New-style output content requirements. + inherit (hash_) outputHashAlgo outputHash; - impureEnvVars = impureEnvVars ++ netrcImpureEnvVars; + # Disable TLS verification only when we know the hash and no credentials are + # needed to access the resource + SSL_CERT_FILE = + if + ( + hash_.outputHash == "" + || hash_.outputHash == lib.fakeSha256 + || hash_.outputHash == lib.fakeSha512 + || hash_.outputHash == lib.fakeHash + || netrcPhase != null + ) + then + "${cacert}/etc/ssl/certs/ca-bundle.crt" + else + "/no-cert-file.crt"; - nixpkgsVersion = lib.trivial.release; + outputHashMode = if (recursiveHash || executable) then "recursive" else "flat"; - inherit preferLocalBuild; - - postHook = - if netrcPhase == null then - null - else + curlOpts = lib.warnIf (lib.isList curlOpts) ( + let + url = toString (builtins.head urls_); + curlOptsRepresentation = lib.generators.toPretty { multiline = false; } curlOpts; + curlOptsAsStringRepresentation = lib.strings.escapeNixString (toString curlOpts); + curlOptsListElementsRepresentation = + lib.concatMapStringsSep " " lib.strings.escapeNixString + curlOpts; + in '' - ${netrcPhase} - curlOpts="$curlOpts --netrc-file $PWD/netrc" - ''; + fetchurl for ${url}: curlOpts is a list (${curlOptsRepresentation}), which is not supported anymore. + - If you wish to get the same effect as before, for elements with spaces (even if escaped) to expand to multiple curl arguments, use a string argument instead: + curlOpts = ${curlOptsAsStringRepresentation}; + - If you wish for each list element to be passed as a separate curl argument, allowing arguments to contain spaces, use curlOptsList instead: + curlOptsList = [ ${curlOptsListElementsRepresentation} ]; + '' + ) curlOpts; - inherit meta; - passthru = { - inherit url resolvedUrl; - } - // passthru; - }; + curlOptsList = lib.escapeShellArgs curlOptsList; + + inherit + showURLs + mirrorsFile + postFetch + downloadToTemp + executable + ; + + impureEnvVars = impureEnvVars ++ netrcImpureEnvVars; + + nixpkgsVersion = lib.trivial.release; + + inherit preferLocalBuild; + + postHook = + if netrcPhase == null then + null + else + '' + ${netrcPhase} + curlOpts="$curlOpts --netrc-file $PWD/netrc" + ''; + + inherit meta; + passthru = { + inherit url resolvedUrl; + } + // passthru; + }; # No ellipsis inheritFunctionArgs = false; diff --git a/pkgs/build-support/fetchzip/default.nix b/pkgs/build-support/fetchzip/default.nix index a5da6f22fb65..830f68085f76 100644 --- a/pkgs/build-support/fetchzip/default.nix +++ b/pkgs/build-support/fetchzip/default.nix @@ -27,87 +27,87 @@ lib.extendMkDerivation { extendDrvArgs = finalAttrs: -{ - url ? "", - urls ? [ ], - name ? repoRevToNameMaybe (if url != "" then url else builtins.head urls) null "unpacked", - nativeBuildInputs ? [ ], - postFetch ? "", - extraPostFetch ? "", + { + url ? "", + urls ? [ ], + name ? repoRevToNameMaybe (if url != "" then url else builtins.head urls) null "unpacked", + nativeBuildInputs ? [ ], + postFetch ? "", + extraPostFetch ? "", - # Optionally move the contents of the unpacked tree up one level. - stripRoot ? true, - # Allows to set the extension for the intermediate downloaded - # file. This can be used as a hint for the unpackCmdHooks to select - # an appropriate unpacking tool. - extension ? null, + # Optionally move the contents of the unpacked tree up one level. + stripRoot ? true, + # Allows to set the extension for the intermediate downloaded + # file. This can be used as a hint for the unpackCmdHooks to select + # an appropriate unpacking tool. + extension ? null, - # the rest are given to fetchurl as is - ... -}@args: + # the rest are given to fetchurl as is + ... + }@args: -let - tmpFilename = - if extension != null then - "download.${extension}" - else - baseNameOf (if url != "" then url else builtins.head urls); -in + let + tmpFilename = + if extension != null then + "download.${extension}" + else + baseNameOf (if url != "" then url else builtins.head urls); + in - { - inherit name; - recursiveHash = true; + { + inherit name; + recursiveHash = true; - downloadToTemp = true; + downloadToTemp = true; - # Have to pull in glibcLocalesUtf8 for unzip in setup-hook.sh to handle - # UTF-8 aware locale: - # https://github.com/NixOS/nixpkgs/issues/176225#issuecomment-1146617263 - nativeBuildInputs = - lib.optionals withUnzip [ - unzip - glibcLocalesUtf8 - ] - ++ nativeBuildInputs; + # Have to pull in glibcLocalesUtf8 for unzip in setup-hook.sh to handle + # UTF-8 aware locale: + # https://github.com/NixOS/nixpkgs/issues/176225#issuecomment-1146617263 + nativeBuildInputs = + lib.optionals withUnzip [ + unzip + glibcLocalesUtf8 + ] + ++ nativeBuildInputs; - postFetch = '' - unpackDir="$TMPDIR/unpack" - mkdir "$unpackDir" - cd "$unpackDir" + postFetch = '' + unpackDir="$TMPDIR/unpack" + mkdir "$unpackDir" + cd "$unpackDir" - renamed="$TMPDIR/${tmpFilename}" - mv "$downloadedFile" "$renamed" - unpackFile "$renamed" - chmod -R +w "$unpackDir" - '' - + ( - if stripRoot then - '' - if [ $(ls -A "$unpackDir" | wc -l) != 1 ]; then - echo "error: zip file must contain a single file or directory." - echo "hint: Pass stripRoot=false; to fetchzip to assume flat list of files." - exit 1 - fi - fn=$(cd "$unpackDir" && ls -A) - if [ -f "$unpackDir/$fn" ]; then - mkdir $out - fi - mv "$unpackDir/$fn" "$out" - '' - else - '' - mv "$unpackDir" "$out" - '' - ) - + '' - ${postFetch} - ${lib.warnIf (extraPostFetch != "") - "use 'postFetch' instead of 'extraPostFetch' with 'fetchzip' and 'fetchFromGitHub' or 'fetchFromGitLab'." - extraPostFetch - } - chmod 755 "$out" - ''; - # ^ Remove non-owner write permissions - # Fixes https://github.com/NixOS/nixpkgs/issues/38649 - }; + renamed="$TMPDIR/${tmpFilename}" + mv "$downloadedFile" "$renamed" + unpackFile "$renamed" + chmod -R +w "$unpackDir" + '' + + ( + if stripRoot then + '' + if [ $(ls -A "$unpackDir" | wc -l) != 1 ]; then + echo "error: zip file must contain a single file or directory." + echo "hint: Pass stripRoot=false; to fetchzip to assume flat list of files." + exit 1 + fi + fn=$(cd "$unpackDir" && ls -A) + if [ -f "$unpackDir/$fn" ]; then + mkdir $out + fi + mv "$unpackDir/$fn" "$out" + '' + else + '' + mv "$unpackDir" "$out" + '' + ) + + '' + ${postFetch} + ${lib.warnIf (extraPostFetch != "") + "use 'postFetch' instead of 'extraPostFetch' with 'fetchzip' and 'fetchFromGitHub' or 'fetchFromGitLab'." + extraPostFetch + } + chmod 755 "$out" + ''; + # ^ Remove non-owner write permissions + # Fixes https://github.com/NixOS/nixpkgs/issues/38649 + }; }