New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nixos/nixpkgs: add override/merging capabilities from the module system to the nixpkgs.config
option
#80582
nixos/nixpkgs: add override/merging capabilities from the module system to the nixpkgs.config
option
#80582
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,32 +14,57 @@ let | |
then f x | ||
else f; | ||
|
||
mergeConfig = lhs_: rhs_: | ||
let | ||
lhs = optCall lhs_ { inherit pkgs; }; | ||
rhs = optCall rhs_ { inherit pkgs; }; | ||
in | ||
recursiveUpdate lhs rhs // | ||
optionalAttrs (lhs ? packageOverrides) { | ||
packageOverrides = pkgs: | ||
optCall lhs.packageOverrides pkgs // | ||
optCall (attrByPath ["packageOverrides"] ({}) rhs) pkgs; | ||
} // | ||
optionalAttrs (lhs ? perlPackageOverrides) { | ||
perlPackageOverrides = pkgs: | ||
optCall lhs.perlPackageOverrides pkgs // | ||
optCall (attrByPath ["perlPackageOverrides"] ({}) rhs) pkgs; | ||
}; | ||
|
||
configType = mkOptionType { | ||
mergableConfigType = mkOptionType { | ||
name = "nixpkgs-config"; | ||
description = "nixpkgs config"; | ||
check = x: | ||
let traceXIfNot = c: | ||
if c x then true | ||
else lib.traceSeqN 1 x false; | ||
in traceXIfNot isConfig; | ||
merge = args: fold (def: mergeConfig def.value) {}; | ||
check = isConfig; | ||
merge = loc: defs: | ||
let | ||
# Ensure that each attribute from nixpkgs.config appears at the | ||
# first iteration to make sure that nothing is lost. | ||
allValues = fold recursiveUpdate {} defs; | ||
|
||
# Recurses through the `config` attr-set for nixpkgs and ensures that | ||
# no conflicting definitions exist and that overrides are resolved properly. | ||
mapFun = path: value: | ||
if isAttrs value && !(value ? _type) then value | ||
else let | ||
# Evaluate mkIf/mkMerge with `lib.dischargeProperties` and append the | ||
# value to the list of declarations. If a value is `null`, it means that | ||
# it was not declared in one of the configs and can be ignored. | ||
appendVal = all: value_: next: | ||
let | ||
# FIXME support `mkMerge [{ snens = mkIf cond val; }]` | ||
discharged = dischargeProperties value_; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned in the comment, |
||
# FIXME check if there's a case where `discharged` is `[]` and | ||
# therefore breaks `head`. | ||
value = let h = head discharged; in if isAttrs h | ||
then foldl recursiveUpdate {} discharged | ||
else h; | ||
in all ++ (if value == null then [] else [{ | ||
inherit (next) file; | ||
inherit value; | ||
}]); | ||
|
||
# Gather all declarations of a value in the `nixpkgs.config` attr-set. | ||
allDeclarations = foldl | ||
(all: next: appendVal all (optCall (attrByPath path null next) finalPkgs) next) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
[] | ||
defs; | ||
|
||
# Evaluate all overrides (defined using mkOverride/mkForce/etc) and pick the | ||
# value with the highes priority. | ||
result = sortProperties (filterOverrides allDeclarations); | ||
|
||
# Merge all declarations (if a list or an attr-set is given, those can be merged together), | ||
# if a "unique" value is given, it's ensured that no conflicting definitions exist. | ||
# | ||
# FIXME This is missing support for separatedString! | ||
merge = let h = (head result).value or null; in | ||
if isList h || isAttrs h then mergeDefaultOption else mergeOneOption; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned in the comment, |
||
in | ||
merge (["nixpkgs" "config"] ++ (tail path)) result; | ||
in mapAttrsRecursiveCond (x: !(x ? _type)) mapFun allValues; | ||
}; | ||
|
||
overlayType = mkOptionType { | ||
|
@@ -113,7 +138,7 @@ in | |
'' | ||
{ allowBroken = true; allowUnfree = true; } | ||
''; | ||
type = configType; | ||
type = mergableConfigType; | ||
description = '' | ||
The configuration of the Nix Packages collection. (For | ||
details, see the Nixpkgs documentation.) It allows you to set | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm aware that this is a gross hack to make sure that any attr-names that are defined in any moduel taken into account is known to the merger. Are there any suggestions for a better workaround? :)