mirror of
https://github.com/NixOS/nix.git
synced 2024-11-24 15:52:30 +00:00
a2fed6db9e
* manual: Contributing -> Development, Hacking -> Building what's currently called "hacking" are really instructions for setting up a development environment and compiling from source. we have a contribution guide in the repo (which rightly focuses on GitHub workflows), and the material in the manual is more about working on the code itself. since we'd otherwise have three headings that amount to "Building Nix", this change also moves the "classic Nix" instructions to the top. we may want to reorganise this in the future, and bring contributor-oriented information closer to the code, but for now let's stick to more accurate names to ease navigation.
208 lines
6.1 KiB
Nix
208 lines
6.1 KiB
Nix
let
|
|
inherit (builtins)
|
|
attrNames
|
|
attrValues
|
|
concatMap
|
|
concatStringsSep
|
|
fromJSON
|
|
groupBy
|
|
length
|
|
lessThan
|
|
listToAttrs
|
|
mapAttrs
|
|
match
|
|
replaceStrings
|
|
sort
|
|
;
|
|
inherit (import <nix/utils.nix>)
|
|
attrsToList
|
|
concatStrings
|
|
filterAttrs
|
|
optionalString
|
|
squash
|
|
trim
|
|
unique
|
|
;
|
|
showStoreDocs = import <nix/generate-store-info.nix>;
|
|
in
|
|
|
|
inlineHTML: commandDump:
|
|
|
|
let
|
|
|
|
commandInfo = fromJSON commandDump;
|
|
|
|
showCommand = { command, details, filename, toplevel }:
|
|
let
|
|
|
|
result = ''
|
|
> **Warning** \
|
|
> This program is
|
|
> [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
|
|
> and its interface is subject to change.
|
|
|
|
# Name
|
|
|
|
`${command}` - ${details.description}
|
|
|
|
# Synopsis
|
|
|
|
${showSynopsis command details.args}
|
|
|
|
${maybeSubcommands}
|
|
|
|
${maybeProse}
|
|
|
|
${maybeOptions}
|
|
'';
|
|
|
|
showSynopsis = command: args:
|
|
let
|
|
showArgument = arg: "*${arg.label}*" + optionalString (! arg ? arity) "...";
|
|
arguments = concatStringsSep " " (map showArgument args);
|
|
in ''
|
|
`${command}` [*option*...] ${arguments}
|
|
'';
|
|
|
|
maybeSubcommands = optionalString (details ? commands && details.commands != {})
|
|
''
|
|
where *subcommand* is one of the following:
|
|
|
|
${subcommands}
|
|
'';
|
|
|
|
subcommands = if length categories > 1
|
|
then listCategories
|
|
else listSubcommands details.commands;
|
|
|
|
categories = sort (x: y: x.id < y.id) (unique (map (cmd: cmd.category) (attrValues details.commands)));
|
|
|
|
listCategories = concatStrings (map showCategory categories);
|
|
|
|
showCategory = cat: ''
|
|
**${toString cat.description}:**
|
|
|
|
${listSubcommands (filterAttrs (n: v: v.category == cat) details.commands)}
|
|
'';
|
|
|
|
listSubcommands = cmds: concatStrings (attrValues (mapAttrs showSubcommand cmds));
|
|
|
|
showSubcommand = name: subcmd: ''
|
|
* [`${command} ${name}`](./${appendName filename name}.md) - ${subcmd.description}
|
|
'';
|
|
|
|
maybeProse =
|
|
# FIXME: this is a horrible hack to keep `nix help-stores` working.
|
|
let
|
|
help-stores = ''
|
|
${index}
|
|
|
|
${allStores}
|
|
'';
|
|
index = replaceStrings
|
|
[ "@store-types@" "./local-store.md" "./local-daemon-store.md" ]
|
|
[ storesOverview "#local-store" "#local-daemon-store" ]
|
|
details.doc;
|
|
storesOverview =
|
|
let
|
|
showEntry = store:
|
|
"- [${store.name}](#${store.slug})";
|
|
in
|
|
concatStringsSep "\n" (map showEntry storesList) + "\n";
|
|
allStores = concatStringsSep "\n" (attrValues storePages);
|
|
storePages = listToAttrs
|
|
(map (s: { name = s.filename; value = s.page; }) storesList);
|
|
storesList = showStoreDocs {
|
|
storeInfo = commandInfo.stores;
|
|
inherit inlineHTML;
|
|
};
|
|
hasInfix = infix: content:
|
|
builtins.stringLength content != builtins.stringLength (replaceStrings [ infix ] [ "" ] content);
|
|
in
|
|
optionalString (details ? doc) (
|
|
# An alternate implementation with builtins.match stack overflowed on some systems.
|
|
if hasInfix "@store-types@" details.doc
|
|
then help-stores
|
|
else details.doc
|
|
);
|
|
|
|
maybeOptions =
|
|
let
|
|
allVisibleOptions = filterAttrs
|
|
(_: o: ! o.hiddenCategory)
|
|
(details.flags // toplevel.flags);
|
|
in
|
|
optionalString (allVisibleOptions != { }) ''
|
|
# Options
|
|
|
|
${showOptions inlineHTML allVisibleOptions}
|
|
|
|
> **Note**
|
|
>
|
|
> See [`man nix.conf`](@docroot@/command-ref/conf-file.md#command-line-flags) for overriding configuration settings with command line flags.
|
|
'';
|
|
|
|
showOptions = inlineHTML: allOptions:
|
|
let
|
|
showCategory = cat: opts: ''
|
|
${optionalString (cat != "") "## ${cat}"}
|
|
|
|
${concatStringsSep "\n" (attrValues (mapAttrs showOption opts))}
|
|
'';
|
|
showOption = name: option:
|
|
let
|
|
result = trim ''
|
|
- ${item}
|
|
|
|
${option.description}
|
|
'';
|
|
item = if inlineHTML
|
|
then ''<span id="opt-${name}">[`--${name}`](#opt-${name})</span> ${shortName} ${labels}''
|
|
else "`--${name}` ${shortName} ${labels}";
|
|
shortName = optionalString
|
|
(option ? shortName)
|
|
("/ `-${option.shortName}`");
|
|
labels = optionalString
|
|
(option ? labels)
|
|
(concatStringsSep " " (map (s: "*${s}*") option.labels));
|
|
in result;
|
|
categories = mapAttrs
|
|
# Convert each group from a list of key-value pairs back to an attrset
|
|
(_: listToAttrs)
|
|
(groupBy
|
|
(cmd: cmd.value.category)
|
|
(attrsToList allOptions));
|
|
in concatStrings (attrValues (mapAttrs showCategory categories));
|
|
in squash result;
|
|
|
|
appendName = filename: name: (if filename == "nix" then "nix3" else filename) + "-" + name;
|
|
|
|
processCommand = { command, details, filename, toplevel }:
|
|
let
|
|
cmd = {
|
|
inherit command;
|
|
name = filename + ".md";
|
|
value = showCommand { inherit command details filename toplevel; };
|
|
};
|
|
subcommand = subCmd: processCommand {
|
|
command = command + " " + subCmd;
|
|
details = details.commands.${subCmd};
|
|
filename = appendName filename subCmd;
|
|
inherit toplevel;
|
|
};
|
|
in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {});
|
|
|
|
manpages = processCommand {
|
|
command = "nix";
|
|
details = commandInfo.args;
|
|
filename = "nix";
|
|
toplevel = commandInfo.args;
|
|
};
|
|
|
|
tableOfContents = let
|
|
showEntry = page:
|
|
" - [${page.command}](command-ref/new-cli/${page.name})";
|
|
in concatStringsSep "\n" (map showEntry manpages) + "\n";
|
|
|
|
in (listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; }
|