# This expression will, as efficiently as possible, dump a # *superset* of all attrpaths of derivations which might be # part of a release on *any* platform. # # Both this expression and what ofborg uses (release-outpaths.nix) # are essentially single-threaded (under the current cppnix # implementation). # # This expression runs much, much, much faster and uses much, much # less memory than the ofborg script by skipping the # platform-relevance checks. The ofborg outpaths.nix script takes # half an hour on a 3ghz core and peaks at 60gbytes of memory; this # expression runs on the same machine in 44 seconds with peak memory # usage of 5gbytes. # # Once you have the list of attrnames you can split it up into # $NUM_CORES batches and run the platform checks separately for each # batch, in parallel. # # To dump the attrnames: # # nix-instantiate --eval --strict --json pkgs/top-level/release-attrpaths-superset.nix -A names # { lib ? import (path + "/lib") , trace ? false , enableWarnings ? true , checkMeta ? true , path ? ./../.. }: let # No release package attrpath may have any of these attrnames as # its initial component. # # If you can find a way to remove any of these entries without # causing CI to fail, please do so. # excluded-toplevel-attrs = { # spliced packagesets __splicedPackages = true; pkgsBuildBuild = true; pkgsBuildHost = true; pkgsBuildTarget = true; pkgsHostHost = true; pkgsHostTarget = true; pkgsTargetTarget = true; buildPackages = true; targetPackages = true; # cross packagesets pkgsLLVM = true; pkgsMusl = true; pkgsStatic = true; pkgsCross = true; pkgsi686Linux = true; }; # No release package attrname may have any of these at a component # anywhere in its attrpath. These are the names of gigantic # top-level attrsets that have leaked into so many sub-packagesets # that it's easier to simply exclude them entirely. # # If you can find a way to remove any of these entries without # causing CI to fail, please do so. # excluded-attrnames-at-any-depth = { lib = true; override = true; __functor = true; __functionArgs = true; newScope = true; scope = true; pkgs = true; buildHaskellPackages = true; buildPackages = true; generateOptparseApplicativeCompletions = true; callPackage = true; mkDerivation = true; overrideDerivation = true; overrideScope = true; overrideScope' = true; # Special case: lib/types.nix leaks into a lot of nixos-related # derivations, and does not eval deeply. type = true; }; # __attrsFailEvaluation is a temporary workaround to get top-level # eval to succeed (under builtins.tryEval) for the entire # packageset, without deep invasve changes into individual # packages. # # Now that CI has been added, ensuring that top-level eval will # not be broken by any new commits, you should not add any new # occurrences of __attrsFailEvaluation, and should remove them # wherever you are able to (doing so will likely require deep # adjustments within packages). Once all of the uses of # __attrsFailEvaluation are removed, it will be deleted from the # routine below. In the meantime, # # The intended semantics are that an attrpath rooted at pkgs is # part of the (unfiltered) release jobset iff all of the following # are true: # # 1. The first component of the attrpath is not in # `excluded-toplevel-attrs` # # 2. No attrname in the attrpath belongs to the list of forbidden # attrnames `excluded-attrnames-at-any-depth` # # 3. The attrpath leads to a value for which lib.isDerivation is true # # 4. No proper prefix of the attrpath has __attrsFailEvaluation=true # # 5. Any proper prefix of the attrpath at which lib.isDerivation # is true also has __recurseIntoDerivationForReleaseJobs=true. # # The last condition is unfortunately necessary because there are # Hydra release jobnames which have proper prefixes which are # attrnames of derivations (!). We should probably restructure # the job tree so that this is not the case. # justAttrNames = path: value: let attempt = if lib.isDerivation value && # in some places we have *derivations* with jobsets as subattributes, ugh !(value.__recurseIntoDerivationForReleaseJobs or false) then [ path ] # Even wackier case: we have meta.broken==true jobs with # !meta.broken jobs as subattributes with license=unfree, and # check-meta.nix won't throw an "unfree" failure because the # enclosing derivation is marked broken. Yeah. Bonkers. # We should just forbid jobsets enclosed by derivations. else if lib.isDerivation value && !value.meta.available then [] else if !(lib.isAttrs value) then [] else if (value.__attrsFailEvaluation or false) then [] else lib.pipe value [ (builtins.mapAttrs (name: value: if excluded-attrnames-at-any-depth.${name} or false then [] else (justAttrNames (path ++ [name]) value))) builtins.attrValues builtins.concatLists ]; seq = builtins.deepSeq attempt attempt; tried = builtins.tryEval seq; result = if tried.success then tried.value else if enableWarnings && path != [ "AAAAAASomeThingsFailToEvaluate" ] then lib.warn "tryEval failed at: ${lib.concatStringsSep "." path}" [] else []; in if !trace then result else lib.trace "** ${lib.concatStringsSep "." path}" result; unfiltered = import ./release-outpaths.nix { inherit checkMeta; attrNamesOnly = true; inherit path; }; filtered = lib.pipe unfiltered [ (pkgs: builtins.removeAttrs pkgs (builtins.attrNames excluded-toplevel-attrs)) ]; paths = [ # I am not entirely sure why these three packages end up in # the Hydra jobset. But they do, and they don't meet the # criteria above, so at the moment they are special-cased. [ "pkgsLLVM" "stdenv" ] [ "pkgsStatic" "stdenv" ] [ "pkgsMusl" "stdenv" ] ] ++ justAttrNames [] filtered; names = map (path: (lib.concatStringsSep "." path)) paths; in { inherit paths names; }