mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-10 03:23:29 +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
|
# 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:
|
||||||
|
|
|
@ -24,10 +24,11 @@ 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 = {
|
||||||
spdxId = "Abstyles";
|
spdxId = "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;
|
||||||
};
|
};
|
||||||
|
|
591
lib/modules.nix
591
lib/modules.nix
|
@ -74,14 +74,16 @@ let
|
||||||
decls
|
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
|
!!! 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,30 +380,30 @@ let
|
||||||
else
|
else
|
||||||
m: m;
|
m: m;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Collects all modules recursively into the form
|
Collects all modules recursively into the form
|
||||||
|
|
||||||
{
|
{
|
||||||
disabled = [ <list of disabled modules> ];
|
disabled = [ <list of disabled modules> ];
|
||||||
# All modules of the main module list
|
# All modules of the main module list
|
||||||
modules = [
|
modules = [
|
||||||
{
|
{
|
||||||
key = <key1>;
|
key = <key1>;
|
||||||
module = <module for key1>;
|
module = <module for key1>;
|
||||||
# All modules imported by the module for key1
|
# All modules imported by the module for key1
|
||||||
modules = [
|
modules = [
|
||||||
{
|
{
|
||||||
key = <key1-1>;
|
key = <key1-1>;
|
||||||
module = <module for key1-1>;
|
module = <module for key1-1>;
|
||||||
# All modules imported by the module for key1-1
|
# All modules imported by the module for key1-1
|
||||||
modules = [ ... ];
|
modules = [ ... ];
|
||||||
}
|
}
|
||||||
...
|
...
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
...
|
...
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
collectStructuredModules =
|
collectStructuredModules =
|
||||||
let
|
let
|
||||||
|
@ -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,26 +560,38 @@ let
|
||||||
# works.
|
# works.
|
||||||
in f (args // extraArgs);
|
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.
|
Merge a list of modules. This will recurse over the option
|
||||||
At the same time, for each option declaration, it will merge the
|
declarations in all modules, combining them into a single set.
|
||||||
corresponding option definitions in all machines, returning them
|
At the same time, for each option declaration, it will merge the
|
||||||
in the ‘value’ attribute of each option.
|
corresponding option definitions in all machines, returning them
|
||||||
|
in the ‘value’ attribute of each option.
|
||||||
|
|
||||||
This returns a set like
|
This returns a set like
|
||||||
{
|
{
|
||||||
# A recursive set of options along with their final values
|
# A recursive set of options along with their final values
|
||||||
matchedOptions = {
|
matchedOptions = {
|
||||||
foo = { _type = "option"; value = "option value of foo"; ... };
|
foo = { _type = "option"; value = "option value of foo"; ... };
|
||||||
bar.baz = { _type = "option"; value = "option value of bar.baz"; ... };
|
bar.baz = { _type = "option"; value = "option value of bar.baz"; ... };
|
||||||
...
|
...
|
||||||
};
|
};
|
||||||
# A list of definitions that weren't matched by any option
|
# A list of definitions that weren't matched by any option
|
||||||
unmatchedDefns = [
|
unmatchedDefns = [
|
||||||
{ file = "file.nix"; prefix = [ "qux" ]; value = "qux"; }
|
{ file = "file.nix"; prefix = [ "qux" ]; value = "qux"; }
|
||||||
...
|
...
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Inputs
|
||||||
|
|
||||||
|
`prefix`
|
||||||
|
|
||||||
|
: 1\. Function argument
|
||||||
|
|
||||||
|
`modules`
|
||||||
|
|
||||||
|
: 2\. Function argument
|
||||||
*/
|
*/
|
||||||
mergeModules = prefix: modules:
|
mergeModules = prefix: modules:
|
||||||
mergeModules' prefix modules
|
mergeModules' prefix modules
|
||||||
|
@ -740,17 +784,30 @@ let
|
||||||
in
|
in
|
||||||
throw (concatStringsSep "\n\n" paragraphs);
|
throw (concatStringsSep "\n\n" paragraphs);
|
||||||
|
|
||||||
/* Merge multiple option declarations into a single declaration. In
|
/**
|
||||||
general, there should be only one declaration of each option.
|
Merge multiple option declarations into a single declaration. In
|
||||||
The exception is the ‘options’ attribute, which specifies
|
general, there should be only one declaration of each option.
|
||||||
sub-options. These can be specified multiple times to allow one
|
The exception is the ‘options’ attribute, which specifies
|
||||||
module to add sub-options to an option declared somewhere else
|
sub-options. These can be specified multiple times to allow one
|
||||||
(e.g. multiple modules define sub-options for ‘fileSystems’).
|
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
|
'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,20 +976,28 @@ let
|
||||||
else {};
|
else {};
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Given a config set, expand mkMerge properties, and push down the
|
/**
|
||||||
other properties into the children. The result is a list of
|
Given a config set, expand mkMerge properties, and push down the
|
||||||
config sets that do not have properties at top-level. For
|
other properties into the children. The result is a list of
|
||||||
example,
|
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
|
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,15 +1009,23 @@ let
|
||||||
else # FIXME: handle mkOrder?
|
else # FIXME: handle mkOrder?
|
||||||
[ cfg ];
|
[ cfg ];
|
||||||
|
|
||||||
/* Given a config value, expand mkMerge properties, and discharge
|
/**
|
||||||
any mkIf conditions. That is, this is the place where mkIf
|
Given a config value, expand mkMerge properties, and discharge
|
||||||
conditions are actually evaluated. The result is a list of
|
any mkIf conditions. That is, this is the place where mkIf
|
||||||
config values. For example, ‘mkIf false x’ yields ‘[]’,
|
conditions are actually evaluated. The result is a list of
|
||||||
‘mkIf true x’ yields ‘[x]’, and
|
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:
|
dischargeProperties = def:
|
||||||
if def._type or "" == "merge" then
|
if def._type or "" == "merge" then
|
||||||
|
@ -951,24 +1041,32 @@ let
|
||||||
else
|
else
|
||||||
[ def ];
|
[ def ];
|
||||||
|
|
||||||
/* Given a list of config values, process the mkOverride properties,
|
/**
|
||||||
that is, return the values that have the highest (that is,
|
Given a list of config values, process the mkOverride properties,
|
||||||
numerically lowest) priority, and strip the mkOverride
|
that is, return the values that have the highest (that is,
|
||||||
properties. For example,
|
numerically lowest) priority, and strip the mkOverride
|
||||||
|
properties. For example,
|
||||||
|
|
||||||
[ { file = "/1"; value = mkOverride 10 "a"; }
|
[ { file = "/1"; value = mkOverride 10 "a"; }
|
||||||
{ file = "/2"; value = mkOverride 20 "b"; }
|
{ file = "/2"; value = mkOverride 20 "b"; }
|
||||||
{ file = "/3"; value = "z"; }
|
{ file = "/3"; value = "z"; }
|
||||||
{ file = "/4"; value = mkOverride 10 "d"; }
|
{ file = "/4"; value = mkOverride 10 "d"; }
|
||||||
]
|
]
|
||||||
|
|
||||||
yields
|
yields
|
||||||
|
|
||||||
[ { file = "/1"; value = "a"; }
|
[ { file = "/1"; value = "a"; }
|
||||||
{ file = "/4"; value = "d"; }
|
{ 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;
|
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
|
/**
|
||||||
defaultOrderPriority by default, but can be overridden by wrapping the property
|
Sort a list of properties. The sort priority of a property is
|
||||||
using mkOrder. */
|
defaultOrderPriority by default, but can be overridden by wrapping the property
|
||||||
|
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:
|
|
||||||
option -> attrsOf { highestPrio, value }
|
# Inputs
|
||||||
|
|
||||||
|
`opt`
|
||||||
|
|
||||||
|
: 1\. Function argument
|
||||||
|
|
||||||
|
# Type
|
||||||
|
|
||||||
|
```
|
||||||
|
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,21 +1246,46 @@ 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
|
/**
|
||||||
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
|
replacementInstructions is a string that provides instructions on
|
||||||
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,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
|
Return a module that causes a warning to be shown if the
|
||||||
forwarded to the "to" option. This can be used to rename options
|
specified "from" option is defined; the defined value is however
|
||||||
while providing backward compatibility. For example,
|
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
|
forwards any definitions of boot.copyKernels to
|
||||||
boot.loader.grub.copyKernels while printing a warning.
|
boot.loader.grub.copyKernels while printing a warning.
|
||||||
|
|
||||||
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,33 +1359,49 @@ 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"
|
/**
|
||||||
option is defined; the defined values can be used in the "mergeFn" to set
|
Return a module that causes a warning to be shown if any of the "from"
|
||||||
the "to" value.
|
option is defined; the defined values can be used in the "mergeFn" to set
|
||||||
This function can be used to merge multiple options into one that has a
|
the "to" value.
|
||||||
different type.
|
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
|
"mergeFn" takes the module "config" as a parameter and must return a value
|
||||||
of "to" option type.
|
of "to" option type.
|
||||||
|
|
||||||
mkMergedOptionModule
|
mkMergedOptionModule
|
||||||
[ [ "a" "b" "c" ]
|
[ [ "a" "b" "c" ]
|
||||||
[ "d" "e" "f" ] ]
|
[ "d" "e" "f" ] ]
|
||||||
[ "x" "y" "z" ]
|
[ "x" "y" "z" ]
|
||||||
(config:
|
(config:
|
||||||
let value = p: getAttrFromPath p config;
|
let value = p: getAttrFromPath p config;
|
||||||
in
|
in
|
||||||
if (value [ "a" "b" "c" ]) == true then "foo"
|
if (value [ "a" "b" "c" ]) == true then "foo"
|
||||||
else if (value [ "d" "e" "f" ]) == true then "bar"
|
else if (value [ "d" "e" "f" ]) == true then "bar"
|
||||||
else "baz")
|
else "baz")
|
||||||
|
|
||||||
- options.a.b.c is a removed boolean option
|
- options.a.b.c is a removed boolean option
|
||||||
- options.d.e.f 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
|
- options.x.y.z is a new str option that combines a.b.c and d.e.f
|
||||||
functionality
|
functionality
|
||||||
|
|
||||||
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,33 +1427,62 @@ let
|
||||||
(mergeFn config)));
|
(mergeFn config)));
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Single "from" version of mkMergedOptionModule.
|
/**
|
||||||
Return a module that causes a warning to be shown if the "from" option is
|
Single "from" version of mkMergedOptionModule.
|
||||||
defined; the defined value can be used in the "mergeFn" to set the "to"
|
Return a module that causes a warning to be shown if the "from" option is
|
||||||
value.
|
defined; the defined value can be used in the "mergeFn" to set the "to"
|
||||||
This function can be used to change an option into another that has a
|
value.
|
||||||
different type.
|
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
|
"mergeFn" takes the module "config" as a parameter and must return a value of
|
||||||
"to" option type.
|
"to" option type.
|
||||||
|
|
||||||
mkChangedOptionModule [ "a" "b" "c" ] [ "x" "y" "z" ]
|
mkChangedOptionModule [ "a" "b" "c" ] [ "x" "y" "z" ]
|
||||||
(config:
|
(config:
|
||||||
let value = getAttrFromPath [ "a" "b" "c" ] config;
|
let value = getAttrFromPath [ "a" "b" "c" ] config;
|
||||||
in
|
in
|
||||||
if value > 100 then "high"
|
if value > 100 then "high"
|
||||||
else "normal")
|
else "normal")
|
||||||
|
|
||||||
- options.a.b.c is a removed int option
|
- options.a.b.c is a removed int option
|
||||||
- options.x.y.z is a new str option that supersedes a.b.c
|
- 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
|
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,10 +1529,10 @@ 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.
|
||||||
*/
|
*/
|
||||||
doRename = {
|
doRename = {
|
||||||
# List of strings representing the attribute path of the old option.
|
# List of strings representing the attribute path of the old option.
|
||||||
from,
|
from,
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
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 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,
|
||||||
# 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
|
# 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;
|
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 = 1; } { value = 2; } ] // => [ 1 2 ]
|
getValues :: [ { value :: a; } ] -> [a]
|
||||||
getValues [ ] // => [ ]
|
```
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
:::{.example}
|
||||||
|
## `getValues` usage example
|
||||||
|
|
||||||
|
```nix
|
||||||
|
getValues [ { value = 1; } { value = 2; } ] // => [ 1 2 ]
|
||||||
|
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 = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ]
|
getFiles :: [ { file :: a; } ] -> [a]
|
||||||
getFiles [ ] // => [ ]
|
```
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
:::{.example}
|
||||||
|
## `getFiles` usage example
|
||||||
|
|
||||||
|
```nix
|
||||||
|
getFiles [ { file = "file1"; } { file = "file2"; } ] // => [ "file1" "file2" ]
|
||||||
|
getFiles [ ] // => [ ]
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
*/
|
*/
|
||||||
getFiles = map (x: x.file);
|
getFiles = map (x: x.file);
|
||||||
|
|
||||||
|
@ -530,16 +578,24 @@ rec {
|
||||||
[ docOption ] ++ optionals subOptionsVisible subOptions) (collect isOption options);
|
[ 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
|
This is to make the generation of `options.xml` much more
|
||||||
efficient: the XML representation of derivations is very large
|
efficient: the XML representation of derivations is very large
|
||||||
(on the order of megabytes) and is not actually used by the
|
(on the order of megabytes) and is not actually used by the
|
||||||
manual generator.
|
manual generator.
|
||||||
|
|
||||||
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
|
/**
|
||||||
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:
|
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
|
/**
|
||||||
given string to be rendered verbatim in the documentation as Nix code. This
|
For use in the `defaultText` and `example` option attributes. Causes the
|
||||||
is necessary for complex values, e.g. functions, or values that depend on
|
given string to be rendered verbatim in the documentation as Nix code. This
|
||||||
other values or packages.
|
is necessary for complex values, e.g. functions, or values that depend on
|
||||||
|
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
|
/**
|
||||||
given MD text to be inserted verbatim in the documentation, for when
|
For use in the `defaultText` and `example` option attributes. Causes the
|
||||||
a `literalExpression` would be too hard to read.
|
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:
|
literalMD = text:
|
||||||
if ! isString text then throw "literalMD expects a string."
|
if ! isString text then throw "literalMD expects a string."
|
||||||
|
@ -581,18 +661,34 @@ rec {
|
||||||
|
|
||||||
# Helper functions.
|
# 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:
|
# Inputs
|
||||||
(showOption ["foo" "*" "bar"]) == "foo.*.bar"
|
|
||||||
(showOption ["foo" "<name>" "bar"]) == "foo.<name>.bar"
|
`parts`
|
||||||
(showOption ["foo" "<myPlaceholder>" "bar"]) == "foo.<myPlaceholder>.bar"
|
|
||||||
|
: 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
|
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.
|
||||||
|
|
|
@ -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,34 +178,55 @@ in
|
||||||
|
|
||||||
append p s == append p (subpath.normalise s)
|
append p s == append p (subpath.normalise s)
|
||||||
|
|
||||||
Type:
|
|
||||||
append :: Path -> String -> Path
|
|
||||||
|
|
||||||
Example:
|
# Inputs
|
||||||
append /foo "bar/baz"
|
|
||||||
=> /foo/bar/baz
|
|
||||||
|
|
||||||
# subpaths don't need to be normalised
|
`path`
|
||||||
append /foo "./bar//baz/./"
|
|
||||||
=> /foo/bar/baz
|
|
||||||
|
|
||||||
# can append to root directory
|
: The absolute path to append to
|
||||||
append /. "foo/bar"
|
|
||||||
=> /foo/bar
|
|
||||||
|
|
||||||
# first argument needs to be a path value type
|
`subpath`
|
||||||
append "/foo" "bar"
|
|
||||||
=> <error>
|
|
||||||
|
|
||||||
# second argument needs to be a valid subpath string
|
: The subpath string to append
|
||||||
append /foo /bar
|
|
||||||
=> <error>
|
# Type
|
||||||
append /foo ""
|
|
||||||
=> <error>
|
```
|
||||||
append /foo "/bar"
|
append :: Path -> String -> Path
|
||||||
=> <error>
|
```
|
||||||
append /foo "../bar"
|
|
||||||
=> <error>
|
# 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 =
|
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,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.
|
- `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
|
||||||
hasPrefix /foo /foo/bar
|
|
||||||
=> true
|
`path1`
|
||||||
hasPrefix /foo /foo
|
|
||||||
=> true
|
: 1\. Function argument
|
||||||
hasPrefix /foo/bar /foo
|
|
||||||
=> false
|
# Type
|
||||||
hasPrefix /. /foo
|
|
||||||
=> true
|
```
|
||||||
|
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 =
|
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,18 +309,35 @@ in
|
||||||
|
|
||||||
removePrefix p (append p s) == subpath.normalise s
|
removePrefix p (append p s) == subpath.normalise s
|
||||||
|
|
||||||
Type:
|
|
||||||
removePrefix :: Path -> Path -> String
|
|
||||||
|
|
||||||
Example:
|
# Inputs
|
||||||
removePrefix /foo /foo/bar/baz
|
|
||||||
=> "./bar/baz"
|
`path1`
|
||||||
removePrefix /foo /foo
|
|
||||||
=> "./."
|
: 1\. Function argument
|
||||||
removePrefix /foo/bar /foo
|
|
||||||
=> <error>
|
# Type
|
||||||
removePrefix /. /foo
|
|
||||||
=> "./foo"
|
```
|
||||||
|
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 =
|
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,22 +383,39 @@ in
|
||||||
|
|
||||||
dirOf (splitRoot p).root == (splitRoot p).root
|
dirOf (splitRoot p).root == (splitRoot p).root
|
||||||
|
|
||||||
Type:
|
|
||||||
splitRoot :: Path -> { root :: Path, subpath :: String }
|
|
||||||
|
|
||||||
Example:
|
# Inputs
|
||||||
splitRoot /foo/bar
|
|
||||||
=> { root = /.; subpath = "./foo/bar"; }
|
|
||||||
|
|
||||||
splitRoot /.
|
`path`
|
||||||
=> { root = /.; subpath = "./."; }
|
|
||||||
|
|
||||||
# Nix neutralises `..` path components for all path values automatically
|
: The path to split the root off of
|
||||||
splitRoot /foo/../bar
|
|
||||||
=> { root = /.; subpath = "./bar"; }
|
|
||||||
|
|
||||||
splitRoot "/foo/bar"
|
# Type
|
||||||
=> <error>
|
|
||||||
|
```
|
||||||
|
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 =
|
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,33 +443,50 @@ 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
|
||||||
# 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
|
`path`
|
||||||
hasStorePathPrefix /nix/store
|
|
||||||
=> false
|
|
||||||
|
|
||||||
# Derivation outputs are store paths themselves
|
: 1\. Function argument
|
||||||
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo
|
|
||||||
=> true
|
|
||||||
|
|
||||||
# Paths outside the Nix store don't have a store path prefix
|
# Type
|
||||||
hasStorePathPrefix /home/user
|
|
||||||
=> false
|
|
||||||
|
|
||||||
# Not all paths under the Nix store are store paths
|
```
|
||||||
hasStorePathPrefix /nix/store/.links/10gg8k3rmbw8p7gszarbk7qyd9jwxhcfq9i6s5i0qikx8alkk4hq
|
hasStorePathPrefix :: Path -> Bool
|
||||||
=> false
|
```
|
||||||
|
|
||||||
# Store derivations are also store paths themselves
|
# Examples
|
||||||
hasStorePathPrefix /nix/store/nvl9ic0pj1fpyln3zaqrf4cclbqdfn1j-foo.drv
|
:::{.example}
|
||||||
=> true
|
## `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 =
|
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,39 +517,56 @@ in
|
||||||
|
|
||||||
- The string doesn't contain any `..` path components.
|
- The string doesn't contain any `..` path components.
|
||||||
|
|
||||||
Type:
|
|
||||||
subpath.isValid :: String -> Bool
|
|
||||||
|
|
||||||
Example:
|
# Inputs
|
||||||
# Not a string
|
|
||||||
subpath.isValid null
|
|
||||||
=> false
|
|
||||||
|
|
||||||
# Empty string
|
`value`
|
||||||
subpath.isValid ""
|
|
||||||
=> false
|
|
||||||
|
|
||||||
# Absolute path
|
: The value to check
|
||||||
subpath.isValid "/foo"
|
|
||||||
=> false
|
|
||||||
|
|
||||||
# Contains a `..` path component
|
# Type
|
||||||
subpath.isValid "../foo"
|
|
||||||
=> false
|
|
||||||
|
|
||||||
# Valid subpath
|
```
|
||||||
subpath.isValid "foo/bar"
|
subpath.isValid :: String -> Bool
|
||||||
=> true
|
```
|
||||||
|
|
||||||
# Doesn't need to be normalised
|
# Examples
|
||||||
subpath.isValid "./foo//bar/"
|
:::{.example}
|
||||||
=> true
|
## `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 =
|
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,30 +598,47 @@ in
|
||||||
|
|
||||||
ps != [] -> subpath.join ps == subpath.normalise (concatStringsSep "/" ps)
|
ps != [] -> subpath.join ps == subpath.normalise (concatStringsSep "/" ps)
|
||||||
|
|
||||||
Type:
|
|
||||||
subpath.join :: [ String ] -> String
|
|
||||||
|
|
||||||
Example:
|
# Inputs
|
||||||
subpath.join [ "foo" "bar/baz" ]
|
|
||||||
=> "./foo/bar/baz"
|
|
||||||
|
|
||||||
# normalise the result
|
`subpaths`
|
||||||
subpath.join [ "./foo" "." "bar//./baz/" ]
|
|
||||||
=> "./foo/bar/baz"
|
|
||||||
|
|
||||||
# passing an empty list results in the current directory
|
: The list of subpaths to join together
|
||||||
subpath.join [ ]
|
|
||||||
=> "./."
|
|
||||||
|
|
||||||
# elements must be valid subpath strings
|
# Type
|
||||||
subpath.join [ /foo ]
|
|
||||||
=> <error>
|
```
|
||||||
subpath.join [ "" ]
|
subpath.join :: [ String ] -> String
|
||||||
=> <error>
|
```
|
||||||
subpath.join [ "/foo" ]
|
|
||||||
=> <error>
|
# Examples
|
||||||
subpath.join [ "../foo" ]
|
:::{.example}
|
||||||
=> <error>
|
## `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 =
|
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,18 +671,35 @@ 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.components "."
|
|
||||||
=> [ ]
|
|
||||||
|
|
||||||
subpath.components "./foo//bar/./baz/"
|
`subpath`
|
||||||
=> [ "foo" "bar" "baz" ]
|
|
||||||
|
|
||||||
subpath.components "/foo"
|
: The subpath string to split into components
|
||||||
=> <error>
|
|
||||||
|
# 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 =
|
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,45 +742,62 @@ 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
|
||||||
# limit repeating `/` to a single one
|
|
||||||
subpath.normalise "foo//bar"
|
|
||||||
=> "./foo/bar"
|
|
||||||
|
|
||||||
# remove redundant `.` components
|
`subpath`
|
||||||
subpath.normalise "foo/./bar"
|
|
||||||
=> "./foo/bar"
|
|
||||||
|
|
||||||
# add leading `./`
|
: The subpath string to normalise
|
||||||
subpath.normalise "foo/bar"
|
|
||||||
=> "./foo/bar"
|
|
||||||
|
|
||||||
# remove trailing `/`
|
# Type
|
||||||
subpath.normalise "foo/bar/"
|
|
||||||
=> "./foo/bar"
|
|
||||||
|
|
||||||
# remove trailing `/.`
|
```
|
||||||
subpath.normalise "foo/bar/."
|
subpath.normalise :: String -> String
|
||||||
=> "./foo/bar"
|
```
|
||||||
|
|
||||||
# Return the current directory as `./.`
|
# Examples
|
||||||
subpath.normalise "."
|
:::{.example}
|
||||||
=> "./."
|
## `subpath.normalise` usage example
|
||||||
|
|
||||||
# error on `..` path components
|
```nix
|
||||||
subpath.normalise "foo/../bar"
|
# limit repeating `/` to a single one
|
||||||
=> <error>
|
subpath.normalise "foo//bar"
|
||||||
|
=> "./foo/bar"
|
||||||
|
|
||||||
# error on empty string
|
# remove redundant `.` components
|
||||||
subpath.normalise ""
|
subpath.normalise "foo/./bar"
|
||||||
=> <error>
|
=> "./foo/bar"
|
||||||
|
|
||||||
# error on absolute path
|
# add leading `./`
|
||||||
subpath.normalise "/foo"
|
subpath.normalise "foo/bar"
|
||||||
=> <error>
|
=> "./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 =
|
subpath.normalise =
|
||||||
# The subpath string to normalise
|
# The subpath string to normalise
|
||||||
|
|
157
lib/sources.nix
157
lib/sources.nix
|
@ -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:
|
|
||||||
cleanSource ./.
|
# Inputs
|
||||||
|
|
||||||
|
`src`
|
||||||
|
|
||||||
|
: 1\. Function argument
|
||||||
|
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
:::{.example}
|
||||||
|
## `cleanSource` usage example
|
||||||
|
|
||||||
|
```nix
|
||||||
|
cleanSource ./.
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
*/
|
*/
|
||||||
cleanSource =
|
cleanSource =
|
||||||
src:
|
src:
|
||||||
|
@ -65,23 +91,31 @@ 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:
|
|
||||||
lib.cleanSourceWith {
|
|
||||||
filter = f;
|
|
||||||
src = lib.cleanSourceWith {
|
|
||||||
filter = g;
|
|
||||||
src = ./.;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
# Succeeds!
|
|
||||||
|
|
||||||
builtins.filterSource f (builtins.filterSource g ./.)
|
# Examples
|
||||||
# Fails!
|
:::{.example}
|
||||||
|
## `cleanSourceWith` usage example
|
||||||
|
|
||||||
|
```nix
|
||||||
|
lib.cleanSourceWith {
|
||||||
|
filter = f;
|
||||||
|
src = lib.cleanSourceWith {
|
||||||
|
filter = g;
|
||||||
|
src = ./.;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
# Succeeds!
|
||||||
|
|
||||||
|
builtins.filterSource f (builtins.filterSource g ./.)
|
||||||
|
# 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:
|
|
||||||
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 =
|
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
|
||||||
sourceFilesBySuffices ./. [ ".xml" ".c" ]
|
|
||||||
|
`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 =
|
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:
|
||||||
|
|
|
@ -1,44 +1,44 @@
|
||||||
{ 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:
|
||||||
builder = writeScript "fsg-4.4-builder"
|
builder = writeScript "fsg-4.4-builder"
|
||||||
(textClosure [doUnpack addInputs preBuild doMake installPhase doForceShare]);
|
(textClosure [doUnpack addInputs preBuild doMake installPhase doForceShare]);
|
||||||
|
|
||||||
a step is defined by noDepEntry, fullDepEntry or packEntry.
|
a step is defined by noDepEntry, fullDepEntry or packEntry.
|
||||||
To ensure that prerequisite are met those are added before the task itself by
|
To ensure that prerequisite are met those are added before the task itself by
|
||||||
textClosureDupList. Duplicated items are removed again.
|
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
|
let
|
||||||
pkgs = (import <nixpkgs>) {};
|
pkgs = (import <nixpkgs>) {};
|
||||||
in let
|
in let
|
||||||
inherit (pkgs.stringsWithDeps) fullDepEntry packEntry noDepEntry textClosureMap;
|
inherit (pkgs.stringsWithDeps) fullDepEntry packEntry noDepEntry textClosureMap;
|
||||||
inherit (pkgs.lib) id;
|
inherit (pkgs.lib) id;
|
||||||
|
|
||||||
nameA = noDepEntry "Text a";
|
nameA = noDepEntry "Text a";
|
||||||
nameB = fullDepEntry "Text b" ["nameA"];
|
nameB = fullDepEntry "Text b" ["nameA"];
|
||||||
nameC = fullDepEntry "Text c" ["nameA"];
|
nameC = fullDepEntry "Text c" ["nameA"];
|
||||||
|
|
||||||
stages = {
|
stages = {
|
||||||
nameHeader = noDepEntry "#! /bin/sh \n";
|
nameHeader = noDepEntry "#! /bin/sh \n";
|
||||||
inherit nameA nameB nameC;
|
inherit nameA nameB nameC;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
textClosureMap id stages
|
textClosureMap id stages
|
||||||
[ "nameHeader" "nameA" "nameB" "nameC"
|
[ "nameHeader" "nameA" "nameB" "nameC"
|
||||||
nameC # <- added twice. add a dep entry if you know that it will be added once only [1]
|
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
|
"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
|
let
|
||||||
|
|
143
lib/versions.nix
143
lib/versions.nix
|
@ -3,62 +3,149 @@
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Break a version string into its component parts.
|
Break a version string into its component parts.
|
||||||
|
|
||||||
Example:
|
|
||||||
splitVersion "1.2.3"
|
# Examples
|
||||||
=> ["1" "2" "3"]
|
:::{.example}
|
||||||
|
## `splitVersion` usage example
|
||||||
|
|
||||||
|
```nix
|
||||||
|
splitVersion "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:
|
|
||||||
major "1.2.3"
|
# Inputs
|
||||||
=> "1"
|
|
||||||
|
`v`
|
||||||
|
|
||||||
|
: 1\. Function argument
|
||||||
|
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
:::{.example}
|
||||||
|
## `major` usage example
|
||||||
|
|
||||||
|
```nix
|
||||||
|
major "1.2.3"
|
||||||
|
=> "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:
|
|
||||||
minor "1.2.3"
|
# Inputs
|
||||||
=> "2"
|
|
||||||
|
`v`
|
||||||
|
|
||||||
|
: 1\. Function argument
|
||||||
|
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
:::{.example}
|
||||||
|
## `minor` usage example
|
||||||
|
|
||||||
|
```nix
|
||||||
|
minor "1.2.3"
|
||||||
|
=> "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:
|
|
||||||
patch "1.2.3"
|
# Inputs
|
||||||
=> "3"
|
|
||||||
|
`v`
|
||||||
|
|
||||||
|
: 1\. Function argument
|
||||||
|
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
:::{.example}
|
||||||
|
## `patch` usage example
|
||||||
|
|
||||||
|
```nix
|
||||||
|
patch "1.2.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:
|
|
||||||
majorMinor "1.2.3"
|
# Inputs
|
||||||
=> "1.2"
|
|
||||||
|
`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));
|
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:
|
|
||||||
pad 3 "1.2"
|
# Inputs
|
||||||
=> "1.2.0"
|
|
||||||
pad 3 "1.3-rc1"
|
`n`
|
||||||
=> "1.3.0-rc1"
|
|
||||||
pad 3 "1.2.3.4"
|
: 1\. Function argument
|
||||||
=> "1.2.3"
|
|
||||||
|
`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 =
|
pad =
|
||||||
n: version:
|
n: version:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue