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;
17 proxyImpureEnvVars = [
18 # We borrow these environment variables from the caller to allow
19 # easy proxy configuration. This is impure, but a fixed-output
20 # derivation like fetchurl is allowed to do so since its result is
33 # https proxies typically need to inject custom root CAs too
38 Converts an attrset containing one of `hash`, `sha256` or `sha512`,
39 into one containing `outputHash{,Algo}` as accepted by `mkDerivation`.
41 An appropriate “fake hash” is substituted when the hash value is `""`,
42 as is the [convention for fetchers](#sec-pkgs-fetchers-updating-source-hashes-fakehash-method).
44 All other attributes in the set remain as-is.
49 normalizeHash { } { hash = ""; foo = "bar"; }
52 outputHash = lib.fakeHash;
53 outputHashAlgo = null;
59 normalizeHash { } { sha256 = lib.fakeSha256; }
62 outputHash = lib.fakeSha256;
63 outputHashAlgo = "sha256";
68 normalizeHash { } { sha512 = lib.fakeSha512; }
71 outputHash = lib.fakeSha512;
72 outputHashAlgo = "sha512";
78 normalizeHash :: { hashTypes :: List String, required :: Bool } -> AttrSet -> AttrSet
84 : the set of attribute names accepted as hash inputs, in addition to `hash`
87 : whether to throw if no hash was present in the input; otherwise returns the original input, unmodified
91 hashTypes ? [ "sha256" ],
101 inherit (lib.attrsets)
108 inherit (commonH hashTypes) hashNames hashSet;
111 if args ? "outputHash" then
115 # The argument hash, as a {name, value} pair
117 # All hashes passed in arguments (possibly 0 or >1) as a list of {name, value} pairs
119 hashesAsNVPairs = attrsToList (intersectAttrs hashSet args);
121 if hashesAsNVPairs == [ ] then
122 throwIf required "fetcher called without `hash`" null
123 else if tail hashesAsNVPairs != [ ] then
124 throw "fetcher called with mutually-incompatible arguments: ${
125 concatMapStringsSep ", " (a: a.name) hashesAsNVPairs
128 head hashesAsNVPairs;
130 removeAttrs args hashNames
131 // (optionalAttrs (h != null) {
132 outputHashAlgo = if h.name == "hash" then null else h.name;
134 if h.value == "" then
135 fakeH.${h.name} or (throw "no “fake hash” defined for ${h.name}")
141 Wraps a function which accepts `outputHash{,Algo}` into one which accepts `hash` or `sha{256,512}`
145 withNormalizedHash { hashTypes = [ "sha256" "sha512" ]; } (
146 { outputHash, outputHashAlgo, ... }:
150 is a function which accepts one of `hash`, `sha256`, or `sha512` (or the original's `outputHash` and `outputHashAlgo`).
152 Its `functionArgs` metadata only lists `hash` as a parameter, optional iff. `outputHash` was an optional parameter of
153 the original function. `sha256`, `sha512`, `outputHash`, or `outputHashAlgo` are not mentioned in the `functionArgs`
158 withNormalizedHash :: { hashTypes :: List String } -> (AttrSet -> T) -> (AttrSet -> T)
164 : the set of attribute names accepted as hash inputs, in addition to `hash`
165 : they must correspond to a valid value for `outputHashAlgo`, currently one of: `md5`, `sha1`, `sha256`, or `sha512`.
168 : the function to be wrapped
171 In nixpkgs, `mkDerivation` rejects MD5 `outputHash`es, and SHA-1 is being deprecated.
173 As such, there is no reason to add `md5` to `hashTypes`, and
174 `sha1` should only ever be included for backwards compatibility.
179 `withNormalizedHash { inherit hashTypes; } f` is functionally equivalent to
181 args: f (normalizeHash {
183 required = !(lib.functionArgs f).outputHash;
187 However, `withNormalizedHash` preserves `functionArgs` metadata insofar as possible,
188 and is implemented somewhat more efficiently.
192 hashTypes ? [ "sha256" ],
196 inherit (lib.attrsets) genAttrs intersectAttrs removeAttrs;
197 inherit (lib.trivial) const functionArgs setFunctionArgs;
199 inherit (commonH hashTypes) hashSet;
200 fArgs = functionArgs fetcher;
202 normalize = normalizeHash {
204 required = !fArgs.outputHash;
207 # The o.g. fetcher must *only* accept outputHash and outputHashAlgo
208 assert fArgs ? outputHash && fArgs ? outputHashAlgo;
209 assert intersectAttrs fArgs hashSet == { };
211 setFunctionArgs (args: fetcher (normalize args)) (
217 hash = fArgs.outputHash;