aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2021-01-25 14:38:15 +0100
committerEelco Dolstra <edolstra@gmail.com>2021-01-25 14:38:15 +0100
commitb159d23800eec55412621a0b3e6c926a1dbb1755 (patch)
tree2d9e4b911548c7f1668bdd507a8757cd70658445 /src
parent488a826842296c9c2933fb53cc884ed8518f9110 (diff)
Make '--help' do the same as 'help' (i.e. show a manpage)
Diffstat (limited to 'src')
-rw-r--r--src/libutil/args.cc89
-rw-r--r--src/libutil/args.hh14
-rw-r--r--src/nix/command.cc5
-rw-r--r--src/nix/command.hh2
-rw-r--r--src/nix/main.cc61
-rw-r--r--src/nix/nar.cc5
-rw-r--r--src/nix/store.cc5
7 files changed, 17 insertions, 164 deletions
diff --git a/src/libutil/args.cc b/src/libutil/args.cc
index fb5cb80fb..2f2e4bb96 100644
--- a/src/libutil/args.cc
+++ b/src/libutil/args.cc
@@ -96,41 +96,6 @@ void Args::parseCmdline(const Strings & _cmdline)
processArgs(pendingArgs, true);
}
-void Args::printHelp(const string & programName, std::ostream & out)
-{
- std::cout << fmt(ANSI_BOLD "Usage:" ANSI_NORMAL " %s " ANSI_ITALIC "FLAGS..." ANSI_NORMAL, programName);
- for (auto & exp : expectedArgs) {
- std::cout << renderLabels({exp.label});
- // FIXME: handle arity > 1
- if (exp.handler.arity == ArityAny) std::cout << "...";
- if (exp.optional) std::cout << "?";
- }
- std::cout << "\n";
-
- auto s = description();
- if (s != "")
- std::cout << "\n" ANSI_BOLD "Summary:" ANSI_NORMAL " " << s << ".\n";
-
- if (longFlags.size()) {
- std::cout << "\n";
- std::cout << ANSI_BOLD "Flags:" ANSI_NORMAL "\n";
- printFlags(out);
- }
-}
-
-void Args::printFlags(std::ostream & out)
-{
- Table2 table;
- for (auto & flag : longFlags) {
- if (hiddenCategories.count(flag.second->category)) continue;
- table.push_back(std::make_pair(
- (flag.second->shortName ? std::string("-") + flag.second->shortName + ", " : " ")
- + "--" + flag.first + renderLabels(flag.second->labels),
- flag.second->description));
- }
- printTable(out, table);
-}
-
bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
{
assert(pos != end);
@@ -331,28 +296,6 @@ Strings argvToStrings(int argc, char * * argv)
return args;
}
-std::string renderLabels(const Strings & labels)
-{
- std::string res;
- for (auto label : labels) {
- for (auto & c : label) c = std::toupper(c);
- res += " " ANSI_ITALIC + label + ANSI_NORMAL;
- }
- return res;
-}
-
-void printTable(std::ostream & out, const Table2 & table)
-{
- size_t max = 0;
- for (auto & row : table)
- max = std::max(max, filterANSIEscapes(row.first, true).size());
- for (auto & row : table) {
- out << " " << row.first
- << std::string(max - filterANSIEscapes(row.first, true).size() + 2, ' ')
- << row.second << "\n";
- }
-}
-
MultiCommand::MultiCommand(const Commands & commands)
: commands(commands)
{
@@ -376,38 +319,6 @@ MultiCommand::MultiCommand(const Commands & commands)
categories[Command::catDefault] = "Available commands";
}
-void MultiCommand::printHelp(const string & programName, std::ostream & out)
-{
- if (command) {
- command->second->printHelp(programName + " " + command->first, out);
- return;
- }
-
- out << fmt(ANSI_BOLD "Usage:" ANSI_NORMAL " %s " ANSI_ITALIC "COMMAND FLAGS... ARGS..." ANSI_NORMAL "\n", programName);
-
- out << "\n" ANSI_BOLD "Common flags:" ANSI_NORMAL "\n";
- printFlags(out);
-
- std::map<Command::Category, std::map<std::string, ref<Command>>> commandsByCategory;
-
- for (auto & [name, commandFun] : commands) {
- auto command = commandFun();
- commandsByCategory[command->category()].insert_or_assign(name, command);
- }
-
- for (auto & [category, commands] : commandsByCategory) {
- out << fmt("\n" ANSI_BOLD "%s:" ANSI_NORMAL "\n", categories[category]);
-
- Table2 table;
- for (auto & [name, command] : commands) {
- auto descr = command->description();
- if (!descr.empty())
- table.push_back(std::make_pair(name, descr));
- }
- printTable(out, table);
- }
-}
-
bool MultiCommand::processFlag(Strings::iterator & pos, Strings::iterator end)
{
if (Args::processFlag(pos, end)) return true;
diff --git a/src/libutil/args.hh b/src/libutil/args.hh
index 3783bc84f..fda7852cd 100644
--- a/src/libutil/args.hh
+++ b/src/libutil/args.hh
@@ -20,8 +20,6 @@ public:
wrong. */
void parseCmdline(const Strings & cmdline);
- virtual void printHelp(const string & programName, std::ostream & out);
-
/* Return a short one-line description of the command. */
virtual std::string description() { return ""; }
@@ -115,8 +113,6 @@ protected:
virtual bool processFlag(Strings::iterator & pos, Strings::iterator end);
- virtual void printFlags(std::ostream & out);
-
/* Positional arguments. */
struct ExpectedArg
{
@@ -223,8 +219,6 @@ public:
MultiCommand(const Commands & commands);
- void printHelp(const string & programName, std::ostream & out) override;
-
bool processFlag(Strings::iterator & pos, Strings::iterator end) override;
bool processArgs(const Strings & args, bool finish) override;
@@ -234,14 +228,6 @@ public:
Strings argvToStrings(int argc, char * * argv);
-/* Helper function for rendering argument labels. */
-std::string renderLabels(const Strings & labels);
-
-/* Helper function for printing 2-column tables. */
-typedef std::vector<std::pair<std::string, std::string>> Table2;
-
-void printTable(std::ostream & out, const Table2 & table);
-
struct Completion {
std::string completion;
std::string description;
diff --git a/src/nix/command.cc b/src/nix/command.cc
index ba58c7d6b..20eeefe91 100644
--- a/src/nix/command.cc
+++ b/src/nix/command.cc
@@ -27,11 +27,6 @@ nix::Commands RegisterCommand::getCommandsFor(const std::vector<std::string> & p
return res;
}
-void NixMultiCommand::printHelp(const string & programName, std::ostream & out)
-{
- MultiCommand::printHelp(programName, out);
-}
-
nlohmann::json NixMultiCommand::toJSON()
{
// FIXME: use Command::toJSON() as well.
diff --git a/src/nix/command.hh b/src/nix/command.hh
index f325cd906..791dd0f1e 100644
--- a/src/nix/command.hh
+++ b/src/nix/command.hh
@@ -25,8 +25,6 @@ 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;
};
diff --git a/src/nix/main.cc b/src/nix/main.cc
index 80422bd24..77a13c913 100644
--- a/src/nix/main.cc
+++ b/src/nix/main.cc
@@ -54,6 +54,8 @@ static bool haveInternet()
std::string programPath;
char * * savedArgv;
+struct HelpRequested { };
+
struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
{
bool printBuildLogs = false;
@@ -71,22 +73,7 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
addFlag({
.longName = "help",
.description = "Show usage information.",
- .handler = {[&]() { if (!completions) showHelpAndExit(); }},
- });
-
- addFlag({
- .longName = "help-config",
- .description = "Show configuration settings.",
- .handler = {[&]() {
- std::cout << "The following configuration settings are available:\n\n";
- Table2 tbl;
- std::map<std::string, Config::SettingInfo> settings;
- globalConfig.getSettings(settings);
- for (const auto & s : settings)
- tbl.emplace_back(s.first, s.second.description);
- printTable(std::cout, tbl);
- throw Exit();
- }},
+ .handler = {[&]() { throw HelpRequested(); }},
});
addFlag({
@@ -154,33 +141,6 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
return pos;
}
- void printFlags(std::ostream & out) override
- {
- Args::printFlags(out);
- std::cout <<
- "\n"
- "In addition, most configuration settings can be overriden using '--" ANSI_ITALIC "name value" ANSI_NORMAL "'.\n"
- "Boolean settings can be overriden using '--" ANSI_ITALIC "name" ANSI_NORMAL "' or '--no-" ANSI_ITALIC "name" ANSI_NORMAL "'. See 'nix\n"
- "--help-config' for a list of configuration settings.\n";
- }
-
- void printHelp(const string & programName, std::ostream & out) override
- {
- MultiCommand::printHelp(programName, out);
-
-#if 0
- out << "\nFor full documentation, run 'man " << programName << "' or 'man " << programName << "-" ANSI_ITALIC "COMMAND" ANSI_NORMAL "'.\n";
-#endif
-
- std::cout << "\nNote: this program is " ANSI_RED "EXPERIMENTAL" ANSI_NORMAL " and subject to change.\n";
- }
-
- void showHelpAndExit()
- {
- printHelp(programName, std::cout);
- throw Exit();
- }
-
std::string description() override
{
return "a tool for reproducible and declarative configuration management";
@@ -298,6 +258,18 @@ void mainWrapped(int argc, char * * argv)
try {
args.parseCmdline(argvToStrings(argc, argv));
+ } catch (HelpRequested &) {
+ std::vector<std::string> subcommand;
+ MultiCommand * command = &args;
+ while (command) {
+ if (command && command->command) {
+ subcommand.push_back(command->command->first);
+ command = dynamic_cast<MultiCommand *>(&*command->command->second);
+ } else
+ break;
+ }
+ showHelp(subcommand);
+ return;
} catch (UsageError &) {
if (!completions) throw;
}
@@ -306,7 +278,8 @@ void mainWrapped(int argc, char * * argv)
initPlugins();
- if (!args.command) args.showHelpAndExit();
+ if (!args.command)
+ throw UsageError("no subcommand specified");
if (args.command->first != "repl"
&& args.command->first != "doctor"
diff --git a/src/nix/nar.cc b/src/nix/nar.cc
index 0775d3c25..dbb043d9b 100644
--- a/src/nix/nar.cc
+++ b/src/nix/nar.cc
@@ -28,11 +28,6 @@ struct CmdNar : NixMultiCommand
command->second->prepare();
command->second->run();
}
-
- void printHelp(const string & programName, std::ostream & out) override
- {
- MultiCommand::printHelp(programName, out);
- }
};
static auto rCmdNar = registerCommand<CmdNar>("nar");
diff --git a/src/nix/store.cc b/src/nix/store.cc
index e91bcc503..44e53c7c7 100644
--- a/src/nix/store.cc
+++ b/src/nix/store.cc
@@ -21,11 +21,6 @@ struct CmdStore : virtual NixMultiCommand
command->second->prepare();
command->second->run();
}
-
- void printHelp(const string & programName, std::ostream & out) override
- {
- MultiCommand::printHelp(programName, out);
- }
};
static auto rCmdStore = registerCommand<CmdStore>("store");