1 # snippets that can be shared by multiple fetchers (pkgs/build-support)
4 commonH = hashTypes: rec {
5 hashNames = [ "hash" ] ++ hashTypes;
6 hashSet = lib.genAttrs hashNames (lib.const {});
11 sha256 = lib.fakeSha256;
12 sha512 = lib.fakeSha512;
16 proxyImpureEnvVars = [
17 # We borrow these environment variables from the caller to allow
18 # easy proxy configuration. This is impure, but a fixed-output
19 # derivation like fetchurl is allowed to do so since its result is
21 "http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy"
22 "HTTP_PROXY" "HTTPS_PROXY" "FTP_PROXY" "ALL_PROXY" "NO_PROXY"
24 # https proxies typically need to inject custom root CAs too
29 Converts an attrset containing one of `hash`, `sha256` or `sha512`,
30 into one containing `outputHash{,Algo}` as accepted by `mkDerivation`.
32 An appropriate “fake hash” is substituted when the hash value is `""`,
33 as is the [convention for fetchers](#sec-pkgs-fetchers-updating-source-hashes-fakehash-method).
35 All other attributes in the set remain as-is.
40 normalizeHash { } { hash = ""; foo = "bar"; }
43 outputHash = lib.fakeHash;
44 outputHashAlgo = null;
50 normalizeHash { } { sha256 = lib.fakeSha256; }
53 outputHash = lib.fakeSha256;
54 outputHashAlgo = "sha256";
59 normalizeHash { } { sha512 = lib.fakeSha512; }
62 outputHash = lib.fakeSha512;
63 outputHashAlgo = "sha512";
69 normalizeHash :: { hashTypes :: List String, required :: Bool } -> AttrSet -> AttrSet
75 : the set of attribute names accepted as hash inputs, in addition to `hash`
78 : whether to throw if no hash was present in the input; otherwise returns the original input, unmodified
81 hashTypes ? [ "sha256" ],
85 inherit (lib) concatMapStringsSep head tail throwIf;
86 inherit (lib.attrsets) attrsToList intersectAttrs removeAttrs optionalAttrs;
88 inherit (commonH hashTypes) hashNames hashSet;
91 if args ? "outputHash" then
95 # The argument hash, as a {name, value} pair
97 # All hashes passed in arguments (possibly 0 or >1) as a list of {name, value} pairs
98 let hashesAsNVPairs = attrsToList (intersectAttrs hashSet args); in
99 if hashesAsNVPairs == [] then
100 throwIf required "fetcher called without `hash`" null
101 else if tail hashesAsNVPairs != [] then
102 throw "fetcher called with mutually-incompatible arguments: ${concatMapStringsSep ", " (a: a.name) hashesAsNVPairs}"
107 removeAttrs args hashNames // (optionalAttrs (h != null) {
108 outputHashAlgo = if h.name == "hash" then null else h.name;
110 if h.value == "" then
111 fakeH.${h.name} or (throw "no “fake hash” defined for ${h.name}")
118 Wraps a function which accepts `outputHash{,Algo}` into one which accepts `hash` or `sha{256,512}`
122 withNormalizedHash { hashTypes = [ "sha256" "sha512" ]; } (
123 { outputHash, outputHashAlgo, ... }:
127 is a function which accepts one of `hash`, `sha256`, or `sha512` (or the original's `outputHash` and `outputHashAlgo`).
129 Its `functionArgs` metadata only lists `hash` as a parameter, optional iff. `outputHash` was an optional parameter of
130 the original function. `sha256`, `sha512`, `outputHash`, or `outputHashAlgo` are not mentioned in the `functionArgs`
135 withNormalizedHash :: { hashTypes :: List String } -> (AttrSet -> T) -> (AttrSet -> T)
141 : the set of attribute names accepted as hash inputs, in addition to `hash`
142 : they must correspond to a valid value for `outputHashAlgo`, currently one of: `md5`, `sha1`, `sha256`, or `sha512`.
145 : the function to be wrapped
148 In nixpkgs, `mkDerivation` rejects MD5 `outputHash`es, and SHA-1 is being deprecated.
150 As such, there is no reason to add `md5` to `hashTypes`, and
151 `sha1` should only ever be included for backwards compatibility.
156 `withNormalizedHash { inherit hashTypes; } f` is functionally equivalent to
158 args: f (normalizeHash {
160 required = !(lib.functionArgs f).outputHash;
164 However, `withNormalizedHash` preserves `functionArgs` metadata insofar as possible,
165 and is implemented somewhat more efficiently.
167 withNormalizedHash = {
168 hashTypes ? [ "sha256" ]
171 inherit (lib.attrsets) genAttrs intersectAttrs removeAttrs;
172 inherit (lib.trivial) const functionArgs setFunctionArgs;
174 inherit (commonH hashTypes) hashSet;
175 fArgs = functionArgs fetcher;
177 normalize = normalizeHash {
179 required = !fArgs.outputHash;
182 # The o.g. fetcher must *only* accept outputHash and outputHashAlgo
183 assert fArgs ? outputHash && fArgs ? outputHashAlgo;
184 assert intersectAttrs fArgs hashSet == {};
187 (args: fetcher (normalize args))
188 (removeAttrs fArgs [ "outputHash" "outputHashAlgo" ] // { hash = fArgs.outputHash; });