diff --git a/lib/fileset/internal.nix b/lib/fileset/internal.nix index 7f002216bc7f..1fd0a7e2350d 100644 --- a/lib/fileset/internal.nix +++ b/lib/fileset/internal.nix @@ -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: diff --git a/lib/licenses.nix b/lib/licenses.nix index f72efa5a6145..5d0aff11b7a3 100644 --- a/lib/licenses.nix +++ b/lib/licenses.nix @@ -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; }; diff --git a/lib/modules.nix b/lib/modules.nix index 4d2d8e0b08b6..935ef4baabad 100644 --- a/lib/modules.nix +++ b/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 = [ ]; - # All modules of the main module list - modules = [ - { - key = ; - module = ; - # All modules imported by the module for key1 - modules = [ - { - key = ; - module = ; - # All modules imported by the module for key1-1 - modules = [ ... ]; - } - ... - ]; - } - ... - ]; - } + { + disabled = [ ]; + # All modules of the main module list + modules = [ + { + key = ; + module = ; + # All modules imported by the module for key1 + modules = [ + { + key = ; + module = ; + # 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" ] "" + mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ] "" - 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; diff --git a/lib/network/internal.nix b/lib/network/internal.nix index 3e05be90c547..20a18e073af5 100644 --- a/lib/network/internal.nix +++ b/lib/network/internal.nix @@ -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 diff --git a/lib/options.nix b/lib/options.nix index fe665040ad03..08ac385ff46f 100644 --- a/lib/options.nix +++ b/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" "" "bar"]) == "foo..bar" - (showOption ["foo" "" "bar"]) == "foo..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" "" "bar"]) == "foo..bar" + (showOption ["foo" "" "bar"]) == "foo..bar" + ``` + + ::: */ showOption = parts: let # If the part is a named placeholder of the form "<...>" don't escape it. diff --git a/lib/path/default.nix b/lib/path/default.nix index e8f0c646c545..62c5b7d3c5da 100644 --- a/lib/path/default.nix +++ b/lib/path/default.nix @@ -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" - => + `subpath` - # second argument needs to be a valid subpath string - append /foo /bar - => - append /foo "" - => - append /foo "/bar" - => - append /foo "../bar" - => + : 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" + => + + # second argument needs to be a valid subpath string + append /foo /bar + => + append /foo "" + => + append /foo "/bar" + => + append /foo "../bar" + => + ``` + + ::: */ 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 - => - 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 + => + 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" - => + # 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" + => + ``` + + ::: */ 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 ] - => - subpath.join [ "" ] - => - subpath.join [ "/foo" ] - => - subpath.join [ "../foo" ] - => + # 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 ] + => + subpath.join [ "" ] + => + subpath.join [ "/foo" ] + => + subpath.join [ "../foo" ] + => + ``` + + ::: */ 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" - => + : 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" + => + ``` + + ::: */ 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" - => + ```nix + # limit repeating `/` to a single one + subpath.normalise "foo//bar" + => "./foo/bar" - # error on empty string - subpath.normalise "" - => + # remove redundant `.` components + subpath.normalise "foo/./bar" + => "./foo/bar" - # error on absolute path - subpath.normalise "/foo" - => + # 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 on empty string + subpath.normalise "" + => + + # error on absolute path + subpath.normalise "/foo" + => + ``` + + ::: */ subpath.normalise = # The subpath string to normalise diff --git a/lib/sources.nix b/lib/sources.nix index 168e58225889..0fcdb18fdfaf 100644 --- a/lib/sources.nix +++ b/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 + + # Inputs + + `path` + + : 1\. Function argument + + + # Examples + :::{.example} + ## `commitIdFromGitRepo` usage example + + ```nix + commitIdFromGitRepo + ``` + + ::: */ commitIdFromGitRepo = path: diff --git a/lib/strings-with-deps.nix b/lib/strings-with-deps.nix index 900827fe0e4b..e22e19def581 100644 --- a/lib/strings-with-deps.nix +++ b/lib/strings-with-deps.nix @@ -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 ) {}; - in let - inherit (pkgs.stringsWithDeps) fullDepEntry packEntry noDepEntry textClosureMap; - inherit (pkgs.lib) id; + let + pkgs = (import ) {}; + 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 diff --git a/lib/versions.nix b/lib/versions.nix index 32b4b5fbf945..cde0acaef0a9 100644 --- a/lib/versions.nix +++ b/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: