aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-08-17 17:44:52 +0200
committerEelco Dolstra <edolstra@gmail.com>2020-08-17 17:44:52 +0200
commita72a20d68fe6ae75f05f69e7de0bc3326d779144 (patch)
treea945dff2d1fbf9a64fa132814a59c4db8020d89e /src
parent7cdc739ece681128dd4153e53acb85867accdd1b (diff)
Add 'nix dump-args' to dump all commands/flags for manpage generation
Diffstat (limited to 'src')
-rw-r--r--src/libutil/args.cc70
-rw-r--r--src/libutil/args.hh8
-rw-r--r--src/nix/command.cc13
-rw-r--r--src/nix/command.hh7
-rw-r--r--src/nix/flake.cc7
-rw-r--r--src/nix/main.cc7
-rw-r--r--src/nix/profile.cc7
-rw-r--r--src/nix/registry.cc7
8 files changed, 108 insertions, 18 deletions
diff --git a/src/libutil/args.cc b/src/libutil/args.cc
index 986c5d1cd..bf5e7ce95 100644
--- a/src/libutil/args.cc
+++ b/src/libutil/args.cc
@@ -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;
+}
+
}
diff --git a/src/libutil/args.hh b/src/libutil/args.hh
index 97a517344..c56044f1d 100644
--- a/src/libutil/args.hh
+++ b/src/libutil/args.hh
@@ -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);
diff --git a/src/nix/command.cc b/src/nix/command.cc
index da32819da..2f1fbded1 100644
--- a/src/nix/command.cc
+++ b/src/nix/command.cc
@@ -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()
{
}
diff --git a/src/nix/command.hh b/src/nix/command.hh
index bc46a2028..d60c8aeb6 100644
--- a/src/nix/command.hh
+++ b/src/nix/command.hh
@@ -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
{
diff --git a/src/nix/flake.cc b/src/nix/flake.cc
index 653f8db1b..ae6f4c5f9 100644
--- a/src/nix/flake.cc
+++ b/src/nix/flake.cc
@@ -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");
diff --git a/src/nix/main.cc b/src/nix/main.cc
index e62657e95..fa04bebea 100644
--- a/src/nix/main.cc
+++ b/src/nix/main.cc
@@ -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) {
diff --git a/src/nix/profile.cc b/src/nix/profile.cc
index cffc9ee44..9241931e9 100644
--- a/src/nix/profile.cc
+++ b/src/nix/profile.cc
@@ -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");
diff --git a/src/nix/registry.cc b/src/nix/registry.cc
index ebee4545c..367268683 100644
--- a/src/nix/registry.cc
+++ b/src/nix/registry.cc
@@ -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");