lib: Add optionalDrvAttr to conditionally set drv attributes.

This allows for adding new, conditionally set, derivation attributes
to an existing derivation without changing any output paths in the
case where the condition is not met.
This commit is contained in:
Shea Levy 2024-01-30 17:29:47 -05:00
parent 5b5e6f9900
commit ca1262a483
No known key found for this signature in database
GPG key ID: 5C0BD6957D86FE27
4 changed files with 47 additions and 2 deletions

View file

@ -25,6 +25,7 @@ let
{ name = "gvariant"; description = "GVariant formatted string serialization functions"; } { name = "gvariant"; description = "GVariant formatted string serialization functions"; }
{ name = "customisation"; description = "Functions to customise (derivation-related) functions, derivatons, or attribute sets"; } { name = "customisation"; description = "Functions to customise (derivation-related) functions, derivatons, or attribute sets"; }
{ name = "meta"; description = "functions for derivation metadata"; } { name = "meta"; description = "functions for derivation metadata"; }
{ name = "derivations"; description = "miscellaneous derivation-specific functions"; }
]; ];
}; };

View file

@ -116,7 +116,7 @@ let
inherit (self.customisation) overrideDerivation makeOverridable inherit (self.customisation) overrideDerivation makeOverridable
callPackageWith callPackagesWith extendDerivation hydraJob callPackageWith callPackagesWith extendDerivation hydraJob
makeScope makeScopeWithSplicing makeScopeWithSplicing'; makeScope makeScopeWithSplicing makeScopeWithSplicing';
inherit (self.derivations) lazyDerivation; inherit (self.derivations) lazyDerivation optionalDrvAttr;
inherit (self.meta) addMetaAttrs dontDistribute setName updateName inherit (self.meta) addMetaAttrs dontDistribute setName updateName
appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio
hiPrioSet getLicenseFromSpdxId getExe getExe'; hiPrioSet getLicenseFromSpdxId getExe getExe';

View file

@ -98,4 +98,30 @@ in
# `lazyDerivation` caller knew a shortcut, be taken from there. # `lazyDerivation` caller knew a shortcut, be taken from there.
meta = args.meta or checked.meta; meta = args.meta or checked.meta;
} // passthru; } // passthru;
/* Conditionally set a derivation attribute.
Because `mkDerivation` sets `__ignoreNulls = true`, a derivation
attribute set to `null` will not impact the derivation output hash.
Thus, this function passes through its `value` argument if the `cond`
is `true`, but returns `null` if not.
Type: optionalDrvAttr :: Bool -> a -> a | Null
Example:
(stdenv.mkDerivation {
name = "foo";
x = optionalDrvAttr true 1;
y = optionalDrvAttr false 1;
}).drvPath == (stdenv.mkDerivation {
name = "foo";
x = 1;
}).drvPath
=> true
*/
optionalDrvAttr =
# Condition
cond:
# Attribute value
value: if cond then value else null;
} }

View file

@ -1902,7 +1902,7 @@ runTests {
expected = true; expected = true;
}; };
# lazyDerivation # DERIVATIONS
testLazyDerivationIsLazyInDerivationForAttrNames = { testLazyDerivationIsLazyInDerivationForAttrNames = {
expr = attrNames (lazyDerivation { expr = attrNames (lazyDerivation {
@ -1955,6 +1955,24 @@ runTests {
expected = derivation; expected = derivation;
}; };
testOptionalDrvAttr = let
mkDerivation = args: derivation (args // {
builder = "builder";
system = "system";
__ignoreNulls = true;
});
in {
expr = (mkDerivation {
name = "foo";
x = optionalDrvAttr true 1;
y = optionalDrvAttr false 1;
}).drvPath;
expected = (mkDerivation {
name = "foo";
x = 1;
}).drvPath;
};
testTypeDescriptionInt = { testTypeDescriptionInt = {
expr = (with types; int).description; expr = (with types; int).description;
expected = "signed integer"; expected = "signed integer";