diff --git a/ci/eval/attrpaths.nix b/ci/eval/attrpaths.nix deleted file mode 100644 index ff1bdabbb3505..0000000000000 --- a/ci/eval/attrpaths.nix +++ /dev/null @@ -1,85 +0,0 @@ -# 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. -# -# This expression runs single-threaded under all current Nix -# implementations, but much faster and with much less memory -# used than ./outpaths.nix itself. -# -# Once you have the list of attrnames you can split it up into -# $NUM_CORES batches and evaluate the outpaths separately for each -# batch, in parallel. -# -# To dump the attrnames: -# -# nix-instantiate --eval --strict --json ci/eval/attrpaths.nix -A names -# -{ - lib ? import (path + "/lib"), - trace ? false, - path ? ./../.., - extraNixpkgsConfigJson ? "{}", -}: -let - - # TODO: Use mapAttrsToListRecursiveCond when this PR lands: - # https://github.com/NixOS/nixpkgs/pull/395160 - justAttrNames = - path: value: - let - result = - if path == [ "AAAAAASomeThingsFailToEvaluate" ] || !(lib.isAttrs value) then - [ ] - else if lib.isDerivation value then - [ path ] - else - lib.pipe value [ - (lib.mapAttrsToList ( - name: value: - lib.addErrorContext "while evaluating package set attribute path '${ - lib.showAttrPath (path ++ [ name ]) - }'" (justAttrNames (path ++ [ name ]) value) - )) - lib.concatLists - ]; - in - lib.traceIf trace "** ${lib.showAttrPath path}" result; - - outpaths = import ./outpaths.nix { - inherit path; - extraNixpkgsConfig = builtins.fromJSON extraNixpkgsConfigJson; - attrNamesOnly = true; - }; - - paths = [ - # Some of the following are based on variants, which are disabled with `attrNamesOnly = true`. - # Until these have been removed from release.nix / hydra, we manually add them to the list. - [ - "pkgsLLVM" - "stdenv" - ] - [ - "pkgsArocc" - "stdenv" - ] - [ - "pkgsZig" - "stdenv" - ] - [ - "pkgsStatic" - "stdenv" - ] - [ - "pkgsMusl" - "stdenv" - ] - ] - ++ justAttrNames [ ] outpaths; - - names = map lib.showAttrPath paths; - -in -{ - inherit paths names; -} diff --git a/ci/eval/chunk.nix b/ci/eval/chunk.nix index e1759c2c6615f..9bea26ce31805 100644 --- a/ci/eval/chunk.nix +++ b/ci/eval/chunk.nix @@ -2,8 +2,8 @@ { lib ? import ../../lib, path ? ../.., - # The file containing all available attribute paths, which are split into chunks here - attrpathFile, + # The file containing the preEval result + preEvalFile, chunkSize, myChunk, includeBroken, @@ -12,12 +12,13 @@ }: let - attrpaths = lib.importJSON attrpathFile; - myAttrpaths = lib.sublist (chunkSize * myChunk) chunkSize attrpaths; + preEvalResult = lib.importJSON preEvalFile; + myAttrpaths = lib.sublist (chunkSize * myChunk) chunkSize preEvalResult.paths; unfiltered = import ./outpaths.nix { inherit path; inherit includeBroken systems; + inherit (preEvalResult) attrPathsDisallowedForInternalUse; extraNixpkgsConfig = builtins.fromJSON extraNixpkgsConfigJson; }; diff --git a/ci/eval/default.nix b/ci/eval/default.nix index 2e8bec41ca5d3..547fcf1f26be0 100644 --- a/ci/eval/default.nix +++ b/ci/eval/default.nix @@ -38,7 +38,7 @@ let fileset = unions ( map (lib.path.append ../..) [ ".version" - "ci/eval/attrpaths.nix" + "ci/eval/pre-eval.nix" "ci/eval/chunk.nix" "ci/eval/outpaths.nix" "default.nix" @@ -56,11 +56,11 @@ let builtins.readFile ../../pkgs/top-level/release-supported-systems.json ); - attrpathsSuperset = + preEval = { evalSystem, }: - runCommand "attrpaths-superset.json" + runCommand "pre-eval" { src = nixpkgs; # Don't depend on -dev outputs to reduce closure size for CI. @@ -73,15 +73,15 @@ let export NIX_STATE_DIR=$(mktemp -d) mkdir $out export GC_INITIAL_HEAP_SIZE=4g - command time -f "Attribute eval done [%MKB max resident, %Es elapsed] %C" \ + command time -f "Pre-eval done [%MKB max resident, %Es elapsed] %C" \ nix-instantiate --eval --strict --json --show-trace \ - "$src/ci/eval/attrpaths.nix" \ - -A paths \ + "$src/ci/eval/pre-eval.nix" \ + -A result \ -I "$src" \ --argstr extraNixpkgsConfigJson ${lib.escapeShellArg (builtins.toJSON extraNixpkgsConfig)} \ --option restrict-eval true \ --option allow-import-from-derivation false \ - --option eval-system "${evalSystem}" > $out/paths.json + --option eval-system "${evalSystem}" > $out/result.json ''; singleSystem = @@ -90,8 +90,8 @@ let # Note that this is intentionally not called `system`, # because `--argstr system` would only be passed to the ci/default.nix file! evalSystem ? builtins.currentSystem, - # The path to the `paths.json` file from `attrpathsSuperset` - attrpathFile ? "${attrpathsSuperset { inherit evalSystem; }}/paths.json", + # The path to the `result.json` file from `preEval` + preEvalFile ? "${preEval { inherit evalSystem; }}/result.json", }: let singleChunk = writeShellScript "single-chunk" '' @@ -121,12 +121,12 @@ let --show-trace \ --arg chunkSize "$chunkSize" \ --arg myChunk "$myChunk" \ - --arg attrpathFile "${attrpathFile}" \ + --arg preEvalFile "${preEvalFile}" \ --arg systems "[ \"$system\" ]" \ --arg includeBroken ${lib.boolToString includeBroken} \ --argstr extraNixpkgsConfigJson ${lib.escapeShellArg (builtins.toJSON extraNixpkgsConfig)} \ -I ${nixpkgs} \ - -I ${attrpathFile} \ + -I ${preEvalFile} \ > "$outputDir/result/$myChunk" \ 2> "$outputDir/stderr/$myChunk" exitCode=$? @@ -164,7 +164,7 @@ let echo "System: $evalSystem" cores=$NIX_BUILD_CORES echo "Cores: $cores" - attrCount=$(jq length "${attrpathFile}") + attrCount=$(jq '.paths | length' "${preEvalFile}") echo "Attribute count: $attrCount" echo "Chunk size: $chunkSize" # Same as `attrCount / chunkSize` but rounded up @@ -316,7 +316,7 @@ let in { inherit - attrpathsSuperset + preEval singleSystem diff combine diff --git a/ci/eval/outpaths.nix b/ci/eval/outpaths.nix index afbce48f33213..512290ce450a8 100755 --- a/ci/eval/outpaths.nix +++ b/ci/eval/outpaths.nix @@ -6,7 +6,7 @@ includeBroken ? true, # set this to false to exclude meta.broken packages from the output path ? ./../.., - # used by ./attrpaths.nix + # used by ./pre-eval.nix attrNamesOnly ? false, # Set this to `null` to build for builtins.currentSystem only @@ -14,6 +14,8 @@ builtins.readFile (path + "/pkgs/top-level/release-supported-systems.json") ), + attrPathsDisallowedForInternalUse ? [ ], + # Customize the config used to evaluate nixpkgs extraNixpkgsConfig ? { }, }: @@ -35,6 +37,22 @@ let allowVariants = !attrNamesOnly; checkMeta = true; + # We don't need to care about problems being caught using the + # standard mechanism, because any problems whose kind is not + # nixpkgsInternalUseAllowed cause the corresponding attributes to + # be disallowed entirely for internal use with + # attrPathsDisallowedForInternalUse, see also ./pre-eval.nix + problems.matchers = lib.mkForce [ + # We only need to set the broken handler to error, so that CI + # doesn't evaluate those. No reason it couldn't evaluate them + # afaik, but this is how it's been before. + { + kind = "broken"; + handler = "error"; + } + ]; + inherit attrPathsDisallowedForInternalUse; + # Silence the `x86_64-darwin` deprecation warning. allowDeprecatedx86_64Darwin = true; diff --git a/ci/eval/pre-eval.nix b/ci/eval/pre-eval.nix new file mode 100644 index 0000000000000..eff8204a7bd52 --- /dev/null +++ b/ci/eval/pre-eval.nix @@ -0,0 +1,128 @@ +# This file does a fast pre-evaluation of Nixpkgs to determine: +# - paths: A *superset* of all attrpaths of derivations which might be part of a release on *any* platform. +# - attrPathsDisallowedForInternalUse: Attribute paths whose meta.problems has problems whose kinds should not be used internally in Nixpkgs +# +# This expression runs single-threaded under all current Nix +# implementations, but much faster and with much less memory +# used than ./outpaths.nix itself. +# +# Once you have the list of attrnames you can split it up into +# $NUM_CORES batches and evaluate the outpaths separately for each +# batch, in parallel. +# +# To dump the result: +# +# nix-instantiate --eval --strict --json ci/eval/pre-eval.nix -A result +# +{ + lib ? import (path + "/lib"), + trace ? false, + path ? ./../.., + extraNixpkgsConfigJson ? "{}", +}: +let + + # TODO: Use mapAttrsToListRecursiveCond when this PR lands: + # https://github.com/NixOS/nixpkgs/pull/395160 + listAttrs = + path: value: + let + result = + if path == [ "AAAAAASomeThingsFailToEvaluate" ] || !(lib.isAttrs value) then + [ ] + else if lib.isDerivation value then + [ + { + inherit path value; + } + ] + else + lib.pipe value [ + (lib.mapAttrsToList ( + name: value: + lib.addErrorContext "while evaluating package set attribute path '${ + lib.showAttrPath (path ++ [ name ]) + }'" (listAttrs (path ++ [ name ]) value) + )) + lib.concatLists + ]; + in + lib.traceIf trace "** ${lib.showAttrPath path}" result; + + outpaths = import ./outpaths.nix { + inherit path; + extraNixpkgsConfig = builtins.fromJSON extraNixpkgsConfigJson; + attrNamesOnly = true; + }; + + list = + map + (path: { + inherit path; + # This looks a bit weird, but the only reason we care about this value + # is for the meta.problems check below, and stdenv's certainly don't + # have any problems, so this is fine :) + value = { }; + }) + [ + # Some of the following are based on variants, which are disabled with `attrNamesOnly = true`. + # Until these have been removed from release.nix / hydra, we manually add them to the list. + [ + "pkgsLLVM" + "stdenv" + ] + [ + "pkgsArocc" + "stdenv" + ] + [ + "pkgsZig" + "stdenv" + ] + [ + "pkgsStatic" + "stdenv" + ] + [ + "pkgsMusl" + "stdenv" + ] + ] + ++ listAttrs [ ] outpaths; + paths = map (attrs: attrs.path) list; + names = map lib.showAttrPath paths; + + inherit (import ../../pkgs/stdenv/generic/problems.nix { inherit lib; }) + disallowNixpkgsInternalUseKinds + ; + + # Determine the list of attributes whose packages have any meta.problems + # with a kind that's disallowed from internal Nixpkgs use + attrPathsDisallowedForInternalUse = lib.pipe list [ + (lib.map ( + attrs: + attrs + // { + problematicProblems = builtins.tryEval ( + lib.filterAttrs (name: problem: disallowNixpkgsInternalUseKinds ? ${problem.kind}) ( + attrs.value.meta.problems or { } + ) + ); + } + )) + (lib.filter (attrs: attrs.problematicProblems.success && attrs.problematicProblems.value != { })) + (lib.map (attrs: { + attrPath = attrs.path; + reason = "it has certain meta.problems whose kinds are disallowed: ${ + lib.generators.toPretty { } attrs.problematicProblems.value + }"; + })) + ]; +in +{ + # TODO: Do we still need these? Probably not + inherit paths names; + result = { + inherit paths attrPathsDisallowedForInternalUse; + }; +} diff --git a/pkgs/stdenv/generic/check-meta.nix b/pkgs/stdenv/generic/check-meta.nix index 70c009c3e83ae..071bfba324520 100644 --- a/pkgs/stdenv/generic/check-meta.nix +++ b/pkgs/stdenv/generic/check-meta.nix @@ -49,6 +49,7 @@ let inherit (import ./problems.nix { inherit lib; }) problemsType genCheckProblems + completeMetaProblems ; checkProblems = genCheckProblems config; @@ -670,6 +671,8 @@ let unsupported = hasUnsupportedPlatform' attrs; insecure = isMarkedInsecure attrs; + problems = completeMetaProblems config attrs; + available = validity.valid != "no" && ((config.checkMetaRecursively or false) -> all (d: d.meta.available or true) references); diff --git a/pkgs/stdenv/generic/problems.nix b/pkgs/stdenv/generic/problems.nix index 0f03c393e384a..e21f2126acbe4 100644 --- a/pkgs/stdenv/generic/problems.nix +++ b/pkgs/stdenv/generic/problems.nix @@ -72,68 +72,81 @@ rec { max = a: b: if lessThan a b then b else a; }; - # TODO: Combine this and automaticProblems into a `{ removal = { manual = true; ... }; ... }` structure for less error-prone changes - kinds = rec { - # Automatic and manual problem kinds - known = map (problem: problem.kindName) automaticProblems ++ manual; - # Problem kinds that are currently allowed to be specified in `meta.problems` - manual = [ - "removal" - "deprecated" - "broken" - ]; - # Problem kinds that are currently only allowed to be specified once - unique = [ - "removal" - ]; + kinds = { + maintainerless = { + manualAllowed = false; + isUnique = false; + nixpkgsInternalUseAllowed = true; + automatic = { + condition = + # To get usable output, we want to avoid flagging "internal" derivations. + # Because we do not have a way to reliably decide between internal or + # external derivation, some heuristics are required to decide. + # + # If `outputHash` is defined, the derivation is a FOD, such as the output of a fetcher. + # If `description` is not defined, the derivation is probably not a package. + # Simply checking whether `meta` is defined is insufficient, + # as some fetchers and trivial builders do define meta. + config: attrs: + # Order of checks optimised for short-circuiting the common case of having maintainers + (attrs.meta.maintainers or [ ] == [ ]) + && (attrs.meta.teams or [ ] == [ ]) + && (!attrs ? outputHash) + && (attrs ? meta.description); + value.message = "This package has no declared maintainer, i.e. an empty `meta.maintainers` and `meta.teams` attribute."; + }; + }; + broken = { + manualAllowed = true; + isUnique = false; + nixpkgsInternalUseAllowed = true; + automatic = { + condition = + config: + let + # TODO: Consider deprecating this or making it generic for all problems + allowBroken = config.allowBroken || builtins.getEnv "NIXPKGS_ALLOW_BROKEN" == "1"; - # Same thing but a set with null values (comes in handy at times) - manual' = genAttrs manual (k: null); - unique' = genAttrs unique (k: null); + allowBrokenPredicate = + lib.warnIf (lib.oldestSupportedReleaseIsAtLeast 2605) + "config.allowBrokenPredicate is deprecated, use config.problems.handlers.myPackage.broken = \"warn\" for individual packages instead." + config.allowBrokenPredicate; + in + if allowBroken then + attrs: false + else if config ? allowBrokenPredicate then + attrs: attrs ? meta.broken && attrs.meta.broken && !allowBrokenPredicate attrs + else + attrs: attrs ? meta.broken && attrs.meta.broken; + value.message = "This package is broken."; + }; + }; + removal = { + manualAllowed = true; + isUnique = true; + nixpkgsInternalUseAllowed = false; + automatic = null; + }; + deprecated = { + manualAllowed = true; + isUnique = false; + nixpkgsInternalUseAllowed = false; + automatic = null; + }; }; - automaticProblems = [ - { - kindName = "maintainerless"; - condition = - # To get usable output, we want to avoid flagging "internal" derivations. - # Because we do not have a way to reliably decide between internal or - # external derivation, some heuristics are required to decide. - # - # If `outputHash` is defined, the derivation is a FOD, such as the output of a fetcher. - # If `description` is not defined, the derivation is probably not a package. - # Simply checking whether `meta` is defined is insufficient, - # as some fetchers and trivial builders do define meta. - config: attrs: - # Order of checks optimised for short-circuiting the common case of having maintainers - (attrs.meta.maintainers or [ ] == [ ]) - && (attrs.meta.teams or [ ] == [ ]) - && (!attrs ? outputHash) - && (attrs ? meta.description); - value.message = "This package has no declared maintainer, i.e. an empty `meta.maintainers` and `meta.teams` attribute."; - } - { - kindName = "broken"; - condition = - config: - let - # TODO: Consider deprecating this or making it generic for all problems - allowBroken = config.allowBroken || builtins.getEnv "NIXPKGS_ALLOW_BROKEN" == "1"; + # Problem kinds that are currently allowed to be specified in `meta.problems` + manualKinds = lib.filterAttrs (name: value: value.manualAllowed) kinds; + # Problem kinds that are currently only allowed to be specified once + uniqueKinds = lib.filterAttrs (name: value: value.isUnique) kinds; - allowBrokenPredicate = - lib.warnIf (lib.oldestSupportedReleaseIsAtLeast 2605) - "config.allowBrokenPredicate is deprecated, use config.problems.handlers.myPackage.broken = \"warn\" for individual packages instead." - config.allowBrokenPredicate; - in - if allowBroken then - attrs: false - else if config ? allowBrokenPredicate then - attrs: attrs ? meta.broken && attrs.meta.broken && !allowBrokenPredicate attrs - else - attrs: attrs ? meta.broken && attrs.meta.broken; - value.message = "This package is broken."; - } - ]; + disallowNixpkgsInternalUseKinds = lib.filterAttrs ( + name: value: !value.nixpkgsInternalUseAllowed + ) kinds; + + automaticProblems = lib.mapAttrsToList (name: value: value.automatic // { kindName = name; }) ( + lib.filterAttrs (name: value: value.automatic != null) kinds + ); genAutomaticProblems = config: attrs: @@ -148,7 +161,7 @@ rec { let types = lib.types; handlerType = types.enum handlers.levels; - problemKindType = types.enum kinds.known; + problemKindType = types.enum (attrNames kinds); in { handlers = lib.mkOption { @@ -250,7 +263,8 @@ rec { record enum ; - kindType = enum kinds.manual; + # While we should only allow manual kinds, we need to allow `meta.problems = otherPackage.meta.problems`, which includes automatic ones as well + kindType = enum (attrNames kinds); subRecord = record { kind = kindType; message = str; @@ -270,7 +284,7 @@ rec { let kindGroups = groupBy (kind: kind) (mapAttrsToList (name: problem: problem.kind or name) v); in - all (kind: kinds.manual' ? ${kind} && (kinds.unique' ? ${kind} -> length kindGroups.${kind} == 1)) ( + all (kind: kinds ? ${kind} && (uniqueKinds ? ${kind} -> length kindGroups.${kind} == 1)) ( attrNames kindGroups ) ); @@ -294,14 +308,14 @@ rec { ++ concatLists ( mapAttrsToList ( kind: kindGroup: - optionals (!kinds.manual' ? ${kind}) ( + optionals (!kinds ? ${kind}) ( map ( el: "${ctx}.${el.name}: Problem kind ${kind}, inferred from the problem name, is invalid; expected ${kindType.name}. You can specify an explicit problem kind with `${ctx}.${el.name}.kind`" ) (filter (el: !el.explicit) kindGroup) ) ++ - optional (kinds.unique' ? ${kind} && length kindGroup > 1) + optional (uniqueKinds ? ${kind} && length kindGroup > 1) "${ctx}: Problem kind ${kind} should be unique, but is used for these problems: ${ concatMapStringsSep ", " (el: el.name) kindGroup }" @@ -510,6 +524,12 @@ rec { in processProblems pname problemsToHandle; + completeMetaProblems = + config: attrs: + mapAttrs (name: problem: { kind = name; } // problem) ( + (attrs.meta.problems or { }) // genAutomaticProblems config attrs + ); + processProblems = pname: problemsToHandle: let diff --git a/pkgs/test/problems/cases/invalid-kind-error/expected-stderr b/pkgs/test/problems/cases/invalid-kind-error/expected-stderr index 07c5a38e1bcb7..6fdf2b1d04b19 100644 --- a/pkgs/test/problems/cases/invalid-kind-error/expected-stderr +++ b/pkgs/test/problems/cases/invalid-kind-error/expected-stderr @@ -1,4 +1,4 @@ (stack trace truncated; use '--show-trace' to show the full, detailed trace) error: Refusing to evaluate package 'a-0' in /nix/store/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-default.nix:11 because it has an invalid meta attrset: - - a.meta.problems.invalid: Problem kind invalid, inferred from the problem name, is invalid; expected enum. You can specify an explicit problem kind with `a.meta.problems.invalid.kind` + - a.meta.problems.invalid: Problem kind invalid, inferred from the problem name, is invalid; expected enum. You can specify an explicit problem kind with `a.meta.problems.invalid.kind` diff --git a/pkgs/top-level/config.nix b/pkgs/top-level/config.nix index f2066315efb5e..de13c0a29993d 100644 --- a/pkgs/top-level/config.nix +++ b/pkgs/top-level/config.nix @@ -58,6 +58,34 @@ let internal = true; }; + attrPathsDisallowedForInternalUse = mkOption { + type = types.listOf ( + types.submodule { + options.attrPath = lib.mkOption { + type = types.listOf types.str; + description = '' + Attribute path to disallow. + ''; + }; + options.reason = lib.mkOption { + type = types.nullOr types.str; + default = null; + example = /* because */ "it's dangerous."; + description = '' + Reason for it being disallowed. + ''; + }; + } + ); + internal = true; + default = [ ]; + description = '' + List of attribute paths that may not be used by other packages in Nixpkgs. + + Should usually only be defined by Nixpkgs CI. + ''; + }; + # Config options warnUndeclaredOptions = mkOption { diff --git a/pkgs/top-level/default.nix b/pkgs/top-level/default.nix index 443496f650fb6..4e19941441daf 100644 --- a/pkgs/top-level/default.nix +++ b/pkgs/top-level/default.nix @@ -214,7 +214,29 @@ let ; }; - pkgs = boot stages; + fixedPoint = boot stages; + + pkgs = + # Generally only set by CI, don't want to cause a performance hit for users + if config.attrPathsDisallowedForInternalUse == [ ] then + fixedPoint + else + # See ./stage.nix, which replaced config.attrPathsDisallowedForInternalUse with aborts. + # We replace these attribute paths with their original derivations again, + # because CI would just error out from the aborting attributes themselves. + # Internally all packages still see the aborting attributes if used as dependencies, + # because we do this here after the fixed-point is calculated. + # Note that we don't want to remove the attributes entirely like what aliases.nix does, + # because unlike aliases, CI still needs to check the packages to evaluate at all, + # which it wouldn't if they're removed entirely. + lib.updateManyAttrsByPath + (map (attrs: { + path = attrs.attrPath; + update = + _: + lib.getAttrFromPath attrs.attrPath fixedPoint.__internalBeforeInternallyDisallowedAttrPathsOverlay; + }) config.attrPathsDisallowedForInternalUse) + (removeAttrs fixedPoint [ "__internalBeforeInternallyDisallowedAttrPathsOverlay" ]); in checked pkgs diff --git a/pkgs/top-level/nixpkgs-basic-release-checks.nix b/pkgs/top-level/nixpkgs-basic-release-checks.nix index 1c7e606559857..e10d6f5e1ed24 100644 --- a/pkgs/top-level/nixpkgs-basic-release-checks.nix +++ b/pkgs/top-level/nixpkgs-basic-release-checks.nix @@ -56,7 +56,7 @@ pkgs.runCommand "nixpkgs-release-checks" set -x nix-env -f $src \ --show-trace --argstr system "$platform" \ - --arg config '{ allowAliases = false; allowDeprecatedx86_64Darwin = true; }' \ + --arg config '{ lib, pkgs }: { problems.matchers = lib.mkForce [ ]; allowAliases = false; allowDeprecatedx86_64Darwin = true; }' \ --option lint-url-literals fatal \ -qa --drv-path --system-filter \* --system \ "''${opts[@]}" 2> eval-warnings.log > packages1 @@ -72,7 +72,7 @@ pkgs.runCommand "nixpkgs-release-checks" nix-env -f $src2 \ --show-trace --argstr system "$platform" \ - --arg config '{ allowAliases = false; allowDeprecatedx86_64Darwin = true; }' \ + --arg config '{ lib, pkgs }: { problems.matchers = lib.mkForce [ ]; allowAliases = false; allowDeprecatedx86_64Darwin = true; }' \ --option lint-url-literals fatal \ -qa --drv-path --system-filter \* --system \ "''${opts[@]}" > packages2 @@ -95,7 +95,7 @@ pkgs.runCommand "nixpkgs-release-checks" nix-env -f $src \ --show-trace --argstr system "$platform" \ - --arg config '{ allowAliases = false; allowDeprecatedx86_64Darwin = true; }' \ + --arg config '{ lib, pkgs }: { problems.matchers = lib.mkForce [ ]; allowAliases = false; allowDeprecatedx86_64Darwin = true; }' \ --option lint-url-literals fatal \ -qa --drv-path --system-filter \* --system --meta --xml \ "''${opts[@]}" > /dev/null diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index 4b0abd0361c6c..bc50a3f24247e 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -309,6 +309,32 @@ let }; }; + # Replaces the attributes in config.attrPathsDisallowedForInternalUse with aborts. + # Not throws because those would be ignored by nix-env, which is what CI uses to evaluate everything + # See also ./default.nix, where these attributes are added back again so they're still checked by CI + internallyDisallowedAttrPathsOverlay = + final: prev: + # Generally only set by CI, don't want to cause a performance hit for users + if config.attrPathsDisallowedForInternalUse == [ ] then + { } + else + { + # So that ./default.nix can add them back again outside the fixed point + # Don't use this in packages! + __internalBeforeInternallyDisallowedAttrPathsOverlay = prev; + } + // lib.updateManyAttrsByPath (map ( + { attrPath, reason }: + { + path = attrPath; + update = + _: + abort "${lib.concatStringsSep "." attrPath} is disallowed from being used within Nixpkgs${ + lib.optionalString (reason != null) ", because ${reason}" + }"; + } + ) config.attrPathsDisallowedForInternalUse) prev; + # The complete chain of package set builders, applied from top to bottom. # stdenvOverlays must be last as it brings package forward from the # previous bootstrapping phases which have already been overlaid. @@ -324,6 +350,7 @@ let aliases variants configOverrides + internallyDisallowedAttrPathsOverlay ] ++ overlays ++ [