Factor out the NixOS `meta.maintainers` module (#431450)

Changed files
+202 -48
ci
doc
modules
generic
meta-maintainers
nixos
+1
ci/eval/default.nix
···
"doc"
"lib"
"maintainers"
+
"modules"
"nixos"
"pkgs"
".version"
+32
doc/doc-support/package.nix
···
markdown-code-runner,
roboto,
treefmt,
+
nixosOptionsDoc,
}:
stdenvNoCC.mkDerivation (
finalAttrs:
let
inherit (finalAttrs.finalPackage.optionsDoc) optionsJSON;
inherit (finalAttrs.finalPackage) epub lib-docs pythonInterpreterTable;
+
+
# Make anything from lib (the module system internals) invisible
+
hide-lib =
+
opt:
+
opt
+
// {
+
visible = if lib.all (decl: decl == "lib/modules.nix") opt.declarations then false else opt.visible;
+
};
+
+
toURL =
+
decl:
+
let
+
declStr = toString decl;
+
root = toString (../..);
+
subpath = lib.removePrefix "/" (lib.removePrefix root declStr);
+
in
+
if lib.hasPrefix root declStr then
+
{
+
url = "https://github.com/NixOS/nixpkgs/blob/master/${subpath}";
+
name = "nixpkgs/${subpath}";
+
}
+
else
+
decl;
+
+
mapURLs = opt: opt // { declarations = map toURL opt.declarations; };
+
+
docs.generic.meta-maintainers = nixosOptionsDoc {
+
inherit (lib.evalModules { modules = [ ../../modules/generic/meta-maintainers.nix ]; }) options;
+
transformOptions = opt: hide-lib (mapURLs opt);
+
};
in
{
name = "nixpkgs-manual";
···
ln -s ${optionsJSON}/share/doc/nixos/options.json ./config-options.json
ln -s ${treefmt.functionsDoc.markdown} ./packages/treefmt-functions.section.md
ln -s ${treefmt.optionsDoc.optionsJSON}/share/doc/nixos/options.json ./treefmt-options.json
+
ln -s ${docs.generic.meta-maintainers.optionsJSON}/share/doc/nixos/options.json ./options-modules-generic-meta-maintainers.json
'';
buildPhase = ''
+1
doc/manual.md.in
···
stdenv.md
toolchains.md
build-helpers.md
+
modules/index.md
development.md
contributing.md
interoperability.md
+16
doc/modules/generic.chapter.md
···
+
+
# Generic {#modules-generic}
+
+
Generic modules can be imported to extend configurations of any [class].
+
+
## `meta-maintainers.nix` {#modules-generic-meta-maintainers}
+
+
The options below become available when using `imports = [ (nixpkgs + "/modules/generic/meta-maintainers.nix") ];`.
+
+
```{=include=} options
+
id-prefix: opt-modules-generic-meta-maintainers-
+
list-id: configuration-variable-list
+
source: ../options-modules-generic-meta-maintainers.json
+
```
+
+
[class]: https://nixos.org/manual/nixpkgs/unstable/#module-system-lib-evalModules-param-class
+12
doc/modules/index.md
···
+
# Modules {#modules}
+
+
The Nixpkgs repository provides [Module System] modules for various purposes.
+
+
The following sections are organized by [module class].
+
+
```{=include=} chapters
+
generic.chapter.md
+
```
+
+
[Module System]: https://nixos.org/manual/nixpkgs/unstable/#module-system
+
[module class]: https://nixos.org/manual/nixpkgs/unstable/#module-system-lib-evalModules-param-class
+9
doc/redirects.json
···
"minor-ghc-deprecation": [
"index.html#minor-ghc-deprecation"
],
+
"modules": [
+
"index.html#modules"
+
],
+
"modules-generic": [
+
"index.html#modules-generic"
+
],
+
"modules-generic-meta-maintainers": [
+
"index.html#modules-generic-meta-maintainers"
+
],
"neovim": [
"index.html#neovim"
],
+9
modules/README.md
···
+
# `<nixpkgs>/modules`
+
+
This directory hosts subdirectories representing each module [class](https://nixos.org/manual/nixpkgs/stable/#module-system-lib-evalModules-param-class) for which the `nixpkgs` repository has user-importable modules.
+
+
Exceptions:
+
- `_class = "nixos";` modules go in the `<nixpkgs>/nixos/modules` tree
+
- modules whose only purpose is to test code in this repository
+
+
The emphasis is on _importable_ modules, i.e. ones that aren't inherent to and built into the Module System application.
+63
modules/generic/meta-maintainers.nix
···
+
# Test:
+
# ./meta-maintainers/test.nix
+
{ lib, ... }:
+
let
+
inherit (lib)
+
mkOption
+
mkOptionType
+
types
+
;
+
+
maintainer = mkOptionType {
+
name = "maintainer";
+
check = email: lib.elem email (lib.attrValues lib.maintainers);
+
merge = loc: defs: {
+
# lib.last: Perhaps this could be merged instead, if "at most once per module"
+
# is a problem (see option description).
+
${(lib.last defs).file} = (lib.last defs).value;
+
};
+
};
+
+
listOfMaintainers = types.listOf maintainer // {
+
merge =
+
loc: defs:
+
lib.zipAttrs (
+
lib.flatten (
+
lib.imap1 (
+
n: def:
+
lib.imap1 (
+
m: def':
+
maintainer.merge (loc ++ [ "[${toString n}-${toString m}]" ]) [
+
{
+
inherit (def) file;
+
value = def';
+
}
+
]
+
) def.value
+
) defs
+
)
+
);
+
};
+
in
+
{
+
_class = null; # not specific to NixOS
+
options = {
+
meta = {
+
maintainers = mkOption {
+
type = listOfMaintainers;
+
default = [ ];
+
example = lib.literalExpression ''[ lib.maintainers.alice lib.maintainers.bob ]'';
+
description = ''
+
List of maintainers of each module.
+
This option should be defined at most once per module.
+
+
The option value is not a list of maintainers, but an attribute set that maps module file names to lists of maintainers.
+
'';
+
};
+
};
+
};
+
meta.maintainers = with lib.maintainers; [
+
pierron
+
roberth
+
];
+
}
+34
modules/generic/meta-maintainers/test.nix
···
+
# Run:
+
# $ nix-instantiate --eval 'modules/generic/meta-maintainers/test.nix'
+
#
+
# Expected output:
+
# { }
+
#
+
# Debugging:
+
# drop .test from the end of this file, then use nix repl on it
+
rec {
+
lib = import ../../../lib;
+
+
example = lib.evalModules {
+
modules = [
+
../meta-maintainers.nix
+
{
+
_file = "eelco.nix";
+
meta.maintainers = [ lib.maintainers.eelco ];
+
}
+
];
+
};
+
+
test =
+
assert
+
example.config.meta.maintainers == {
+
${toString ../meta-maintainers.nix} = [
+
lib.maintainers.pierron
+
lib.maintainers.roberth
+
];
+
"eelco.nix" = [ lib.maintainers.eelco ];
+
};
+
{ };
+
+
}
+
.test
+1
nixos/lib/eval-cacheable-options.nix
···
version = release;
revision = "release-${release}";
prefix = modulesPath;
+
extraSources = [ (dirOf nixosPath) ];
};
in
docs.optionsNix
+18 -2
nixos/modules/misc/documentation.nix
···
&& (t == "directory" -> baseNameOf n != "tests")
&& (t == "file" -> hasSuffix ".nix" n)
);
+
prefixRegex = "^" + lib.strings.escapeRegex (toString pkgs.path) + "($|/(modules|nixos)($|/.*))";
+
filteredModules = builtins.path {
+
name = "source";
+
inherit (pkgs) path;
+
filter =
+
n: t:
+
builtins.match prefixRegex n != null
+
&& cleanSourceFilter n t
+
&& (t == "directory" -> baseNameOf n != "tests")
+
&& (t == "file" -> hasSuffix ".nix" n);
+
};
in
pkgs.runCommand "lazy-options.json"
-
{
+
rec {
libPath = filter (pkgs.path + "/lib");
pkgsLibPath = filter (pkgs.path + "/pkgs/pkgs-lib");
-
nixosPath = filter (pkgs.path + "/nixos");
+
nixosPath = filteredModules + "/nixos";
NIX_ABORT_ON_WARN = warningsAreErrors;
modules =
"[ "
+ concatMapStringsSep " " (p: ''"${removePrefix "${modulesPath}/" (toString p)}"'') docModules.lazy
+ " ]";
passAsFile = [ "modules" ];
+
disallowedReferences = [
+
filteredModules
+
libPath
+
pkgsLibPath
+
];
}
''
export NIX_STORE_DIR=$TMPDIR/store
+6 -46
nixos/modules/misc/meta.nix
···
{ lib, ... }:
let
-
maintainer = lib.mkOptionType {
-
name = "maintainer";
-
check = email: lib.elem email (lib.attrValues lib.maintainers);
-
merge =
-
loc: defs:
-
lib.listToAttrs (lib.singleton (lib.nameValuePair (lib.last defs).file (lib.last defs).value));
-
};
-
-
listOfMaintainers = lib.types.listOf maintainer // {
-
# Returns list of
-
# { "module-file" = [
-
# "maintainer1 <first@nixos.org>"
-
# "maintainer2 <second@nixos.org>" ];
-
# }
-
merge =
-
loc: defs:
-
lib.zipAttrs (
-
lib.flatten (
-
lib.imap1 (
-
n: def:
-
lib.imap1 (
-
m: def':
-
maintainer.merge (loc ++ [ "[${toString n}-${toString m}]" ]) [
-
{
-
inherit (def) file;
-
value = def';
-
}
-
]
-
) def.value
-
) defs
-
)
-
);
-
};
-
docFile = lib.types.path // {
# Returns tuples of
# { file = "module location"; value = <path/to/doc.xml>; }
···
in
{
+
imports = [ ../../../modules/generic/meta-maintainers.nix ];
+
options = {
meta = {
-
maintainers = lib.mkOption {
-
type = listOfMaintainers;
-
internal = true;
-
default = [ ];
-
example = lib.literalExpression ''[ lib.maintainers.all ]'';
-
description = ''
-
List of maintainers of each module. This option should be defined at
-
most once per module.
-
'';
-
};
-
doc = lib.mkOption {
type = docFile;
internal = true;
···
};
};
-
meta.maintainers = lib.singleton lib.maintainers.pierron;
+
meta.maintainers = with lib.maintainers; [
+
pierron
+
roberth
+
];
}