nix store --help: Include store type documentation

This commit is contained in:
Eelco Dolstra 2023-03-21 12:58:14 +01:00
parent cdfa59daa1
commit 8d6d59cb1b
9 changed files with 102 additions and 60 deletions

View file

@ -1,4 +1,4 @@
{ toplevel }: cliDumpStr:
with builtins; with builtins;
with import ./utils.nix; with import ./utils.nix;
@ -63,7 +63,10 @@ let
* [`${command} ${name}`](./${appendName filename name}.md) - ${subcmd.description} * [`${command} ${name}`](./${appendName filename name}.md) - ${subcmd.description}
''; '';
maybeDocumentation = if details ? doc then details.doc else ""; maybeDocumentation =
if details ? doc
then replaceStrings ["@stores@"] [storeDocs] details.doc
else "";
maybeOptions = if details.flags == {} then "" else '' maybeOptions = if details.flags == {} then "" else ''
# Options # Options
@ -110,13 +113,13 @@ let
}; };
in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {}); in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {});
parsedToplevel = builtins.fromJSON toplevel; cliDump = builtins.fromJSON cliDumpStr;
manpages = processCommand { manpages = processCommand {
command = "nix"; command = "nix";
details = parsedToplevel; details = cliDump.args;
filename = "nix"; filename = "nix";
toplevel = parsedToplevel; toplevel = cliDump.args;
}; };
tableOfContents = let tableOfContents = let
@ -124,4 +127,14 @@ let
" - [${page.command}](command-ref/new-cli/${page.name})"; " - [${page.command}](command-ref/new-cli/${page.name})";
in concatStringsSep "\n" (map showEntry manpages) + "\n"; in concatStringsSep "\n" (map showEntry manpages) + "\n";
storeDocs =
let
showStore = name: { settings }:
''
## ${name}
${showSettings false settings}
'';
in concatStrings (attrValues (mapAttrs showStore cliDump.stores));
in (listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; } in (listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; }

View file

@ -1,41 +0,0 @@
let
inherit (builtins) attrNames concatStringsSep isAttrs isBool;
inherit (import ./utils.nix) concatStrings squash splitLines;
in
optionsInfo:
let
showOption = name:
let
inherit (optionsInfo.${name}) description documentDefault defaultValue aliases;
result = squash ''
- <span id="conf-${name}">[`${name}`](#conf-${name})</span>
${indent " " body}
'';
# separate body to cleanly handle indentation
body = ''
${description}
**Default:** ${showDefault documentDefault defaultValue}
${showAliases aliases}
'';
showDefault = documentDefault: defaultValue:
if documentDefault then
# a StringMap value type is specified as a string, but
# this shows the value type. The empty stringmap is `null` in
# JSON, but that converts to `{ }` here.
if defaultValue == "" || defaultValue == [] || isAttrs defaultValue
then "*empty*"
else if isBool defaultValue then
if defaultValue then "`true`" else "`false`"
else "`${toString defaultValue}`"
else "*machine-specific*";
showAliases = aliases:
if aliases == [] then "" else
"**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}";
indent = prefix: s:
concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s));
in result;
in concatStrings (map showOption (attrNames optionsInfo))

View file

@ -60,17 +60,17 @@ $(d)/src/SUMMARY.md: $(d)/src/SUMMARY.md.in $(d)/src/command-ref/new-cli
@$(call process-includes,$@,$@) @$(call process-includes,$@,$@)
$(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/generate-manpage.nix $(bindir)/nix $(d)/src/command-ref/new-cli: $(d)/nix.json $(d)/generate-manpage.nix $(bindir)/nix
@rm -rf $@ @rm -rf $@ $@.tmp
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-manpage.nix { toplevel = builtins.readFile $<; }' $(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-manpage.nix (builtins.readFile $<)'
@mv $@.tmp $@ @mv $@.tmp $@
$(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/generate-options.nix $(d)/src/command-ref/conf-file-prefix.md $(bindir)/nix $(d)/src/command-ref/conf-file.md: $(d)/conf-file.json $(d)/utils.nix $(d)/src/command-ref/conf-file-prefix.md $(bindir)/nix
@cat doc/manual/src/command-ref/conf-file-prefix.md > $@.tmp @cat doc/manual/src/command-ref/conf-file-prefix.md > $@.tmp
$(trace-gen) $(nix-eval) --expr 'import doc/manual/generate-options.nix (builtins.fromJSON (builtins.readFile $<))' >> $@.tmp; $(trace-gen) $(nix-eval) --expr '(import doc/manual/utils.nix).showSettings true (builtins.fromJSON (builtins.readFile $<))' >> $@.tmp;
@mv $@.tmp $@ @mv $@.tmp $@
$(d)/nix.json: $(bindir)/nix $(d)/nix.json: $(bindir)/nix
$(trace-gen) $(dummy-env) $(bindir)/nix __dump-args > $@.tmp $(trace-gen) $(dummy-env) $(bindir)/nix __dump-cli > $@.tmp
@mv $@.tmp $@ @mv $@.tmp $@
$(d)/conf-file.json: $(bindir)/nix $(d)/conf-file.json: $(bindir)/nix

View file

@ -38,4 +38,41 @@ rec {
filterAttrs = pred: set: filterAttrs = pred: set:
listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set)); listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set));
showSetting = useSpans: name: { description, documentDefault, defaultValue, aliases, ... }:
let
result = squash ''
- ${if useSpans
then ''<span id="conf-${name}">[`${name}`](#conf-${name})</span>''
else ''[`${name}`](#conf-${name})''}
${indent " " body}
'';
# separate body to cleanly handle indentation
body = ''
${description}
**Default:** ${showDefault documentDefault defaultValue}
${showAliases aliases}
'';
showDefault = documentDefault: defaultValue:
if documentDefault then
# a StringMap value type is specified as a string, but
# this shows the value type. The empty stringmap is `null` in
# JSON, but that converts to `{ }` here.
if defaultValue == "" || defaultValue == [] || isAttrs defaultValue
then "*empty*"
else if isBool defaultValue then
if defaultValue then "`true`" else "`false`"
else "`${toString defaultValue}`"
else "*machine-specific*";
showAliases = aliases:
if aliases == [] then "" else
"**Deprecated alias:** ${(concatStringsSep ", " (map (s: "`${s}`") aliases))}";
indent = prefix: s:
concatStringsSep "\n" (map (x: if x == "" then x else "${prefix}${x}") (splitLines s));
in result;
showSettings = useSpans: settingsInfo: concatStrings (attrValues (mapAttrs (showSetting useSpans) settingsInfo));
} }

View file

@ -12,7 +12,7 @@ struct HttpBinaryCacheStoreConfig : virtual BinaryCacheStoreConfig
{ {
using BinaryCacheStoreConfig::BinaryCacheStoreConfig; using BinaryCacheStoreConfig::BinaryCacheStoreConfig;
const std::string name() override { return "Http Binary Cache Store"; } const std::string name() override { return "HTTP Binary Cache Store"; }
}; };
class HttpBinaryCacheStore : public virtual HttpBinaryCacheStoreConfig, public virtual BinaryCacheStore class HttpBinaryCacheStore : public virtual HttpBinaryCacheStoreConfig, public virtual BinaryCacheStore

View file

@ -22,7 +22,7 @@ struct CmdDescribeStores : Command, MixJSON
for (auto & implem : *Implementations::registered) { for (auto & implem : *Implementations::registered) {
auto storeConfig = implem.getConfig(); auto storeConfig = implem.getConfig();
auto storeName = storeConfig->name(); auto storeName = storeConfig->name();
res[storeName] = storeConfig->toJSON(); res[storeName]["settings"] = storeConfig->toJSON();
} }
if (json) { if (json) {
logger->cout("%s", res); logger->cout("%s", res);

View file

@ -164,11 +164,28 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
{ {
commands = RegisterCommand::getCommandsFor({}); commands = RegisterCommand::getCommandsFor({});
} }
std::string dumpCli()
{
auto res = nlohmann::json::object();
res["args"] = toJSON();
auto stores = nlohmann::json::object();
for (auto & implem : *Implementations::registered) {
auto storeConfig = implem.getConfig();
auto storeName = storeConfig->name();
stores[storeName]["settings"] = storeConfig->toJSON();
}
res["stores"] = std::move(stores);
return res.dump();
}
}; };
/* Render the help for the specified subcommand to stdout using /* Render the help for the specified subcommand to stdout using
lowdown. */ lowdown. */
static void showHelp(std::vector<std::string> subcommand, MultiCommand & toplevel) static void showHelp(std::vector<std::string> subcommand, NixArgs & toplevel)
{ {
auto mdName = subcommand.empty() ? "nix" : fmt("nix3-%s", concatStringsSep("-", subcommand)); auto mdName = subcommand.empty() ? "nix" : fmt("nix3-%s", concatStringsSep("-", subcommand));
@ -189,11 +206,11 @@ static void showHelp(std::vector<std::string> subcommand, MultiCommand & topleve
, "/"), , "/"),
*vUtils); *vUtils);
auto attrs = state.buildBindings(16); auto vDump = state.allocValue();
attrs.alloc("toplevel").mkString(toplevel.toJSON().dump()); vDump->mkString(toplevel.dumpCli());
auto vRes = state.allocValue(); auto vRes = state.allocValue();
state.callFunction(*vGenerateManpage, state.allocValue()->mkAttrs(attrs), *vRes, noPos); state.callFunction(*vGenerateManpage, *vDump, *vRes, noPos);
auto attr = vRes->attrs->get(state.symbols.create(mdName + ".md")); auto attr = vRes->attrs->get(state.symbols.create(mdName + ".md"));
if (!attr) if (!attr)
@ -234,7 +251,7 @@ struct CmdHelp : Command
assert(parent); assert(parent);
MultiCommand * toplevel = parent; MultiCommand * toplevel = parent;
while (toplevel->parent) toplevel = toplevel->parent; while (toplevel->parent) toplevel = toplevel->parent;
showHelp(subcommand, *toplevel); showHelp(subcommand, dynamic_cast<NixArgs &>(*toplevel));
} }
}; };
@ -291,8 +308,8 @@ void mainWrapped(int argc, char * * argv)
NixArgs args; NixArgs args;
if (argc == 2 && std::string(argv[1]) == "__dump-args") { if (argc == 2 && std::string(argv[1]) == "__dump-cli") {
logger->cout("%s", args.toJSON()); logger->cout(args.dumpCli());
return; return;
} }

View file

@ -12,6 +12,13 @@ struct CmdStore : virtual NixMultiCommand
return "manipulate a Nix store"; return "manipulate a Nix store";
} }
std::string doc() override
{
return
#include "store.md"
;
}
Category category() override { return catUtility; } Category category() override { return catUtility; }
void run() override void run() override

9
src/nix/store.md Normal file
View file

@ -0,0 +1,9 @@
R"(
# Store types
Nix supports different types of stores. These are listed below.
@stores@
)"