Merge pull request #126213 from ryantm/lib-doc-gen
doc: auto-generate asserts and attrset library docs
This commit is contained in:
commit
a2b6bd7b35
@ -17,6 +17,8 @@ with pkgs; stdenv.mkDerivation {
|
|||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
ln -s ${locationsXml} $out/locations.xml
|
ln -s ${locationsXml} $out/locations.xml
|
||||||
|
|
||||||
|
docgen asserts 'Assert functions'
|
||||||
|
docgen attrsets 'Attribute-set functions'
|
||||||
docgen strings 'String manipulation functions'
|
docgen strings 'String manipulation functions'
|
||||||
docgen trivial 'Miscellaneous functions'
|
docgen trivial 'Miscellaneous functions'
|
||||||
docgen lists 'List manipulation functions'
|
docgen lists 'List manipulation functions'
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
Nixpkgs provides a standard library at <varname>pkgs.lib</varname>, or through <code>import <nixpkgs/lib></code>.
|
Nixpkgs provides a standard library at <varname>pkgs.lib</varname>, or through <code>import <nixpkgs/lib></code>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<xi:include href="./library/asserts.xml" />
|
|
||||||
|
|
||||||
<xi:include href="./library/attrsets.xml" />
|
|
||||||
|
|
||||||
<!-- These docs are generated via nixdoc. To add another generated
|
<!-- These docs are generated via nixdoc. To add another generated
|
||||||
library function file to this list, the file
|
library function file to this list, the file
|
||||||
`lib-function-docs.nix` must also be updated. -->
|
`lib-function-docs.nix` must also be updated. -->
|
||||||
|
|
||||||
|
<xi:include href="./library/generated/asserts.xml" />
|
||||||
|
|
||||||
|
<xi:include href="./library/generated/attrsets.xml" />
|
||||||
|
|
||||||
<xi:include href="./library/generated/strings.xml" />
|
<xi:include href="./library/generated/strings.xml" />
|
||||||
|
|
||||||
<xi:include href="./library/generated/trivial.xml" />
|
<xi:include href="./library/generated/trivial.xml" />
|
||||||
|
0
doc/functions/library/.gitkeep
Normal file
0
doc/functions/library/.gitkeep
Normal file
@ -1,112 +0,0 @@
|
|||||||
<section xmlns="http://docbook.org/ns/docbook"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
|
||||||
xml:id="sec-functions-library-asserts">
|
|
||||||
<title>Assert functions</title>
|
|
||||||
|
|
||||||
<section xml:id="function-library-lib.asserts.assertMsg">
|
|
||||||
<title><function>lib.asserts.assertMsg</function></title>
|
|
||||||
|
|
||||||
<subtitle><literal>assertMsg :: Bool -> String -> Bool</literal>
|
|
||||||
</subtitle>
|
|
||||||
|
|
||||||
<xi:include href="./locations.xml" xpointer="lib.asserts.assertMsg" />
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Print a trace message if <literal>pred</literal> is false.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Intended to be used to augment asserts with helpful error messages.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>pred</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Condition under which the <varname>msg</varname> should <emphasis>not</emphasis> be printed.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>msg</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Message to print.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
|
|
||||||
<example xml:id="function-library-lib.asserts.assertMsg-example-false">
|
|
||||||
<title>Printing when the predicate is false</title>
|
|
||||||
<programlisting><![CDATA[
|
|
||||||
assert lib.asserts.assertMsg ("foo" == "bar") "foo is not bar, silly"
|
|
||||||
stderr> trace: foo is not bar, silly
|
|
||||||
stderr> assert failed
|
|
||||||
]]></programlisting>
|
|
||||||
</example>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section xml:id="function-library-lib.asserts.assertOneOf">
|
|
||||||
<title><function>lib.asserts.assertOneOf</function></title>
|
|
||||||
|
|
||||||
<subtitle><literal>assertOneOf :: String -> String ->
|
|
||||||
StringList -> Bool</literal>
|
|
||||||
</subtitle>
|
|
||||||
|
|
||||||
<xi:include href="./locations.xml" xpointer="lib.asserts.assertOneOf" />
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Specialized <function>asserts.assertMsg</function> for checking if <varname>val</varname> is one of the elements of <varname>xs</varname>. Useful for checking enums.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>name</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The name of the variable the user entered <varname>val</varname> into, for inclusion in the error message.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>val</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The value of what the user provided, to be compared against the values in <varname>xs</varname>.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term>
|
|
||||||
<varname>xs</varname>
|
|
||||||
</term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The list of valid values.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
|
|
||||||
<example xml:id="function-library-lib.asserts.assertOneOf-example">
|
|
||||||
<title>Ensuring a user provided a possible value</title>
|
|
||||||
<programlisting><![CDATA[
|
|
||||||
let sslLibrary = "bearssl";
|
|
||||||
in lib.asserts.assertOneOf "sslLibrary" sslLibrary [ "openssl" "libressl" ];
|
|
||||||
=> false
|
|
||||||
stderr> trace: sslLibrary must be one of "openssl", "libressl", but is: "bearssl"
|
|
||||||
]]></programlisting>
|
|
||||||
</example>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
File diff suppressed because it is too large
Load Diff
@ -16,11 +16,15 @@ rec {
|
|||||||
assertMsg :: Bool -> String -> Bool
|
assertMsg :: Bool -> String -> Bool
|
||||||
*/
|
*/
|
||||||
# TODO(Profpatsch): add tests that check stderr
|
# TODO(Profpatsch): add tests that check stderr
|
||||||
assertMsg = pred: msg:
|
assertMsg =
|
||||||
|
# Predicate that needs to succeed, otherwise `msg` is thrown
|
||||||
|
pred:
|
||||||
|
# Message to throw in case `pred` fails
|
||||||
|
msg:
|
||||||
pred || builtins.throw msg;
|
pred || builtins.throw msg;
|
||||||
|
|
||||||
/* Specialized `assertMsg` for checking if val is one of the elements
|
/* Specialized `assertMsg` for checking if `val` is one of the elements
|
||||||
of a list. Useful for checking enums.
|
of the list `xs`. Useful for checking enums.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
let sslLibrary = "libressl";
|
let sslLibrary = "libressl";
|
||||||
@ -33,7 +37,14 @@ rec {
|
|||||||
Type:
|
Type:
|
||||||
assertOneOf :: String -> ComparableVal -> List ComparableVal -> Bool
|
assertOneOf :: String -> ComparableVal -> List ComparableVal -> Bool
|
||||||
*/
|
*/
|
||||||
assertOneOf = name: val: xs: assertMsg
|
assertOneOf =
|
||||||
|
# The name of the variable the user entered `val` into, for inclusion in the error message
|
||||||
|
name:
|
||||||
|
# The value of what the user provided, to be compared against the values in `xs`
|
||||||
|
val:
|
||||||
|
# The list of valid values
|
||||||
|
xs:
|
||||||
|
assertMsg
|
||||||
(lib.elem val xs)
|
(lib.elem val xs)
|
||||||
"${name} must be one of ${
|
"${name} must be one of ${
|
||||||
lib.generators.toPretty {} xs}, but is: ${
|
lib.generators.toPretty {} xs}, but is: ${
|
||||||
|
455
lib/attrsets.nix
455
lib/attrsets.nix
@ -20,13 +20,22 @@ rec {
|
|||||||
=> 3
|
=> 3
|
||||||
attrByPath ["z" "z"] 6 x
|
attrByPath ["z" "z"] 6 x
|
||||||
=> 6
|
=> 6
|
||||||
|
|
||||||
|
Type:
|
||||||
|
attrByPath :: [String] -> Any -> AttrSet -> Any
|
||||||
*/
|
*/
|
||||||
attrByPath = attrPath: default: e:
|
attrByPath =
|
||||||
|
# A list of strings representing the attribute path to return from `set`
|
||||||
|
attrPath:
|
||||||
|
# Default value if `attrPath` does not resolve to an existing value
|
||||||
|
default:
|
||||||
|
# The nested attribute set to select values from
|
||||||
|
set:
|
||||||
let attr = head attrPath;
|
let attr = head attrPath;
|
||||||
in
|
in
|
||||||
if attrPath == [] then e
|
if attrPath == [] then set
|
||||||
else if e ? ${attr}
|
else if set ? ${attr}
|
||||||
then attrByPath (tail attrPath) default e.${attr}
|
then attrByPath (tail attrPath) default set.${attr}
|
||||||
else default;
|
else default;
|
||||||
|
|
||||||
/* Return if an attribute from nested attribute set exists.
|
/* Return if an attribute from nested attribute set exists.
|
||||||
@ -38,8 +47,14 @@ rec {
|
|||||||
hasAttrByPath ["z" "z"] x
|
hasAttrByPath ["z" "z"] x
|
||||||
=> false
|
=> false
|
||||||
|
|
||||||
|
Type:
|
||||||
|
hasAttrByPath :: [String] -> AttrSet -> Bool
|
||||||
*/
|
*/
|
||||||
hasAttrByPath = attrPath: e:
|
hasAttrByPath =
|
||||||
|
# A list of strings representing the attribute path to check from `set`
|
||||||
|
attrPath:
|
||||||
|
# The nested attribute set to check
|
||||||
|
e:
|
||||||
let attr = head attrPath;
|
let attr = head attrPath;
|
||||||
in
|
in
|
||||||
if attrPath == [] then true
|
if attrPath == [] then true
|
||||||
@ -48,13 +63,20 @@ rec {
|
|||||||
else false;
|
else false;
|
||||||
|
|
||||||
|
|
||||||
/* Return nested attribute set in which an attribute is set.
|
/* Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
setAttrByPath ["a" "b"] 3
|
setAttrByPath ["a" "b"] 3
|
||||||
=> { a = { b = 3; }; }
|
=> { a = { b = 3; }; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
setAttrByPath :: [String] -> Any -> AttrSet
|
||||||
*/
|
*/
|
||||||
setAttrByPath = attrPath: value:
|
setAttrByPath =
|
||||||
|
# A list of strings representing the attribute path to set
|
||||||
|
attrPath:
|
||||||
|
# The value to set at the location described by `attrPath`
|
||||||
|
value:
|
||||||
let
|
let
|
||||||
len = length attrPath;
|
len = length attrPath;
|
||||||
atDepth = n:
|
atDepth = n:
|
||||||
@ -63,8 +85,8 @@ rec {
|
|||||||
else { ${elemAt attrPath n} = atDepth (n + 1); };
|
else { ${elemAt attrPath n} = atDepth (n + 1); };
|
||||||
in atDepth 0;
|
in atDepth 0;
|
||||||
|
|
||||||
/* Like `attrByPath' without a default value. If it doesn't find the
|
/* Like `attrByPath', but without a default value. If it doesn't find the
|
||||||
path it will throw.
|
path it will throw an error.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
x = { a = { b = 3; }; }
|
x = { a = { b = 3; }; }
|
||||||
@ -72,10 +94,17 @@ rec {
|
|||||||
=> 3
|
=> 3
|
||||||
getAttrFromPath ["z" "z"] x
|
getAttrFromPath ["z" "z"] x
|
||||||
=> error: cannot find attribute `z.z'
|
=> error: cannot find attribute `z.z'
|
||||||
|
|
||||||
|
Type:
|
||||||
|
getAttrFromPath :: [String] -> AttrSet -> Value
|
||||||
*/
|
*/
|
||||||
getAttrFromPath = attrPath:
|
getAttrFromPath =
|
||||||
|
# A list of strings representing the attribute path to get from `set`
|
||||||
|
attrPath:
|
||||||
|
# The nested attribute set to find the value in.
|
||||||
|
set:
|
||||||
let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
|
let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
|
||||||
in attrByPath attrPath (abort errorMsg);
|
in attrByPath attrPath (abort errorMsg) set;
|
||||||
|
|
||||||
/* Map each attribute in the given set and merge them into a new attribute set.
|
/* Map each attribute in the given set and merge them into a new attribute set.
|
||||||
|
|
||||||
@ -101,19 +130,23 @@ rec {
|
|||||||
|
|
||||||
Takes a list of updates to apply and an attribute set to apply them to,
|
Takes a list of updates to apply and an attribute set to apply them to,
|
||||||
and returns the attribute set with the updates applied. Updates are
|
and returns the attribute set with the updates applied. Updates are
|
||||||
represented as { path = ...; update = ...; } values, where `path` is a
|
represented as `{ path = ...; update = ...; }` values, where `path` is a
|
||||||
list of strings representing the attribute path that should be updated,
|
list of strings representing the attribute path that should be updated,
|
||||||
and `update` is a function that takes the old value at that attribute path
|
and `update` is a function that takes the old value at that attribute path
|
||||||
as an argument and returns the new
|
as an argument and returns the new
|
||||||
value it should be.
|
value it should be.
|
||||||
|
|
||||||
Properties:
|
Properties:
|
||||||
|
|
||||||
- Updates to deeper attribute paths are applied before updates to more
|
- Updates to deeper attribute paths are applied before updates to more
|
||||||
shallow attribute paths
|
shallow attribute paths
|
||||||
|
|
||||||
- Multiple updates to the same attribute path are applied in the order
|
- Multiple updates to the same attribute path are applied in the order
|
||||||
they appear in the update list
|
they appear in the update list
|
||||||
|
|
||||||
- If any but the last `path` element leads into a value that is not an
|
- If any but the last `path` element leads into a value that is not an
|
||||||
attribute set, an error is thrown
|
attribute set, an error is thrown
|
||||||
|
|
||||||
- If there is an update for an attribute path that doesn't exist,
|
- If there is an update for an attribute path that doesn't exist,
|
||||||
accessing the argument in the update function causes an error, but
|
accessing the argument in the update function causes an error, but
|
||||||
intermediate attribute sets are implicitly created as needed
|
intermediate attribute sets are implicitly created as needed
|
||||||
@ -134,6 +167,9 @@ rec {
|
|||||||
}
|
}
|
||||||
] { a.b.c = 0; }
|
] { a.b.c = 0; }
|
||||||
=> { a = { b = { d = 1; }; }; x = { y = "xy"; }; }
|
=> { a = { b = { d = 1; }; }; x = { y = "xy"; }; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
updateManyAttrsByPath :: [AttrSet] -> AttrSet -> AttrSet
|
||||||
*/
|
*/
|
||||||
updateManyAttrsByPath = let
|
updateManyAttrsByPath = let
|
||||||
# When recursing into attributes, instead of updating the `path` of each
|
# When recursing into attributes, instead of updating the `path` of each
|
||||||
@ -199,8 +235,15 @@ rec {
|
|||||||
Example:
|
Example:
|
||||||
attrVals ["a" "b" "c"] as
|
attrVals ["a" "b" "c"] as
|
||||||
=> [as.a as.b as.c]
|
=> [as.a as.b as.c]
|
||||||
|
|
||||||
|
Type:
|
||||||
|
attrVals :: [String] -> AttrSet -> [Any]
|
||||||
*/
|
*/
|
||||||
attrVals = nameList: set: map (x: set.${x}) nameList;
|
attrVals =
|
||||||
|
# The list of attributes to fetch from `set`. Each attribute name must exist on the attrbitue set
|
||||||
|
nameList:
|
||||||
|
# The set to get attribute values from
|
||||||
|
set: map (x: set.${x}) nameList;
|
||||||
|
|
||||||
|
|
||||||
/* Return the values of all attributes in the given set, sorted by
|
/* Return the values of all attributes in the given set, sorted by
|
||||||
@ -209,6 +252,8 @@ rec {
|
|||||||
Example:
|
Example:
|
||||||
attrValues {c = 3; a = 1; b = 2;}
|
attrValues {c = 3; a = 1; b = 2;}
|
||||||
=> [1 2 3]
|
=> [1 2 3]
|
||||||
|
Type:
|
||||||
|
attrValues :: AttrSet -> [Any]
|
||||||
*/
|
*/
|
||||||
attrValues = builtins.attrValues or (attrs: attrVals (attrNames attrs) attrs);
|
attrValues = builtins.attrValues or (attrs: attrVals (attrNames attrs) attrs);
|
||||||
|
|
||||||
@ -219,8 +264,15 @@ rec {
|
|||||||
Example:
|
Example:
|
||||||
getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; }
|
getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; }
|
||||||
=> { a = 1; b = 2; }
|
=> { a = 1; b = 2; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
getAttrs :: [String] -> AttrSet -> AttrSet
|
||||||
*/
|
*/
|
||||||
getAttrs = names: attrs: genAttrs names (name: attrs.${name});
|
getAttrs =
|
||||||
|
# A list of attribute names to get out of `set`
|
||||||
|
names:
|
||||||
|
# The set to get the named attributes from
|
||||||
|
attrs: genAttrs names (name: attrs.${name});
|
||||||
|
|
||||||
/* Collect each attribute named `attr' from a list of attribute
|
/* Collect each attribute named `attr' from a list of attribute
|
||||||
sets. Sets that don't contain the named attribute are ignored.
|
sets. Sets that don't contain the named attribute are ignored.
|
||||||
@ -228,6 +280,9 @@ rec {
|
|||||||
Example:
|
Example:
|
||||||
catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
|
catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
|
||||||
=> [1 2]
|
=> [1 2]
|
||||||
|
|
||||||
|
Type:
|
||||||
|
catAttrs :: String -> [AttrSet] -> [Any]
|
||||||
*/
|
*/
|
||||||
catAttrs = builtins.catAttrs or
|
catAttrs = builtins.catAttrs or
|
||||||
(attr: l: concatLists (map (s: if s ? ${attr} then [s.${attr}] else []) l));
|
(attr: l: concatLists (map (s: if s ? ${attr} then [s.${attr}] else []) l));
|
||||||
@ -239,8 +294,15 @@ rec {
|
|||||||
Example:
|
Example:
|
||||||
filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; }
|
filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; }
|
||||||
=> { foo = 1; }
|
=> { foo = 1; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
filterAttrs :: (String -> Any -> Bool) -> AttrSet -> AttrSet
|
||||||
*/
|
*/
|
||||||
filterAttrs = pred: set:
|
filterAttrs =
|
||||||
|
# Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute.
|
||||||
|
pred:
|
||||||
|
# The attribute set to filter
|
||||||
|
set:
|
||||||
listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set));
|
listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set));
|
||||||
|
|
||||||
|
|
||||||
@ -250,8 +312,15 @@ rec {
|
|||||||
Example:
|
Example:
|
||||||
filterAttrsRecursive (n: v: v != null) { foo = { bar = null; }; }
|
filterAttrsRecursive (n: v: v != null) { foo = { bar = null; }; }
|
||||||
=> { foo = {}; }
|
=> { foo = {}; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
filterAttrsRecursive :: (String -> Any -> Bool) -> AttrSet -> AttrSet
|
||||||
*/
|
*/
|
||||||
filterAttrsRecursive = pred: set:
|
filterAttrsRecursive =
|
||||||
|
# Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute.
|
||||||
|
pred:
|
||||||
|
# The attribute set to filter
|
||||||
|
set:
|
||||||
listToAttrs (
|
listToAttrs (
|
||||||
concatMap (name:
|
concatMap (name:
|
||||||
let v = set.${name}; in
|
let v = set.${name}; in
|
||||||
@ -269,23 +338,28 @@ rec {
|
|||||||
Example:
|
Example:
|
||||||
foldAttrs (item: acc: [item] ++ acc) [] [{ a = 2; } { a = 3; }]
|
foldAttrs (item: acc: [item] ++ acc) [] [{ a = 2; } { a = 3; }]
|
||||||
=> { a = [ 2 3 ]; }
|
=> { a = [ 2 3 ]; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
foldAttrs :: (Any -> Any -> Any) -> Any -> [AttrSets] -> Any
|
||||||
*/
|
*/
|
||||||
foldAttrs = op: nul:
|
foldAttrs =
|
||||||
|
# A function, given a value and a collector combines the two.
|
||||||
|
op:
|
||||||
|
# The starting value.
|
||||||
|
nul:
|
||||||
|
# A list of attribute sets to fold together by key.
|
||||||
|
list_of_attrs:
|
||||||
foldr (n: a:
|
foldr (n: a:
|
||||||
foldr (name: o:
|
foldr (name: o:
|
||||||
o // { ${name} = op n.${name} (a.${name} or nul); }
|
o // { ${name} = op n.${name} (a.${name} or nul); }
|
||||||
) a (attrNames n)
|
) a (attrNames n)
|
||||||
) {};
|
) {} list_of_attrs;
|
||||||
|
|
||||||
|
|
||||||
/* Recursively collect sets that verify a given predicate named `pred'
|
/* Recursively collect sets that verify a given predicate named `pred'
|
||||||
from the set `attrs'. The recursion is stopped when the predicate is
|
from the set `attrs'. The recursion is stopped when the predicate is
|
||||||
verified.
|
verified.
|
||||||
|
|
||||||
Type:
|
|
||||||
collect ::
|
|
||||||
(AttrSet -> Bool) -> AttrSet -> [x]
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
collect isList { a = { b = ["b"]; }; c = [1]; }
|
collect isList { a = { b = ["b"]; }; c = [1]; }
|
||||||
=> [["b"] [1]]
|
=> [["b"] [1]]
|
||||||
@ -293,8 +367,15 @@ rec {
|
|||||||
collect (x: x ? outPath)
|
collect (x: x ? outPath)
|
||||||
{ a = { outPath = "a/"; }; b = { outPath = "b/"; }; }
|
{ a = { outPath = "a/"; }; b = { outPath = "b/"; }; }
|
||||||
=> [{ outPath = "a/"; } { outPath = "b/"; }]
|
=> [{ outPath = "a/"; } { outPath = "b/"; }]
|
||||||
|
|
||||||
|
Type:
|
||||||
|
collect :: (AttrSet -> Bool) -> AttrSet -> [x]
|
||||||
*/
|
*/
|
||||||
collect = pred: attrs:
|
collect =
|
||||||
|
# Given an attribute's value, determine if recursion should stop.
|
||||||
|
pred:
|
||||||
|
# The attribute set to recursively collect.
|
||||||
|
attrs:
|
||||||
if pred attrs then
|
if pred attrs then
|
||||||
[ attrs ]
|
[ attrs ]
|
||||||
else if isAttrs attrs then
|
else if isAttrs attrs then
|
||||||
@ -312,8 +393,12 @@ rec {
|
|||||||
{ a = 2; b = 10; }
|
{ a = 2; b = 10; }
|
||||||
{ a = 2; b = 20; }
|
{ a = 2; b = 20; }
|
||||||
]
|
]
|
||||||
|
Type:
|
||||||
|
cartesianProductOfSets :: AttrSet -> [AttrSet]
|
||||||
*/
|
*/
|
||||||
cartesianProductOfSets = attrsOfLists:
|
cartesianProductOfSets =
|
||||||
|
# Attribute set with attributes that are lists of values
|
||||||
|
attrsOfLists:
|
||||||
foldl' (listOfAttrs: attrName:
|
foldl' (listOfAttrs: attrName:
|
||||||
concatMap (attrs:
|
concatMap (attrs:
|
||||||
map (listValue: attrs // { ${attrName} = listValue; }) attrsOfLists.${attrName}
|
map (listValue: attrs // { ${attrName} = listValue; }) attrsOfLists.${attrName}
|
||||||
@ -321,25 +406,32 @@ rec {
|
|||||||
) [{}] (attrNames attrsOfLists);
|
) [{}] (attrNames attrsOfLists);
|
||||||
|
|
||||||
|
|
||||||
/* Utility function that creates a {name, value} pair as expected by
|
/* Utility function that creates a `{name, value}` pair as expected by `builtins.listToAttrs`.
|
||||||
builtins.listToAttrs.
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
nameValuePair "some" 6
|
nameValuePair "some" 6
|
||||||
=> { name = "some"; value = 6; }
|
=> { name = "some"; value = 6; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
nameValuePair :: String -> Any -> AttrSet
|
||||||
*/
|
*/
|
||||||
nameValuePair = name: value: { inherit name value; };
|
nameValuePair =
|
||||||
|
# Attribute name
|
||||||
|
name:
|
||||||
|
# Attribute value
|
||||||
|
value:
|
||||||
|
{ inherit name value; };
|
||||||
|
|
||||||
|
|
||||||
/* Apply a function to each element in an attribute set. The
|
/* Apply a function to each element in an attribute set, creating a new attribute set.
|
||||||
function takes two arguments --- the attribute name and its value
|
|
||||||
--- and returns the new value for the attribute. The result is a
|
|
||||||
new attribute set.
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
mapAttrs (name: value: name + "-" + value)
|
mapAttrs (name: value: name + "-" + value)
|
||||||
{ x = "foo"; y = "bar"; }
|
{ x = "foo"; y = "bar"; }
|
||||||
=> { x = "x-foo"; y = "y-bar"; }
|
=> { x = "x-foo"; y = "y-bar"; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
mapAttrs :: (String -> Any -> Any) -> AttrSet -> AttrSet
|
||||||
*/
|
*/
|
||||||
mapAttrs = builtins.mapAttrs or
|
mapAttrs = builtins.mapAttrs or
|
||||||
(f: set:
|
(f: set:
|
||||||
@ -354,24 +446,35 @@ rec {
|
|||||||
mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value))
|
mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value))
|
||||||
{ x = "a"; y = "b"; }
|
{ x = "a"; y = "b"; }
|
||||||
=> { foo_x = "bar-a"; foo_y = "bar-b"; }
|
=> { foo_x = "bar-a"; foo_y = "bar-b"; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
mapAttrs' :: (String -> Any -> { name = String; value = Any }) -> AttrSet -> AttrSet
|
||||||
*/
|
*/
|
||||||
mapAttrs' = f: set:
|
mapAttrs' =
|
||||||
|
# A function, given an attribute's name and value, returns a new `nameValuePair`.
|
||||||
|
f:
|
||||||
|
# Attribute set to map over.
|
||||||
|
set:
|
||||||
listToAttrs (map (attr: f attr set.${attr}) (attrNames set));
|
listToAttrs (map (attr: f attr set.${attr}) (attrNames set));
|
||||||
|
|
||||||
|
|
||||||
/* Call a function for each attribute in the given set and return
|
/* Call a function for each attribute in the given set and return
|
||||||
the result in a list.
|
the result in a list.
|
||||||
|
|
||||||
Type:
|
|
||||||
mapAttrsToList ::
|
|
||||||
(String -> a -> b) -> AttrSet -> [b]
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
mapAttrsToList (name: value: name + value)
|
mapAttrsToList (name: value: name + value)
|
||||||
{ x = "a"; y = "b"; }
|
{ x = "a"; y = "b"; }
|
||||||
=> [ "xa" "yb" ]
|
=> [ "xa" "yb" ]
|
||||||
|
|
||||||
|
Type:
|
||||||
|
mapAttrsToList :: (String -> a -> b) -> AttrSet -> [b]
|
||||||
|
|
||||||
*/
|
*/
|
||||||
mapAttrsToList = f: attrs:
|
mapAttrsToList =
|
||||||
|
# A function, given an attribute's name and value, returns a new value.
|
||||||
|
f:
|
||||||
|
# Attribute set to map over.
|
||||||
|
attrs:
|
||||||
map (name: f name attrs.${name}) (attrNames attrs);
|
map (name: f name attrs.${name}) (attrNames attrs);
|
||||||
|
|
||||||
|
|
||||||
@ -379,16 +482,20 @@ rec {
|
|||||||
attribute sets. Also, the first argument of the argument
|
attribute sets. Also, the first argument of the argument
|
||||||
function is a *list* of the names of the containing attributes.
|
function is a *list* of the names of the containing attributes.
|
||||||
|
|
||||||
Type:
|
|
||||||
mapAttrsRecursive ::
|
|
||||||
([String] -> a -> b) -> AttrSet -> AttrSet
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
mapAttrsRecursive (path: value: concatStringsSep "-" (path ++ [value]))
|
mapAttrsRecursive (path: value: concatStringsSep "-" (path ++ [value]))
|
||||||
{ n = { a = "A"; m = { b = "B"; c = "C"; }; }; d = "D"; }
|
{ n = { a = "A"; m = { b = "B"; c = "C"; }; }; d = "D"; }
|
||||||
=> { n = { a = "n-a-A"; m = { b = "n-m-b-B"; c = "n-m-c-C"; }; }; d = "d-D"; }
|
=> { n = { a = "n-a-A"; m = { b = "n-m-b-B"; c = "n-m-c-C"; }; }; d = "d-D"; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
mapAttrsRecursive :: ([String] -> a -> b) -> AttrSet -> AttrSet
|
||||||
*/
|
*/
|
||||||
mapAttrsRecursive = mapAttrsRecursiveCond (as: true);
|
mapAttrsRecursive =
|
||||||
|
# A function, given a list of attribute names and a value, returns a new value.
|
||||||
|
f:
|
||||||
|
# Set to recursively map over.
|
||||||
|
set:
|
||||||
|
mapAttrsRecursiveCond (as: true) f set;
|
||||||
|
|
||||||
|
|
||||||
/* Like `mapAttrsRecursive', but it takes an additional predicate
|
/* Like `mapAttrsRecursive', but it takes an additional predicate
|
||||||
@ -397,10 +504,6 @@ rec {
|
|||||||
recurse, but does apply the map function. If it returns true, it
|
recurse, but does apply the map function. If it returns true, it
|
||||||
does recurse, and does not apply the map function.
|
does recurse, and does not apply the map function.
|
||||||
|
|
||||||
Type:
|
|
||||||
mapAttrsRecursiveCond ::
|
|
||||||
(AttrSet -> Bool) -> ([String] -> a -> b) -> AttrSet -> AttrSet
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
# To prevent recursing into derivations (which are attribute
|
# To prevent recursing into derivations (which are attribute
|
||||||
# sets with the attribute "type" equal to "derivation"):
|
# sets with the attribute "type" equal to "derivation"):
|
||||||
@ -408,8 +511,17 @@ rec {
|
|||||||
(as: !(as ? "type" && as.type == "derivation"))
|
(as: !(as ? "type" && as.type == "derivation"))
|
||||||
(x: ... do something ...)
|
(x: ... do something ...)
|
||||||
attrs
|
attrs
|
||||||
|
|
||||||
|
Type:
|
||||||
|
mapAttrsRecursiveCond :: (AttrSet -> Bool) -> ([String] -> a -> b) -> AttrSet -> AttrSet
|
||||||
*/
|
*/
|
||||||
mapAttrsRecursiveCond = cond: f: set:
|
mapAttrsRecursiveCond =
|
||||||
|
# A function, given the attribute set the recursion is currently at, determine if to recurse deeper into that attribute set.
|
||||||
|
cond:
|
||||||
|
# A function, given a list of attribute names and a value, returns a new value.
|
||||||
|
f:
|
||||||
|
# Attribute set to recursively map over.
|
||||||
|
set:
|
||||||
let
|
let
|
||||||
recurse = path:
|
recurse = path:
|
||||||
let
|
let
|
||||||
@ -428,13 +540,20 @@ rec {
|
|||||||
Example:
|
Example:
|
||||||
genAttrs [ "foo" "bar" ] (name: "x_" + name)
|
genAttrs [ "foo" "bar" ] (name: "x_" + name)
|
||||||
=> { foo = "x_foo"; bar = "x_bar"; }
|
=> { foo = "x_foo"; bar = "x_bar"; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
genAttrs :: [ String ] -> (String -> Any) -> AttrSet
|
||||||
*/
|
*/
|
||||||
genAttrs = names: f:
|
genAttrs =
|
||||||
|
# Names of values in the resulting attribute set.
|
||||||
|
names:
|
||||||
|
# A function, given the name of the attribute, returns the attribute's value.
|
||||||
|
f:
|
||||||
listToAttrs (map (n: nameValuePair n (f n)) names);
|
listToAttrs (map (n: nameValuePair n (f n)) names);
|
||||||
|
|
||||||
|
|
||||||
/* Check whether the argument is a derivation. Any set with
|
/* Check whether the argument is a derivation. Any set with
|
||||||
{ type = "derivation"; } counts as a derivation.
|
`{ type = "derivation"; }` counts as a derivation.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
nixpkgs = import <nixpkgs> {}
|
nixpkgs = import <nixpkgs> {}
|
||||||
@ -442,25 +561,36 @@ rec {
|
|||||||
=> true
|
=> true
|
||||||
isDerivation "foobar"
|
isDerivation "foobar"
|
||||||
=> false
|
=> false
|
||||||
*/
|
|
||||||
isDerivation = x: x.type or null == "derivation";
|
|
||||||
|
|
||||||
/* Converts a store path to a fake derivation. */
|
Type:
|
||||||
toDerivation = path:
|
isDerivation :: Any -> Bool
|
||||||
let
|
*/
|
||||||
path' = builtins.storePath path;
|
isDerivation =
|
||||||
res =
|
# Value to check.
|
||||||
{ type = "derivation";
|
value: value.type or null == "derivation";
|
||||||
name = sanitizeDerivationName (builtins.substring 33 (-1) (baseNameOf path'));
|
|
||||||
outPath = path';
|
/* Converts a store path to a fake derivation.
|
||||||
outputs = [ "out" ];
|
|
||||||
out = res;
|
Type:
|
||||||
outputName = "out";
|
toDerivation :: Path -> Derivation
|
||||||
};
|
*/
|
||||||
|
toDerivation =
|
||||||
|
# A store path to convert to a derivation.
|
||||||
|
path:
|
||||||
|
let
|
||||||
|
path' = builtins.storePath path;
|
||||||
|
res =
|
||||||
|
{ type = "derivation";
|
||||||
|
name = sanitizeDerivationName (builtins.substring 33 (-1) (baseNameOf path'));
|
||||||
|
outPath = path';
|
||||||
|
outputs = [ "out" ];
|
||||||
|
out = res;
|
||||||
|
outputName = "out";
|
||||||
|
};
|
||||||
in res;
|
in res;
|
||||||
|
|
||||||
|
|
||||||
/* If `cond' is true, return the attribute set `as',
|
/* If `cond` is true, return the attribute set `as`,
|
||||||
otherwise an empty attribute set.
|
otherwise an empty attribute set.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -468,47 +598,82 @@ rec {
|
|||||||
=> { my = "set"; }
|
=> { my = "set"; }
|
||||||
optionalAttrs (false) { my = "set"; }
|
optionalAttrs (false) { my = "set"; }
|
||||||
=> { }
|
=> { }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
optionalAttrs :: Bool -> AttrSet
|
||||||
*/
|
*/
|
||||||
optionalAttrs = cond: as: if cond then as else {};
|
optionalAttrs =
|
||||||
|
# Condition under which the `as` attribute set is returned.
|
||||||
|
cond:
|
||||||
|
# The attribute set to return if `cond` is `true`.
|
||||||
|
as:
|
||||||
|
if cond then as else {};
|
||||||
|
|
||||||
|
|
||||||
/* Merge sets of attributes and use the function f to merge attributes
|
/* Merge sets of attributes and use the function `f` to merge attributes
|
||||||
values.
|
values.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
zipAttrsWithNames ["a"] (name: vs: vs) [{a = "x";} {a = "y"; b = "z";}]
|
zipAttrsWithNames ["a"] (name: vs: vs) [{a = "x";} {a = "y"; b = "z";}]
|
||||||
=> { a = ["x" "y"]; }
|
=> { a = ["x" "y"]; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
zipAttrsWithNames :: [ String ] -> (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet
|
||||||
*/
|
*/
|
||||||
zipAttrsWithNames = names: f: sets:
|
zipAttrsWithNames =
|
||||||
|
# List of attribute names to zip.
|
||||||
|
names:
|
||||||
|
# A function, accepts an attribute name, all the values, and returns a combined value.
|
||||||
|
f:
|
||||||
|
# List of values from the list of attribute sets.
|
||||||
|
sets:
|
||||||
listToAttrs (map (name: {
|
listToAttrs (map (name: {
|
||||||
inherit name;
|
inherit name;
|
||||||
value = f name (catAttrs name sets);
|
value = f name (catAttrs name sets);
|
||||||
}) names);
|
}) names);
|
||||||
|
|
||||||
/* Implementation note: Common names appear multiple times in the list of
|
|
||||||
|
/* Merge sets of attributes and use the function f to merge attribute values.
|
||||||
|
Like `lib.attrsets.zipAttrsWithNames` with all key names are passed for `names`.
|
||||||
|
|
||||||
|
Implementation note: Common names appear multiple times in the list of
|
||||||
names, hopefully this does not affect the system because the maximal
|
names, hopefully this does not affect the system because the maximal
|
||||||
laziness avoid computing twice the same expression and listToAttrs does
|
laziness avoid computing twice the same expression and `listToAttrs` does
|
||||||
not care about duplicated attribute names.
|
not care about duplicated attribute names.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}]
|
zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}]
|
||||||
=> { a = ["x" "y"]; b = ["z"] }
|
=> { a = ["x" "y"]; b = ["z"] }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
zipAttrsWith :: (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet
|
||||||
*/
|
*/
|
||||||
zipAttrsWith =
|
zipAttrsWith =
|
||||||
builtins.zipAttrsWith or (f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets);
|
builtins.zipAttrsWith or (f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets);
|
||||||
/* Like `zipAttrsWith' with `(name: values: values)' as the function.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
zipAttrs [{a = "x";} {a = "y"; b = "z";}]
|
/* Merge sets of attributes and combine each attribute value in to a list.
|
||||||
=> { a = ["x" "y"]; b = ["z"] }
|
|
||||||
|
Like `lib.attrsets.zipAttrsWith' with `(name: values: values)' as the function.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
zipAttrs [{a = "x";} {a = "y"; b = "z";}]
|
||||||
|
=> { a = ["x" "y"]; b = ["z"] }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
zipAttrs :: [ AttrSet ] -> AttrSet
|
||||||
*/
|
*/
|
||||||
zipAttrs = zipAttrsWith (name: values: values);
|
zipAttrs =
|
||||||
|
# List of attribute sets to zip together.
|
||||||
|
sets:
|
||||||
|
zipAttrsWith (name: values: values) sets;
|
||||||
|
|
||||||
|
|
||||||
/* Does the same as the update operator '//' except that attributes are
|
/* Does the same as the update operator '//' except that attributes are
|
||||||
merged until the given predicate is verified. The predicate should
|
merged until the given predicate is verified. The predicate should
|
||||||
accept 3 arguments which are the path to reach the attribute, a part of
|
accept 3 arguments which are the path to reach the attribute, a part of
|
||||||
the first attribute set and a part of the second attribute set. When
|
the first attribute set and a part of the second attribute set. When
|
||||||
the predicate is verified, the value of the first attribute set is
|
the predicate is satisfied, the value of the first attribute set is
|
||||||
replaced by the value of the second attribute set.
|
replaced by the value of the second attribute set.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -524,15 +689,23 @@ rec {
|
|||||||
baz = 4;
|
baz = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
returns: {
|
=> {
|
||||||
foo.bar = 1; # 'foo.*' from the second set
|
foo.bar = 1; # 'foo.*' from the second set
|
||||||
foo.quz = 2; #
|
foo.quz = 2; #
|
||||||
bar = 3; # 'bar' from the first set
|
bar = 3; # 'bar' from the first set
|
||||||
baz = 4; # 'baz' from the second set
|
baz = 4; # 'baz' from the second set
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
Type:
|
||||||
recursiveUpdateUntil = pred: lhs: rhs:
|
recursiveUpdateUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet
|
||||||
|
*/
|
||||||
|
recursiveUpdateUntil =
|
||||||
|
# Predicate, taking the path to the current attribute as a list of strings for attribute names, and the two values at that path from the original arguments.
|
||||||
|
pred:
|
||||||
|
# Left attribute set of the merge.
|
||||||
|
lhs:
|
||||||
|
# Right attribute set of the merge.
|
||||||
|
rhs:
|
||||||
let f = attrPath:
|
let f = attrPath:
|
||||||
zipAttrsWith (n: values:
|
zipAttrsWith (n: values:
|
||||||
let here = attrPath ++ [n]; in
|
let here = attrPath ++ [n]; in
|
||||||
@ -544,6 +717,7 @@ rec {
|
|||||||
);
|
);
|
||||||
in f [] [rhs lhs];
|
in f [] [rhs lhs];
|
||||||
|
|
||||||
|
|
||||||
/* A recursive variant of the update operator ‘//’. The recursion
|
/* A recursive variant of the update operator ‘//’. The recursion
|
||||||
stops when one of the attribute values is not an attribute set,
|
stops when one of the attribute values is not an attribute set,
|
||||||
in which case the right hand side value takes precedence over the
|
in which case the right hand side value takes precedence over the
|
||||||
@ -562,16 +736,32 @@ rec {
|
|||||||
boot.loader.grub.device = "";
|
boot.loader.grub.device = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
Type:
|
||||||
recursiveUpdate = recursiveUpdateUntil (path: lhs: rhs: !(isAttrs lhs && isAttrs rhs));
|
recursiveUpdate :: AttrSet -> AttrSet -> AttrSet
|
||||||
|
*/
|
||||||
|
recursiveUpdate =
|
||||||
|
# Left attribute set of the merge.
|
||||||
|
lhs:
|
||||||
|
# Right attribute set of the merge.
|
||||||
|
rhs:
|
||||||
|
recursiveUpdateUntil (path: lhs: rhs: !(isAttrs lhs && isAttrs rhs)) lhs rhs;
|
||||||
|
|
||||||
|
|
||||||
/* Returns true if the pattern is contained in the set. False otherwise.
|
/* Returns true if the pattern is contained in the set. False otherwise.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
matchAttrs { cpu = {}; } { cpu = { bits = 64; }; }
|
matchAttrs { cpu = {}; } { cpu = { bits = 64; }; }
|
||||||
=> true
|
=> true
|
||||||
*/
|
|
||||||
matchAttrs = pattern: attrs: assert isAttrs pattern;
|
Type:
|
||||||
|
matchAttrs :: AttrSet -> AttrSet -> Bool
|
||||||
|
*/
|
||||||
|
matchAttrs =
|
||||||
|
# Attribute set strucutre to match
|
||||||
|
pattern:
|
||||||
|
# Attribute set to find patterns in
|
||||||
|
attrs:
|
||||||
|
assert isAttrs pattern;
|
||||||
all id (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
|
all id (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
|
||||||
let pat = head values; val = elemAt values 1; in
|
let pat = head values; val = elemAt values 1; in
|
||||||
if length values == 1 then false
|
if length values == 1 then false
|
||||||
@ -579,6 +769,7 @@ rec {
|
|||||||
else pat == val
|
else pat == val
|
||||||
) [pattern attrs]));
|
) [pattern attrs]));
|
||||||
|
|
||||||
|
|
||||||
/* Override only the attributes that are already present in the old set
|
/* Override only the attributes that are already present in the old set
|
||||||
useful for deep-overriding.
|
useful for deep-overriding.
|
||||||
|
|
||||||
@ -589,10 +780,18 @@ rec {
|
|||||||
=> { b = 2; }
|
=> { b = 2; }
|
||||||
overrideExisting { a = 3; b = 2; } { a = 1; }
|
overrideExisting { a = 3; b = 2; } { a = 1; }
|
||||||
=> { a = 1; b = 2; }
|
=> { a = 1; b = 2; }
|
||||||
|
|
||||||
|
Type:
|
||||||
|
overrideExisting :: AttrSet -> AttrSet -> AttrSet
|
||||||
*/
|
*/
|
||||||
overrideExisting = old: new:
|
overrideExisting =
|
||||||
|
# Original attribute set
|
||||||
|
old:
|
||||||
|
# Attribute set with attributes to override in `old`.
|
||||||
|
new:
|
||||||
mapAttrs (name: value: new.${name} or value) old;
|
mapAttrs (name: value: new.${name} or value) old;
|
||||||
|
|
||||||
|
|
||||||
/* Turns a list of strings into a human-readable description of those
|
/* Turns a list of strings into a human-readable description of those
|
||||||
strings represented as an attribute path. The result of this function is
|
strings represented as an attribute path. The result of this function is
|
||||||
not intended to be machine-readable.
|
not intended to be machine-readable.
|
||||||
@ -602,44 +801,120 @@ rec {
|
|||||||
=> "foo.\"10\".bar"
|
=> "foo.\"10\".bar"
|
||||||
showAttrPath []
|
showAttrPath []
|
||||||
=> "<root attribute path>"
|
=> "<root attribute path>"
|
||||||
|
|
||||||
|
Type:
|
||||||
|
showAttrPath :: [String] -> String
|
||||||
*/
|
*/
|
||||||
showAttrPath = path:
|
showAttrPath =
|
||||||
|
# Attribute path to render to a string
|
||||||
|
path:
|
||||||
if path == [] then "<root attribute path>"
|
if path == [] then "<root attribute path>"
|
||||||
else concatMapStringsSep "." escapeNixIdentifier path;
|
else concatMapStringsSep "." escapeNixIdentifier path;
|
||||||
|
|
||||||
|
|
||||||
/* Get a package output.
|
/* Get a package output.
|
||||||
If no output is found, fallback to `.out` and then to the default.
|
If no output is found, fallback to `.out` and then to the default.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
getOutput "dev" pkgs.openssl
|
getOutput "dev" pkgs.openssl
|
||||||
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"
|
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"
|
||||||
|
|
||||||
|
Type:
|
||||||
|
getOutput :: String -> Derivation -> String
|
||||||
*/
|
*/
|
||||||
getOutput = output: pkg:
|
getOutput = output: pkg:
|
||||||
if ! pkg ? outputSpecified || ! pkg.outputSpecified
|
if ! pkg ? outputSpecified || ! pkg.outputSpecified
|
||||||
then pkg.${output} or pkg.out or pkg
|
then pkg.${output} or pkg.out or pkg
|
||||||
else pkg;
|
else pkg;
|
||||||
|
|
||||||
|
/* Get a package's `bin` output.
|
||||||
|
If the output does not exist, fallback to `.out` and then to the default.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
getOutput pkgs.openssl
|
||||||
|
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r"
|
||||||
|
|
||||||
|
Type:
|
||||||
|
getOutput :: Derivation -> String
|
||||||
|
*/
|
||||||
getBin = getOutput "bin";
|
getBin = getOutput "bin";
|
||||||
|
|
||||||
|
|
||||||
|
/* Get a package's `lib` output.
|
||||||
|
If the output does not exist, fallback to `.out` and then to the default.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
getOutput pkgs.openssl
|
||||||
|
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-lib"
|
||||||
|
|
||||||
|
Type:
|
||||||
|
getOutput :: Derivation -> String
|
||||||
|
*/
|
||||||
getLib = getOutput "lib";
|
getLib = getOutput "lib";
|
||||||
|
|
||||||
|
|
||||||
|
/* Get a package's `dev` output.
|
||||||
|
If the output does not exist, fallback to `.out` and then to the default.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
getOutput pkgs.openssl
|
||||||
|
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"
|
||||||
|
|
||||||
|
Type:
|
||||||
|
getOutput :: Derivation -> String
|
||||||
|
*/
|
||||||
getDev = getOutput "dev";
|
getDev = getOutput "dev";
|
||||||
|
|
||||||
|
|
||||||
|
/* Get a package's `man` output.
|
||||||
|
If the output does not exist, fallback to `.out` and then to the default.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
getOutput pkgs.openssl
|
||||||
|
=> "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-man"
|
||||||
|
|
||||||
|
Type:
|
||||||
|
getOutput :: Derivation -> String
|
||||||
|
*/
|
||||||
getMan = getOutput "man";
|
getMan = getOutput "man";
|
||||||
|
|
||||||
/* Pick the outputs of packages to place in buildInputs */
|
/* Pick the outputs of packages to place in `buildInputs` */
|
||||||
chooseDevOutputs = builtins.map getDev;
|
chooseDevOutputs =
|
||||||
|
# List of packages to pick `dev` outputs from
|
||||||
|
drvs:
|
||||||
|
builtins.map getDev drvs;
|
||||||
|
|
||||||
/* Make various Nix tools consider the contents of the resulting
|
/* Make various Nix tools consider the contents of the resulting
|
||||||
attribute set when looking for what to build, find, etc.
|
attribute set when looking for what to build, find, etc.
|
||||||
|
|
||||||
This function only affects a single attribute set; it does not
|
This function only affects a single attribute set; it does not
|
||||||
apply itself recursively for nested attribute sets.
|
apply itself recursively for nested attribute sets.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
{
|
||||||
|
myTools = pkgs.lib.recurseIntoAttrs {
|
||||||
|
inherit (pkgs) hello figlet;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Type:
|
||||||
|
recurseIntoAttrs :: AttrSet -> AttrSet
|
||||||
*/
|
*/
|
||||||
recurseIntoAttrs =
|
recurseIntoAttrs =
|
||||||
attrs: attrs // { recurseForDerivations = true; };
|
# An attribute set to scan for derivations.
|
||||||
|
attrs:
|
||||||
|
attrs // { recurseForDerivations = true; };
|
||||||
|
|
||||||
/* Undo the effect of recurseIntoAttrs.
|
/* Undo the effect of recurseIntoAttrs.
|
||||||
|
|
||||||
|
Type:
|
||||||
|
recurseIntoAttrs :: AttrSet -> AttrSet
|
||||||
*/
|
*/
|
||||||
dontRecurseIntoAttrs =
|
dontRecurseIntoAttrs =
|
||||||
attrs: attrs // { recurseForDerivations = false; };
|
# An attribute set to not scan for derivations.
|
||||||
|
attrs:
|
||||||
|
attrs // { recurseForDerivations = false; };
|
||||||
|
|
||||||
/* `unionOfDisjoint x y` is equal to `x // y // z` where the
|
/* `unionOfDisjoint x y` is equal to `x // y // z` where the
|
||||||
attrnames in `z` are the intersection of the attrnames in `x` and
|
attrnames in `z` are the intersection of the attrnames in `x` and
|
||||||
@ -655,9 +930,9 @@ rec {
|
|||||||
in
|
in
|
||||||
(x // y) // mask;
|
(x // y) // mask;
|
||||||
|
|
||||||
/*** deprecated stuff ***/
|
# deprecated
|
||||||
|
|
||||||
zipWithNames = zipAttrsWithNames;
|
zipWithNames = zipAttrsWithNames;
|
||||||
|
# deprecated
|
||||||
zip = builtins.trace
|
zip = builtins.trace
|
||||||
"lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
|
"lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user