Add 'nix dump-args' to dump all commands/flags for manpage generation

This commit is contained in:
Eelco Dolstra 2020-08-17 17:44:52 +02:00
parent 7cdc739ece
commit a72a20d68f
No known key found for this signature in database
GPG Key ID: 8170B4726D7198DE
8 changed files with 108 additions and 18 deletions

View File

@ -3,6 +3,8 @@
#include <glob.h>
#include <nlohmann/json.hpp>
namespace nix {
void Args::addFlag(Flag && flag_)
@ -205,6 +207,42 @@ bool Args::processArgs(const Strings & args, bool finish)
return res;
}
nlohmann::json Args::toJSON()
{
auto flags = nlohmann::json::object();
for (auto & [name, flag] : longFlags) {
auto j = nlohmann::json::object();
if (flag->shortName)
j["shortName"] = std::string(1, flag->shortName);
if (flag->description != "")
j["description"] = flag->description;
if (flag->category != "")
j["category"] = flag->category;
if (flag->handler.arity != ArityAny)
j["arity"] = flag->handler.arity;
if (!flag->labels.empty())
j["labels"] = flag->labels;
flags[name] = std::move(j);
}
auto args = nlohmann::json::array();
for (auto & arg : expectedArgs) {
auto j = nlohmann::json::object();
j["label"] = arg.label;
j["optional"] = arg.optional;
if (arg.handler.arity != ArityAny)
j["arity"] = arg.handler.arity;
args.push_back(std::move(j));
}
auto res = nlohmann::json::object();
res["flags"] = std::move(flags);
res["args"] = std::move(args);
return res;
}
static void hashTypeCompleter(size_t index, std::string_view prefix)
{
for (auto & type : hashTypes)
@ -313,6 +351,22 @@ void Command::printHelp(const string & programName, std::ostream & out)
}
}
nlohmann::json Command::toJSON()
{
auto exs = nlohmann::json::array();
for (auto & example : examples()) {
auto ex = nlohmann::json::object();
ex["description"] = example.description;
ex["command"] = example.command;
exs.push_back(std::move(ex));
}
auto res = Args::toJSON();
res["examples"] = std::move(exs);
return res;
}
MultiCommand::MultiCommand(const Commands & commands)
: commands(commands)
{
@ -387,4 +441,20 @@ bool MultiCommand::processArgs(const Strings & args, bool finish)
return Args::processArgs(args, finish);
}
nlohmann::json MultiCommand::toJSON()
{
auto cmds = nlohmann::json::object();
for (auto & [name, commandFun] : commands) {
auto command = commandFun();
auto j = command->toJSON();
j["category"] = categories[command->category()];
cmds[name] = std::move(j);
}
auto res = Args::toJSON();
res["commands"] = std::move(cmds);
return res;
}
}

View File

@ -4,6 +4,8 @@
#include <map>
#include <memory>
#include <nlohmann/json_fwd.hpp>
#include "util.hh"
namespace nix {
@ -203,6 +205,8 @@ public:
});
}
virtual nlohmann::json toJSON();
friend class MultiCommand;
};
@ -234,6 +238,8 @@ struct Command : virtual Args
virtual Category category() { return catDefault; }
void printHelp(const string & programName, std::ostream & out) override;
nlohmann::json toJSON() override;
};
typedef std::map<std::string, std::function<ref<Command>()>> Commands;
@ -259,6 +265,8 @@ public:
bool processFlag(Strings::iterator & pos, Strings::iterator end) override;
bool processArgs(const Strings & args, bool finish) override;
nlohmann::json toJSON() override;
};
Strings argvToStrings(int argc, char * * argv);

View File

@ -4,12 +4,25 @@
#include "nixexpr.hh"
#include "profiles.hh"
#include <nlohmann/json.hpp>
extern char * * environ __attribute__((weak));
namespace nix {
Commands * RegisterCommand::commands = nullptr;
void NixMultiCommand::printHelp(const string & programName, std::ostream & out)
{
MultiCommand::printHelp(programName, out);
}
nlohmann::json NixMultiCommand::toJSON()
{
// FIXME: use Command::toJSON() as well.
return MultiCommand::toJSON();
}
StoreCommand::StoreCommand()
{
}

View File

@ -21,6 +21,13 @@ static constexpr Command::Category catSecondary = 100;
static constexpr Command::Category catUtility = 101;
static constexpr Command::Category catNixInstallation = 102;
struct NixMultiCommand : virtual MultiCommand, virtual Command
{
void printHelp(const string & programName, std::ostream & out) override;
nlohmann::json toJSON() override;
};
/* A command that requires a Nix store. */
struct StoreCommand : virtual Command
{

View File

@ -933,7 +933,7 @@ struct CmdFlakeShow : FlakeCommand
}
};
struct CmdFlake : virtual MultiCommand, virtual Command
struct CmdFlake : NixMultiCommand
{
CmdFlake()
: MultiCommand({
@ -963,11 +963,6 @@ struct CmdFlake : virtual MultiCommand, virtual Command
command->second->prepare();
command->second->run();
}
void printHelp(const string & programName, std::ostream & out) override
{
MultiCommand::printHelp(programName, out);
}
};
static auto r1 = registerCommand<CmdFlake>("flake");

View File

@ -17,6 +17,8 @@
#include <netdb.h>
#include <netinet/in.h>
#include <nlohmann/json.hpp>
extern std::string chrootHelperName;
void chrootHelper(int argc, char * * argv);
@ -172,6 +174,11 @@ void mainWrapped(int argc, char * * argv)
NixArgs args;
if (argc == 2 && std::string(argv[1]) == "dump-args") {
std::cout << args.toJSON().dump() << "\n";
return;
}
Finally printCompletions([&]()
{
if (completions) {

View File

@ -437,7 +437,7 @@ struct CmdProfileDiffClosures : virtual StoreCommand, MixDefaultProfile
}
};
struct CmdProfile : virtual MultiCommand, virtual Command
struct CmdProfile : NixMultiCommand
{
CmdProfile()
: MultiCommand({
@ -461,11 +461,6 @@ struct CmdProfile : virtual MultiCommand, virtual Command
command->second->prepare();
command->second->run();
}
void printHelp(const string & programName, std::ostream & out) override
{
MultiCommand::printHelp(programName, out);
}
};
static auto r1 = registerCommand<CmdProfile>("profile");

View File

@ -115,7 +115,7 @@ struct CmdRegistryPin : virtual Args, EvalCommand
}
};
struct CmdRegistry : virtual MultiCommand, virtual Command
struct CmdRegistry : virtual NixMultiCommand
{
CmdRegistry()
: MultiCommand({
@ -141,11 +141,6 @@ struct CmdRegistry : virtual MultiCommand, virtual Command
command->second->prepare();
command->second->run();
}
void printHelp(const string & programName, std::ostream & out) override
{
MultiCommand::printHelp(programName, out);
}
};
static auto r1 = registerCommand<CmdRegistry>("registry");