Docs: migrate format of comments to doc-comments

This commit is contained in:
Johannes Kirschbauer 2025-02-12 14:38:20 +07:00
parent 8e066cbb1d
commit 88f912da48
No known key found for this signature in database
9 changed files with 1199 additions and 478 deletions

View file

@ -267,7 +267,7 @@ rec {
# Set all entries not present to null # Set all entries not present to null
mapAttrs (name: value: null) (readDir path) // value; mapAttrs (name: value: null) (readDir path) // value;
/* /**
A normalisation of a filesetTree suitable filtering with `builtins.path`: A normalisation of a filesetTree suitable filtering with `builtins.path`:
- Replace all directories that have no files with `null`. - Replace all directories that have no files with `null`.
This removes directories that would be empty This removes directories that would be empty
@ -276,7 +276,22 @@ rec {
Note that this function is strict, it evaluates the entire tree Note that this function is strict, it evaluates the entire tree
Type: Path -> filesetTree -> filesetTree
# Inputs
`path`
: 1\. Function argument
`tree`
: 2\. Function argument
# Type
```
Path -> filesetTree -> filesetTree
```
*/ */
_normaliseTreeFilter = _normaliseTreeFilter =
path: tree: path: tree:
@ -298,7 +313,7 @@ rec {
else else
tree; tree;
/* /**
A minimal normalisation of a filesetTree, intended for pretty-printing: A minimal normalisation of a filesetTree, intended for pretty-printing:
- If all children of a path are recursively included or empty directories, the path itself is also recursively included - If all children of a path are recursively included or empty directories, the path itself is also recursively included
- If all children of a path are fully excluded or empty directories, the path itself is an empty directory - If all children of a path are fully excluded or empty directories, the path itself is an empty directory
@ -307,7 +322,22 @@ rec {
Note that this function is partially lazy. Note that this function is partially lazy.
Type: Path -> filesetTree -> filesetTree (with "emptyDir"'s)
# Inputs
`path`
: 1\. Function argument
`tree`
: 2\. Function argument
# Type
```
Path -> filesetTree -> filesetTree (with "emptyDir"'s)
```
*/ */
_normaliseTreeMinimal = _normaliseTreeMinimal =
path: tree: path: tree:

View file

@ -24,9 +24,10 @@ let
in in
lib.mapAttrs mkLicense ({ lib.mapAttrs mkLicense ({
/* License identifiers from spdx.org where possible. /**
* If you cannot find your license here, then look for a similar license or License identifiers from spdx.org where possible.
* add it to this list. The URL mentioned above is a good source for inspiration. If you cannot find your license here, then look for a similar license or
add it to this list. The URL mentioned above is a good source for inspiration.
*/ */
abstyles = { abstyles = {
@ -37,7 +38,9 @@ lib.mapAttrs mkLicense ({
acsl14 = { acsl14 = {
fullName = "Anti-Capitalist Software License v1.4"; fullName = "Anti-Capitalist Software License v1.4";
url = "https://anticapitalist.software/"; url = "https://anticapitalist.software/";
/* restrictions on corporations apply for both use and redistribution */ /**
restrictions on corporations apply for both use and redistribution
*/
free = false; free = false;
redistributable = false; redistributable = false;
}; };

View file

@ -74,14 +74,16 @@ let
decls decls
)); ));
/* See https://nixos.org/manual/nixpkgs/unstable/#module-system-lib-evalModules /**
See https://nixos.org/manual/nixpkgs/unstable/#module-system-lib-evalModules
or file://./../doc/module-system/module-system.chapter.md or file://./../doc/module-system/module-system.chapter.md
!!! Please think twice before adding to this argument list! The more !!! Please think twice before adding to this argument list! The more
that is specified here instead of in the modules themselves the harder that is specified here instead of in the modules themselves the harder
it is to transparently move a set of modules to be a submodule of another it is to transparently move a set of modules to be a submodule of another
config (as the proper arguments need to be replicated at each call to config (as the proper arguments need to be replicated at each call to
evalModules) and the less declarative the module set is. */ evalModules) and the less declarative the module set is.
*/
evalModules = evalModulesArgs@ evalModules = evalModulesArgs@
{ modules { modules
, prefix ? [] , prefix ? []
@ -378,7 +380,7 @@ let
else else
m: m; m: m;
/* /**
Collects all modules recursively into the form Collects all modules recursively into the form
{ {
@ -459,12 +461,42 @@ let
in modulesPath: initialModules: args: in modulesPath: initialModules: args:
filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args); filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args);
/* Wrap a module with a default location for reporting errors. */ /**
Wrap a module with a default location for reporting errors.
# Inputs
`file`
: 1\. Function argument
`m`
: 2\. Function argument
*/
setDefaultModuleLocation = file: m: setDefaultModuleLocation = file: m:
{ _file = file; imports = [ m ]; }; { _file = file; imports = [ m ]; };
/* Massage a module into canonical form, that is, a set consisting /**
of options, config and imports attributes. */ Massage a module into canonical form, that is, a set consisting
of options, config and imports attributes.
# Inputs
`file`
: 1\. Function argument
`key`
: 2\. Function argument
`m`
: 3\. Function argument
*/
unifyModuleSyntax = file: key: m: unifyModuleSyntax = file: key: m:
let let
addMeta = config: if m ? meta addMeta = config: if m ? meta
@ -528,7 +560,8 @@ let
# works. # works.
in f (args // extraArgs); in f (args // extraArgs);
/* Merge a list of modules. This will recurse over the option /**
Merge a list of modules. This will recurse over the option
declarations in all modules, combining them into a single set. declarations in all modules, combining them into a single set.
At the same time, for each option declaration, it will merge the At the same time, for each option declaration, it will merge the
corresponding option definitions in all machines, returning them corresponding option definitions in all machines, returning them
@ -548,6 +581,17 @@ let
... ...
]; ];
} }
# Inputs
`prefix`
: 1\. Function argument
`modules`
: 2\. Function argument
*/ */
mergeModules = prefix: modules: mergeModules = prefix: modules:
mergeModules' prefix modules mergeModules' prefix modules
@ -740,7 +784,8 @@ let
in in
throw (concatStringsSep "\n\n" paragraphs); throw (concatStringsSep "\n\n" paragraphs);
/* Merge multiple option declarations into a single declaration. In /**
Merge multiple option declarations into a single declaration. In
general, there should be only one declaration of each option. general, there should be only one declaration of each option.
The exception is the options attribute, which specifies The exception is the options attribute, which specifies
sub-options. These can be specified multiple times to allow one sub-options. These can be specified multiple times to allow one
@ -750,7 +795,19 @@ let
'loc' is the list of attribute names where the option is located. 'loc' is the list of attribute names where the option is located.
'opts' is a list of modules. Each module has an options attribute which 'opts' is a list of modules. Each module has an options attribute which
correspond to the definition of 'loc' in 'opt.file'. */ correspond to the definition of 'loc' in 'opt.file'.
# Inputs
`loc`
: 1\. Function argument
`opts`
: 2\. Function argument
*/
mergeOptionDecls = mergeOptionDecls =
loc: opts: loc: opts:
foldl' (res: opt: foldl' (res: opt:
@ -819,8 +876,25 @@ let
} // typeSet } // typeSet
) { inherit loc; declarations = []; declarationPositions = []; options = []; } opts; ) { inherit loc; declarations = []; declarationPositions = []; options = []; } opts;
/* Merge all the definitions of an option to produce the final /**
config value. */ Merge all the definitions of an option to produce the final
config value.
# Inputs
`loc`
: 1\. Function argument
`opt`
: 2\. Function argument
`defs`
: 3\. Function argument
*/
evalOptionValue = loc: opt: defs: evalOptionValue = loc: opt: defs:
let let
# Add in the default value for this option, if any. # Add in the default value for this option, if any.
@ -902,7 +976,8 @@ let
else {}; else {};
}; };
/* Given a config set, expand mkMerge properties, and push down the /**
Given a config set, expand mkMerge properties, and push down the
other properties into the children. The result is a list of other properties into the children. The result is a list of
config sets that do not have properties at top-level. For config sets that do not have properties at top-level. For
example, example,
@ -916,6 +991,13 @@ let
This transform is the critical step that allows mkIf conditions This transform is the critical step that allows mkIf conditions
to refer to the full configuration without creating an infinite to refer to the full configuration without creating an infinite
recursion. recursion.
# Inputs
`cfg`
: 1\. Function argument
*/ */
pushDownProperties = cfg: pushDownProperties = cfg:
if cfg._type or "" == "merge" then if cfg._type or "" == "merge" then
@ -927,7 +1009,8 @@ let
else # FIXME: handle mkOrder? else # FIXME: handle mkOrder?
[ cfg ]; [ cfg ];
/* Given a config value, expand mkMerge properties, and discharge /**
Given a config value, expand mkMerge properties, and discharge
any mkIf conditions. That is, this is the place where mkIf any mkIf conditions. That is, this is the place where mkIf
conditions are actually evaluated. The result is a list of conditions are actually evaluated. The result is a list of
config values. For example, mkIf false x yields [], config values. For example, mkIf false x yields [],
@ -936,6 +1019,13 @@ let
mkMerge [ 1 (mkIf true 2) (mkIf true (mkIf false 3)) ] mkMerge [ 1 (mkIf true 2) (mkIf true (mkIf false 3)) ]
yields [ 1 2 ]. yields [ 1 2 ].
# Inputs
`def`
: 1\. Function argument
*/ */
dischargeProperties = def: dischargeProperties = def:
if def._type or "" == "merge" then if def._type or "" == "merge" then
@ -951,7 +1041,8 @@ let
else else
[ def ]; [ def ];
/* Given a list of config values, process the mkOverride properties, /**
Given a list of config values, process the mkOverride properties,
that is, return the values that have the highest (that is, that is, return the values that have the highest (that is,
numerically lowest) priority, and strip the mkOverride numerically lowest) priority, and strip the mkOverride
properties. For example, properties. For example,
@ -969,6 +1060,13 @@ let
] ]
Note that "z" has the default priority 100. Note that "z" has the default priority 100.
# Inputs
`defs`
: 1\. Function argument
*/ */
filterOverrides = defs: (filterOverrides' defs).values; filterOverrides = defs: (filterOverrides' defs).values;
@ -982,9 +1080,18 @@ let
inherit highestPrio; inherit highestPrio;
}; };
/* Sort a list of properties. The sort priority of a property is /**
Sort a list of properties. The sort priority of a property is
defaultOrderPriority by default, but can be overridden by wrapping the property defaultOrderPriority by default, but can be overridden by wrapping the property
using mkOrder. */ using mkOrder.
# Inputs
`defs`
: 1\. Function argument
*/
sortProperties = defs: sortProperties = defs:
let let
strip = def: strip = def:
@ -1004,14 +1111,24 @@ let
else opt // { type = opt.type.substSubModules opt.options; options = []; }; else opt // { type = opt.type.substSubModules opt.options; options = []; };
/* /**
Merge an option's definitions in a way that preserves the priority of the Merge an option's definitions in a way that preserves the priority of the
individual attributes in the option value. individual attributes in the option value.
This does not account for all option semantics, such as readOnly. This does not account for all option semantics, such as readOnly.
Type:
# Inputs
`opt`
: 1\. Function argument
# Type
```
option -> attrsOf { highestPrio, value } option -> attrsOf { highestPrio, value }
```
*/ */
mergeAttrDefinitionsWithPrio = opt: mergeAttrDefinitionsWithPrio = opt:
let let
@ -1038,7 +1155,20 @@ let
}) })
defsByAttr; defsByAttr;
/* Properties. */ /**
Properties.
# Inputs
`condition`
: 1\. Function argument
`content`
: 2\. Function argument
*/
mkIf = condition: content: mkIf = condition: content:
{ _type = "if"; { _type = "if";
@ -1116,11 +1246,25 @@ let
mkAliasIfDef = option: mkAliasIfDef = option:
mkIf (isOption option && option.isDefined); mkIf (isOption option && option.isDefined);
/* Compatibility. */ /**
Compatibility.
# Inputs
`modules`
: 1\. Function argument
`args`
: 2\. Function argument
*/
fixMergeModules = modules: args: evalModules { inherit modules args; check = false; }; fixMergeModules = modules: args: evalModules { inherit modules args; check = false; };
/* Return a module that causes a warning to be shown if the /**
Return a module that causes a warning to be shown if the
specified option is defined. For example, specified option is defined. For example,
mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ] "<replacement instructions>" mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ] "<replacement instructions>"
@ -1131,6 +1275,17 @@ let
how to achieve the same functionality without the removed option, how to achieve the same functionality without the removed option,
or alternatively a reasoning why the functionality is not needed. or alternatively a reasoning why the functionality is not needed.
replacementInstructions SHOULD be provided! replacementInstructions SHOULD be provided!
# Inputs
`optionName`
: 1\. Function argument
`replacementInstructions`
: 2\. Function argument
*/ */
mkRemovedOptionModule = optionName: replacementInstructions: mkRemovedOptionModule = optionName: replacementInstructions:
{ options, ... }: { options, ... }:
@ -1148,7 +1303,8 @@ let
}]; }];
}; };
/* Return a module that causes a warning to be shown if the /**
Return a module that causes a warning to be shown if the
specified "from" option is defined; the defined value is however specified "from" option is defined; the defined value is however
forwarded to the "to" option. This can be used to rename options forwarded to the "to" option. This can be used to rename options
while providing backward compatibility. For example, while providing backward compatibility. For example,
@ -1160,6 +1316,17 @@ let
This also copies over the priority from the aliased option to the This also copies over the priority from the aliased option to the
non-aliased option. non-aliased option.
# Inputs
`from`
: 1\. Function argument
`to`
: 2\. Function argument
*/ */
mkRenamedOptionModule = from: to: doRename { mkRenamedOptionModule = from: to: doRename {
inherit from to; inherit from to;
@ -1169,12 +1336,16 @@ let
}; };
mkRenamedOptionModuleWith = { mkRenamedOptionModuleWith = {
/* Old option path as list of strings. */ /**
Old option path as list of strings.
*/
from, from,
/* New option path as list of strings. */ /**
New option path as list of strings.
*/
to, to,
/* /**
Release number of the first release that contains the rename, ignoring backports. Release number of the first release that contains the rename, ignoring backports.
Set it to the upcoming release, matching the nixpkgs/.version file. Set it to the upcoming release, matching the nixpkgs/.version file.
*/ */
@ -1188,7 +1359,8 @@ let
"Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'."; "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'.";
}; };
/* Return a module that causes a warning to be shown if any of the "from" /**
Return a module that causes a warning to be shown if any of the "from"
option is defined; the defined values can be used in the "mergeFn" to set option is defined; the defined values can be used in the "mergeFn" to set
the "to" value. the "to" value.
This function can be used to merge multiple options into one that has a This function can be used to merge multiple options into one that has a
@ -1215,6 +1387,21 @@ let
This show a warning if any a.b.c or d.e.f is set, and set the value of This show a warning if any a.b.c or d.e.f is set, and set the value of
x.y.z to the result of the merge function x.y.z to the result of the merge function
# Inputs
`from`
: 1\. Function argument
`to`
: 2\. Function argument
`mergeFn`
: 3\. Function argument
*/ */
mkMergedOptionModule = from: to: mergeFn: mkMergedOptionModule = from: to: mergeFn:
{ config, options, ... }: { config, options, ... }:
@ -1240,7 +1427,8 @@ let
(mergeFn config))); (mergeFn config)));
}; };
/* Single "from" version of mkMergedOptionModule. /**
Single "from" version of mkMergedOptionModule.
Return a module that causes a warning to be shown if the "from" option is Return a module that causes a warning to be shown if the "from" option is
defined; the defined value can be used in the "mergeFn" to set the "to" defined; the defined value can be used in the "mergeFn" to set the "to"
value. value.
@ -1262,11 +1450,39 @@ let
This show a warning if a.b.c is set, and set the value of x.y.z to the This show a warning if a.b.c is set, and set the value of x.y.z to the
result of the change function result of the change function
# Inputs
`from`
: 1\. Function argument
`to`
: 2\. Function argument
`changeFn`
: 3\. Function argument
*/ */
mkChangedOptionModule = from: to: changeFn: mkChangedOptionModule = from: to: changeFn:
mkMergedOptionModule [ from ] to changeFn; mkMergedOptionModule [ from ] to changeFn;
/* Like mkRenamedOptionModule, but doesn't show a warning. */ /**
Like mkRenamedOptionModule, but doesn't show a warning.
# Inputs
`from`
: 1\. Function argument
`to`
: 2\. Function argument
*/
mkAliasOptionModule = from: to: doRename { mkAliasOptionModule = from: to: doRename {
inherit from to; inherit from to;
visible = true; visible = true;
@ -1274,13 +1490,15 @@ let
use = id; use = id;
}; };
/* Transitional version of mkAliasOptionModule that uses MD docs. /**
Transitional version of mkAliasOptionModule that uses MD docs.
This function is no longer necessary and merely an alias of `mkAliasOptionModule`. This function is no longer necessary and merely an alias of `mkAliasOptionModule`.
*/ */
mkAliasOptionModuleMD = mkAliasOptionModule; mkAliasOptionModuleMD = mkAliasOptionModule;
/* mkDerivedConfig : Option a -> (a -> Definition b) -> Definition b /**
mkDerivedConfig : Option a -> (a -> Definition b) -> Definition b
Create config definitions with the same priority as the definition of another option. Create config definitions with the same priority as the definition of another option.
This should be used for option definitions where one option sets the value of another as a convenience. This should be used for option definitions where one option sets the value of another as a convenience.
@ -1288,6 +1506,17 @@ let
value using `mkDerivedConfig options.text (pkgs.writeText "filename.conf")`. value using `mkDerivedConfig options.text (pkgs.writeText "filename.conf")`.
It takes care of setting the right priority using `mkOverride`. It takes care of setting the right priority using `mkOverride`.
# Inputs
`opt`
: 1\. Function argument
`f`
: 2\. Function argument
*/ */
# TODO: make the module system error message include information about `opt` in # TODO: make the module system error message include information about `opt` in
# error messages about conflicts. E.g. introduce a variation of `mkOverride` which # error messages about conflicts. E.g. introduce a variation of `mkOverride` which
@ -1300,7 +1529,7 @@ let
(opt.highestPrio or defaultOverridePriority) (opt.highestPrio or defaultOverridePriority)
(f opt.value); (f opt.value);
/* /**
Return a module that help declares an option that has been renamed. Return a module that help declares an option that has been renamed.
When a value is defined for the old option, it is forwarded to the `to` option. When a value is defined for the old option, it is forwarded to the `to` option.
*/ */
@ -1450,18 +1679,34 @@ let
modulePath: staticArg: modulePath: staticArg:
lib.setDefaultModuleLocation modulePath (import modulePath staticArg); lib.setDefaultModuleLocation modulePath (import modulePath staticArg);
/* Use this function to import a JSON file as NixOS configuration. /**
Use this function to import a JSON file as NixOS configuration.
modules.importJSON :: path -> attrs modules.importJSON :: path -> attrs
# Inputs
`file`
: 1\. Function argument
*/ */
importJSON = file: { importJSON = file: {
_file = file; _file = file;
config = lib.importJSON file; config = lib.importJSON file;
}; };
/* Use this function to import a TOML file as NixOS configuration. /**
Use this function to import a TOML file as NixOS configuration.
modules.importTOML :: path -> attrs modules.importTOML :: path -> attrs
# Inputs
`file`
: 1\. Function argument
*/ */
importTOML = file: { importTOML = file: {
_file = file; _file = file;

View file

@ -16,7 +16,7 @@ let
inherit (lib.lists) last; inherit (lib.lists) last;
/* /**
IPv6 addresses are 128-bit identifiers. The preferred form is 'x:x:x:x:x:x:x:x', IPv6 addresses are 128-bit identifiers. The preferred form is 'x:x:x:x:x:x:x:x',
where the 'x's are one to four hexadecimal digits of the eight 16-bit pieces of where the 'x's are one to four hexadecimal digits of the eight 16-bit pieces of
the address. See RFC 4291. the address. See RFC 4291.
@ -138,7 +138,7 @@ let
parseIpv6FromString = addr: parseExpandedIpv6 (expandIpv6 addr); parseIpv6FromString = addr: parseExpandedIpv6 (expandIpv6 addr);
in in
{ {
/* /**
Internally, an IPv6 address is stored as a list of 16-bit integers with 8 Internally, an IPv6 address is stored as a list of 16-bit integers with 8
elements. Wherever you see `IPv6` in internal functions docs, it means that elements. Wherever you see `IPv6` in internal functions docs, it means that
it is a list of integers produced by one of the internal parsers, such as it is a list of integers produced by one of the internal parsers, such as

View file

@ -426,17 +426,28 @@ rec {
else if all isInt list && all (x: x == head list) list then head list else if all isInt list && all (x: x == head list) list then head list
else throw "Cannot merge definitions of `${showOption loc}'. Definition values:${showDefs defs}"; else throw "Cannot merge definitions of `${showOption loc}'. Definition values:${showDefs defs}";
/* /**
Require a single definition. Require a single definition.
WARNING: Does not perform nested checks, as this does not run the merge function! WARNING: Does not perform nested checks, as this does not run the merge function!
*/ */
mergeOneOption = mergeUniqueOption { message = ""; }; mergeOneOption = mergeUniqueOption { message = ""; };
/* /**
Require a single definition. Require a single definition.
NOTE: When the type is not checked completely by check, pass a merge function for further checking (of sub-attributes, etc). NOTE: When the type is not checked completely by check, pass a merge function for further checking (of sub-attributes, etc).
# Inputs
`loc`
: 2\. Function argument
`defs`
: 3\. Function argument
*/ */
mergeUniqueOption = args@{ mergeUniqueOption = args@{
message, message,
@ -452,7 +463,20 @@ rec {
assert length defs > 1; assert length defs > 1;
throw "The option `${showOption loc}' is defined multiple times while it's expected to be unique.\n${message}\nDefinition values:${showDefs defs}\n${prioritySuggestion}"; throw "The option `${showOption loc}' is defined multiple times while it's expected to be unique.\n${message}\nDefinition values:${showDefs defs}\n${prioritySuggestion}";
/* "Merge" option definitions by checking that they all have the same value. */ /**
"Merge" option definitions by checking that they all have the same value.
# Inputs
`loc`
: 1\. Function argument
`defs`
: 2\. Function argument
*/
mergeEqualOption = loc: defs: mergeEqualOption = loc: defs:
if defs == [] then abort "This case should never happen." if defs == [] then abort "This case should never happen."
# Return early if we only have one element # Return early if we only have one element
@ -465,23 +489,47 @@ rec {
else else
first) (head defs) (tail defs)).value; first) (head defs) (tail defs)).value;
/* Extracts values of all "value" keys of the given list. /**
Extracts values of all "value" keys of the given list.
Type: getValues :: [ { value :: a; } ] -> [a] # Type
Example: ```
getValues :: [ { value :: a; } ] -> [a]
```
# Examples
:::{.example}
## `getValues` usage example
```nix
getValues [ { value = 1; } { value = 2; } ] // => [ 1 2 ] getValues [ { value = 1; } { value = 2; } ] // => [ 1 2 ]
getValues [ ] // => [ ] getValues [ ] // => [ ]
```
:::
*/ */
getValues = map (x: x.value); getValues = map (x: x.value);
/* Extracts values of all "file" keys of the given list /**
Extracts values of all "file" keys of the given list
Type: getFiles :: [ { file :: a; } ] -> [a] # Type
Example: ```
getFiles :: [ { file :: a; } ] -> [a]
```
# Examples
:::{.example}
## `getFiles` usage example
```nix
getFiles [ { file = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ] getFiles [ { file = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ]
getFiles [ ] // => [ ] getFiles [ ] // => [ ]
```
:::
*/ */
getFiles = map (x: x.file); getFiles = map (x: x.file);
@ -530,7 +578,8 @@ rec {
[ docOption ] ++ optionals subOptionsVisible subOptions) (collect isOption options); [ docOption ] ++ optionals subOptionsVisible subOptions) (collect isOption options);
/* This function recursively removes all derivation attributes from /**
This function recursively removes all derivation attributes from
`x` except for the `name` attribute. `x` except for the `name` attribute.
This is to make the generation of `options.xml` much more This is to make the generation of `options.xml` much more
@ -540,6 +589,13 @@ rec {
This function was made obsolete by renderOptionValue and is kept for This function was made obsolete by renderOptionValue and is kept for
compatibility with out-of-tree code. compatibility with out-of-tree code.
# Inputs
`x`
: 1\. Function argument
*/ */
scrubOptionValue = x: scrubOptionValue = x:
if isDerivation x then if isDerivation x then
@ -549,8 +605,16 @@ rec {
else x; else x;
/* Ensures that the given option value (default or example) is a `_type`d string /**
Ensures that the given option value (default or example) is a `_type`d string
by rendering Nix values to `literalExpression`s. by rendering Nix values to `literalExpression`s.
# Inputs
`v`
: 1\. Function argument
*/ */
renderOptionValue = v: renderOptionValue = v:
if v ? _type && v ? text then v if v ? _type && v ? text then v
@ -560,10 +624,18 @@ rec {
} v); } v);
/* For use in the `defaultText` and `example` option attributes. Causes the /**
For use in the `defaultText` and `example` option attributes. Causes the
given string to be rendered verbatim in the documentation as Nix code. This given string to be rendered verbatim in the documentation as Nix code. This
is necessary for complex values, e.g. functions, or values that depend on is necessary for complex values, e.g. functions, or values that depend on
other values or packages. other values or packages.
# Inputs
`text`
: 1\. Function argument
*/ */
literalExpression = text: literalExpression = text:
if ! isString text then throw "literalExpression expects a string." if ! isString text then throw "literalExpression expects a string."
@ -571,9 +643,17 @@ rec {
literalExample = lib.warn "lib.literalExample is deprecated, use lib.literalExpression instead, or use lib.literalMD for a non-Nix description." literalExpression; literalExample = lib.warn "lib.literalExample is deprecated, use lib.literalExpression instead, or use lib.literalMD for a non-Nix description." literalExpression;
/* For use in the `defaultText` and `example` option attributes. Causes the /**
For use in the `defaultText` and `example` option attributes. Causes the
given MD text to be inserted verbatim in the documentation, for when given MD text to be inserted verbatim in the documentation, for when
a `literalExpression` would be too hard to read. a `literalExpression` would be too hard to read.
# Inputs
`text`
: 1\. Function argument
*/ */
literalMD = text: literalMD = text:
if ! isString text then throw "literalMD expects a string." if ! isString text then throw "literalMD expects a string."
@ -581,10 +661,23 @@ rec {
# Helper functions. # Helper functions.
/* Convert an option, described as a list of the option parts to a /**
Convert an option, described as a list of the option parts to a
human-readable version. human-readable version.
Example:
# Inputs
`parts`
: 1\. Function argument
# Examples
:::{.example}
## `showOption` usage example
```nix
(showOption ["foo" "bar" "baz"]) == "foo.bar.baz" (showOption ["foo" "bar" "baz"]) == "foo.bar.baz"
(showOption ["foo" "bar.baz" "tux"]) == "foo.\"bar.baz\".tux" (showOption ["foo" "bar.baz" "tux"]) == "foo.\"bar.baz\".tux"
(showOption ["windowManager" "2bwm" "enable"]) == "windowManager.\"2bwm\".enable" (showOption ["windowManager" "2bwm" "enable"]) == "windowManager.\"2bwm\".enable"
@ -593,6 +686,9 @@ rec {
(showOption ["foo" "*" "bar"]) == "foo.*.bar" (showOption ["foo" "*" "bar"]) == "foo.*.bar"
(showOption ["foo" "<name>" "bar"]) == "foo.<name>.bar" (showOption ["foo" "<name>" "bar"]) == "foo.<name>.bar"
(showOption ["foo" "<myPlaceholder>" "bar"]) == "foo.<myPlaceholder>.bar" (showOption ["foo" "<myPlaceholder>" "bar"]) == "foo.<myPlaceholder>.bar"
```
:::
*/ */
showOption = parts: let showOption = parts: let
# If the part is a named placeholder of the form "<...>" don't escape it. # If the part is a named placeholder of the form "<...>" don't escape it.

View file

@ -165,7 +165,7 @@ in
# No rec! Add dependencies on this file at the top. # No rec! Add dependencies on this file at the top.
{ {
/* /**
Append a subpath string to a path. Append a subpath string to a path.
Like `path + ("/" + string)` but safer, because it errors instead of returning potentially surprising results. Like `path + ("/" + string)` but safer, because it errors instead of returning potentially surprising results.
@ -178,10 +178,28 @@ in
append p s == append p (subpath.normalise s) append p s == append p (subpath.normalise s)
Type:
append :: Path -> String -> Path
Example: # Inputs
`path`
: The absolute path to append to
`subpath`
: The subpath string to append
# Type
```
append :: Path -> String -> Path
```
# Examples
:::{.example}
## `append` usage example
```nix
append /foo "bar/baz" append /foo "bar/baz"
=> /foo/bar/baz => /foo/bar/baz
@ -206,6 +224,9 @@ in
=> <error> => <error>
append /foo "../bar" append /foo "../bar"
=> <error> => <error>
```
:::
*/ */
append = append =
# The absolute path to append to # The absolute path to append to
@ -219,7 +240,7 @@ in
${subpathInvalidReason subpath}''; ${subpathInvalidReason subpath}'';
path + ("/" + subpath); path + ("/" + subpath);
/* /**
Whether the first path is a component-wise prefix of the second path. Whether the first path is a component-wise prefix of the second path.
Laws: Laws:
@ -228,10 +249,24 @@ in
- `hasPrefix` is a [non-strict partial order](https://en.wikipedia.org/wiki/Partially_ordered_set#Non-strict_partial_order) over the set of all path values. - `hasPrefix` is a [non-strict partial order](https://en.wikipedia.org/wiki/Partially_ordered_set#Non-strict_partial_order) over the set of all path values.
Type:
hasPrefix :: Path -> Path -> Bool
Example: # Inputs
`path1`
: 1\. Function argument
# Type
```
hasPrefix :: Path -> Path -> Bool
```
# Examples
:::{.example}
## `hasPrefix` usage example
```nix
hasPrefix /foo /foo/bar hasPrefix /foo /foo/bar
=> true => true
hasPrefix /foo /foo hasPrefix /foo /foo
@ -240,6 +275,9 @@ in
=> false => false
hasPrefix /. /foo hasPrefix /. /foo
=> true => true
```
:::
*/ */
hasPrefix = hasPrefix =
path1: path1:
@ -261,7 +299,7 @@ in
take (length path1Deconstructed.components) path2Deconstructed.components take (length path1Deconstructed.components) path2Deconstructed.components
== path1Deconstructed.components; == path1Deconstructed.components;
/* /**
Remove the first path as a component-wise prefix from the second path. Remove the first path as a component-wise prefix from the second path.
The result is a [normalised subpath string](#function-library-lib.path.subpath.normalise). The result is a [normalised subpath string](#function-library-lib.path.subpath.normalise).
@ -271,10 +309,24 @@ in
removePrefix p (append p s) == subpath.normalise s removePrefix p (append p s) == subpath.normalise s
Type:
removePrefix :: Path -> Path -> String
Example: # Inputs
`path1`
: 1\. Function argument
# Type
```
removePrefix :: Path -> Path -> String
```
# Examples
:::{.example}
## `removePrefix` usage example
```nix
removePrefix /foo /foo/bar/baz removePrefix /foo /foo/bar/baz
=> "./bar/baz" => "./bar/baz"
removePrefix /foo /foo removePrefix /foo /foo
@ -283,6 +335,9 @@ in
=> <error> => <error>
removePrefix /. /foo removePrefix /. /foo
=> "./foo" => "./foo"
```
:::
*/ */
removePrefix = removePrefix =
path1: path1:
@ -310,7 +365,7 @@ in
second argument: "${toString path2}" with root "${toString path2Deconstructed.root}"''; second argument: "${toString path2}" with root "${toString path2Deconstructed.root}"'';
joinRelPath components; joinRelPath components;
/* /**
Split the filesystem root from a [path](https://nixos.org/manual/nix/stable/language/values.html#type-path). Split the filesystem root from a [path](https://nixos.org/manual/nix/stable/language/values.html#type-path).
The result is an attribute set with these attributes: The result is an attribute set with these attributes:
- `root`: The filesystem root of the path, meaning that this directory has no parent directory. - `root`: The filesystem root of the path, meaning that this directory has no parent directory.
@ -328,10 +383,24 @@ in
dirOf (splitRoot p).root == (splitRoot p).root dirOf (splitRoot p).root == (splitRoot p).root
Type:
splitRoot :: Path -> { root :: Path, subpath :: String }
Example: # Inputs
`path`
: The path to split the root off of
# Type
```
splitRoot :: Path -> { root :: Path, subpath :: String }
```
# Examples
:::{.example}
## `splitRoot` usage example
```nix
splitRoot /foo/bar splitRoot /foo/bar
=> { root = /.; subpath = "./foo/bar"; } => { root = /.; subpath = "./foo/bar"; }
@ -344,6 +413,9 @@ in
splitRoot "/foo/bar" splitRoot "/foo/bar"
=> <error> => <error>
```
:::
*/ */
splitRoot = splitRoot =
# The path to split the root off of # The path to split the root off of
@ -358,7 +430,7 @@ in
subpath = joinRelPath deconstructed.components; subpath = joinRelPath deconstructed.components;
}; };
/* /**
Whether a [path](https://nixos.org/manual/nix/stable/language/values.html#type-path) Whether a [path](https://nixos.org/manual/nix/stable/language/values.html#type-path)
has a [store path](https://nixos.org/manual/nix/stable/store/store-path.html#store-path) has a [store path](https://nixos.org/manual/nix/stable/store/store-path.html#store-path)
as a prefix. as a prefix.
@ -371,10 +443,24 @@ in
which occur when Nix files in the store use relative path expressions. which occur when Nix files in the store use relative path expressions.
::: :::
Type:
hasStorePathPrefix :: Path -> Bool
Example: # Inputs
`path`
: 1\. Function argument
# Type
```
hasStorePathPrefix :: Path -> Bool
```
# Examples
:::{.example}
## `hasStorePathPrefix` usage example
```nix
# Subpaths of derivation outputs have a store path as a prefix # Subpaths of derivation outputs have a store path as a prefix
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo/bar/baz hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo/bar/baz
=> true => true
@ -398,6 +484,9 @@ in
# Store derivations are also store paths themselves # Store derivations are also store paths themselves
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo.drv hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo.drv
=> true => true
```
:::
*/ */
hasStorePathPrefix = hasStorePathPrefix =
path: path:
@ -414,7 +503,7 @@ in
"lib.path.hasStorePathPrefix: Argument has a filesystem root (${toString deconstructed.root}) that's not /, which is currently not supported."; "lib.path.hasStorePathPrefix: Argument has a filesystem root (${toString deconstructed.root}) that's not /, which is currently not supported.";
componentsHaveStorePathPrefix deconstructed.components; componentsHaveStorePathPrefix deconstructed.components;
/* /**
Whether a value is a valid subpath string. Whether a value is a valid subpath string.
A subpath string points to a specific file or directory within an absolute base directory. A subpath string points to a specific file or directory within an absolute base directory.
@ -428,10 +517,24 @@ in
- The string doesn't contain any `..` path components. - The string doesn't contain any `..` path components.
Type:
subpath.isValid :: String -> Bool
Example: # Inputs
`value`
: The value to check
# Type
```
subpath.isValid :: String -> Bool
```
# Examples
:::{.example}
## `subpath.isValid` usage example
```nix
# Not a string # Not a string
subpath.isValid null subpath.isValid null
=> false => false
@ -455,12 +558,15 @@ in
# Doesn't need to be normalised # Doesn't need to be normalised
subpath.isValid "./foo//bar/" subpath.isValid "./foo//bar/"
=> true => true
```
:::
*/ */
subpath.isValid = subpath.isValid =
# The value to check # The value to check
value: subpathInvalidReason value == null; value: subpathInvalidReason value == null;
/* /**
Join subpath strings together using `/`, returning a normalised subpath string. Join subpath strings together using `/`, returning a normalised subpath string.
Like `concatStringsSep "/"` but safer, specifically: Like `concatStringsSep "/"` but safer, specifically:
@ -492,10 +598,24 @@ in
ps != [] -> subpath.join ps == subpath.normalise (concatStringsSep "/" ps) ps != [] -> subpath.join ps == subpath.normalise (concatStringsSep "/" ps)
Type:
subpath.join :: [ String ] -> String
Example: # Inputs
`subpaths`
: The list of subpaths to join together
# Type
```
subpath.join :: [ String ] -> String
```
# Examples
:::{.example}
## `subpath.join` usage example
```nix
subpath.join [ "foo" "bar/baz" ] subpath.join [ "foo" "bar/baz" ]
=> "./foo/bar/baz" => "./foo/bar/baz"
@ -516,6 +636,9 @@ in
=> <error> => <error>
subpath.join [ "../foo" ] subpath.join [ "../foo" ]
=> <error> => <error>
```
:::
*/ */
subpath.join = subpath.join =
# The list of subpaths to join together # The list of subpaths to join together
@ -537,7 +660,7 @@ in
${subpathInvalidReason path}'' ${subpathInvalidReason path}''
) 0 subpaths; ) 0 subpaths;
/* /**
Split [a subpath](#function-library-lib.path.subpath.isValid) into its path component strings. Split [a subpath](#function-library-lib.path.subpath.isValid) into its path component strings.
Throw an error if the subpath isn't valid. Throw an error if the subpath isn't valid.
Note that the returned path components are also [valid subpath strings](#function-library-lib.path.subpath.isValid), though they are intentionally not [normalised](#function-library-lib.path.subpath.normalise). Note that the returned path components are also [valid subpath strings](#function-library-lib.path.subpath.isValid), though they are intentionally not [normalised](#function-library-lib.path.subpath.normalise).
@ -548,10 +671,24 @@ in
subpath.join (subpath.components s) == subpath.normalise s subpath.join (subpath.components s) == subpath.normalise s
Type:
subpath.components :: String -> [ String ]
Example: # Inputs
`subpath`
: The subpath string to split into components
# Type
```
subpath.components :: String -> [ String ]
```
# Examples
:::{.example}
## `subpath.components` usage example
```nix
subpath.components "." subpath.components "."
=> [ ] => [ ]
@ -560,6 +697,9 @@ in
subpath.components "/foo" subpath.components "/foo"
=> <error> => <error>
```
:::
*/ */
subpath.components = subpath.components =
# The subpath string to split into components # The subpath string to split into components
@ -569,7 +709,7 @@ in
${subpathInvalidReason subpath}''; ${subpathInvalidReason subpath}'';
splitRelPath subpath; splitRelPath subpath;
/* /**
Normalise a subpath. Throw an error if the subpath isn't [valid](#function-library-lib.path.subpath.isValid). Normalise a subpath. Throw an error if the subpath isn't [valid](#function-library-lib.path.subpath.isValid).
- Limit repeating `/` to a single one. - Limit repeating `/` to a single one.
@ -602,10 +742,24 @@ in
builtins.tryEval (subpath.normalise p)).success == subpath.isValid p builtins.tryEval (subpath.normalise p)).success == subpath.isValid p
Type:
subpath.normalise :: String -> String
Example: # Inputs
`subpath`
: The subpath string to normalise
# Type
```
subpath.normalise :: String -> String
```
# Examples
:::{.example}
## `subpath.normalise` usage example
```nix
# limit repeating `/` to a single one # limit repeating `/` to a single one
subpath.normalise "foo//bar" subpath.normalise "foo//bar"
=> "./foo/bar" => "./foo/bar"
@ -641,6 +795,9 @@ in
# error on absolute path # error on absolute path
subpath.normalise "/foo" subpath.normalise "/foo"
=> <error> => <error>
```
:::
*/ */
subpath.normalise = subpath.normalise =
# The subpath string to normalise # The subpath string to normalise

View file

@ -18,10 +18,21 @@ let
pathIsRegularFile pathIsRegularFile
; ;
/* /**
A basic filter for `cleanSourceWith` that removes A basic filter for `cleanSourceWith` that removes
directories of version control system, backup files (*~) directories of version control system, backup files (*~)
and some generated files. and some generated files.
# Inputs
`name`
: 1\. Function argument
`type`
: 2\. Function argument
*/ */
cleanSourceFilter = cleanSourceFilter =
name: type: name: type:
@ -52,11 +63,26 @@ let
(type == "unknown") (type == "unknown")
); );
/* /**
Filters a source tree removing version control files and directories using cleanSourceFilter. Filters a source tree removing version control files and directories using cleanSourceFilter.
Example:
# Inputs
`src`
: 1\. Function argument
# Examples
:::{.example}
## `cleanSource` usage example
```nix
cleanSource ./. cleanSource ./.
```
:::
*/ */
cleanSource = cleanSource =
src: src:
@ -65,12 +91,17 @@ let
inherit src; inherit src;
}; };
/* /**
Like `builtins.filterSource`, except it will compose with itself, Like `builtins.filterSource`, except it will compose with itself,
allowing you to chain multiple calls together without any allowing you to chain multiple calls together without any
intermediate copies being put in the nix store. intermediate copies being put in the nix store.
Example:
# Examples
:::{.example}
## `cleanSourceWith` usage example
```nix
lib.cleanSourceWith { lib.cleanSourceWith {
filter = f; filter = f;
src = lib.cleanSourceWith { src = lib.cleanSourceWith {
@ -82,6 +113,9 @@ let
builtins.filterSource f (builtins.filterSource g ./.) builtins.filterSource f (builtins.filterSource g ./.)
# Fails! # Fails!
```
:::
*/ */
cleanSourceWith = cleanSourceWith =
{ {
@ -107,10 +141,21 @@ let
name = if name != null then name else orig.name; name = if name != null then name else orig.name;
}; };
/* /**
Add logging to a source, for troubleshooting the filtering behavior. Add logging to a source, for troubleshooting the filtering behavior.
Type:
# Inputs
`src`
: Source to debug. The returned source will behave like this source, but also log its filter invocations.
# Type
```
sources.trace :: sourceLike -> Source sources.trace :: sourceLike -> Source
```
*/ */
trace = trace =
# Source to debug. The returned source will behave like this source, but also log its filter invocations. # Source to debug. The returned source will behave like this source, but also log its filter invocations.
@ -133,10 +178,30 @@ let
satisfiesSubpathInvariant = src ? satisfiesSubpathInvariant && src.satisfiesSubpathInvariant; satisfiesSubpathInvariant = src ? satisfiesSubpathInvariant && src.satisfiesSubpathInvariant;
}; };
/* /**
Filter sources by a list of regular expressions. Filter sources by a list of regular expressions.
Example: src = sourceByRegex ./my-subproject [".*\.py$" "^database.sql$"]
# Inputs
`src`
: 1\. Function argument
`regexes`
: 2\. Function argument
# Examples
:::{.example}
## `sourceByRegex` usage example
```nix
src = sourceByRegex ./my-subproject [".*\.py$" "^database.sql$"]
```
:::
*/ */
sourceByRegex = sourceByRegex =
src: regexes: src: regexes:
@ -155,16 +220,38 @@ let
inherit src; inherit src;
}; };
/* /**
Get all files ending with the specified suffices from the given Get all files ending with the specified suffices from the given
source directory or its descendants, omitting files that do not match source directory or its descendants, omitting files that do not match
any suffix. The result of the example below will include files like any suffix. The result of the example below will include files like
`./dir/module.c` and `./dir/subdir/doc.xml` if present. `./dir/module.c` and `./dir/subdir/doc.xml` if present.
Type: sourceLike -> [String] -> Source
Example: # Inputs
`src`
: Path or source containing the files to be returned
`exts`
: A list of file suffix strings
# Type
```
sourceLike -> [String] -> Source
```
# Examples
:::{.example}
## `sourceFilesBySuffices` usage example
```nix
sourceFilesBySuffices ./. [ ".xml" ".c" ] sourceFilesBySuffices ./. [ ".xml" ".c" ]
```
:::
*/ */
sourceFilesBySuffices = sourceFilesBySuffices =
# Path or source containing the files to be returned # Path or source containing the files to be returned
@ -183,10 +270,26 @@ let
pathIsGitRepo = path: (_commitIdFromGitRepoOrError path) ? value; pathIsGitRepo = path: (_commitIdFromGitRepoOrError path) ? value;
/* /**
Get the commit id of a git repo. Get the commit id of a git repo.
Example: commitIdFromGitRepo <nixpkgs/.git>
# Inputs
`path`
: 1\. Function argument
# Examples
:::{.example}
## `commitIdFromGitRepo` usage example
```nix
commitIdFromGitRepo <nixpkgs/.git>
```
:::
*/ */
commitIdFromGitRepo = commitIdFromGitRepo =
path: path:

View file

@ -1,6 +1,6 @@
{ lib }: { lib }:
/* /**
Usage: Usage:
You define you custom builder script by adding all build steps to a list. You define you custom builder script by adding all build steps to a list.
for example: for example:

View file

@ -3,62 +3,149 @@
rec { rec {
/* /**
Break a version string into its component parts. Break a version string into its component parts.
Example:
# Examples
:::{.example}
## `splitVersion` usage example
```nix
splitVersion "1.2.3" splitVersion "1.2.3"
=> ["1" "2" "3"] => ["1" "2" "3"]
```
:::
*/ */
splitVersion = builtins.splitVersion; splitVersion = builtins.splitVersion;
/* /**
Get the major version string from a string. Get the major version string from a string.
Example:
# Inputs
`v`
: 1\. Function argument
# Examples
:::{.example}
## `major` usage example
```nix
major "1.2.3" major "1.2.3"
=> "1" => "1"
```
:::
*/ */
major = v: builtins.elemAt (splitVersion v) 0; major = v: builtins.elemAt (splitVersion v) 0;
/* /**
Get the minor version string from a string. Get the minor version string from a string.
Example:
# Inputs
`v`
: 1\. Function argument
# Examples
:::{.example}
## `minor` usage example
```nix
minor "1.2.3" minor "1.2.3"
=> "2" => "2"
```
:::
*/ */
minor = v: builtins.elemAt (splitVersion v) 1; minor = v: builtins.elemAt (splitVersion v) 1;
/* /**
Get the patch version string from a string. Get the patch version string from a string.
Example:
# Inputs
`v`
: 1\. Function argument
# Examples
:::{.example}
## `patch` usage example
```nix
patch "1.2.3" patch "1.2.3"
=> "3" => "3"
```
:::
*/ */
patch = v: builtins.elemAt (splitVersion v) 2; patch = v: builtins.elemAt (splitVersion v) 2;
/* /**
Get string of the first two parts (major and minor) Get string of the first two parts (major and minor)
of a version string. of a version string.
Example:
# Inputs
`v`
: 1\. Function argument
# Examples
:::{.example}
## `majorMinor` usage example
```nix
majorMinor "1.2.3" majorMinor "1.2.3"
=> "1.2" => "1.2"
```
:::
*/ */
majorMinor = v: builtins.concatStringsSep "." (lib.take 2 (splitVersion v)); majorMinor = v: builtins.concatStringsSep "." (lib.take 2 (splitVersion v));
/* /**
Pad a version string with zeros to match the given number of components. Pad a version string with zeros to match the given number of components.
Example:
# Inputs
`n`
: 1\. Function argument
`version`
: 2\. Function argument
# Examples
:::{.example}
## `pad` usage example
```nix
pad 3 "1.2" pad 3 "1.2"
=> "1.2.0" => "1.2.0"
pad 3 "1.3-rc1" pad 3 "1.3-rc1"
=> "1.3.0-rc1" => "1.3.0-rc1"
pad 3 "1.2.3.4" pad 3 "1.2.3.4"
=> "1.2.3" => "1.2.3"
```
:::
*/ */
pad = pad =
n: version: n: version: