about summary refs log tree commit diff
path: root/src/nix/command.cc
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2016-02-09T20·28+0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2016-02-09T20·28+0100
commitcd2196b08981a96cf607ad4a8f2f0dfa8cdf2add (patch)
treeb8f213b8790dc55812dae9fd1403bb352ccad0e2 /src/nix/command.cc
parent0db9e6cd1af299f7d65e0b99019f0ccdbb1aaf3f (diff)
Start of new Nix command-line interface
Diffstat (limited to 'src/nix/command.cc')
-rw-r--r--src/nix/command.cc65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/nix/command.cc b/src/nix/command.cc
new file mode 100644
index 000000000000..698863349334
--- /dev/null
+++ b/src/nix/command.cc
@@ -0,0 +1,65 @@
+#include "command.hh"
+#include "store-api.hh"
+
+namespace nix {
+
+Commands * RegisterCommand::commands = 0;
+
+MultiCommand::MultiCommand(const Commands & _commands)
+    : commands(_commands)
+{
+    expectedArgs.push_back(ExpectedArg{"command", 1, [=](Strings ss) {
+        assert(!command);
+        auto i = commands.find(ss.front());
+        if (i == commands.end())
+            throw UsageError(format("‘%1%’ is not a recognised command") % ss.front());
+        command = i->second;
+    }});
+}
+
+void MultiCommand::printHelp(const string & programName, std::ostream & out)
+{
+    if (command) {
+        command->printHelp(programName + " " + command->name(), out);
+        return;
+    }
+
+    out << "Usage: " << programName << " <COMMAND> <FLAGS>... <ARGS>...\n";
+
+    out << "\n";
+    out << "Common flags:\n";
+    printFlags(out);
+
+    out << "\n";
+    out << "Available commands:\n";
+
+    Table2 table;
+    for (auto & command : commands)
+        table.push_back(std::make_pair(command.second->name(), command.second->description()));
+    printTable(out, table);
+
+    out << "\n";
+    out << "For full documentation, run ‘man " << programName << "’ or ‘man " << programName << "-<COMMAND>’.\n";
+}
+
+bool MultiCommand::processFlag(Strings::iterator & pos, Strings::iterator end)
+{
+    if (Args::processFlag(pos, end)) return true;
+    if (command && command->processFlag(pos, end)) return true;
+    return false;
+}
+
+bool MultiCommand::processArgs(const Strings & args, bool finish)
+{
+    if (command)
+        return command->processArgs(args, finish);
+    else
+        return Args::processArgs(args, finish);
+}
+
+void StoreCommand::run()
+{
+    run(openStore(reserveSpace));
+}
+
+}