lix/src/nix/command.hh
Eelco Dolstra 6438ba22af
StorePathsCommand: Don't build installables
On second though this was annoying. E.g. "nix log nixpkgs.hello" would
build/download Hello first, even though the log can be fetched
directly from the binary cache.

May need to revisit this.
2017-07-14 18:29:07 +02:00

166 lines
3.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "args.hh"
namespace nix {
struct Value;
class EvalState;
/* A command is an argument parser that can be executed by calling its
run() method. */
struct Command : virtual Args
{
virtual std::string name() = 0;
virtual void prepare() { };
virtual void run() = 0;
struct Example
{
std::string description;
std::string command;
};
typedef std::list<Example> Examples;
virtual Examples examples() { return Examples(); }
void printHelp(const string & programName, std::ostream & out) override;
};
class Store;
/* A command that require a Nix store. */
struct StoreCommand : virtual Command
{
std::string storeUri;
StoreCommand();
void run() override;
ref<Store> getStore();
virtual ref<Store> createStore();
virtual void run(ref<Store>) = 0;
private:
std::shared_ptr<Store> _store;
};
struct Installable
{
virtual std::string what() = 0;
virtual PathSet toBuildable()
{
throw Error("argument %s cannot be built", what());
}
virtual Value * toValue(EvalState & state)
{
throw Error("argument %s cannot be evaluated", what());
}
};
/* A command that operates on a list of "installables", which can be
store paths, attribute paths, Nix expressions, etc. */
struct InstallablesCommand : virtual Args, StoreCommand
{
std::vector<std::shared_ptr<Installable>> installables;
Path file;
InstallablesCommand()
{
mkFlag('f', "file", "file", "evaluate FILE rather than the default", &file);
expectArgs("installables", &_installables);
}
/* Return a value representing the Nix expression from which we
are installing. This is either the file specified by --file,
or an attribute set constructed from $NIX_PATH, e.g. { nixpkgs
= import ...; bla = import ...; }. */
Value * getSourceExpr(EvalState & state);
std::vector<std::shared_ptr<Installable>> parseInstallables(ref<Store> store, Strings ss);
enum ToStorePathsMode { Build, NoBuild, DryRun };
PathSet toStorePaths(ref<Store> store, ToStorePathsMode mode);
ref<EvalState> getEvalState();
void prepare() override;
virtual bool useDefaultInstallables() { return true; }
private:
Strings _installables;
std::shared_ptr<EvalState> evalState;
Value * vSourceExpr = 0;
};
/* A command that operates on zero or more store paths. */
struct StorePathsCommand : public InstallablesCommand
{
private:
bool recursive = false;
bool all = false;
public:
StorePathsCommand();
using StoreCommand::run;
virtual void run(ref<Store> store, Paths storePaths) = 0;
void run(ref<Store> store) override;
bool useDefaultInstallables() override { return !all; }
};
/* A command that operates on exactly one store path. */
struct StorePathCommand : public InstallablesCommand
{
using StoreCommand::run;
virtual void run(ref<Store> store, const Path & storePath) = 0;
void run(ref<Store> store) override;
};
typedef std::map<std::string, ref<Command>> Commands;
/* An argument parser that supports multiple subcommands,
i.e. <command> <subcommand>. */
class MultiCommand : virtual Args
{
public:
Commands commands;
std::shared_ptr<Command> command;
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;
};
/* A helper class for registering commands globally. */
struct RegisterCommand
{
static Commands * commands;
RegisterCommand(ref<Command> command)
{
if (!commands) commands = new Commands;
commands->emplace(command->name(), command);
}
};
}