diff --git a/doc/default.nix b/doc/default.nix index 26aae9efa573..bcbc20b9f983 100644 --- a/doc/default.nix +++ b/doc/default.nix @@ -25,6 +25,7 @@ let { name = "gvariant"; description = "GVariant formatted string serialization functions"; } { name = "customisation"; description = "Functions to customise (derivation-related) functions, derivatons, or attribute sets"; } { name = "meta"; description = "functions for derivation metadata"; } + { name = "derivations"; description = "miscellaneous derivation-specific functions"; } ]; }; diff --git a/lib/default.nix b/lib/default.nix index f6c94ae91634..a17307be6e07 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -116,7 +116,7 @@ let inherit (self.customisation) overrideDerivation makeOverridable callPackageWith callPackagesWith extendDerivation hydraJob makeScope makeScopeWithSplicing makeScopeWithSplicing'; - inherit (self.derivations) lazyDerivation; + inherit (self.derivations) lazyDerivation optionalDrvAttr; inherit (self.meta) addMetaAttrs dontDistribute setName updateName appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio hiPrioSet getLicenseFromSpdxId getExe getExe'; diff --git a/lib/derivations.nix b/lib/derivations.nix index 5b7ed1868e86..44b727ee31cc 100644 --- a/lib/derivations.nix +++ b/lib/derivations.nix @@ -98,4 +98,30 @@ in # `lazyDerivation` caller knew a shortcut, be taken from there. meta = args.meta or checked.meta; } // 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; } diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 3059878ba069..193e68a96933 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -1902,7 +1902,7 @@ runTests { expected = true; }; - # lazyDerivation + # DERIVATIONS testLazyDerivationIsLazyInDerivationForAttrNames = { expr = attrNames (lazyDerivation { @@ -1955,6 +1955,24 @@ runTests { 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 = { expr = (with types; int).description; expected = "signed integer";