From ca4beaaf1cf89deb630987361fa824c785c894f3 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Sun, 20 Jul 2025 12:34:42 +0200 Subject: [PATCH] lib: Add splice structure utilities --- lib/customisation.nix | 121 ++++++++++++++++++++++++++++++++++++++++++ lib/default.nix | 3 ++ lib/tests/misc.nix | 78 +++++++++++++++++++++++++++ 3 files changed, 202 insertions(+) diff --git a/lib/customisation.nix b/lib/customisation.nix index 16f248cd1b20..a20b352dfdf4 100644 --- a/lib/customisation.nix +++ b/lib/customisation.nix @@ -863,4 +863,125 @@ rec { transformDrv ; }; + + /** + Removes a prefix from the attribute names of a set of splices. + + # Inputs + + `prefix` + : The prefix to remove from splice attribute names + + `splices` + : A set of splices with prefixed names + + # Type + + ``` + renameSplicesFrom :: String -> AttrSet -> AttrSet + ``` + + # Examples + + :::{.example} + ## `lib.customisation.renameSplicesFrom` usage example + + ```nix + renameSplicesFrom "pkgs" { pkgsBuildBuild = ...; pkgsBuildHost = ...; ... } + => { buildBuild = ...; buildHost = ...; ... } + ``` + ::: + */ + renameSplicesFrom = prefix: x: { + buildBuild = x."${prefix}BuildBuild"; + buildHost = x."${prefix}BuildHost"; + buildTarget = x."${prefix}BuildTarget"; + hostHost = x."${prefix}HostHost"; + hostTarget = x."${prefix}HostTarget"; + targetTarget = x."${prefix}TargetTarget"; + }; + + /** + Adds a prefix to the attribute names of a set of splices. + + # Inputs + + `prefix` + : The prefix to add to splice attribute names + + `splices` + : A set of splices to be prefixed + + # Type + + ``` + renameSplicesTo :: String -> AttrSet -> AttrSet + ``` + + # Examples + + :::{.example} + ## `lib.customisation.renameSplicesTo` usage example + + ```nix + renameSplicesTo "self" { buildBuild = ...; buildHost = ...; ... } + => { selfBuildBuild = ...; selfBuildHost = ...; ... } + ``` + ::: + */ + renameSplicesTo = prefix: x: { + "${prefix}BuildBuild" = x.buildBuild; + "${prefix}BuildHost" = x.buildHost; + "${prefix}BuildTarget" = x.buildTarget; + "${prefix}HostHost" = x.hostHost; + "${prefix}HostTarget" = x.hostTarget; + "${prefix}TargetTarget" = x.targetTarget; + }; + + /** + Takes a function and applies it pointwise to each splice. + + # Inputs + + `f` + : Function to apply to each splice value + + `splices` + : A set of splices to transform + + # Type + + ``` + mapSplices :: (a -> b) -> AttrSet -> AttrSet + ``` + + # Examples + + :::{.example} + ## `lib.customisation.mapSplices` usage example + + ```nix + mapSplices (x: x * 10) { buildBuild = 1; buildHost = 2; ... } + => { buildBuild = 10; buildHost = 20; ... } + ``` + ::: + */ + mapSplices = + f: + { + buildBuild, + buildHost, + buildTarget, + hostHost, + hostTarget, + targetTarget, + }: + { + buildBuild = f buildBuild; + buildHost = f buildHost; + buildTarget = f buildTarget; + hostHost = f hostHost; + hostTarget = f hostTarget; + targetTarget = f targetTarget; + }; } diff --git a/lib/default.nix b/lib/default.nix index 009140f23047..9b9f8bcba1e8 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -398,6 +398,9 @@ let makeScopeWithSplicing makeScopeWithSplicing' extendMkDerivation + renameSplicesFrom + renameSplicesTo + mapSplices ; inherit (self.derivations) lazyDerivation optionalDrvAttr warnOnInstantiate; inherit (self.generators) mkLuaInline; diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index bb5603de75bd..4f321d2658e3 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -4432,4 +4432,82 @@ runTests { expected = "/non-existent/this/does/not/exist/for/real/please-dont-mess-with-your-local-fs/default.nix"; }; + # Tests for splicing utilities + + testRenameSplicesFrom = { + expr = lib.renameSplicesFrom "pkgs" { + pkgsBuildBuild = "dummy-build-build"; + pkgsBuildHost = "dummy-build-host"; + pkgsBuildTarget = "dummy-build-target"; + pkgsHostHost = "dummy-host-host"; + pkgsHostTarget = "dummy-host-target"; + pkgsTargetTarget = "dummy-target-target"; + }; + expected = { + buildBuild = "dummy-build-build"; + buildHost = "dummy-build-host"; + buildTarget = "dummy-build-target"; + hostHost = "dummy-host-host"; + hostTarget = "dummy-host-target"; + targetTarget = "dummy-target-target"; + }; + }; + + testRenameSplicesTo = { + expr = lib.renameSplicesTo "self" { + buildBuild = "dummy-build-build"; + buildHost = "dummy-build-host"; + buildTarget = "dummy-build-target"; + hostHost = "dummy-host-host"; + hostTarget = "dummy-host-target"; + targetTarget = "dummy-target-target"; + }; + expected = { + selfBuildBuild = "dummy-build-build"; + selfBuildHost = "dummy-build-host"; + selfBuildTarget = "dummy-build-target"; + selfHostHost = "dummy-host-host"; + selfHostTarget = "dummy-host-target"; + selfTargetTarget = "dummy-target-target"; + }; + }; + + testMapSplices = { + expr = lib.mapSplices (x: x * 10) { + buildBuild = 1; + buildHost = 2; + buildTarget = 3; + hostHost = 4; + hostTarget = 5; + targetTarget = 6; + }; + expected = { + buildBuild = 10; + buildHost = 20; + buildTarget = 30; + hostHost = 40; + hostTarget = 50; + targetTarget = 60; + }; + }; + + testMapSplicesString = { + expr = lib.mapSplices (x: "prefix-${x}") { + buildBuild = "bb"; + buildHost = "bh"; + buildTarget = "bt"; + hostHost = "hh"; + hostTarget = "ht"; + targetTarget = "tt"; + }; + expected = { + buildBuild = "prefix-bb"; + buildHost = "prefix-bh"; + buildTarget = "prefix-bt"; + hostHost = "prefix-hh"; + hostTarget = "prefix-ht"; + targetTarget = "prefix-tt"; + }; + }; + }