mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-09 11:03:15 +03:00
Docs: migrate format of comments to doc-comments
This commit is contained in:
parent
8e066cbb1d
commit
88f912da48
9 changed files with 1199 additions and 478 deletions
|
@ -267,7 +267,7 @@ rec {
|
|||
# Set all entries not present to null
|
||||
mapAttrs (name: value: null) (readDir path) // value;
|
||||
|
||||
/*
|
||||
/**
|
||||
A normalisation of a filesetTree suitable filtering with `builtins.path`:
|
||||
- Replace all directories that have no files with `null`.
|
||||
This removes directories that would be empty
|
||||
|
@ -276,7 +276,22 @@ rec {
|
|||
|
||||
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 =
|
||||
path: tree:
|
||||
|
@ -298,7 +313,7 @@ rec {
|
|||
else
|
||||
tree;
|
||||
|
||||
/*
|
||||
/**
|
||||
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 fully excluded or empty directories, the path itself is an empty directory
|
||||
|
@ -307,7 +322,22 @@ rec {
|
|||
|
||||
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 =
|
||||
path: tree:
|
||||
|
|
|
@ -24,10 +24,11 @@ let
|
|||
|
||||
in
|
||||
lib.mapAttrs mkLicense ({
|
||||
/* License identifiers from spdx.org where possible.
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
License identifiers from spdx.org where possible.
|
||||
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 = {
|
||||
spdxId = "Abstyles";
|
||||
|
@ -37,7 +38,9 @@ lib.mapAttrs mkLicense ({
|
|||
acsl14 = {
|
||||
fullName = "Anti-Capitalist Software License v1.4";
|
||||
url = "https://anticapitalist.software/";
|
||||
/* restrictions on corporations apply for both use and redistribution */
|
||||
/**
|
||||
restrictions on corporations apply for both use and redistribution
|
||||
*/
|
||||
free = false;
|
||||
redistributable = false;
|
||||
};
|
||||
|
|
591
lib/modules.nix
591
lib/modules.nix
|
@ -74,14 +74,16 @@ let
|
|||
decls
|
||||
));
|
||||
|
||||
/* See https://nixos.org/manual/nixpkgs/unstable/#module-system-lib-evalModules
|
||||
or file://./../doc/module-system/module-system.chapter.md
|
||||
/**
|
||||
See https://nixos.org/manual/nixpkgs/unstable/#module-system-lib-evalModules
|
||||
or file://./../doc/module-system/module-system.chapter.md
|
||||
|
||||
!!! Please think twice before adding to this argument list! The more
|
||||
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
|
||||
config (as the proper arguments need to be replicated at each call to
|
||||
evalModules) and the less declarative the module set is. */
|
||||
!!! Please think twice before adding to this argument list! The more
|
||||
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
|
||||
config (as the proper arguments need to be replicated at each call to
|
||||
evalModules) and the less declarative the module set is.
|
||||
*/
|
||||
evalModules = evalModulesArgs@
|
||||
{ modules
|
||||
, prefix ? []
|
||||
|
@ -378,30 +380,30 @@ let
|
|||
else
|
||||
m: m;
|
||||
|
||||
/*
|
||||
Collects all modules recursively into the form
|
||||
/**
|
||||
Collects all modules recursively into the form
|
||||
|
||||
{
|
||||
disabled = [ <list of disabled modules> ];
|
||||
# All modules of the main module list
|
||||
modules = [
|
||||
{
|
||||
key = <key1>;
|
||||
module = <module for key1>;
|
||||
# All modules imported by the module for key1
|
||||
modules = [
|
||||
{
|
||||
key = <key1-1>;
|
||||
module = <module for key1-1>;
|
||||
# All modules imported by the module for key1-1
|
||||
modules = [ ... ];
|
||||
}
|
||||
...
|
||||
];
|
||||
}
|
||||
...
|
||||
];
|
||||
}
|
||||
{
|
||||
disabled = [ <list of disabled modules> ];
|
||||
# All modules of the main module list
|
||||
modules = [
|
||||
{
|
||||
key = <key1>;
|
||||
module = <module for key1>;
|
||||
# All modules imported by the module for key1
|
||||
modules = [
|
||||
{
|
||||
key = <key1-1>;
|
||||
module = <module for key1-1>;
|
||||
# All modules imported by the module for key1-1
|
||||
modules = [ ... ];
|
||||
}
|
||||
...
|
||||
];
|
||||
}
|
||||
...
|
||||
];
|
||||
}
|
||||
*/
|
||||
collectStructuredModules =
|
||||
let
|
||||
|
@ -459,12 +461,42 @@ let
|
|||
in modulesPath: 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:
|
||||
{ _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:
|
||||
let
|
||||
addMeta = config: if m ? meta
|
||||
|
@ -528,26 +560,38 @@ let
|
|||
# works.
|
||||
in f (args // extraArgs);
|
||||
|
||||
/* Merge a list of modules. This will recurse over the option
|
||||
declarations in all modules, combining them into a single set.
|
||||
At the same time, for each option declaration, it will merge the
|
||||
corresponding option definitions in all machines, returning them
|
||||
in the ‘value’ attribute of each option.
|
||||
/**
|
||||
Merge a list of modules. This will recurse over the option
|
||||
declarations in all modules, combining them into a single set.
|
||||
At the same time, for each option declaration, it will merge the
|
||||
corresponding option definitions in all machines, returning them
|
||||
in the ‘value’ attribute of each option.
|
||||
|
||||
This returns a set like
|
||||
{
|
||||
# A recursive set of options along with their final values
|
||||
matchedOptions = {
|
||||
foo = { _type = "option"; value = "option value of foo"; ... };
|
||||
bar.baz = { _type = "option"; value = "option value of bar.baz"; ... };
|
||||
...
|
||||
};
|
||||
# A list of definitions that weren't matched by any option
|
||||
unmatchedDefns = [
|
||||
{ file = "file.nix"; prefix = [ "qux" ]; value = "qux"; }
|
||||
...
|
||||
];
|
||||
}
|
||||
This returns a set like
|
||||
{
|
||||
# A recursive set of options along with their final values
|
||||
matchedOptions = {
|
||||
foo = { _type = "option"; value = "option value of foo"; ... };
|
||||
bar.baz = { _type = "option"; value = "option value of bar.baz"; ... };
|
||||
...
|
||||
};
|
||||
# A list of definitions that weren't matched by any option
|
||||
unmatchedDefns = [
|
||||
{ file = "file.nix"; prefix = [ "qux" ]; value = "qux"; }
|
||||
...
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`prefix`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
`modules`
|
||||
|
||||
: 2\. Function argument
|
||||
*/
|
||||
mergeModules = prefix: modules:
|
||||
mergeModules' prefix modules
|
||||
|
@ -740,17 +784,30 @@ let
|
|||
in
|
||||
throw (concatStringsSep "\n\n" paragraphs);
|
||||
|
||||
/* Merge multiple option declarations into a single declaration. In
|
||||
general, there should be only one declaration of each option.
|
||||
The exception is the ‘options’ attribute, which specifies
|
||||
sub-options. These can be specified multiple times to allow one
|
||||
module to add sub-options to an option declared somewhere else
|
||||
(e.g. multiple modules define sub-options for ‘fileSystems’).
|
||||
/**
|
||||
Merge multiple option declarations into a single declaration. In
|
||||
general, there should be only one declaration of each option.
|
||||
The exception is the ‘options’ attribute, which specifies
|
||||
sub-options. These can be specified multiple times to allow one
|
||||
module to add sub-options to an option declared somewhere else
|
||||
(e.g. multiple modules define sub-options for ‘fileSystems’).
|
||||
|
||||
'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
|
||||
correspond to the definition of 'loc' in 'opt.file'. */
|
||||
'opts' is a list of modules. Each module has an options attribute which
|
||||
correspond to the definition of 'loc' in 'opt.file'.
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`loc`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
`opts`
|
||||
|
||||
: 2\. Function argument
|
||||
*/
|
||||
mergeOptionDecls =
|
||||
loc: opts:
|
||||
foldl' (res: opt:
|
||||
|
@ -819,8 +876,25 @@ let
|
|||
} // typeSet
|
||||
) { 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:
|
||||
let
|
||||
# Add in the default value for this option, if any.
|
||||
|
@ -902,20 +976,28 @@ let
|
|||
else {};
|
||||
};
|
||||
|
||||
/* Given a config set, expand mkMerge properties, and push down the
|
||||
other properties into the children. The result is a list of
|
||||
config sets that do not have properties at top-level. For
|
||||
example,
|
||||
/**
|
||||
Given a config set, expand mkMerge properties, and push down the
|
||||
other properties into the children. The result is a list of
|
||||
config sets that do not have properties at top-level. For
|
||||
example,
|
||||
|
||||
mkMerge [ { boot = set1; } (mkIf cond { boot = set2; services = set3; }) ]
|
||||
mkMerge [ { boot = set1; } (mkIf cond { boot = set2; services = set3; }) ]
|
||||
|
||||
is transformed into
|
||||
is transformed into
|
||||
|
||||
[ { boot = set1; } { boot = mkIf cond set2; services = mkIf cond set3; } ].
|
||||
[ { boot = set1; } { boot = mkIf cond set2; services = mkIf cond set3; } ].
|
||||
|
||||
This transform is the critical step that allows mkIf conditions
|
||||
to refer to the full configuration without creating an infinite
|
||||
recursion.
|
||||
This transform is the critical step that allows mkIf conditions
|
||||
to refer to the full configuration without creating an infinite
|
||||
recursion.
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`cfg`
|
||||
|
||||
: 1\. Function argument
|
||||
*/
|
||||
pushDownProperties = cfg:
|
||||
if cfg._type or "" == "merge" then
|
||||
|
@ -927,15 +1009,23 @@ let
|
|||
else # FIXME: handle mkOrder?
|
||||
[ cfg ];
|
||||
|
||||
/* Given a config value, expand mkMerge properties, and discharge
|
||||
any mkIf conditions. That is, this is the place where mkIf
|
||||
conditions are actually evaluated. The result is a list of
|
||||
config values. For example, ‘mkIf false x’ yields ‘[]’,
|
||||
‘mkIf true x’ yields ‘[x]’, and
|
||||
/**
|
||||
Given a config value, expand mkMerge properties, and discharge
|
||||
any mkIf conditions. That is, this is the place where mkIf
|
||||
conditions are actually evaluated. The result is a list of
|
||||
config values. For example, ‘mkIf false x’ yields ‘[]’,
|
||||
‘mkIf true x’ yields ‘[x]’, and
|
||||
|
||||
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:
|
||||
if def._type or "" == "merge" then
|
||||
|
@ -951,24 +1041,32 @@ let
|
|||
else
|
||||
[ def ];
|
||||
|
||||
/* Given a list of config values, process the mkOverride properties,
|
||||
that is, return the values that have the highest (that is,
|
||||
numerically lowest) priority, and strip the mkOverride
|
||||
properties. For example,
|
||||
/**
|
||||
Given a list of config values, process the mkOverride properties,
|
||||
that is, return the values that have the highest (that is,
|
||||
numerically lowest) priority, and strip the mkOverride
|
||||
properties. For example,
|
||||
|
||||
[ { file = "/1"; value = mkOverride 10 "a"; }
|
||||
{ file = "/2"; value = mkOverride 20 "b"; }
|
||||
{ file = "/3"; value = "z"; }
|
||||
{ file = "/4"; value = mkOverride 10 "d"; }
|
||||
]
|
||||
[ { file = "/1"; value = mkOverride 10 "a"; }
|
||||
{ file = "/2"; value = mkOverride 20 "b"; }
|
||||
{ file = "/3"; value = "z"; }
|
||||
{ file = "/4"; value = mkOverride 10 "d"; }
|
||||
]
|
||||
|
||||
yields
|
||||
yields
|
||||
|
||||
[ { file = "/1"; value = "a"; }
|
||||
{ file = "/4"; value = "d"; }
|
||||
]
|
||||
[ { file = "/1"; value = "a"; }
|
||||
{ file = "/4"; value = "d"; }
|
||||
]
|
||||
|
||||
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;
|
||||
|
||||
|
@ -982,9 +1080,18 @@ let
|
|||
inherit highestPrio;
|
||||
};
|
||||
|
||||
/* Sort a list of properties. The sort priority of a property is
|
||||
defaultOrderPriority by default, but can be overridden by wrapping the property
|
||||
using mkOrder. */
|
||||
/**
|
||||
Sort a list of properties. The sort priority of a property is
|
||||
defaultOrderPriority by default, but can be overridden by wrapping the property
|
||||
using mkOrder.
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`defs`
|
||||
|
||||
: 1\. Function argument
|
||||
*/
|
||||
sortProperties = defs:
|
||||
let
|
||||
strip = def:
|
||||
|
@ -1004,14 +1111,24 @@ let
|
|||
else opt // { type = opt.type.substSubModules opt.options; options = []; };
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Merge an option's definitions in a way that preserves the priority of the
|
||||
individual attributes in the option value.
|
||||
|
||||
This does not account for all option semantics, such as readOnly.
|
||||
|
||||
Type:
|
||||
option -> attrsOf { highestPrio, value }
|
||||
|
||||
# Inputs
|
||||
|
||||
`opt`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
option -> attrsOf { highestPrio, value }
|
||||
```
|
||||
*/
|
||||
mergeAttrDefinitionsWithPrio = opt:
|
||||
let
|
||||
|
@ -1038,7 +1155,20 @@ let
|
|||
})
|
||||
defsByAttr;
|
||||
|
||||
/* Properties. */
|
||||
/**
|
||||
Properties.
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`condition`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
`content`
|
||||
|
||||
: 2\. Function argument
|
||||
*/
|
||||
|
||||
mkIf = condition: content:
|
||||
{ _type = "if";
|
||||
|
@ -1116,21 +1246,46 @@ let
|
|||
mkAliasIfDef = option:
|
||||
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; };
|
||||
|
||||
|
||||
/* Return a module that causes a warning to be shown if the
|
||||
specified option is defined. For example,
|
||||
/**
|
||||
Return a module that causes a warning to be shown if the
|
||||
specified option is defined. For example,
|
||||
|
||||
mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ] "<replacement instructions>"
|
||||
mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ] "<replacement instructions>"
|
||||
|
||||
causes a assertion if the user defines boot.loader.grub.bootDevice.
|
||||
causes a assertion if the user defines boot.loader.grub.bootDevice.
|
||||
|
||||
replacementInstructions is a string that provides instructions on
|
||||
how to achieve the same functionality without the removed option,
|
||||
or alternatively a reasoning why the functionality is not needed.
|
||||
replacementInstructions SHOULD be provided!
|
||||
replacementInstructions is a string that provides instructions on
|
||||
how to achieve the same functionality without the removed option,
|
||||
or alternatively a reasoning why the functionality is not needed.
|
||||
replacementInstructions SHOULD be provided!
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`optionName`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
`replacementInstructions`
|
||||
|
||||
: 2\. Function argument
|
||||
*/
|
||||
mkRemovedOptionModule = optionName: replacementInstructions:
|
||||
{ options, ... }:
|
||||
|
@ -1148,18 +1303,30 @@ let
|
|||
}];
|
||||
};
|
||||
|
||||
/* Return a module that causes a warning to be shown if the
|
||||
specified "from" option is defined; the defined value is however
|
||||
forwarded to the "to" option. This can be used to rename options
|
||||
while providing backward compatibility. For example,
|
||||
/**
|
||||
Return a module that causes a warning to be shown if the
|
||||
specified "from" option is defined; the defined value is however
|
||||
forwarded to the "to" option. This can be used to rename options
|
||||
while providing backward compatibility. For example,
|
||||
|
||||
mkRenamedOptionModule [ "boot" "copyKernels" ] [ "boot" "loader" "grub" "copyKernels" ]
|
||||
mkRenamedOptionModule [ "boot" "copyKernels" ] [ "boot" "loader" "grub" "copyKernels" ]
|
||||
|
||||
forwards any definitions of boot.copyKernels to
|
||||
boot.loader.grub.copyKernels while printing a warning.
|
||||
forwards any definitions of boot.copyKernels to
|
||||
boot.loader.grub.copyKernels while printing a warning.
|
||||
|
||||
This also copies over the priority from the aliased option to the
|
||||
non-aliased option.
|
||||
This also copies over the priority from the aliased option to the
|
||||
non-aliased option.
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`from`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
`to`
|
||||
|
||||
: 2\. Function argument
|
||||
*/
|
||||
mkRenamedOptionModule = from: to: doRename {
|
||||
inherit from to;
|
||||
|
@ -1169,12 +1336,16 @@ let
|
|||
};
|
||||
|
||||
mkRenamedOptionModuleWith = {
|
||||
/* Old option path as list of strings. */
|
||||
/**
|
||||
Old option path as list of strings.
|
||||
*/
|
||||
from,
|
||||
/* New option path as list of strings. */
|
||||
/**
|
||||
New option path as list of strings.
|
||||
*/
|
||||
to,
|
||||
|
||||
/*
|
||||
/**
|
||||
Release number of the first release that contains the rename, ignoring backports.
|
||||
Set it to the upcoming release, matching the nixpkgs/.version file.
|
||||
*/
|
||||
|
@ -1188,33 +1359,49 @@ let
|
|||
"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"
|
||||
option is defined; the defined values can be used in the "mergeFn" to set
|
||||
the "to" value.
|
||||
This function can be used to merge multiple options into one that has a
|
||||
different type.
|
||||
/**
|
||||
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
|
||||
the "to" value.
|
||||
This function can be used to merge multiple options into one that has a
|
||||
different type.
|
||||
|
||||
"mergeFn" takes the module "config" as a parameter and must return a value
|
||||
of "to" option type.
|
||||
"mergeFn" takes the module "config" as a parameter and must return a value
|
||||
of "to" option type.
|
||||
|
||||
mkMergedOptionModule
|
||||
[ [ "a" "b" "c" ]
|
||||
[ "d" "e" "f" ] ]
|
||||
[ "x" "y" "z" ]
|
||||
(config:
|
||||
let value = p: getAttrFromPath p config;
|
||||
in
|
||||
if (value [ "a" "b" "c" ]) == true then "foo"
|
||||
else if (value [ "d" "e" "f" ]) == true then "bar"
|
||||
else "baz")
|
||||
mkMergedOptionModule
|
||||
[ [ "a" "b" "c" ]
|
||||
[ "d" "e" "f" ] ]
|
||||
[ "x" "y" "z" ]
|
||||
(config:
|
||||
let value = p: getAttrFromPath p config;
|
||||
in
|
||||
if (value [ "a" "b" "c" ]) == true then "foo"
|
||||
else if (value [ "d" "e" "f" ]) == true then "bar"
|
||||
else "baz")
|
||||
|
||||
- options.a.b.c is a removed boolean option
|
||||
- options.d.e.f is a removed boolean option
|
||||
- options.x.y.z is a new str option that combines a.b.c and d.e.f
|
||||
functionality
|
||||
- options.a.b.c is a removed boolean option
|
||||
- options.d.e.f is a removed boolean option
|
||||
- options.x.y.z is a new str option that combines a.b.c and d.e.f
|
||||
functionality
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`from`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
`to`
|
||||
|
||||
: 2\. Function argument
|
||||
|
||||
`mergeFn`
|
||||
|
||||
: 3\. Function argument
|
||||
*/
|
||||
mkMergedOptionModule = from: to: mergeFn:
|
||||
{ config, options, ... }:
|
||||
|
@ -1240,33 +1427,62 @@ let
|
|||
(mergeFn config)));
|
||||
};
|
||||
|
||||
/* Single "from" version of mkMergedOptionModule.
|
||||
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"
|
||||
value.
|
||||
This function can be used to change an option into another that has a
|
||||
different type.
|
||||
/**
|
||||
Single "from" version of mkMergedOptionModule.
|
||||
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"
|
||||
value.
|
||||
This function can be used to change an option into another that has a
|
||||
different type.
|
||||
|
||||
"mergeFn" takes the module "config" as a parameter and must return a value of
|
||||
"to" option type.
|
||||
"mergeFn" takes the module "config" as a parameter and must return a value of
|
||||
"to" option type.
|
||||
|
||||
mkChangedOptionModule [ "a" "b" "c" ] [ "x" "y" "z" ]
|
||||
(config:
|
||||
let value = getAttrFromPath [ "a" "b" "c" ] config;
|
||||
in
|
||||
if value > 100 then "high"
|
||||
else "normal")
|
||||
mkChangedOptionModule [ "a" "b" "c" ] [ "x" "y" "z" ]
|
||||
(config:
|
||||
let value = getAttrFromPath [ "a" "b" "c" ] config;
|
||||
in
|
||||
if value > 100 then "high"
|
||||
else "normal")
|
||||
|
||||
- options.a.b.c is a removed int option
|
||||
- options.x.y.z is a new str option that supersedes a.b.c
|
||||
- options.a.b.c is a removed int option
|
||||
- options.x.y.z is a new str option that supersedes a.b.c
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`from`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
`to`
|
||||
|
||||
: 2\. Function argument
|
||||
|
||||
`changeFn`
|
||||
|
||||
: 3\. Function argument
|
||||
*/
|
||||
mkChangedOptionModule = 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 {
|
||||
inherit from to;
|
||||
visible = true;
|
||||
|
@ -1274,13 +1490,15 @@ let
|
|||
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;
|
||||
|
||||
/* 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.
|
||||
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")`.
|
||||
|
||||
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
|
||||
# error messages about conflicts. E.g. introduce a variation of `mkOverride` which
|
||||
|
@ -1300,10 +1529,10 @@ let
|
|||
(opt.highestPrio or defaultOverridePriority)
|
||||
(f opt.value);
|
||||
|
||||
/*
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
*/
|
||||
doRename = {
|
||||
# List of strings representing the attribute path of the old option.
|
||||
from,
|
||||
|
@ -1450,18 +1679,34 @@ let
|
|||
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: {
|
||||
_file = 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: {
|
||||
_file = file;
|
||||
|
|
|
@ -16,7 +16,7 @@ let
|
|||
|
||||
inherit (lib.lists) last;
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
the address. See RFC 4291.
|
||||
|
@ -138,7 +138,7 @@ let
|
|||
parseIpv6FromString = addr: parseExpandedIpv6 (expandIpv6 addr);
|
||||
in
|
||||
{
|
||||
/*
|
||||
/**
|
||||
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
|
||||
it is a list of integers produced by one of the internal parsers, such as
|
||||
|
|
178
lib/options.nix
178
lib/options.nix
|
@ -426,18 +426,29 @@ rec {
|
|||
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}";
|
||||
|
||||
/*
|
||||
/**
|
||||
Require a single definition.
|
||||
|
||||
WARNING: Does not perform nested checks, as this does not run the merge function!
|
||||
*/
|
||||
mergeOneOption = mergeUniqueOption { message = ""; };
|
||||
|
||||
/*
|
||||
/**
|
||||
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).
|
||||
*/
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`loc`
|
||||
|
||||
: 2\. Function argument
|
||||
|
||||
`defs`
|
||||
|
||||
: 3\. Function argument
|
||||
*/
|
||||
mergeUniqueOption = args@{
|
||||
message,
|
||||
# WARNING: the default merge function assumes that the definition is a valid (option) value. You MUST pass a merge function if the return value needs to be
|
||||
|
@ -452,7 +463,20 @@ rec {
|
|||
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}";
|
||||
|
||||
/* "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:
|
||||
if defs == [] then abort "This case should never happen."
|
||||
# Return early if we only have one element
|
||||
|
@ -465,23 +489,47 @@ rec {
|
|||
else
|
||||
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 = 1; } { value = 2; } ] // => [ 1 2 ]
|
||||
getValues [ ] // => [ ]
|
||||
```
|
||||
getValues :: [ { value :: a; } ] -> [a]
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `getValues` usage example
|
||||
|
||||
```nix
|
||||
getValues [ { value = 1; } { value = 2; } ] // => [ 1 2 ]
|
||||
getValues [ ] // => [ ]
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
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 = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ]
|
||||
getFiles [ ] // => [ ]
|
||||
```
|
||||
getFiles :: [ { file :: a; } ] -> [a]
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `getFiles` usage example
|
||||
|
||||
```nix
|
||||
getFiles [ { file = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ]
|
||||
getFiles [ ] // => [ ]
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
getFiles = map (x: x.file);
|
||||
|
||||
|
@ -530,16 +578,24 @@ rec {
|
|||
[ docOption ] ++ optionals subOptionsVisible subOptions) (collect isOption options);
|
||||
|
||||
|
||||
/* This function recursively removes all derivation attributes from
|
||||
`x` except for the `name` attribute.
|
||||
/**
|
||||
This function recursively removes all derivation attributes from
|
||||
`x` except for the `name` attribute.
|
||||
|
||||
This is to make the generation of `options.xml` much more
|
||||
efficient: the XML representation of derivations is very large
|
||||
(on the order of megabytes) and is not actually used by the
|
||||
manual generator.
|
||||
This is to make the generation of `options.xml` much more
|
||||
efficient: the XML representation of derivations is very large
|
||||
(on the order of megabytes) and is not actually used by the
|
||||
manual generator.
|
||||
|
||||
This function was made obsolete by renderOptionValue and is kept for
|
||||
compatibility with out-of-tree code.
|
||||
This function was made obsolete by renderOptionValue and is kept for
|
||||
compatibility with out-of-tree code.
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`x`
|
||||
|
||||
: 1\. Function argument
|
||||
*/
|
||||
scrubOptionValue = x:
|
||||
if isDerivation x then
|
||||
|
@ -549,8 +605,16 @@ rec {
|
|||
else x;
|
||||
|
||||
|
||||
/* Ensures that the given option value (default or example) is a `_type`d string
|
||||
by rendering Nix values to `literalExpression`s.
|
||||
/**
|
||||
Ensures that the given option value (default or example) is a `_type`d string
|
||||
by rendering Nix values to `literalExpression`s.
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`v`
|
||||
|
||||
: 1\. Function argument
|
||||
*/
|
||||
renderOptionValue = v:
|
||||
if v ? _type && v ? text then v
|
||||
|
@ -560,10 +624,18 @@ rec {
|
|||
} v);
|
||||
|
||||
|
||||
/* For use in the `defaultText` and `example` option attributes. Causes the
|
||||
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
|
||||
other values or packages.
|
||||
/**
|
||||
For use in the `defaultText` and `example` option attributes. Causes the
|
||||
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
|
||||
other values or packages.
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`text`
|
||||
|
||||
: 1\. Function argument
|
||||
*/
|
||||
literalExpression = text:
|
||||
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;
|
||||
|
||||
/* For use in the `defaultText` and `example` option attributes. Causes the
|
||||
given MD text to be inserted verbatim in the documentation, for when
|
||||
a `literalExpression` would be too hard to read.
|
||||
/**
|
||||
For use in the `defaultText` and `example` option attributes. Causes the
|
||||
given MD text to be inserted verbatim in the documentation, for when
|
||||
a `literalExpression` would be too hard to read.
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`text`
|
||||
|
||||
: 1\. Function argument
|
||||
*/
|
||||
literalMD = text:
|
||||
if ! isString text then throw "literalMD expects a string."
|
||||
|
@ -581,18 +661,34 @@ rec {
|
|||
|
||||
# Helper functions.
|
||||
|
||||
/* Convert an option, described as a list of the option parts to a
|
||||
human-readable version.
|
||||
/**
|
||||
Convert an option, described as a list of the option parts to a
|
||||
human-readable version.
|
||||
|
||||
Example:
|
||||
(showOption ["foo" "bar" "baz"]) == "foo.bar.baz"
|
||||
(showOption ["foo" "bar.baz" "tux"]) == "foo.\"bar.baz\".tux"
|
||||
(showOption ["windowManager" "2bwm" "enable"]) == "windowManager.\"2bwm\".enable"
|
||||
|
||||
Placeholders will not be quoted as they are not actual values:
|
||||
(showOption ["foo" "*" "bar"]) == "foo.*.bar"
|
||||
(showOption ["foo" "<name>" "bar"]) == "foo.<name>.bar"
|
||||
(showOption ["foo" "<myPlaceholder>" "bar"]) == "foo.<myPlaceholder>.bar"
|
||||
# Inputs
|
||||
|
||||
`parts`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `showOption` usage example
|
||||
|
||||
```nix
|
||||
(showOption ["foo" "bar" "baz"]) == "foo.bar.baz"
|
||||
(showOption ["foo" "bar.baz" "tux"]) == "foo.\"bar.baz\".tux"
|
||||
(showOption ["windowManager" "2bwm" "enable"]) == "windowManager.\"2bwm\".enable"
|
||||
|
||||
Placeholders will not be quoted as they are not actual values:
|
||||
(showOption ["foo" "*" "bar"]) == "foo.*.bar"
|
||||
(showOption ["foo" "<name>" "bar"]) == "foo.<name>.bar"
|
||||
(showOption ["foo" "<myPlaceholder>" "bar"]) == "foo.<myPlaceholder>.bar"
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
showOption = parts: let
|
||||
# If the part is a named placeholder of the form "<...>" don't escape it.
|
||||
|
|
|
@ -165,7 +165,7 @@ in
|
|||
# No rec! Add dependencies on this file at the top.
|
||||
{
|
||||
|
||||
/*
|
||||
/**
|
||||
Append a subpath string to a path.
|
||||
|
||||
Like `path + ("/" + string)` but safer, because it errors instead of returning potentially surprising results.
|
||||
|
@ -178,34 +178,55 @@ in
|
|||
|
||||
append p s == append p (subpath.normalise s)
|
||||
|
||||
Type:
|
||||
append :: Path -> String -> Path
|
||||
|
||||
Example:
|
||||
append /foo "bar/baz"
|
||||
=> /foo/bar/baz
|
||||
# Inputs
|
||||
|
||||
# subpaths don't need to be normalised
|
||||
append /foo "./bar//baz/./"
|
||||
=> /foo/bar/baz
|
||||
`path`
|
||||
|
||||
# can append to root directory
|
||||
append /. "foo/bar"
|
||||
=> /foo/bar
|
||||
: The absolute path to append to
|
||||
|
||||
# first argument needs to be a path value type
|
||||
append "/foo" "bar"
|
||||
=> <error>
|
||||
`subpath`
|
||||
|
||||
# second argument needs to be a valid subpath string
|
||||
append /foo /bar
|
||||
=> <error>
|
||||
append /foo ""
|
||||
=> <error>
|
||||
append /foo "/bar"
|
||||
=> <error>
|
||||
append /foo "../bar"
|
||||
=> <error>
|
||||
: The subpath string to append
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
append :: Path -> String -> Path
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `append` usage example
|
||||
|
||||
```nix
|
||||
append /foo "bar/baz"
|
||||
=> /foo/bar/baz
|
||||
|
||||
# subpaths don't need to be normalised
|
||||
append /foo "./bar//baz/./"
|
||||
=> /foo/bar/baz
|
||||
|
||||
# can append to root directory
|
||||
append /. "foo/bar"
|
||||
=> /foo/bar
|
||||
|
||||
# first argument needs to be a path value type
|
||||
append "/foo" "bar"
|
||||
=> <error>
|
||||
|
||||
# second argument needs to be a valid subpath string
|
||||
append /foo /bar
|
||||
=> <error>
|
||||
append /foo ""
|
||||
=> <error>
|
||||
append /foo "/bar"
|
||||
=> <error>
|
||||
append /foo "../bar"
|
||||
=> <error>
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
append =
|
||||
# The absolute path to append to
|
||||
|
@ -219,7 +240,7 @@ in
|
|||
${subpathInvalidReason subpath}'';
|
||||
path + ("/" + subpath);
|
||||
|
||||
/*
|
||||
/**
|
||||
Whether the first path is a component-wise prefix of the second path.
|
||||
|
||||
Laws:
|
||||
|
@ -228,18 +249,35 @@ 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.
|
||||
|
||||
Type:
|
||||
hasPrefix :: Path -> Path -> Bool
|
||||
|
||||
Example:
|
||||
hasPrefix /foo /foo/bar
|
||||
=> true
|
||||
hasPrefix /foo /foo
|
||||
=> true
|
||||
hasPrefix /foo/bar /foo
|
||||
=> false
|
||||
hasPrefix /. /foo
|
||||
=> true
|
||||
# Inputs
|
||||
|
||||
`path1`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
hasPrefix :: Path -> Path -> Bool
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `hasPrefix` usage example
|
||||
|
||||
```nix
|
||||
hasPrefix /foo /foo/bar
|
||||
=> true
|
||||
hasPrefix /foo /foo
|
||||
=> true
|
||||
hasPrefix /foo/bar /foo
|
||||
=> false
|
||||
hasPrefix /. /foo
|
||||
=> true
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
hasPrefix =
|
||||
path1:
|
||||
|
@ -261,7 +299,7 @@ in
|
|||
take (length path1Deconstructed.components) path2Deconstructed.components
|
||||
== path1Deconstructed.components;
|
||||
|
||||
/*
|
||||
/**
|
||||
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).
|
||||
|
||||
|
@ -271,18 +309,35 @@ in
|
|||
|
||||
removePrefix p (append p s) == subpath.normalise s
|
||||
|
||||
Type:
|
||||
removePrefix :: Path -> Path -> String
|
||||
|
||||
Example:
|
||||
removePrefix /foo /foo/bar/baz
|
||||
=> "./bar/baz"
|
||||
removePrefix /foo /foo
|
||||
=> "./."
|
||||
removePrefix /foo/bar /foo
|
||||
=> <error>
|
||||
removePrefix /. /foo
|
||||
=> "./foo"
|
||||
# Inputs
|
||||
|
||||
`path1`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
removePrefix :: Path -> Path -> String
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `removePrefix` usage example
|
||||
|
||||
```nix
|
||||
removePrefix /foo /foo/bar/baz
|
||||
=> "./bar/baz"
|
||||
removePrefix /foo /foo
|
||||
=> "./."
|
||||
removePrefix /foo/bar /foo
|
||||
=> <error>
|
||||
removePrefix /. /foo
|
||||
=> "./foo"
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
removePrefix =
|
||||
path1:
|
||||
|
@ -310,7 +365,7 @@ in
|
|||
second argument: "${toString path2}" with root "${toString path2Deconstructed.root}"'';
|
||||
joinRelPath components;
|
||||
|
||||
/*
|
||||
/**
|
||||
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:
|
||||
- `root`: The filesystem root of the path, meaning that this directory has no parent directory.
|
||||
|
@ -328,22 +383,39 @@ in
|
|||
|
||||
dirOf (splitRoot p).root == (splitRoot p).root
|
||||
|
||||
Type:
|
||||
splitRoot :: Path -> { root :: Path, subpath :: String }
|
||||
|
||||
Example:
|
||||
splitRoot /foo/bar
|
||||
=> { root = /.; subpath = "./foo/bar"; }
|
||||
# Inputs
|
||||
|
||||
splitRoot /.
|
||||
=> { root = /.; subpath = "./."; }
|
||||
`path`
|
||||
|
||||
# Nix neutralises `..` path components for all path values automatically
|
||||
splitRoot /foo/../bar
|
||||
=> { root = /.; subpath = "./bar"; }
|
||||
: The path to split the root off of
|
||||
|
||||
splitRoot "/foo/bar"
|
||||
=> <error>
|
||||
# Type
|
||||
|
||||
```
|
||||
splitRoot :: Path -> { root :: Path, subpath :: String }
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `splitRoot` usage example
|
||||
|
||||
```nix
|
||||
splitRoot /foo/bar
|
||||
=> { root = /.; subpath = "./foo/bar"; }
|
||||
|
||||
splitRoot /.
|
||||
=> { root = /.; subpath = "./."; }
|
||||
|
||||
# Nix neutralises `..` path components for all path values automatically
|
||||
splitRoot /foo/../bar
|
||||
=> { root = /.; subpath = "./bar"; }
|
||||
|
||||
splitRoot "/foo/bar"
|
||||
=> <error>
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
splitRoot =
|
||||
# The path to split the root off of
|
||||
|
@ -358,7 +430,7 @@ in
|
|||
subpath = joinRelPath deconstructed.components;
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
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)
|
||||
as a prefix.
|
||||
|
@ -371,33 +443,50 @@ in
|
|||
which occur when Nix files in the store use relative path expressions.
|
||||
:::
|
||||
|
||||
Type:
|
||||
hasStorePathPrefix :: Path -> Bool
|
||||
|
||||
Example:
|
||||
# Subpaths of derivation outputs have a store path as a prefix
|
||||
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo/bar/baz
|
||||
=> true
|
||||
# Inputs
|
||||
|
||||
# The store directory itself is not a store path
|
||||
hasStorePathPrefix /nix/store
|
||||
=> false
|
||||
`path`
|
||||
|
||||
# Derivation outputs are store paths themselves
|
||||
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo
|
||||
=> true
|
||||
: 1\. Function argument
|
||||
|
||||
# Paths outside the Nix store don't have a store path prefix
|
||||
hasStorePathPrefix /home/user
|
||||
=> false
|
||||
# Type
|
||||
|
||||
# Not all paths under the Nix store are store paths
|
||||
hasStorePathPrefix /nix/store/.links/10gg8k3rmbw8p7gszarbk7qyd9jwxhcfq9i6s5i0qikx8alkk4hq
|
||||
=> false
|
||||
```
|
||||
hasStorePathPrefix :: Path -> Bool
|
||||
```
|
||||
|
||||
# Store derivations are also store paths themselves
|
||||
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo.drv
|
||||
=> true
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `hasStorePathPrefix` usage example
|
||||
|
||||
```nix
|
||||
# Subpaths of derivation outputs have a store path as a prefix
|
||||
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo/bar/baz
|
||||
=> true
|
||||
|
||||
# The store directory itself is not a store path
|
||||
hasStorePathPrefix /nix/store
|
||||
=> false
|
||||
|
||||
# Derivation outputs are store paths themselves
|
||||
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo
|
||||
=> true
|
||||
|
||||
# Paths outside the Nix store don't have a store path prefix
|
||||
hasStorePathPrefix /home/user
|
||||
=> false
|
||||
|
||||
# Not all paths under the Nix store are store paths
|
||||
hasStorePathPrefix /nix/store/.links/10gg8k3rmbw8p7gszarbk7qyd9jwxhcfq9i6s5i0qikx8alkk4hq
|
||||
=> false
|
||||
|
||||
# Store derivations are also store paths themselves
|
||||
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo.drv
|
||||
=> true
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
hasStorePathPrefix =
|
||||
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.";
|
||||
componentsHaveStorePathPrefix deconstructed.components;
|
||||
|
||||
/*
|
||||
/**
|
||||
Whether a value is a valid subpath string.
|
||||
|
||||
A subpath string points to a specific file or directory within an absolute base directory.
|
||||
|
@ -428,39 +517,56 @@ in
|
|||
|
||||
- The string doesn't contain any `..` path components.
|
||||
|
||||
Type:
|
||||
subpath.isValid :: String -> Bool
|
||||
|
||||
Example:
|
||||
# Not a string
|
||||
subpath.isValid null
|
||||
=> false
|
||||
# Inputs
|
||||
|
||||
# Empty string
|
||||
subpath.isValid ""
|
||||
=> false
|
||||
`value`
|
||||
|
||||
# Absolute path
|
||||
subpath.isValid "/foo"
|
||||
=> false
|
||||
: The value to check
|
||||
|
||||
# Contains a `..` path component
|
||||
subpath.isValid "../foo"
|
||||
=> false
|
||||
# Type
|
||||
|
||||
# Valid subpath
|
||||
subpath.isValid "foo/bar"
|
||||
=> true
|
||||
```
|
||||
subpath.isValid :: String -> Bool
|
||||
```
|
||||
|
||||
# Doesn't need to be normalised
|
||||
subpath.isValid "./foo//bar/"
|
||||
=> true
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `subpath.isValid` usage example
|
||||
|
||||
```nix
|
||||
# Not a string
|
||||
subpath.isValid null
|
||||
=> false
|
||||
|
||||
# Empty string
|
||||
subpath.isValid ""
|
||||
=> false
|
||||
|
||||
# Absolute path
|
||||
subpath.isValid "/foo"
|
||||
=> false
|
||||
|
||||
# Contains a `..` path component
|
||||
subpath.isValid "../foo"
|
||||
=> false
|
||||
|
||||
# Valid subpath
|
||||
subpath.isValid "foo/bar"
|
||||
=> true
|
||||
|
||||
# Doesn't need to be normalised
|
||||
subpath.isValid "./foo//bar/"
|
||||
=> true
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
subpath.isValid =
|
||||
# The value to check
|
||||
value: subpathInvalidReason value == null;
|
||||
|
||||
/*
|
||||
/**
|
||||
Join subpath strings together using `/`, returning a normalised subpath string.
|
||||
|
||||
Like `concatStringsSep "/"` but safer, specifically:
|
||||
|
@ -492,30 +598,47 @@ in
|
|||
|
||||
ps != [] -> subpath.join ps == subpath.normalise (concatStringsSep "/" ps)
|
||||
|
||||
Type:
|
||||
subpath.join :: [ String ] -> String
|
||||
|
||||
Example:
|
||||
subpath.join [ "foo" "bar/baz" ]
|
||||
=> "./foo/bar/baz"
|
||||
# Inputs
|
||||
|
||||
# normalise the result
|
||||
subpath.join [ "./foo" "." "bar//./baz/" ]
|
||||
=> "./foo/bar/baz"
|
||||
`subpaths`
|
||||
|
||||
# passing an empty list results in the current directory
|
||||
subpath.join [ ]
|
||||
=> "./."
|
||||
: The list of subpaths to join together
|
||||
|
||||
# elements must be valid subpath strings
|
||||
subpath.join [ /foo ]
|
||||
=> <error>
|
||||
subpath.join [ "" ]
|
||||
=> <error>
|
||||
subpath.join [ "/foo" ]
|
||||
=> <error>
|
||||
subpath.join [ "../foo" ]
|
||||
=> <error>
|
||||
# Type
|
||||
|
||||
```
|
||||
subpath.join :: [ String ] -> String
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `subpath.join` usage example
|
||||
|
||||
```nix
|
||||
subpath.join [ "foo" "bar/baz" ]
|
||||
=> "./foo/bar/baz"
|
||||
|
||||
# normalise the result
|
||||
subpath.join [ "./foo" "." "bar//./baz/" ]
|
||||
=> "./foo/bar/baz"
|
||||
|
||||
# passing an empty list results in the current directory
|
||||
subpath.join [ ]
|
||||
=> "./."
|
||||
|
||||
# elements must be valid subpath strings
|
||||
subpath.join [ /foo ]
|
||||
=> <error>
|
||||
subpath.join [ "" ]
|
||||
=> <error>
|
||||
subpath.join [ "/foo" ]
|
||||
=> <error>
|
||||
subpath.join [ "../foo" ]
|
||||
=> <error>
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
subpath.join =
|
||||
# The list of subpaths to join together
|
||||
|
@ -537,7 +660,7 @@ in
|
|||
${subpathInvalidReason path}''
|
||||
) 0 subpaths;
|
||||
|
||||
/*
|
||||
/**
|
||||
Split [a subpath](#function-library-lib.path.subpath.isValid) into its path component strings.
|
||||
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).
|
||||
|
@ -548,18 +671,35 @@ in
|
|||
|
||||
subpath.join (subpath.components s) == subpath.normalise s
|
||||
|
||||
Type:
|
||||
subpath.components :: String -> [ String ]
|
||||
|
||||
Example:
|
||||
subpath.components "."
|
||||
=> [ ]
|
||||
# Inputs
|
||||
|
||||
subpath.components "./foo//bar/./baz/"
|
||||
=> [ "foo" "bar" "baz" ]
|
||||
`subpath`
|
||||
|
||||
subpath.components "/foo"
|
||||
=> <error>
|
||||
: The subpath string to split into components
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
subpath.components :: String -> [ String ]
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `subpath.components` usage example
|
||||
|
||||
```nix
|
||||
subpath.components "."
|
||||
=> [ ]
|
||||
|
||||
subpath.components "./foo//bar/./baz/"
|
||||
=> [ "foo" "bar" "baz" ]
|
||||
|
||||
subpath.components "/foo"
|
||||
=> <error>
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
subpath.components =
|
||||
# The subpath string to split into components
|
||||
|
@ -569,7 +709,7 @@ in
|
|||
${subpathInvalidReason subpath}'';
|
||||
splitRelPath subpath;
|
||||
|
||||
/*
|
||||
/**
|
||||
Normalise a subpath. Throw an error if the subpath isn't [valid](#function-library-lib.path.subpath.isValid).
|
||||
|
||||
- Limit repeating `/` to a single one.
|
||||
|
@ -602,45 +742,62 @@ in
|
|||
|
||||
builtins.tryEval (subpath.normalise p)).success == subpath.isValid p
|
||||
|
||||
Type:
|
||||
subpath.normalise :: String -> String
|
||||
|
||||
Example:
|
||||
# limit repeating `/` to a single one
|
||||
subpath.normalise "foo//bar"
|
||||
=> "./foo/bar"
|
||||
# Inputs
|
||||
|
||||
# remove redundant `.` components
|
||||
subpath.normalise "foo/./bar"
|
||||
=> "./foo/bar"
|
||||
`subpath`
|
||||
|
||||
# add leading `./`
|
||||
subpath.normalise "foo/bar"
|
||||
=> "./foo/bar"
|
||||
: The subpath string to normalise
|
||||
|
||||
# remove trailing `/`
|
||||
subpath.normalise "foo/bar/"
|
||||
=> "./foo/bar"
|
||||
# Type
|
||||
|
||||
# remove trailing `/.`
|
||||
subpath.normalise "foo/bar/."
|
||||
=> "./foo/bar"
|
||||
```
|
||||
subpath.normalise :: String -> String
|
||||
```
|
||||
|
||||
# Return the current directory as `./.`
|
||||
subpath.normalise "."
|
||||
=> "./."
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `subpath.normalise` usage example
|
||||
|
||||
# error on `..` path components
|
||||
subpath.normalise "foo/../bar"
|
||||
=> <error>
|
||||
```nix
|
||||
# limit repeating `/` to a single one
|
||||
subpath.normalise "foo//bar"
|
||||
=> "./foo/bar"
|
||||
|
||||
# error on empty string
|
||||
subpath.normalise ""
|
||||
=> <error>
|
||||
# remove redundant `.` components
|
||||
subpath.normalise "foo/./bar"
|
||||
=> "./foo/bar"
|
||||
|
||||
# error on absolute path
|
||||
subpath.normalise "/foo"
|
||||
=> <error>
|
||||
# add leading `./`
|
||||
subpath.normalise "foo/bar"
|
||||
=> "./foo/bar"
|
||||
|
||||
# remove trailing `/`
|
||||
subpath.normalise "foo/bar/"
|
||||
=> "./foo/bar"
|
||||
|
||||
# remove trailing `/.`
|
||||
subpath.normalise "foo/bar/."
|
||||
=> "./foo/bar"
|
||||
|
||||
# Return the current directory as `./.`
|
||||
subpath.normalise "."
|
||||
=> "./."
|
||||
|
||||
# error on `..` path components
|
||||
subpath.normalise "foo/../bar"
|
||||
=> <error>
|
||||
|
||||
# error on empty string
|
||||
subpath.normalise ""
|
||||
=> <error>
|
||||
|
||||
# error on absolute path
|
||||
subpath.normalise "/foo"
|
||||
=> <error>
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
subpath.normalise =
|
||||
# The subpath string to normalise
|
||||
|
|
157
lib/sources.nix
157
lib/sources.nix
|
@ -18,10 +18,21 @@ let
|
|||
pathIsRegularFile
|
||||
;
|
||||
|
||||
/*
|
||||
/**
|
||||
A basic filter for `cleanSourceWith` that removes
|
||||
directories of version control system, backup files (*~)
|
||||
and some generated files.
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`name`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
`type`
|
||||
|
||||
: 2\. Function argument
|
||||
*/
|
||||
cleanSourceFilter =
|
||||
name: type:
|
||||
|
@ -52,11 +63,26 @@ let
|
|||
(type == "unknown")
|
||||
);
|
||||
|
||||
/*
|
||||
/**
|
||||
Filters a source tree removing version control files and directories using cleanSourceFilter.
|
||||
|
||||
Example:
|
||||
cleanSource ./.
|
||||
|
||||
# Inputs
|
||||
|
||||
`src`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `cleanSource` usage example
|
||||
|
||||
```nix
|
||||
cleanSource ./.
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
cleanSource =
|
||||
src:
|
||||
|
@ -65,23 +91,31 @@ let
|
|||
inherit src;
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
Like `builtins.filterSource`, except it will compose with itself,
|
||||
allowing you to chain multiple calls together without any
|
||||
intermediate copies being put in the nix store.
|
||||
|
||||
Example:
|
||||
lib.cleanSourceWith {
|
||||
filter = f;
|
||||
src = lib.cleanSourceWith {
|
||||
filter = g;
|
||||
src = ./.;
|
||||
};
|
||||
}
|
||||
# Succeeds!
|
||||
|
||||
builtins.filterSource f (builtins.filterSource g ./.)
|
||||
# Fails!
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `cleanSourceWith` usage example
|
||||
|
||||
```nix
|
||||
lib.cleanSourceWith {
|
||||
filter = f;
|
||||
src = lib.cleanSourceWith {
|
||||
filter = g;
|
||||
src = ./.;
|
||||
};
|
||||
}
|
||||
# Succeeds!
|
||||
|
||||
builtins.filterSource f (builtins.filterSource g ./.)
|
||||
# Fails!
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
cleanSourceWith =
|
||||
{
|
||||
|
@ -107,10 +141,21 @@ let
|
|||
name = if name != null then name else orig.name;
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
Add logging to a source, for troubleshooting the filtering behavior.
|
||||
Type:
|
||||
sources.trace :: sourceLike -> Source
|
||||
|
||||
|
||||
# Inputs
|
||||
|
||||
`src`
|
||||
|
||||
: Source to debug. The returned source will behave like this source, but also log its filter invocations.
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
sources.trace :: sourceLike -> Source
|
||||
```
|
||||
*/
|
||||
trace =
|
||||
# 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;
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
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 =
|
||||
src: regexes:
|
||||
|
@ -155,16 +220,38 @@ let
|
|||
inherit src;
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
Get all files ending with the specified suffices from the given
|
||||
source directory or its descendants, omitting files that do not match
|
||||
any suffix. The result of the example below will include files like
|
||||
`./dir/module.c` and `./dir/subdir/doc.xml` if present.
|
||||
|
||||
Type: sourceLike -> [String] -> Source
|
||||
|
||||
Example:
|
||||
sourceFilesBySuffices ./. [ ".xml" ".c" ]
|
||||
# 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 =
|
||||
# Path or source containing the files to be returned
|
||||
|
@ -183,10 +270,26 @@ let
|
|||
|
||||
pathIsGitRepo = path: (_commitIdFromGitRepoOrError path) ? value;
|
||||
|
||||
/*
|
||||
/**
|
||||
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 =
|
||||
path:
|
||||
|
|
|
@ -1,44 +1,44 @@
|
|||
{ lib }:
|
||||
/*
|
||||
Usage:
|
||||
/**
|
||||
Usage:
|
||||
|
||||
You define you custom builder script by adding all build steps to a list.
|
||||
for example:
|
||||
builder = writeScript "fsg-4.4-builder"
|
||||
(textClosure [doUnpack addInputs preBuild doMake installPhase doForceShare]);
|
||||
You define you custom builder script by adding all build steps to a list.
|
||||
for example:
|
||||
builder = writeScript "fsg-4.4-builder"
|
||||
(textClosure [doUnpack addInputs preBuild doMake installPhase doForceShare]);
|
||||
|
||||
a step is defined by noDepEntry, fullDepEntry or packEntry.
|
||||
To ensure that prerequisite are met those are added before the task itself by
|
||||
textClosureDupList. Duplicated items are removed again.
|
||||
a step is defined by noDepEntry, fullDepEntry or packEntry.
|
||||
To ensure that prerequisite are met those are added before the task itself by
|
||||
textClosureDupList. Duplicated items are removed again.
|
||||
|
||||
See trace/nixpkgs/trunk/pkgs/top-level/builder-defs.nix for some predefined build steps
|
||||
See trace/nixpkgs/trunk/pkgs/top-level/builder-defs.nix for some predefined build steps
|
||||
|
||||
Attention:
|
||||
Attention:
|
||||
|
||||
let
|
||||
pkgs = (import <nixpkgs>) {};
|
||||
in let
|
||||
inherit (pkgs.stringsWithDeps) fullDepEntry packEntry noDepEntry textClosureMap;
|
||||
inherit (pkgs.lib) id;
|
||||
let
|
||||
pkgs = (import <nixpkgs>) {};
|
||||
in let
|
||||
inherit (pkgs.stringsWithDeps) fullDepEntry packEntry noDepEntry textClosureMap;
|
||||
inherit (pkgs.lib) id;
|
||||
|
||||
nameA = noDepEntry "Text a";
|
||||
nameB = fullDepEntry "Text b" ["nameA"];
|
||||
nameC = fullDepEntry "Text c" ["nameA"];
|
||||
nameA = noDepEntry "Text a";
|
||||
nameB = fullDepEntry "Text b" ["nameA"];
|
||||
nameC = fullDepEntry "Text c" ["nameA"];
|
||||
|
||||
stages = {
|
||||
nameHeader = noDepEntry "#! /bin/sh \n";
|
||||
inherit nameA nameB nameC;
|
||||
};
|
||||
in
|
||||
textClosureMap id stages
|
||||
[ "nameHeader" "nameA" "nameB" "nameC"
|
||||
nameC # <- added twice. add a dep entry if you know that it will be added once only [1]
|
||||
"nameB" # <- this will not be added again because the attr name (reference) is used
|
||||
]
|
||||
stages = {
|
||||
nameHeader = noDepEntry "#! /bin/sh \n";
|
||||
inherit nameA nameB nameC;
|
||||
};
|
||||
in
|
||||
textClosureMap id stages
|
||||
[ "nameHeader" "nameA" "nameB" "nameC"
|
||||
nameC # <- added twice. add a dep entry if you know that it will be added once only [1]
|
||||
"nameB" # <- this will not be added again because the attr name (reference) is used
|
||||
]
|
||||
|
||||
# result: Str("#! /bin/sh \n\nText a\nText b\nText c\nText c",[])
|
||||
# result: Str("#! /bin/sh \n\nText a\nText b\nText c\nText c",[])
|
||||
|
||||
[1] maybe this behaviour should be removed to keep things simple (?)
|
||||
[1] maybe this behaviour should be removed to keep things simple (?)
|
||||
*/
|
||||
|
||||
let
|
||||
|
|
143
lib/versions.nix
143
lib/versions.nix
|
@ -3,62 +3,149 @@
|
|||
|
||||
rec {
|
||||
|
||||
/*
|
||||
/**
|
||||
Break a version string into its component parts.
|
||||
|
||||
Example:
|
||||
splitVersion "1.2.3"
|
||||
=> ["1" "2" "3"]
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `splitVersion` usage example
|
||||
|
||||
```nix
|
||||
splitVersion "1.2.3"
|
||||
=> ["1" "2" "3"]
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
splitVersion = builtins.splitVersion;
|
||||
|
||||
/*
|
||||
/**
|
||||
Get the major version string from a string.
|
||||
|
||||
Example:
|
||||
major "1.2.3"
|
||||
=> "1"
|
||||
|
||||
# Inputs
|
||||
|
||||
`v`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `major` usage example
|
||||
|
||||
```nix
|
||||
major "1.2.3"
|
||||
=> "1"
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
major = v: builtins.elemAt (splitVersion v) 0;
|
||||
|
||||
/*
|
||||
/**
|
||||
Get the minor version string from a string.
|
||||
|
||||
Example:
|
||||
minor "1.2.3"
|
||||
=> "2"
|
||||
|
||||
# Inputs
|
||||
|
||||
`v`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `minor` usage example
|
||||
|
||||
```nix
|
||||
minor "1.2.3"
|
||||
=> "2"
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
minor = v: builtins.elemAt (splitVersion v) 1;
|
||||
|
||||
/*
|
||||
/**
|
||||
Get the patch version string from a string.
|
||||
|
||||
Example:
|
||||
patch "1.2.3"
|
||||
=> "3"
|
||||
|
||||
# Inputs
|
||||
|
||||
`v`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `patch` usage example
|
||||
|
||||
```nix
|
||||
patch "1.2.3"
|
||||
=> "3"
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
patch = v: builtins.elemAt (splitVersion v) 2;
|
||||
|
||||
/*
|
||||
/**
|
||||
Get string of the first two parts (major and minor)
|
||||
of a version string.
|
||||
|
||||
Example:
|
||||
majorMinor "1.2.3"
|
||||
=> "1.2"
|
||||
|
||||
# Inputs
|
||||
|
||||
`v`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `majorMinor` usage example
|
||||
|
||||
```nix
|
||||
majorMinor "1.2.3"
|
||||
=> "1.2"
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
majorMinor = v: builtins.concatStringsSep "." (lib.take 2 (splitVersion v));
|
||||
|
||||
/*
|
||||
/**
|
||||
Pad a version string with zeros to match the given number of components.
|
||||
|
||||
Example:
|
||||
pad 3 "1.2"
|
||||
=> "1.2.0"
|
||||
pad 3 "1.3-rc1"
|
||||
=> "1.3.0-rc1"
|
||||
pad 3 "1.2.3.4"
|
||||
=> "1.2.3"
|
||||
|
||||
# Inputs
|
||||
|
||||
`n`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
`version`
|
||||
|
||||
: 2\. Function argument
|
||||
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `pad` usage example
|
||||
|
||||
```nix
|
||||
pad 3 "1.2"
|
||||
=> "1.2.0"
|
||||
pad 3 "1.3-rc1"
|
||||
=> "1.3.0-rc1"
|
||||
pad 3 "1.2.3.4"
|
||||
=> "1.2.3"
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
pad =
|
||||
n: version:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue