base16-schemes: unstable-2024-06-21 -> unstable-2024-11-12 (#356361)
[NixPkgs.git] / pkgs / top-level / release-attrpaths-superset.nix
blob293c856488a20b400532842ede08fb8a68526a03
1 # This expression will, as efficiently as possible, dump a
2 # *superset* of all attrpaths of derivations which might be
3 # part of a release on *any* platform.
5 # Both this expression and what ofborg uses (release-outpaths.nix)
6 # are essentially single-threaded (under the current cppnix
7 # implementation).
9 # This expression runs much, much, much faster and uses much, much
10 # less memory than the ofborg script by skipping the
11 # platform-relevance checks.  The ofborg outpaths.nix script takes
12 # half an hour on a 3ghz core and peaks at 60gbytes of memory; this
13 # expression runs on the same machine in 44 seconds with peak memory
14 # usage of 5gbytes.
16 # Once you have the list of attrnames you can split it up into
17 # $NUM_CORES batches and run the platform checks separately for each
18 # batch, in parallel.
20 # To dump the attrnames:
22 #   nix-instantiate --eval --strict --json pkgs/top-level/release-attrpaths-superset.nix -A names
24 { lib ? import (path + "/lib")
25 , trace ? false
26 , enableWarnings ? true
27 , checkMeta ? true
28 , path ? ./../..
30 let
32   # No release package attrpath may have any of these attrnames as
33   # its initial component.
34   #
35   # If you can find a way to remove any of these entries without
36   # causing CI to fail, please do so.
37   #
38   excluded-toplevel-attrs = {
39     # spliced packagesets
40     __splicedPackages = true;
41     pkgsBuildBuild = true;
42     pkgsBuildHost = true;
43     pkgsBuildTarget = true;
44     pkgsHostHost = true;
45     pkgsHostTarget = true;
46     pkgsTargetTarget = true;
47     buildPackages = true;
48     targetPackages = true;
50     # cross packagesets
51     pkgsLLVM = true;
52     pkgsMusl = true;
53     pkgsStatic = true;
54     pkgsCross = true;
55     pkgsx86_64Darwin = true;
56     pkgsi686Linux = true;
57     pkgsLinux = true;
58     pkgsExtraHardening = true;
59   };
61   # No release package attrname may have any of these at a component
62   # anywhere in its attrpath.  These are the names of gigantic
63   # top-level attrsets that have leaked into so many sub-packagesets
64   # that it's easier to simply exclude them entirely.
65   #
66   # If you can find a way to remove any of these entries without
67   # causing CI to fail, please do so.
68   #
69   excluded-attrnames-at-any-depth = {
70     lib = true;
71     override = true;
72     __functor = true;
73     __functionArgs = true;
74     __splicedPackages = true;
75     newScope = true;
76     scope = true;
77     pkgs = true;
78     test-pkgs = true;
79     callPackage = true;
80     mkDerivation = true;
81     overrideDerivation = true;
82     overrideScope = true;
83     overrideScope' = true;
85     # Special case: lib/types.nix leaks into a lot of nixos-related
86     # derivations, and does not eval deeply.
87     type = true;
88   };
90   # __attrsFailEvaluation is a temporary workaround to get top-level
91   # eval to succeed (under builtins.tryEval) for the entire
92   # packageset, without deep invasve changes into individual
93   # packages.
94   #
95   # Now that CI has been added, ensuring that top-level eval will
96   # not be broken by any new commits, you should not add any new
97   # occurrences of __attrsFailEvaluation, and should remove them
98   # wherever you are able to (doing so will likely require deep
99   # adjustments within packages).  Once all of the uses of
100   # __attrsFailEvaluation are removed, it will be deleted from the
101   # routine below.  In the meantime,
102   #
103   # The intended semantics are that an attrpath rooted at pkgs is
104   # part of the (unfiltered) release jobset iff all of the following
105   # are true:
106   #
107   # 1. The first component of the attrpath is not in
108   #    `excluded-toplevel-attrs`
109   #
110   # 2. No attrname in the attrpath belongs to the list of forbidden
111   #    attrnames `excluded-attrnames-at-any-depth`
112   #
113   # 3. The attrpath leads to a value for which lib.isDerivation is true
114   #
115   # 4. No proper prefix of the attrpath has __attrsFailEvaluation=true
116   #
117   # 5. Any proper prefix of the attrpath at which lib.isDerivation
118   #    is true also has __recurseIntoDerivationForReleaseJobs=true.
119   #
120   # The last condition is unfortunately necessary because there are
121   # Hydra release jobnames which have proper prefixes which are
122   # attrnames of derivations (!).  We should probably restructure
123   # the job tree so that this is not the case.
124   #
125   justAttrNames = path: value:
126     let
127       attempt =
128         if lib.isDerivation value &&
129            # in some places we have *derivations* with jobsets as subattributes, ugh
130            !(value.__recurseIntoDerivationForReleaseJobs or false) then
131              [ path ]
133         # Even wackier case: we have meta.broken==true jobs with
134         # !meta.broken jobs as subattributes with license=unfree, and
135         # check-meta.nix won't throw an "unfree" failure because the
136         # enclosing derivation is marked broken.  Yeah.  Bonkers.
137         # We should just forbid jobsets enclosed by derivations.
138         else if lib.isDerivation value &&
139                 !value.meta.available then []
141         else if !(lib.isAttrs value) then []
142         else if (value.__attrsFailEvaluation or false) then []
143         else lib.pipe value [
144           (builtins.mapAttrs
145             (name: value:
146               if excluded-attrnames-at-any-depth.${name} or false then [] else
147               (justAttrNames (path ++ [name]) value)))
148           builtins.attrValues
149           builtins.concatLists
150         ];
152       seq = builtins.deepSeq attempt attempt;
153       tried = builtins.tryEval seq;
155       result =
156         if tried.success
157         then tried.value
158         else if enableWarnings && path != [ "AAAAAASomeThingsFailToEvaluate" ]
159         then lib.warn "tryEval failed at: ${lib.concatStringsSep "." path}" []
160         else [];
161     in
162       if !trace
163       then result
164       else lib.trace "** ${lib.concatStringsSep "." path}" result;
166   unfiltered = import ./release-outpaths.nix {
167     inherit checkMeta;
168     attrNamesOnly = true;
169     inherit path;
170   };
172   filtered = lib.pipe unfiltered [
173     (pkgs: builtins.removeAttrs pkgs (builtins.attrNames excluded-toplevel-attrs))
174   ];
176   paths =
177     [
178       # I am not entirely sure why these three packages end up in
179       # the Hydra jobset.  But they do, and they don't meet the
180       # criteria above, so at the moment they are special-cased.
181       [ "pkgsLLVM" "stdenv" ]
182       [ "pkgsStatic" "stdenv" ]
183       [ "pkgsMusl" "stdenv" ]
184     ] ++ justAttrNames [] filtered;
186   names =
187     map (path: (lib.concatStringsSep "." path)) paths;
191   inherit paths names;