wlvncc: unstable-2023-01-05 -> unstable-2024-11-24 (#357566)
[NixPkgs.git] / pkgs / top-level / release-lib.nix
blobc7581c47d3414383f3d6608063380d688242f9f9
1 { supportedSystems
2 , system ? builtins.currentSystem
3 , packageSet ? (import ../..)
4 , scrubJobs ? true
5 , # Attributes passed to nixpkgs. Don't build packages marked as unfree.
6   nixpkgsArgs ? { config = { allowUnfree = false; inHydra = true; }; }
7 }:
9 let
10   lib = import ../../lib;
12   inherit (lib)
13     addMetaAttrs
14     any
15     derivations
16     filter
17     flip
18     genAttrs
19     getAttrFromPath
20     hydraJob
21     id
22     isDerivation
23     lists
24     maintainers
25     mapAttrs
26     mapAttrs'
27     mapAttrsRecursive
28     matchAttrs
29     meta
30     nameValuePair
31     platforms
32     recursiveUpdate
33     subtractLists
34     systems
35     ;
37   pkgs = packageSet (recursiveUpdate { inherit system; config.allowUnsupportedSystem = true; } nixpkgsArgs);
39   hydraJob' = if scrubJobs then hydraJob else id;
42   /* !!! Hack: poor man's memoisation function.  Necessary to prevent
43      Nixpkgs from being evaluated again and again for every
44      job/platform pair. */
45   mkPkgsFor = crossSystem: let
46     packageSet' = args: packageSet (args // { inherit crossSystem; } // nixpkgsArgs);
48     pkgs_x86_64_linux = packageSet' { system = "x86_64-linux"; };
49     pkgs_i686_linux = packageSet' { system = "i686-linux"; };
50     pkgs_aarch64_linux = packageSet' { system = "aarch64-linux"; };
51     pkgs_riscv64_linux = packageSet' { system = "riscv64-linux"; };
52     pkgs_aarch64_darwin = packageSet' { system = "aarch64-darwin"; };
53     pkgs_armv6l_linux = packageSet' { system = "armv6l-linux"; };
54     pkgs_armv7l_linux = packageSet' { system = "armv7l-linux"; };
55     pkgs_x86_64_darwin = packageSet' { system = "x86_64-darwin"; };
56     pkgs_x86_64_freebsd = packageSet' { system = "x86_64-freebsd"; };
57     pkgs_i686_freebsd = packageSet' { system = "i686-freebsd"; };
58     pkgs_i686_cygwin = packageSet' { system = "i686-cygwin"; };
59     pkgs_x86_64_cygwin = packageSet' { system = "x86_64-cygwin"; };
61     in system:
62       if system == "x86_64-linux" then pkgs_x86_64_linux
63       else if system == "i686-linux" then pkgs_i686_linux
64       else if system == "aarch64-linux" then pkgs_aarch64_linux
65       else if system == "riscv64-linux" then pkgs_riscv64_linux
66       else if system == "aarch64-darwin" then pkgs_aarch64_darwin
67       else if system == "armv6l-linux" then pkgs_armv6l_linux
68       else if system == "armv7l-linux" then pkgs_armv7l_linux
69       else if system == "x86_64-darwin" then pkgs_x86_64_darwin
70       else if system == "x86_64-freebsd" then pkgs_x86_64_freebsd
71       else if system == "i686-freebsd" then pkgs_i686_freebsd
72       else if system == "i686-cygwin" then pkgs_i686_cygwin
73       else if system == "x86_64-cygwin" then pkgs_x86_64_cygwin
74       else abort "unsupported system type: ${system}";
76   pkgsFor = pkgsForCross null;
79   # More poor man's memoisation
80   pkgsForCross = let
81     examplesByConfig = flip mapAttrs'
82       systems.examples
83       (_: crossSystem: nameValuePair crossSystem.config {
84         inherit crossSystem;
85         pkgsFor = mkPkgsFor crossSystem;
86       });
87     native = mkPkgsFor null;
88   in crossSystem: let
89     candidate = examplesByConfig.${crossSystem.config} or null;
90   in if crossSystem == null
91       then native
92     else if candidate != null && matchAttrs crossSystem candidate.crossSystem
93       then candidate.pkgsFor
94     else mkPkgsFor crossSystem; # uncached fallback
97   # Given a list of 'meta.platforms'-style patterns, return the sublist of
98   # `supportedSystems` containing systems that matches at least one of the given
99   # patterns.
100   #
101   # This is written in a funny way so that we only elaborate the systems once.
102   supportedMatches = let
103       supportedPlatforms = map
104         (system: systems.elaborate { inherit system; })
105         supportedSystems;
106     in metaPatterns: let
107       anyMatch = platform:
108         any (meta.platformMatch platform) metaPatterns;
109       matchingPlatforms = filter anyMatch supportedPlatforms;
110     in map ({ system, ...}: system) matchingPlatforms;
113   assertTrue = bool:
114     if bool
115     then pkgs.runCommand "evaluated-to-true" {} "touch $out"
116     else pkgs.runCommand "evaluated-to-false" {} "false";
119   /* The working or failing mails for cross builds will be sent only to
120      the following maintainers, as most package maintainers will not be
121      interested in the result of cross building a package. */
122   crossMaintainers = [ ];
125   # Generate attributes for all supported systems.
126   forAllSystems = genAttrs supportedSystems;
129   # Generate attributes for all systems matching at least one of the given
130   # patterns
131   forMatchingSystems = metaPatterns: genAttrs (supportedMatches metaPatterns);
134   /* Build a package on the given set of platforms.  The function `f'
135      is called for each supported platform with Nixpkgs for that
136      platform as an argument .  We return an attribute set containing
137      a derivation for each supported platform, i.e. ‘{ x86_64-linux =
138      f pkgs_x86_64_linux; i686-linux = f pkgs_i686_linux; ... }’. */
139   testOn = testOnCross null;
142   /* Similar to the testOn function, but with an additional
143      'crossSystem' parameter for packageSet', defining the target
144      platform for cross builds. */
145   testOnCross = crossSystem: metaPatterns: f: forMatchingSystems metaPatterns
146     (system: hydraJob' (f (pkgsForCross crossSystem system)));
149   /* Given a nested set where the leaf nodes are lists of platforms,
150      map each leaf node to `testOn [platforms...] (pkgs:
151      pkgs.<attrPath>)'. */
152   mapTestOn = _mapTestOnHelper id null;
155   _mapTestOnHelper = f: crossSystem: mapAttrsRecursive
156     (path: metaPatterns: testOnCross crossSystem metaPatterns
157       (pkgs: f (getAttrFromPath path pkgs)));
159   /* Similar to the testOn function, but with an additional 'crossSystem'
160    * parameter for packageSet', defining the target platform for cross builds,
161    * and triggering the build of the host derivation. */
162   mapTestOnCross = _mapTestOnHelper
163     (addMetaAttrs { maintainers = crossMaintainers; });
166   /* Recursive for packages and apply a function to them */
167   recursiveMapPackages = f: mapAttrs (name: value:
168       if isDerivation value then
169         f value
170       else if value.recurseForDerivations or false || value.recurseForRelease or false then
171         recursiveMapPackages f value
172       else
173         []
174     );
176   /* Gets the list of Hydra platforms for a derivation */
177   getPlatforms = drv:
178     drv.meta.hydraPlatforms
179       or (subtractLists (drv.meta.badPlatforms or [])
180            (drv.meta.platforms or supportedSystems));
182   /* Recursively map a (nested) set of derivations to an isomorphic
183      set of meta.platforms values. */
184   packagePlatforms = recursiveMapPackages getPlatforms;
186 in {
187   /* Common platform groups on which to test packages. */
188   inherit (platforms) unix linux darwin cygwin all;
190   inherit
191     assertTrue
192     forAllSystems
193     forMatchingSystems
194     hydraJob'
195     lib
196     mapTestOn
197     mapTestOnCross
198     recursiveMapPackages
199     getPlatforms
200     packagePlatforms
201     pkgs
202     pkgsFor
203     pkgsForCross
204     supportedMatches
205     testOn
206     testOnCross
207     ;