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 <glob.h>
#include <nlohmann/json.hpp>
namespace nix { namespace nix {
void Args::addFlag(Flag && flag_) void Args::addFlag(Flag && flag_)
@ -205,6 +207,42 @@ bool Args::processArgs(const Strings & args, bool finish)
return res; 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) static void hashTypeCompleter(size_t index, std::string_view prefix)
{ {
for (auto & type : hashTypes) 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) MultiCommand::MultiCommand(const Commands & commands)
: commands(commands) : commands(commands)
{ {
@ -387,4 +441,20 @@ bool MultiCommand::processArgs(const Strings & args, bool finish)
return Args::processArgs(args, 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 <map>
#include <memory> #include <memory>
#include <nlohmann/json_fwd.hpp>
#include "util.hh" #include "util.hh"
namespace nix { namespace nix {
@ -203,6 +205,8 @@ public:
}); });
} }
virtual nlohmann::json toJSON();
friend class MultiCommand; friend class MultiCommand;
}; };
@ -234,6 +238,8 @@ struct Command : virtual Args
virtual Category category() { return catDefault; } virtual Category category() { return catDefault; }
void printHelp(const string & programName, std::ostream & out) override; void printHelp(const string & programName, std::ostream & out) override;
nlohmann::json toJSON() override;
}; };
typedef std::map<std::string, std::function<ref<Command>()>> Commands; 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 processFlag(Strings::iterator & pos, Strings::iterator end) override;
bool processArgs(const Strings & args, bool finish) override; bool processArgs(const Strings & args, bool finish) override;
nlohmann::json toJSON() override;
}; };
Strings argvToStrings(int argc, char * * argv); Strings argvToStrings(int argc, char * * argv);

View file

@ -4,12 +4,25 @@
#include "nixexpr.hh" #include "nixexpr.hh"
#include "profiles.hh" #include "profiles.hh"
#include <nlohmann/json.hpp>
extern char * * environ __attribute__((weak)); extern char * * environ __attribute__((weak));
namespace nix { namespace nix {
Commands * RegisterCommand::commands = nullptr; 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() StoreCommand::StoreCommand()
{ {
} }

View file

@ -21,6 +21,13 @@ static constexpr Command::Category catSecondary = 100;
static constexpr Command::Category catUtility = 101; static constexpr Command::Category catUtility = 101;
static constexpr Command::Category catNixInstallation = 102; 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. */ /* A command that requires a Nix store. */
struct StoreCommand : virtual Command struct StoreCommand : virtual Command
{ {

View file

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

View file

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

View file

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