Refactor option handling

This commit is contained in:
Eelco Dolstra 2014-08-13 03:50:44 +02:00
parent 5bed74d1b0
commit 47e185847e
10 changed files with 503 additions and 531 deletions

View file

@ -91,9 +91,12 @@ static void query(std::pair<FdSink, FdSource> & pipes)
} }
void run(Strings args) int main(int argc, char * * argv)
{ {
if (args.empty()) return handleExceptions(argv[0], [&]() {
initNix();
if (argc < 2)
throw UsageError("download-via-ssh requires an argument"); throw UsageError("download-via-ssh requires an argument");
if (settings.sshSubstituterHosts.empty()) if (settings.sshSubstituterHosts.empty())
@ -101,8 +104,8 @@ void run(Strings args)
std::cout << std::endl; std::cout << std::endl;
/* Pass on the location of the daemon client's SSH authentication /* Pass on the location of the daemon client's SSH
socket. */ authentication socket. */
string sshAuthSock = settings.get("ssh-auth-sock", ""); string sshAuthSock = settings.get("ssh-auth-sock", "");
if (sshAuthSock != "") setenv("SSH_AUTH_SOCK", sshAuthSock.c_str(), 1); if (sshAuthSock != "") setenv("SSH_AUTH_SOCK", sshAuthSock.c_str(), 1);
@ -119,27 +122,18 @@ void run(Strings args)
writeInt(SERVE_PROTOCOL_VERSION, pipes.first); writeInt(SERVE_PROTOCOL_VERSION, pipes.first);
pipes.first.flush(); pipes.first.flush();
Strings::iterator i = args.begin(); string arg = argv[1];
if (*i == "--query") if (arg == "--query")
query(pipes); query(pipes);
else if (*i == "--substitute") else if (arg == "--substitute") {
if (args.size() != 3) if (argc != 4)
throw UsageError("download-via-ssh: --substitute takes exactly two arguments"); throw UsageError("download-via-ssh: --substitute takes exactly two arguments");
else { Path storePath = argv[2];
Path storePath = *++i; Path destPath = argv[3];
Path destPath = *++i;
printMsg(lvlError, format("downloading `%1%' via SSH from `%2%'...") % storePath % host); printMsg(lvlError, format("downloading `%1%' via SSH from `%2%'...") % storePath % host);
substitute(pipes, storePath, destPath); substitute(pipes, storePath, destPath);
} }
else else
throw UsageError(format("download-via-ssh: unknown command `%1%'") % *i); throw UsageError(format("download-via-ssh: unknown command `%1%'") % arg);
});
} }
void printHelp()
{
std::cerr << "Usage: download-via-ssh --query|--substitute store-path dest-path" << std::endl;
}
string programId = "download-via-ssh";

View file

@ -6,40 +6,45 @@
namespace nix { namespace nix {
bool parseOptionArg(const string & arg, Strings::iterator & i, bool parseAutoArgs(Strings::iterator & i,
const Strings::iterator & argsEnd, EvalState & state, const Strings::iterator & argsEnd, std::map<string, string> & res)
Bindings & autoArgs)
{ {
string arg = *i;
if (arg != "--arg" && arg != "--argstr") return false; if (arg != "--arg" && arg != "--argstr") return false;
UsageError error(format("`%1%' requires two arguments") % arg); UsageError error(format("`%1%' requires two arguments") % arg);
if (i == argsEnd) throw error; if (++i == argsEnd) throw error;
string name = *i++; string name = *i;
if (i == argsEnd) throw error; if (++i == argsEnd) throw error;
string value = *i++; string value = *i;
/* !!! check for duplicates! */ res[name] = (arg == "--arg" ? 'E' : 'S') + value;
Value * v = state.allocValue();
autoArgs.push_back(Attr(state.symbols.create(name), v));
if (arg == "--arg")
state.mkThunk_(*v, state.parseExprFromString(value, absPath(".")));
else
mkString(*v, value);
autoArgs.sort(); // !!! inefficient
return true; return true;
} }
bool parseSearchPathArg(const string & arg, Strings::iterator & i, void evalAutoArgs(EvalState & state, std::map<string, string> & in, Bindings & out)
{
for (auto & i: in) {
Value * v = state.allocValue();
if (i.second[0] == 'E')
state.mkThunk_(*v, state.parseExprFromString(string(i.second, 1), absPath(".")));
else
mkString(*v, string(i.second, 1));
out.push_back(Attr(state.symbols.create(i.first), v));
}
out.sort();
}
bool parseSearchPathArg(Strings::iterator & i,
const Strings::iterator & argsEnd, Strings & searchPath) const Strings::iterator & argsEnd, Strings & searchPath)
{ {
if (arg != "-I") return false; if (*i != "-I") return false;
if (i == argsEnd) throw UsageError(format("`%1%' requires an argument") % arg);; if (++i == argsEnd) throw UsageError("`-I' requires an argument");
searchPath.push_back(*i++); searchPath.push_back(*i);
return true; return true;
} }

View file

@ -5,11 +5,12 @@
namespace nix { namespace nix {
/* Some common option parsing between nix-env and nix-instantiate. */ /* Some common option parsing between nix-env and nix-instantiate. */
bool parseOptionArg(const string & arg, Strings::iterator & i, bool parseAutoArgs(Strings::iterator & i,
const Strings::iterator & argsEnd, EvalState & state, const Strings::iterator & argsEnd, std::map<string, string> & res);
Bindings & autoArgs);
bool parseSearchPathArg(const string & arg, Strings::iterator & i, void evalAutoArgs(EvalState & state, std::map<string, string> & in, Bindings & out);
bool parseSearchPathArg(Strings::iterator & i,
const Strings::iterator & argsEnd, Strings & searchPath); const Strings::iterator & argsEnd, Strings & searchPath);
Path lookupFileArg(EvalState & state, string s); Path lookupFileArg(EvalState & state, string s);

View file

@ -100,10 +100,16 @@ string getArg(const string & opt,
void detectStackOverflow(); void detectStackOverflow();
/* Initialize and reorder arguments, then call the actual argument void initNix()
processor. */
static void initAndRun(int argc, char * * argv)
{ {
/* Turn on buffering for cerr. */
#if HAVE_PUBSETBUF
static char buf[1024];
std::cerr.rdbuf()->pubsetbuf(buf, sizeof(buf));
#endif
std::ios::sync_with_stdio(false);
settings.processEnvironment(); settings.processEnvironment();
settings.loadConfFile(); settings.loadConfFile();
@ -144,6 +150,14 @@ static void initAndRun(int argc, char * * argv)
gettimeofday(&tv, 0); gettimeofday(&tv, 0);
srandom(tv.tv_usec); srandom(tv.tv_usec);
if (char *pack = getenv("_NIX_OPTIONS"))
settings.unpack(pack);
}
void parseCmdLine(int argc, char * * argv,
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg)
{
/* Put the arguments in a vector. */ /* Put the arguments in a vector. */
Strings args, remaining; Strings args, remaining;
while (argc--) args.push_back(*argv++); while (argc--) args.push_back(*argv++);
@ -164,7 +178,6 @@ static void initAndRun(int argc, char * * argv)
} else remaining.push_back(arg); } else remaining.push_back(arg);
} }
args = remaining; args = remaining;
remaining.clear();
/* Process default options. */ /* Process default options. */
for (Strings::iterator i = args.begin(); i != args.end(); ++i) { for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
@ -179,14 +192,6 @@ static void initAndRun(int argc, char * * argv)
settings.buildVerbosity = lvlVomit; settings.buildVerbosity = lvlVomit;
else if (arg == "--print-build-trace") else if (arg == "--print-build-trace")
settings.printBuildTrace = true; settings.printBuildTrace = true;
else if (arg == "--help") {
printHelp();
return;
}
else if (arg == "--version") {
std::cout << format("%1% (Nix) %2%") % programId % nixVersion << std::endl;
return;
}
else if (arg == "--keep-failed" || arg == "-K") else if (arg == "--keep-failed" || arg == "-K")
settings.keepFailed = true; settings.keepFailed = true;
else if (arg == "--keep-going" || arg == "-k") else if (arg == "--keep-going" || arg == "-k")
@ -216,25 +221,20 @@ static void initAndRun(int argc, char * * argv)
string value = *i; string value = *i;
settings.set(name, value); settings.set(name, value);
} }
else if (arg == "--arg" || arg == "--argstr") { else {
remaining.push_back(arg); if (!parseArg(i, args.end()))
++i; if (i == args.end()) throw UsageError(format("`%1%' requires two arguments") % arg); throw UsageError(format("unrecognised option `%1%'") % *i);
remaining.push_back(*i);
++i; if (i == args.end()) throw UsageError(format("`%1%' requires two arguments") % arg);
remaining.push_back(*i);
} }
else remaining.push_back(arg);
} }
if (char *pack = getenv("_NIX_OPTIONS"))
settings.unpack(pack);
settings.update(); settings.update();
}
run(remaining);
/* Close the Nix database. */ void printVersion(const string & programName)
store.reset((StoreAPI *) 0); {
std::cout << format("%1% (Nix) %2%") % programName % nixVersion << std::endl;
throw Exit();
} }
@ -246,30 +246,11 @@ void showManPage(const string & name)
} }
int exitCode = 0; int handleExceptions(const string & programName, std::function<void()> fun)
char * * argvSaved = 0;
}
static char buf[1024];
int main(int argc, char * * argv)
{ {
using namespace nix;
argvSaved = argv;
/* Turn on buffering for cerr. */
#if HAVE_PUBSETBUF
std::cerr.rdbuf()->pubsetbuf(buf, sizeof(buf));
#endif
std::ios::sync_with_stdio(false);
try { try {
try { try {
initAndRun(argc, argv); fun();
} catch (...) { } catch (...) {
/* Subtle: we have to make sure that any `interrupted' /* Subtle: we have to make sure that any `interrupted'
condition is discharged before we reach printMsg() condition is discharged before we reach printMsg()
@ -279,12 +260,14 @@ int main(int argc, char * * argv)
_isInterrupted = 0; _isInterrupted = 0;
throw; throw;
} }
} catch (Exit & e) {
return e.status;
} catch (UsageError & e) { } catch (UsageError & e) {
printMsg(lvlError, printMsg(lvlError,
format( format(
"error: %1%\n" "error: %1%\n"
"Try `%2% --help' for more information.") "Try `%2% --help' for more information.")
% e.what() % programId); % e.what() % programName);
return 1; return 1;
} catch (BaseError & e) { } catch (BaseError & e) {
printMsg(lvlError, format("error: %1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg()); printMsg(lvlError, format("error: %1%%2%") % (settings.showTrace ? e.prefix() : "") % e.msg());
@ -299,5 +282,8 @@ int main(int argc, char * * argv)
return 1; return 1;
} }
return exitCode; return 0;
}
} }

View file

@ -7,26 +7,29 @@
#include <locale> #include <locale>
/* These are not implemented here, but must be implemented by a
program linking against libmain. */
/* Main program. Called by main() after the ATerm library has been
initialised and some default arguments have been processed (and
removed from `args'). main() will catch all exceptions. */
void run(nix::Strings args);
/* Should print a help message to stdout and return. */
void printHelp();
extern std::string programId;
namespace nix { namespace nix {
MakeError(UsageError, nix::Error); MakeError(UsageError, nix::Error);
class Exit : public std::exception
{
public:
int status;
Exit() : status(0) { }
Exit(int status) : status(status) { }
};
class StoreAPI; class StoreAPI;
int handleExceptions(const string & programName, std::function<void()> fun);
void initNix();
void parseCmdLine(int argc, char * * argv,
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
void printVersion(const string & programName);
/* Ugh. No better place to put this. */ /* Ugh. No better place to put this. */
void printGCWarning(); void printGCWarning();
@ -36,6 +39,9 @@ void printMissing(const PathSet & willBuild,
const PathSet & willSubstitute, const PathSet & unknown, const PathSet & willSubstitute, const PathSet & unknown,
unsigned long long downloadSize, unsigned long long narSize); unsigned long long downloadSize, unsigned long long narSize);
string getArg(const string & opt,
Strings::iterator & i, const Strings::iterator & end);
template<class N> N getIntArg(const string & opt, template<class N> N getIntArg(const string & opt,
Strings::iterator & i, const Strings::iterator & end, bool allowUnit) Strings::iterator & i, const Strings::iterator & end, bool allowUnit)
{ {
@ -65,9 +71,4 @@ void showManPage(const string & name);
extern volatile ::sig_atomic_t blockInt; extern volatile ::sig_atomic_t blockInt;
/* Exit code of the program. */
extern int exitCode;
extern char * * argvSaved;
} }

View file

@ -645,8 +645,10 @@ bool matchUser(const string & user, const string & group, const Strings & users)
#define SD_LISTEN_FDS_START 3 #define SD_LISTEN_FDS_START 3
static void daemonLoop() static void daemonLoop(char * * argv)
{ {
chdir("/");
/* Get rid of children automatically; don't let them become /* Get rid of children automatically; don't let them become
zombies. */ zombies. */
setSigChldAction(true); setSigChldAction(true);
@ -766,9 +768,9 @@ static void daemonLoop()
setSigChldAction(false); setSigChldAction(false);
/* For debugging, stuff the pid into argv[1]. */ /* For debugging, stuff the pid into argv[1]. */
if (clientPid != -1 && argvSaved[1]) { if (clientPid != -1 && argv[1]) {
string processName = int2String(clientPid); string processName = int2String(clientPid);
strncpy(argvSaved[1], processName.c_str(), strlen(argvSaved[1])); strncpy(argv[1], processName.c_str(), strlen(argv[1]));
} }
/* Handle the connection. */ /* Handle the connection. */
@ -792,18 +794,27 @@ void run(Strings args)
{ {
for (Strings::iterator i = args.begin(); i != args.end(); ) { for (Strings::iterator i = args.begin(); i != args.end(); ) {
string arg = *i++; string arg = *i++;
if (arg == "--daemon") /* ignored for backwards compatibility */;
} }
chdir("/");
daemonLoop();
} }
void printHelp() int main(int argc, char * * argv)
{ {
return handleExceptions(argv[0], [&]() {
initNix();
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
if (*arg == "--daemon")
; /* ignored for backwards compatibility */
else if (*arg == "--help")
showManPage("nix-daemon"); showManPage("nix-daemon");
else if (*arg == "--version")
printVersion("nix-daemon");
else return false;
return true;
});
daemonLoop(argv);
});
} }
string programId = "nix-daemon";

View file

@ -52,24 +52,17 @@ struct Globals
{ {
InstallSourceInfo instSource; InstallSourceInfo instSource;
Path profile; Path profile;
EvalState state; std::shared_ptr<EvalState> state;
bool dryRun; bool dryRun;
bool preserveInstalled; bool preserveInstalled;
bool removeAll; bool removeAll;
string forceName; string forceName;
bool prebuiltOnly; bool prebuiltOnly;
Globals(const Strings & searchPath) : state(searchPath) { }
}; };
typedef void (* Operation) (Globals & globals, typedef void (* Operation) (Globals & globals,
Strings args, Strings opFlags, Strings opArgs); Strings opFlags, Strings opArgs);
void printHelp()
{
showManPage("nix-env");
}
static string needArg(Strings::iterator & i, static string needArg(Strings::iterator & i,
@ -467,11 +460,11 @@ static void installDerivations(Globals & globals,
/* Get the set of user environment elements to be installed. */ /* Get the set of user environment elements to be installed. */
DrvInfos newElems, newElemsTmp; DrvInfos newElems, newElemsTmp;
queryInstSources(globals.state, globals.instSource, args, newElemsTmp, true); queryInstSources(*globals.state, globals.instSource, args, newElemsTmp, true);
/* If --prebuilt-only is given, filter out source-only packages. */ /* If --prebuilt-only is given, filter out source-only packages. */
foreach (DrvInfos::iterator, i, newElemsTmp) foreach (DrvInfos::iterator, i, newElemsTmp)
if (!globals.prebuiltOnly || isPrebuilt(globals.state, *i)) if (!globals.prebuiltOnly || isPrebuilt(*globals.state, *i))
newElems.push_back(*i); newElems.push_back(*i);
StringSet newNames; StringSet newNames;
@ -494,7 +487,7 @@ static void installDerivations(Globals & globals,
/* Add in the already installed derivations, unless they have /* Add in the already installed derivations, unless they have
the same name as a to-be-installed element. */ the same name as a to-be-installed element. */
if (!globals.removeAll) { if (!globals.removeAll) {
DrvInfos installedElems = queryInstalled(globals.state, profile); DrvInfos installedElems = queryInstalled(*globals.state, profile);
foreach (DrvInfos::iterator, i, installedElems) { foreach (DrvInfos::iterator, i, installedElems) {
DrvName drvName(i->name); DrvName drvName(i->name);
@ -510,18 +503,17 @@ static void installDerivations(Globals & globals,
printMsg(lvlInfo, format("installing `%1%'") % i->name); printMsg(lvlInfo, format("installing `%1%'") % i->name);
} }
printMissing(globals.state, newElems); printMissing(*globals.state, newElems);
if (globals.dryRun) return; if (globals.dryRun) return;
if (createUserEnv(globals.state, allElems, if (createUserEnv(*globals.state, allElems,
profile, settings.envKeepDerivations, lockToken)) break; profile, settings.envKeepDerivations, lockToken)) break;
} }
} }
static void opInstall(Globals & globals, static void opInstall(Globals & globals, Strings opFlags, Strings opArgs)
Strings args, Strings opFlags, Strings opArgs)
{ {
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) { for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
string arg = *i++; string arg = *i++;
@ -553,11 +545,11 @@ static void upgradeDerivations(Globals & globals,
while (true) { while (true) {
string lockToken = optimisticLockProfile(globals.profile); string lockToken = optimisticLockProfile(globals.profile);
DrvInfos installedElems = queryInstalled(globals.state, globals.profile); DrvInfos installedElems = queryInstalled(*globals.state, globals.profile);
/* Fetch all derivations from the input file. */ /* Fetch all derivations from the input file. */
DrvInfos availElems; DrvInfos availElems;
queryInstSources(globals.state, globals.instSource, args, availElems, false); queryInstSources(*globals.state, globals.instSource, args, availElems, false);
/* Go through all installed derivations. */ /* Go through all installed derivations. */
DrvInfos newElems; DrvInfos newElems;
@ -582,7 +574,7 @@ static void upgradeDerivations(Globals & globals,
foreach (DrvInfos::iterator, j, availElems) { foreach (DrvInfos::iterator, j, availElems) {
DrvName newName(j->name); DrvName newName(j->name);
if (newName.name == drvName.name) { if (newName.name == drvName.name) {
int d = comparePriorities(globals.state, *i, *j); int d = comparePriorities(*globals.state, *i, *j);
if (d == 0) d = compareVersions(drvName.version, newName.version); if (d == 0) d = compareVersions(drvName.version, newName.version);
if ((upgradeType == utLt && d < 0) || if ((upgradeType == utLt && d < 0) ||
(upgradeType == utLeq && d <= 0) || (upgradeType == utLeq && d <= 0) ||
@ -591,10 +583,10 @@ static void upgradeDerivations(Globals & globals,
{ {
int d2 = -1; int d2 = -1;
if (bestElem != availElems.end()) { if (bestElem != availElems.end()) {
d2 = comparePriorities(globals.state, *bestElem, *j); d2 = comparePriorities(*globals.state, *bestElem, *j);
if (d2 == 0) d2 = compareVersions(bestName.version, newName.version); if (d2 == 0) d2 = compareVersions(bestName.version, newName.version);
} }
if (d2 < 0 && (!globals.prebuiltOnly || isPrebuilt(globals.state, *j))) { if (d2 < 0 && (!globals.prebuiltOnly || isPrebuilt(*globals.state, *j))) {
bestElem = j; bestElem = j;
bestName = newName; bestName = newName;
} }
@ -618,18 +610,17 @@ static void upgradeDerivations(Globals & globals,
} }
} }
printMissing(globals.state, newElems); printMissing(*globals.state, newElems);
if (globals.dryRun) return; if (globals.dryRun) return;
if (createUserEnv(globals.state, newElems, if (createUserEnv(*globals.state, newElems,
globals.profile, settings.envKeepDerivations, lockToken)) break; globals.profile, settings.envKeepDerivations, lockToken)) break;
} }
} }
static void opUpgrade(Globals & globals, static void opUpgrade(Globals & globals, Strings opFlags, Strings opArgs)
Strings args, Strings opFlags, Strings opArgs)
{ {
UpgradeType upgradeType = utLt; UpgradeType upgradeType = utLt;
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) { for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
@ -655,8 +646,7 @@ static void setMetaFlag(EvalState & state, DrvInfo & drv,
} }
static void opSetFlag(Globals & globals, static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs)
Strings args, Strings opFlags, Strings opArgs)
{ {
if (opFlags.size() > 0) if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front()); throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@ -671,7 +661,7 @@ static void opSetFlag(Globals & globals,
while (true) { while (true) {
string lockToken = optimisticLockProfile(globals.profile); string lockToken = optimisticLockProfile(globals.profile);
DrvInfos installedElems = queryInstalled(globals.state, globals.profile); DrvInfos installedElems = queryInstalled(*globals.state, globals.profile);
/* Update all matching derivations. */ /* Update all matching derivations. */
foreach (DrvInfos::iterator, i, installedElems) { foreach (DrvInfos::iterator, i, installedElems) {
@ -680,7 +670,7 @@ static void opSetFlag(Globals & globals,
if (j->matches(drvName)) { if (j->matches(drvName)) {
printMsg(lvlInfo, format("setting flag on `%1%'") % i->name); printMsg(lvlInfo, format("setting flag on `%1%'") % i->name);
j->hits++; j->hits++;
setMetaFlag(globals.state, *i, flagName, flagValue); setMetaFlag(*globals.state, *i, flagName, flagValue);
break; break;
} }
} }
@ -688,14 +678,13 @@ static void opSetFlag(Globals & globals,
checkSelectorUse(selectors); checkSelectorUse(selectors);
/* Write the new user environment. */ /* Write the new user environment. */
if (createUserEnv(globals.state, installedElems, if (createUserEnv(*globals.state, installedElems,
globals.profile, settings.envKeepDerivations, lockToken)) break; globals.profile, settings.envKeepDerivations, lockToken)) break;
} }
} }
static void opSet(Globals & globals, static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
Strings args, Strings opFlags, Strings opArgs)
{ {
for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) { for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
string arg = *i++; string arg = *i++;
@ -704,7 +693,7 @@ static void opSet(Globals & globals,
} }
DrvInfos elems; DrvInfos elems;
queryInstSources(globals.state, globals.instSource, opArgs, elems, true); queryInstSources(*globals.state, globals.instSource, opArgs, elems, true);
if (elems.size() != 1) if (elems.size() != 1)
throw Error("--set requires exactly one derivation"); throw Error("--set requires exactly one derivation");
@ -715,7 +704,7 @@ static void opSet(Globals & globals,
PathSet paths = singleton<PathSet>(drv.queryDrvPath()); PathSet paths = singleton<PathSet>(drv.queryDrvPath());
printMissing(*store, paths); printMissing(*store, paths);
if (globals.dryRun) return; if (globals.dryRun) return;
store->buildPaths(paths, globals.state.repair ? bmRepair : bmNormal); store->buildPaths(paths, globals.state->repair ? bmRepair : bmNormal);
} }
else { else {
printMissing(*store, singleton<PathSet>(drv.queryOutPath())); printMissing(*store, singleton<PathSet>(drv.queryOutPath()));
@ -735,7 +724,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
while (true) { while (true) {
string lockToken = optimisticLockProfile(profile); string lockToken = optimisticLockProfile(profile);
DrvInfos installedElems = queryInstalled(globals.state, profile); DrvInfos installedElems = queryInstalled(*globals.state, profile);
DrvInfos newElems; DrvInfos newElems;
foreach (DrvInfos::iterator, i, installedElems) { foreach (DrvInfos::iterator, i, installedElems) {
@ -756,14 +745,13 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
if (globals.dryRun) return; if (globals.dryRun) return;
if (createUserEnv(globals.state, newElems, if (createUserEnv(*globals.state, newElems,
profile, settings.envKeepDerivations, lockToken)) break; profile, settings.envKeepDerivations, lockToken)) break;
} }
} }
static void opUninstall(Globals & globals, static void opUninstall(Globals & globals, Strings opFlags, Strings opArgs)
Strings args, Strings opFlags, Strings opArgs)
{ {
if (opFlags.size() > 0) if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front()); throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@ -887,15 +875,14 @@ static void queryJSON(Globals & globals, vector<DrvInfo> & elems)
cout << "null"; cout << "null";
} else { } else {
PathSet context; PathSet context;
printValueAsJSON(globals.state, true, *v, cout, context); printValueAsJSON(*globals.state, true, *v, cout, context);
} }
} }
} }
} }
static void opQuery(Globals & globals, static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
Strings args, Strings opFlags, Strings opArgs)
{ {
Strings remaining; Strings remaining;
string attrPath; string attrPath;
@ -916,7 +903,7 @@ static void opQuery(Globals & globals,
settings.readOnlyMode = true; /* makes evaluation a bit faster */ settings.readOnlyMode = true; /* makes evaluation a bit faster */
for (Strings::iterator i = args.begin(); i != args.end(); ) { for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) {
string arg = *i++; string arg = *i++;
if (arg == "--status" || arg == "-s") printStatus = true; if (arg == "--status" || arg == "-s") printStatus = true;
else if (arg == "--no-name") printName = false; else if (arg == "--no-name") printName = false;
@ -932,10 +919,9 @@ static void opQuery(Globals & globals,
else if (arg == "--json") jsonOutput = true; else if (arg == "--json") jsonOutput = true;
else if (arg == "--attr-path" || arg == "-P") printAttrPath = true; else if (arg == "--attr-path" || arg == "-P") printAttrPath = true;
else if (arg == "--attr" || arg == "-A") else if (arg == "--attr" || arg == "-A")
attrPath = needArg(i, args, arg); attrPath = needArg(i, opFlags, arg);
else if (arg[0] == '-') else
throw UsageError(format("unknown flag `%1%'") % arg); throw UsageError(format("unknown flag `%1%'") % arg);
else remaining.push_back(arg);
} }
@ -943,16 +929,16 @@ static void opQuery(Globals & globals,
DrvInfos availElems, installedElems; DrvInfos availElems, installedElems;
if (source == sInstalled || compareVersions || printStatus) if (source == sInstalled || compareVersions || printStatus)
installedElems = queryInstalled(globals.state, globals.profile); installedElems = queryInstalled(*globals.state, globals.profile);
if (source == sAvailable || compareVersions) if (source == sAvailable || compareVersions)
loadDerivations(globals.state, globals.instSource.nixExprPath, loadDerivations(*globals.state, globals.instSource.nixExprPath,
globals.instSource.systemFilter, globals.instSource.autoArgs, globals.instSource.systemFilter, globals.instSource.autoArgs,
attrPath, availElems); attrPath, availElems);
DrvInfos elems_ = filterBySelector(globals.state, DrvInfos elems_ = filterBySelector(*globals.state,
source == sInstalled ? installedElems : availElems, source == sInstalled ? installedElems : availElems,
remaining, false); opArgs, false);
DrvInfos & otherElems(source == sInstalled ? availElems : installedElems); DrvInfos & otherElems(source == sInstalled ? availElems : installedElems);
@ -1173,8 +1159,7 @@ static void opQuery(Globals & globals,
} }
static void opSwitchProfile(Globals & globals, static void opSwitchProfile(Globals & globals, Strings opFlags, Strings opArgs)
Strings args, Strings opFlags, Strings opArgs)
{ {
if (opFlags.size() > 0) if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front()); throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@ -1222,8 +1207,7 @@ static void switchGeneration(Globals & globals, int dstGen)
} }
static void opSwitchGeneration(Globals & globals, static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArgs)
Strings args, Strings opFlags, Strings opArgs)
{ {
if (opFlags.size() > 0) if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front()); throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@ -1238,8 +1222,7 @@ static void opSwitchGeneration(Globals & globals,
} }
static void opRollback(Globals & globals, static void opRollback(Globals & globals, Strings opFlags, Strings opArgs)
Strings args, Strings opFlags, Strings opArgs)
{ {
if (opFlags.size() > 0) if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front()); throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@ -1250,8 +1233,7 @@ static void opRollback(Globals & globals,
} }
static void opListGenerations(Globals & globals, static void opListGenerations(Globals & globals, Strings opFlags, Strings opArgs)
Strings args, Strings opFlags, Strings opArgs)
{ {
if (opFlags.size() > 0) if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front()); throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@ -1288,8 +1270,7 @@ static void deleteGeneration2(Globals & globals, unsigned int gen)
} }
static void opDeleteGenerations(Globals & globals, static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opArgs)
Strings args, Strings opFlags, Strings opArgs)
{ {
if (opFlags.size() > 0) if (opFlags.size() > 0)
throw UsageError(format("unknown flag `%1%'") % opFlags.front()); throw UsageError(format("unknown flag `%1%'") % opFlags.front());
@ -1348,22 +1329,18 @@ static void opDeleteGenerations(Globals & globals,
} }
void run(Strings args) int main(int argc, char * * argv)
{ {
Strings opFlags, opArgs, remaining; return handleExceptions(argv[0], [&]() {
initNix();
Strings opFlags, opArgs, searchPath;
std::map<string, string> autoArgs_;
Operation op = 0; Operation op = 0;
bool repair = false;
string file;
/* FIXME: hack. */ Globals globals;
Strings searchPath;
Strings args2;
for (Strings::iterator i = args.begin(); i != args.end(); ) {
string arg = *i++;
if (!parseSearchPathArg(arg, i, args.end(), searchPath))
args2.push_back(arg);
}
args = args2;
Globals globals(searchPath);
globals.instSource.type = srcUnknown; globals.instSource.type = srcUnknown;
globals.instSource.nixExprPath = getDefNixExprPath(); globals.instSource.nixExprPath = getDefNixExprPath();
@ -1374,68 +1351,79 @@ void run(Strings args)
globals.removeAll = false; globals.removeAll = false;
globals.prebuiltOnly = false; globals.prebuiltOnly = false;
for (Strings::iterator i = args.begin(); i != args.end(); ) { parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
string arg = *i++;
Operation oldOp = op; Operation oldOp = op;
if (arg == "--install" || arg == "-i") if (*arg == "--help")
showManPage("nix-env");
else if (*arg == "--version")
printVersion("nix-env");
else if (*arg == "--install" || *arg == "-i")
op = opInstall; op = opInstall;
else if (parseOptionArg(arg, i, args.end(), else if (parseAutoArgs(arg, end, autoArgs_))
globals.state, globals.instSource.autoArgs))
; ;
else if (arg == "--force-name") // undocumented flag for nix-install-package else if (parseSearchPathArg(arg, end, searchPath))
globals.forceName = needArg(i, args, arg); ;
else if (arg == "--uninstall" || arg == "-e") else if (*arg == "--force-name") // undocumented flag for nix-install-package
globals.forceName = getArg(*arg, arg, end);
else if (*arg == "--uninstall" || *arg == "-e")
op = opUninstall; op = opUninstall;
else if (arg == "--upgrade" || arg == "-u") else if (*arg == "--upgrade" || *arg == "-u")
op = opUpgrade; op = opUpgrade;
else if (arg == "--set-flag") else if (*arg == "--set-flag")
op = opSetFlag; op = opSetFlag;
else if (arg == "--set") else if (*arg == "--set")
op = opSet; op = opSet;
else if (arg == "--query" || arg == "-q") else if (*arg == "--query" || *arg == "-q")
op = opQuery; op = opQuery;
else if (arg == "--profile" || arg == "-p") else if (*arg == "--profile" || *arg == "-p")
globals.profile = absPath(needArg(i, args, arg)); globals.profile = absPath(getArg(*arg, arg, end));
else if (arg == "--file" || arg == "-f") else if (*arg == "--file" || *arg == "-f")
globals.instSource.nixExprPath = lookupFileArg(globals.state, needArg(i, args, arg)); file = getArg(*arg, arg, end);
else if (arg == "--switch-profile" || arg == "-S") else if (*arg == "--switch-profile" || *arg == "-S")
op = opSwitchProfile; op = opSwitchProfile;
else if (arg == "--switch-generation" || arg == "-G") else if (*arg == "--switch-generation" || *arg == "-G")
op = opSwitchGeneration; op = opSwitchGeneration;
else if (arg == "--rollback") else if (*arg == "--rollback")
op = opRollback; op = opRollback;
else if (arg == "--list-generations") else if (*arg == "--list-generations")
op = opListGenerations; op = opListGenerations;
else if (arg == "--delete-generations") else if (*arg == "--delete-generations")
op = opDeleteGenerations; op = opDeleteGenerations;
else if (arg == "--dry-run") { else if (*arg == "--dry-run") {
printMsg(lvlInfo, "(dry run; not doing anything)"); printMsg(lvlInfo, "(dry run; not doing anything)");
globals.dryRun = true; globals.dryRun = true;
} }
else if (arg == "--system-filter") else if (*arg == "--system-filter")
globals.instSource.systemFilter = needArg(i, args, arg); globals.instSource.systemFilter = getArg(*arg, arg, end);
else if (arg == "--prebuilt-only" || arg == "-b") else if (*arg == "--prebuilt-only" || *arg == "-b")
globals.prebuiltOnly = true; globals.prebuiltOnly = true;
else if (arg == "--repair") else if (*arg == "--repair")
globals.state.repair = true; repair = true;
else { else if (*arg != "" && arg->at(0) == '-') {
remaining.push_back(arg); opFlags.push_back(*arg);
if (arg[0] == '-') { if (*arg == "--from-profile" || *arg == "--atr" || *arg == "-A") /* !!! hack */
opFlags.push_back(arg); opFlags.push_back(getArg(*arg, arg, end));
if (arg == "--from-profile") { /* !!! hack */
if (i != args.end()) opFlags.push_back(*i++);
}
} else opArgs.push_back(arg);
} }
else
opArgs.push_back(*arg);
if (oldOp && oldOp != op) if (oldOp && oldOp != op)
throw UsageError("only one operation may be specified"); throw UsageError("only one operation may be specified");
}
return true;
});
if (!op) throw UsageError("no operation specified"); if (!op) throw UsageError("no operation specified");
globals.state = std::shared_ptr<EvalState>(new EvalState(searchPath));
globals.state->repair = repair;
if (file != "")
globals.instSource.nixExprPath = lookupFileArg(*globals.state, file);
evalAutoArgs(*globals.state, autoArgs_, globals.instSource.autoArgs);
if (globals.profile == "") if (globals.profile == "")
globals.profile = getEnv("NIX_PROFILE", ""); globals.profile = getEnv("NIX_PROFILE", "");
@ -1448,10 +1436,8 @@ void run(Strings args)
store = openStore(); store = openStore();
op(globals, remaining, opFlags, opArgs); op(globals, opFlags, opArgs);
globals.state.printStats(); globals.state->printStats();
});
} }
string programId = "nix-env";

View file

@ -3,17 +3,10 @@
#include <iostream> #include <iostream>
using namespace nix; using namespace nix;
void printHelp() int main(int argc, char * * argv)
{
showManPage("nix-hash");
}
void run(Strings args)
{ {
HashType ht = htMD5; HashType ht = htMD5;
bool flat = false; bool flat = false;
@ -23,27 +16,35 @@ void run(Strings args)
Strings ss; Strings ss;
for (Strings::iterator i = args.begin(); return handleExceptions(argv[0], [&]() {
i != args.end(); i++) initNix();
{
if (*i == "--flat") flat = true; parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
else if (*i == "--base32") base32 = true; if (*arg == "--help")
else if (*i == "--truncate") truncate = true; showManPage("nix-hash");
else if (*i == "--type") { else if (*arg == "--version")
++i; printVersion("nix-hash");
if (i == args.end()) throw UsageError("`--type' requires an argument"); else if (*arg == "--flat") flat = true;
ht = parseHashType(*i); else if (*arg == "--base32") base32 = true;
else if (*arg == "--truncate") truncate = true;
else if (*arg == "--type") {
string s = getArg(*arg, arg, end);
ht = parseHashType(s);
if (ht == htUnknown) if (ht == htUnknown)
throw UsageError(format("unknown hash type `%1%'") % *i); throw UsageError(format("unknown hash type `%1%'") % s);
}
else if (*i == "--to-base16") op = opTo16;
else if (*i == "--to-base32") op = opTo32;
else ss.push_back(*i);
} }
else if (*arg == "--to-base16") op = opTo16;
else if (*arg == "--to-base32") op = opTo32;
else if (*arg != "" && arg->at(0) == '-')
return false;
else
ss.push_back(*arg);
return true;
});
if (op == opHash) { if (op == opHash) {
foreach (Strings::iterator, i, ss) { for (auto & i : ss) {
Hash h = flat ? hashFile(ht, *i) : hashPath(ht, *i).first; Hash h = flat ? hashFile(ht, i) : hashPath(ht, i).first;
if (truncate && h.hashSize > 20) h = compressHash(h, 20); if (truncate && h.hashSize > 20) h = compressHash(h, 20);
std::cout << format("%1%\n") % std::cout << format("%1%\n") %
(base32 ? printHash32(h) : printHash(h)); (base32 ? printHash32(h) : printHash(h));
@ -51,14 +52,12 @@ void run(Strings args)
} }
else { else {
foreach (Strings::iterator, i, ss) { for (auto & i : ss) {
Hash h = parseHash16or32(ht, *i); Hash h = parseHash16or32(ht, i);
std::cout << format("%1%\n") % std::cout << format("%1%\n") %
(op == opTo16 ? printHash(h) : printHash32(h)); (op == opTo16 ? printHash(h) : printHash32(h));
} }
} }
});
} }
string programId = "nix-hash";

View file

@ -18,12 +18,6 @@
using namespace nix; using namespace nix;
void printHelp()
{
showManPage("nix-instantiate");
}
static Expr * parseStdin(EvalState & state) static Expr * parseStdin(EvalState & state)
{ {
startNest(nest, lvlTalkative, format("parsing standard input")); startNest(nest, lvlTalkative, format("parsing standard input"));
@ -95,20 +89,12 @@ void processExpr(EvalState & state, const Strings & attrPaths,
} }
void run(Strings args) int main(int argc, char * * argv)
{ {
/* FIXME: hack. */ return handleExceptions(argv[0], [&]() {
Strings searchPath; initNix();
Strings args2;
for (Strings::iterator i = args.begin(); i != args.end(); ) {
string arg = *i++;
if (!parseSearchPathArg(arg, i, args.end(), searchPath))
args2.push_back(arg);
}
args = args2;
EvalState state(searchPath); Strings files, searchPath;
Strings files;
bool readStdin = false; bool readStdin = false;
bool fromArgs = false; bool fromArgs = false;
bool findFile = false; bool findFile = false;
@ -118,55 +104,61 @@ void run(Strings args)
bool xmlOutputSourceLocation = true; bool xmlOutputSourceLocation = true;
bool strict = false; bool strict = false;
Strings attrPaths; Strings attrPaths;
Bindings autoArgs;
bool wantsReadWrite = false; bool wantsReadWrite = false;
std::map<string, string> autoArgs_;
bool repair = false;
for (Strings::iterator i = args.begin(); i != args.end(); ) { parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
string arg = *i++; if (*arg == "--help")
showManPage("nix-instantiate");
if (arg == "-") else if (*arg == "--version")
printVersion("nix-instantiate");
else if (*arg == "-")
readStdin = true; readStdin = true;
else if (arg == "--expr" || arg == "-E") else if (*arg == "--expr" || *arg == "-E")
fromArgs = true; fromArgs = true;
else if (arg == "--eval" || arg == "--eval-only") else if (*arg == "--eval" || *arg == "--eval-only")
evalOnly = true; evalOnly = true;
else if (arg == "--read-write-mode") else if (*arg == "--read-write-mode")
wantsReadWrite = true; wantsReadWrite = true;
else if (arg == "--parse" || arg == "--parse-only") else if (*arg == "--parse" || *arg == "--parse-only")
parseOnly = evalOnly = true; parseOnly = evalOnly = true;
else if (arg == "--find-file") else if (*arg == "--find-file")
findFile = true; findFile = true;
else if (arg == "--attr" || arg == "-A") { else if (*arg == "--attr" || *arg == "-A")
if (i == args.end()) attrPaths.push_back(getArg(*arg, arg, end));
throw UsageError("`--attr' requires an argument"); else if (parseAutoArgs(arg, end, autoArgs_))
attrPaths.push_back(*i++);
}
else if (parseOptionArg(arg, i, args.end(), state, autoArgs))
; ;
else if (arg == "--add-root") { else if (parseSearchPathArg(arg, end, searchPath))
if (i == args.end()) ;
throw UsageError("`--add-root' requires an argument"); else if (*arg == "--add-root")
gcRoot = absPath(*i++); gcRoot = getArg(*arg, arg, end);
} else if (*arg == "--indirect")
else if (arg == "--indirect")
indirectRoot = true; indirectRoot = true;
else if (arg == "--xml") else if (*arg == "--xml")
outputKind = okXML; outputKind = okXML;
else if (arg == "--json") else if (*arg == "--json")
outputKind = okJSON; outputKind = okJSON;
else if (arg == "--no-location") else if (*arg == "--no-location")
xmlOutputSourceLocation = false; xmlOutputSourceLocation = false;
else if (arg == "--strict") else if (*arg == "--strict")
strict = true; strict = true;
else if (arg == "--repair") else if (*arg == "--repair")
state.repair = true; repair = true;
else if (arg == "--dry-run") else if (*arg == "--dry-run")
settings.readOnlyMode = true; settings.readOnlyMode = true;
else if (arg[0] == '-') else if (*arg != "" && arg->at(0) == '-')
throw UsageError(format("unknown flag `%1%'") % arg); return false;
else else
files.push_back(arg); files.push_back(*arg);
} return true;
});
EvalState state(searchPath);
state.repair = repair;
Bindings autoArgs;
evalAutoArgs(state, autoArgs_, autoArgs);
if (evalOnly && !wantsReadWrite) if (evalOnly && !wantsReadWrite)
settings.readOnlyMode = true; settings.readOnlyMode = true;
@ -200,7 +192,5 @@ void run(Strings args)
} }
state.printStats(); state.printStats();
});
} }
string programId = "nix-instantiate";

View file

@ -29,12 +29,6 @@ using std::cout;
typedef void (* Operation) (Strings opFlags, Strings opArgs); typedef void (* Operation) (Strings opFlags, Strings opArgs);
void printHelp()
{
showManPage("nix-store");
}
static Path gcRoot; static Path gcRoot;
static int rootNr = 0; static int rootNr = 0;
static bool indirectRoot = false; static bool indirectRoot = false;
@ -782,7 +776,7 @@ static void opVerify(Strings opFlags, Strings opArgs)
if (ensureLocalStore().verifyStore(checkContents, repair)) { if (ensureLocalStore().verifyStore(checkContents, repair)) {
printMsg(lvlError, "warning: not all errors were fixed"); printMsg(lvlError, "warning: not all errors were fixed");
exitCode = 1; throw Exit(1);
} }
} }
@ -793,6 +787,8 @@ static void opVerifyPath(Strings opFlags, Strings opArgs)
if (!opFlags.empty()) if (!opFlags.empty())
throw UsageError("no flags expected"); throw UsageError("no flags expected");
int status = 0;
foreach (Strings::iterator, i, opArgs) { foreach (Strings::iterator, i, opArgs) {
Path path = followLinksToStorePath(*i); Path path = followLinksToStorePath(*i);
printMsg(lvlTalkative, format("checking path `%1%'...") % path); printMsg(lvlTalkative, format("checking path `%1%'...") % path);
@ -802,9 +798,11 @@ static void opVerifyPath(Strings opFlags, Strings opArgs)
printMsg(lvlError, printMsg(lvlError,
format("path `%1%' was modified! expected hash `%2%', got `%3%'") format("path `%1%' was modified! expected hash `%2%', got `%3%'")
% path % printHash(info.hash) % printHash(current.first)); % path % printHash(info.hash) % printHash(current.first));
exitCode = 1; status = 1;
} }
} }
throw Exit(status);
} }
@ -1017,87 +1015,90 @@ static void opServe(Strings opFlags, Strings opArgs)
/* Scan the arguments; find the operation, set global flags, put all /* Scan the arguments; find the operation, set global flags, put all
other flags in a list, and put all other arguments in another other flags in a list, and put all other arguments in another
list. */ list. */
void run(Strings args) int main(int argc, char * * argv)
{ {
return handleExceptions(argv[0], [&]() {
initNix();
Strings opFlags, opArgs; Strings opFlags, opArgs;
Operation op = 0; Operation op = 0;
for (Strings::iterator i = args.begin(); i != args.end(); ) { parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
string arg = *i++;
Operation oldOp = op; Operation oldOp = op;
if (arg == "--realise" || arg == "--realize" || arg == "-r") if (*arg == "--help")
showManPage("nix-store");
else if (*arg == "--version")
printVersion("nix-store");
else if (*arg == "--realise" || *arg == "--realize" || *arg == "-r")
op = opRealise; op = opRealise;
else if (arg == "--add" || arg == "-A") else if (*arg == "--add" || *arg == "-A")
op = opAdd; op = opAdd;
else if (arg == "--add-fixed") else if (*arg == "--add-fixed")
op = opAddFixed; op = opAddFixed;
else if (arg == "--print-fixed-path") else if (*arg == "--print-fixed-path")
op = opPrintFixedPath; op = opPrintFixedPath;
else if (arg == "--delete") else if (*arg == "--delete")
op = opDelete; op = opDelete;
else if (arg == "--query" || arg == "-q") else if (*arg == "--query" || *arg == "-q")
op = opQuery; op = opQuery;
else if (arg == "--print-env") else if (*arg == "--print-env")
op = opPrintEnv; op = opPrintEnv;
else if (arg == "--read-log" || arg == "-l") else if (*arg == "--read-log" || *arg == "-l")
op = opReadLog; op = opReadLog;
else if (arg == "--dump-db") else if (*arg == "--dump-db")
op = opDumpDB; op = opDumpDB;
else if (arg == "--load-db") else if (*arg == "--load-db")
op = opLoadDB; op = opLoadDB;
else if (arg == "--register-validity") else if (*arg == "--register-validity")
op = opRegisterValidity; op = opRegisterValidity;
else if (arg == "--check-validity") else if (*arg == "--check-validity")
op = opCheckValidity; op = opCheckValidity;
else if (arg == "--gc") else if (*arg == "--gc")
op = opGC; op = opGC;
else if (arg == "--dump") else if (*arg == "--dump")
op = opDump; op = opDump;
else if (arg == "--restore") else if (*arg == "--restore")
op = opRestore; op = opRestore;
else if (arg == "--export") else if (*arg == "--export")
op = opExport; op = opExport;
else if (arg == "--import") else if (*arg == "--import")
op = opImport; op = opImport;
else if (arg == "--init") else if (*arg == "--init")
op = opInit; op = opInit;
else if (arg == "--verify") else if (*arg == "--verify")
op = opVerify; op = opVerify;
else if (arg == "--verify-path") else if (*arg == "--verify-path")
op = opVerifyPath; op = opVerifyPath;
else if (arg == "--repair-path") else if (*arg == "--repair-path")
op = opRepairPath; op = opRepairPath;
else if (arg == "--optimise" || arg == "--optimize") else if (*arg == "--optimise" || *arg == "--optimize")
op = opOptimise; op = opOptimise;
else if (arg == "--query-failed-paths") else if (*arg == "--query-failed-paths")
op = opQueryFailedPaths; op = opQueryFailedPaths;
else if (arg == "--clear-failed-paths") else if (*arg == "--clear-failed-paths")
op = opClearFailedPaths; op = opClearFailedPaths;
else if (arg == "--add-root") { else if (*arg == "--add-root")
if (i == args.end()) gcRoot = absPath(getArg(*arg, arg, end));
throw UsageError("`--add-root requires an argument"); else if (*arg == "--indirect")
gcRoot = absPath(*i++);
}
else if (arg == "--indirect")
indirectRoot = true; indirectRoot = true;
else if (arg == "--no-output") else if (*arg == "--no-output")
noOutput = true; noOutput = true;
else if (arg == "--serve") else if (*arg == "--serve")
op = opServe; op = opServe;
else if (arg[0] == '-') { else if (*arg != "" && arg->at(0) == '-') {
opFlags.push_back(arg); opFlags.push_back(*arg);
if (arg == "--max-freed" || arg == "--max-links" || arg == "--max-atime") { /* !!! hack */ if (*arg == "--max-freed" || *arg == "--max-links" || *arg == "--max-atime") /* !!! hack */
if (i != args.end()) opFlags.push_back(*i++); opFlags.push_back(getArg(*arg, arg, end));
}
} }
else else
opArgs.push_back(arg); opArgs.push_back(*arg);
if (oldOp && oldOp != op) if (oldOp && oldOp != op)
throw UsageError("only one operation may be specified"); throw UsageError("only one operation may be specified");
}
return true;
});
if (!op) throw UsageError("no operation specified"); if (!op) throw UsageError("no operation specified");
@ -1105,7 +1106,5 @@ void run(Strings args)
store = openStore(op != opGC); store = openStore(op != opGC);
op(opFlags, opArgs); op(opFlags, opArgs);
});
} }
string programId = "nix-store";