mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-07-06 17:13:24 -05:00
[Backport release-26.05] Allow meta.problems while preventing internal use of certain kinds (#535859)
This commit is contained in:
commit
3a45106ee8
12 changed files with 333 additions and 171 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
128
ci/eval/pre-eval.nix
Normal file
128
ci/eval/pre-eval.nix
Normal file
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
@ -50,6 +50,7 @@ let
|
|||
inherit (import ./problems.nix { inherit lib; })
|
||||
problemsType
|
||||
genCheckProblems
|
||||
completeMetaProblems
|
||||
;
|
||||
checkProblems = genCheckProblems config;
|
||||
|
||||
|
|
@ -639,6 +640,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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<removal,deprecated,broken>. 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<broken,deprecated,removal>. You can specify an explicit problem kind with `a.meta.problems.invalid.kind`
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -316,6 +316,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.
|
||||
|
|
@ -331,6 +357,7 @@ let
|
|||
aliases
|
||||
variants
|
||||
configOverrides
|
||||
internallyDisallowedAttrPathsOverlay
|
||||
]
|
||||
++ overlays
|
||||
++ [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue