diff --git a/lib/attrsets.nix b/lib/attrsets.nix index a88947b45858..7a3df9059c08 100644 --- a/lib/attrsets.nix +++ b/lib/attrsets.nix @@ -4,7 +4,7 @@ let inherit (builtins) head tail length; inherit (lib.trivial) id; - inherit (lib.strings) concatStringsSep sanitizeDerivationName; + inherit (lib.strings) concatStringsSep concatMapStringsSep escapeNixIdentifier sanitizeDerivationName; inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all; in @@ -477,6 +477,20 @@ rec { overrideExisting = old: new: mapAttrs (name: value: new.${name} or value) old; + /* Turns a list of strings into a human-readable description of those + strings represented as an attribute path. The result of this function is + not intended to be machine-readable. + + Example: + showAttrPath [ "foo" "10" "bar" ] + => "foo.\"10\".bar" + showAttrPath [] + => "" + */ + showAttrPath = path: + if path == [] then "" + else concatMapStringsSep "." escapeNixIdentifier path; + /* Get a package output. If no output is found, fallback to `.out` and then to the default. diff --git a/lib/default.nix b/lib/default.nix index 3fead03a4636..6e5465bc003e 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -78,7 +78,7 @@ let mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond genAttrs isDerivation toDerivation optionalAttrs zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil - recursiveUpdate matchAttrs overrideExisting getOutput getBin + recursiveUpdate matchAttrs overrideExisting showAttrPath getOutput getBin getLib getDev getMan chooseDevOutputs zipWithNames zip recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets; inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1 diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 5fa95828df69..c4a34369f50f 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -761,4 +761,26 @@ runTests { { a = 3; b = 30; c = 300; } ]; }; + + # The example from the showAttrPath documentation + testShowAttrPathExample = { + expr = showAttrPath [ "foo" "10" "bar" ]; + expected = "foo.\"10\".bar"; + }; + + testShowAttrPathEmpty = { + expr = showAttrPath []; + expected = ""; + }; + + testShowAttrPathVarious = { + expr = showAttrPath [ + "." + "foo" + "2" + "a2-b" + "_bc'de" + ]; + expected = "\".\".foo.\"2\".a2-b._bc'de"; + }; }