2016-02-09 21:28:29 +01:00
|
|
|
|
#include "command.hh"
|
|
|
|
|
#include "store-api.hh"
|
|
|
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
|
|
|
|
Commands * RegisterCommand::commands = 0;
|
|
|
|
|
|
2016-04-21 14:58:32 +02:00
|
|
|
|
void Command::printHelp(const string & programName, std::ostream & out)
|
|
|
|
|
{
|
|
|
|
|
Args::printHelp(programName, out);
|
|
|
|
|
|
|
|
|
|
auto exs = examples();
|
|
|
|
|
if (!exs.empty()) {
|
|
|
|
|
out << "\n";
|
|
|
|
|
out << "Examples:\n";
|
|
|
|
|
for (auto & ex : exs)
|
|
|
|
|
out << "\n"
|
|
|
|
|
<< " " << ex.description << "\n" // FIXME: wrap
|
|
|
|
|
<< " $ " << ex.command << "\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-09 21:28:29 +01:00
|
|
|
|
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())
|
2016-11-26 00:37:43 +01:00
|
|
|
|
throw UsageError(format("‘%1%’ is not a recognised command") % ss.front());
|
2016-02-09 21:28:29 +01:00
|
|
|
|
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";
|
2016-11-26 00:37:43 +01:00
|
|
|
|
out << "For full documentation, run ‘man " << programName << "’ or ‘man " << programName << "-<COMMAND>’.\n";
|
2016-02-09 21:28:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-21 18:03:36 +01:00
|
|
|
|
StoreCommand::StoreCommand()
|
|
|
|
|
{
|
|
|
|
|
storeUri = getEnv("NIX_REMOTE");
|
|
|
|
|
|
|
|
|
|
mkFlag(0, "store", "store-uri", "URI of the Nix store to use", &storeUri);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-16 14:25:54 +01:00
|
|
|
|
ref<Store> StoreCommand::createStore()
|
|
|
|
|
{
|
|
|
|
|
return openStore(storeUri);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-09 21:28:29 +01:00
|
|
|
|
void StoreCommand::run()
|
|
|
|
|
{
|
2017-03-16 14:25:54 +01:00
|
|
|
|
run(createStore());
|
2016-02-09 21:28:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-29 14:29:50 +02:00
|
|
|
|
StorePathsCommand::StorePathsCommand()
|
|
|
|
|
{
|
|
|
|
|
expectArgs("paths", &storePaths);
|
|
|
|
|
mkFlag('r', "recursive", "apply operation to closure of the specified paths", &recursive);
|
2016-04-14 21:14:29 +02:00
|
|
|
|
mkFlag(0, "all", "apply operation to the entire store", &all);
|
2016-03-29 14:29:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StorePathsCommand::run(ref<Store> store)
|
|
|
|
|
{
|
2016-04-14 21:14:29 +02:00
|
|
|
|
if (all) {
|
|
|
|
|
if (storePaths.size())
|
2016-11-26 00:37:43 +01:00
|
|
|
|
throw UsageError("‘--all’ does not expect arguments");
|
2016-04-14 21:14:29 +02:00
|
|
|
|
for (auto & p : store->queryAllValidPaths())
|
|
|
|
|
storePaths.push_back(p);
|
|
|
|
|
}
|
2016-03-29 14:29:50 +02:00
|
|
|
|
|
2016-04-14 21:14:29 +02:00
|
|
|
|
else {
|
2016-03-29 14:29:50 +02:00
|
|
|
|
for (auto & storePath : storePaths)
|
2016-06-01 14:49:12 +02:00
|
|
|
|
storePath = store->followLinksToStorePath(storePath);
|
2016-04-14 21:14:29 +02:00
|
|
|
|
|
|
|
|
|
if (recursive) {
|
|
|
|
|
PathSet closure;
|
2016-11-10 17:45:04 +01:00
|
|
|
|
store->computeFSClosure(PathSet(storePaths.begin(), storePaths.end()),
|
|
|
|
|
closure, false, false);
|
2016-05-04 13:36:54 +02:00
|
|
|
|
storePaths = Paths(closure.begin(), closure.end());
|
2016-04-14 21:14:29 +02:00
|
|
|
|
}
|
2016-03-29 14:29:50 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run(store, storePaths);
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-09 21:28:29 +01:00
|
|
|
|
}
|