diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-08-13T01·50+0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-08-13T01·50+0200 |
commit | 47e185847e729d49e6aa376e8299fd66ef834a0a (patch) | |
tree | 6abfc9e9d5744e78b123c73182c30253c9a39681 /src/nix-env/nix-env.cc | |
parent | 5bed74d1b0acd8d8083fb82a31d907ad2348a91b (diff) |
Refactor option handling
Diffstat (limited to 'src/nix-env/nix-env.cc')
-rw-r--r-- | src/nix-env/nix-env.cc | 292 |
1 files changed, 139 insertions, 153 deletions
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 062118d8a095..e65dc4e51a64 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -52,24 +52,17 @@ struct Globals { InstallSourceInfo instSource; Path profile; - EvalState state; + std::shared_ptr<EvalState> state; bool dryRun; bool preserveInstalled; bool removeAll; string forceName; bool prebuiltOnly; - Globals(const Strings & searchPath) : state(searchPath) { } }; typedef void (* Operation) (Globals & globals, - Strings args, Strings opFlags, Strings opArgs); - - -void printHelp() -{ - showManPage("nix-env"); -} + Strings opFlags, Strings opArgs); 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. */ 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. */ foreach (DrvInfos::iterator, i, newElemsTmp) - if (!globals.prebuiltOnly || isPrebuilt(globals.state, *i)) + if (!globals.prebuiltOnly || isPrebuilt(*globals.state, *i)) newElems.push_back(*i); StringSet newNames; @@ -494,7 +487,7 @@ static void installDerivations(Globals & globals, /* Add in the already installed derivations, unless they have the same name as a to-be-installed element. */ if (!globals.removeAll) { - DrvInfos installedElems = queryInstalled(globals.state, profile); + DrvInfos installedElems = queryInstalled(*globals.state, profile); foreach (DrvInfos::iterator, i, installedElems) { DrvName drvName(i->name); @@ -510,18 +503,17 @@ static void installDerivations(Globals & globals, printMsg(lvlInfo, format("installing `%1%'") % i->name); } - printMissing(globals.state, newElems); + printMissing(*globals.state, newElems); if (globals.dryRun) return; - if (createUserEnv(globals.state, allElems, + if (createUserEnv(*globals.state, allElems, profile, settings.envKeepDerivations, lockToken)) break; } } -static void opInstall(Globals & globals, - Strings args, Strings opFlags, Strings opArgs) +static void opInstall(Globals & globals, Strings opFlags, Strings opArgs) { for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) { string arg = *i++; @@ -553,11 +545,11 @@ static void upgradeDerivations(Globals & globals, while (true) { 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. */ DrvInfos availElems; - queryInstSources(globals.state, globals.instSource, args, availElems, false); + queryInstSources(*globals.state, globals.instSource, args, availElems, false); /* Go through all installed derivations. */ DrvInfos newElems; @@ -582,7 +574,7 @@ static void upgradeDerivations(Globals & globals, foreach (DrvInfos::iterator, j, availElems) { DrvName newName(j->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 ((upgradeType == utLt && d < 0) || (upgradeType == utLeq && d <= 0) || @@ -591,10 +583,10 @@ static void upgradeDerivations(Globals & globals, { int d2 = -1; 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 && (!globals.prebuiltOnly || isPrebuilt(globals.state, *j))) { + if (d2 < 0 && (!globals.prebuiltOnly || isPrebuilt(*globals.state, *j))) { bestElem = j; bestName = newName; } @@ -618,18 +610,17 @@ static void upgradeDerivations(Globals & globals, } } - printMissing(globals.state, newElems); + printMissing(*globals.state, newElems); if (globals.dryRun) return; - if (createUserEnv(globals.state, newElems, + if (createUserEnv(*globals.state, newElems, globals.profile, settings.envKeepDerivations, lockToken)) break; } } -static void opUpgrade(Globals & globals, - Strings args, Strings opFlags, Strings opArgs) +static void opUpgrade(Globals & globals, Strings opFlags, Strings opArgs) { UpgradeType upgradeType = utLt; 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, - Strings args, Strings opFlags, Strings opArgs) +static void opSetFlag(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -671,7 +661,7 @@ static void opSetFlag(Globals & globals, while (true) { string lockToken = optimisticLockProfile(globals.profile); - DrvInfos installedElems = queryInstalled(globals.state, globals.profile); + DrvInfos installedElems = queryInstalled(*globals.state, globals.profile); /* Update all matching derivations. */ foreach (DrvInfos::iterator, i, installedElems) { @@ -680,7 +670,7 @@ static void opSetFlag(Globals & globals, if (j->matches(drvName)) { printMsg(lvlInfo, format("setting flag on `%1%'") % i->name); j->hits++; - setMetaFlag(globals.state, *i, flagName, flagValue); + setMetaFlag(*globals.state, *i, flagName, flagValue); break; } } @@ -688,14 +678,13 @@ static void opSetFlag(Globals & globals, checkSelectorUse(selectors); /* Write the new user environment. */ - if (createUserEnv(globals.state, installedElems, + if (createUserEnv(*globals.state, installedElems, globals.profile, settings.envKeepDerivations, lockToken)) break; } } -static void opSet(Globals & globals, - Strings args, Strings opFlags, Strings opArgs) +static void opSet(Globals & globals, Strings opFlags, Strings opArgs) { for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); ) { string arg = *i++; @@ -704,7 +693,7 @@ static void opSet(Globals & globals, } DrvInfos elems; - queryInstSources(globals.state, globals.instSource, opArgs, elems, true); + queryInstSources(*globals.state, globals.instSource, opArgs, elems, true); if (elems.size() != 1) throw Error("--set requires exactly one derivation"); @@ -715,7 +704,7 @@ static void opSet(Globals & globals, PathSet paths = singleton<PathSet>(drv.queryDrvPath()); printMissing(*store, paths); if (globals.dryRun) return; - store->buildPaths(paths, globals.state.repair ? bmRepair : bmNormal); + store->buildPaths(paths, globals.state->repair ? bmRepair : bmNormal); } else { printMissing(*store, singleton<PathSet>(drv.queryOutPath())); @@ -735,7 +724,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors, while (true) { string lockToken = optimisticLockProfile(profile); - DrvInfos installedElems = queryInstalled(globals.state, profile); + DrvInfos installedElems = queryInstalled(*globals.state, profile); DrvInfos newElems; foreach (DrvInfos::iterator, i, installedElems) { @@ -756,14 +745,13 @@ static void uninstallDerivations(Globals & globals, Strings & selectors, if (globals.dryRun) return; - if (createUserEnv(globals.state, newElems, + if (createUserEnv(*globals.state, newElems, profile, settings.envKeepDerivations, lockToken)) break; } } -static void opUninstall(Globals & globals, - Strings args, Strings opFlags, Strings opArgs) +static void opUninstall(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -887,15 +875,14 @@ static void queryJSON(Globals & globals, vector<DrvInfo> & elems) cout << "null"; } else { PathSet context; - printValueAsJSON(globals.state, true, *v, cout, context); + printValueAsJSON(*globals.state, true, *v, cout, context); } } } } -static void opQuery(Globals & globals, - Strings args, Strings opFlags, Strings opArgs) +static void opQuery(Globals & globals, Strings opFlags, Strings opArgs) { Strings remaining; string attrPath; @@ -916,7 +903,7 @@ static void opQuery(Globals & globals, 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++; if (arg == "--status" || arg == "-s") printStatus = true; 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 == "--attr-path" || arg == "-P") printAttrPath = true; else if (arg == "--attr" || arg == "-A") - attrPath = needArg(i, args, arg); - else if (arg[0] == '-') + attrPath = needArg(i, opFlags, arg); + else throw UsageError(format("unknown flag `%1%'") % arg); - else remaining.push_back(arg); } @@ -943,16 +929,16 @@ static void opQuery(Globals & globals, DrvInfos availElems, installedElems; if (source == sInstalled || compareVersions || printStatus) - installedElems = queryInstalled(globals.state, globals.profile); + installedElems = queryInstalled(*globals.state, globals.profile); if (source == sAvailable || compareVersions) - loadDerivations(globals.state, globals.instSource.nixExprPath, + loadDerivations(*globals.state, globals.instSource.nixExprPath, globals.instSource.systemFilter, globals.instSource.autoArgs, attrPath, availElems); - DrvInfos elems_ = filterBySelector(globals.state, + DrvInfos elems_ = filterBySelector(*globals.state, source == sInstalled ? installedElems : availElems, - remaining, false); + opArgs, false); DrvInfos & otherElems(source == sInstalled ? availElems : installedElems); @@ -1173,8 +1159,7 @@ static void opQuery(Globals & globals, } -static void opSwitchProfile(Globals & globals, - Strings args, Strings opFlags, Strings opArgs) +static void opSwitchProfile(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -1222,8 +1207,7 @@ static void switchGeneration(Globals & globals, int dstGen) } -static void opSwitchGeneration(Globals & globals, - Strings args, Strings opFlags, Strings opArgs) +static void opSwitchGeneration(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -1238,8 +1222,7 @@ static void opSwitchGeneration(Globals & globals, } -static void opRollback(Globals & globals, - Strings args, Strings opFlags, Strings opArgs) +static void opRollback(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -1250,8 +1233,7 @@ static void opRollback(Globals & globals, } -static void opListGenerations(Globals & globals, - Strings args, Strings opFlags, Strings opArgs) +static void opListGenerations(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) 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, - Strings args, Strings opFlags, Strings opArgs) +static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opArgs) { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); @@ -1348,110 +1329,115 @@ static void opDeleteGenerations(Globals & globals, } -void run(Strings args) +int main(int argc, char * * argv) { - Strings opFlags, opArgs, remaining; - Operation op = 0; - - /* FIXME: hack. */ - 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); + return handleExceptions(argv[0], [&]() { + initNix(); + + Strings opFlags, opArgs, searchPath; + std::map<string, string> autoArgs_; + Operation op = 0; + bool repair = false; + string file; + + Globals globals; + + globals.instSource.type = srcUnknown; + globals.instSource.nixExprPath = getDefNixExprPath(); + globals.instSource.systemFilter = "*"; + + globals.dryRun = false; + globals.preserveInstalled = false; + globals.removeAll = false; + globals.prebuiltOnly = false; + + parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) { + Operation oldOp = op; + + if (*arg == "--help") + showManPage("nix-env"); + else if (*arg == "--version") + printVersion("nix-env"); + else if (*arg == "--install" || *arg == "-i") + op = opInstall; + else if (parseAutoArgs(arg, end, autoArgs_)) + ; + else if (parseSearchPathArg(arg, end, searchPath)) + ; + 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; + else if (*arg == "--upgrade" || *arg == "-u") + op = opUpgrade; + else if (*arg == "--set-flag") + op = opSetFlag; + else if (*arg == "--set") + op = opSet; + else if (*arg == "--query" || *arg == "-q") + op = opQuery; + else if (*arg == "--profile" || *arg == "-p") + globals.profile = absPath(getArg(*arg, arg, end)); + else if (*arg == "--file" || *arg == "-f") + file = getArg(*arg, arg, end); + else if (*arg == "--switch-profile" || *arg == "-S") + op = opSwitchProfile; + else if (*arg == "--switch-generation" || *arg == "-G") + op = opSwitchGeneration; + else if (*arg == "--rollback") + op = opRollback; + else if (*arg == "--list-generations") + op = opListGenerations; + else if (*arg == "--delete-generations") + op = opDeleteGenerations; + else if (*arg == "--dry-run") { + printMsg(lvlInfo, "(dry run; not doing anything)"); + globals.dryRun = true; + } + else if (*arg == "--system-filter") + globals.instSource.systemFilter = getArg(*arg, arg, end); + else if (*arg == "--prebuilt-only" || *arg == "-b") + globals.prebuiltOnly = true; + else if (*arg == "--repair") + repair = true; + else if (*arg != "" && arg->at(0) == '-') { + opFlags.push_back(*arg); + if (*arg == "--from-profile" || *arg == "--atr" || *arg == "-A") /* !!! hack */ + opFlags.push_back(getArg(*arg, arg, end)); + } + else + opArgs.push_back(*arg); - globals.instSource.type = srcUnknown; - globals.instSource.nixExprPath = getDefNixExprPath(); - globals.instSource.systemFilter = "*"; + if (oldOp && oldOp != op) + throw UsageError("only one operation may be specified"); - globals.dryRun = false; - globals.preserveInstalled = false; - globals.removeAll = false; - globals.prebuiltOnly = false; + return true; + }); - for (Strings::iterator i = args.begin(); i != args.end(); ) { - string arg = *i++; + if (!op) throw UsageError("no operation specified"); - Operation oldOp = op; - - if (arg == "--install" || arg == "-i") - op = opInstall; - else if (parseOptionArg(arg, i, args.end(), - globals.state, globals.instSource.autoArgs)) - ; - else if (arg == "--force-name") // undocumented flag for nix-install-package - globals.forceName = needArg(i, args, arg); - else if (arg == "--uninstall" || arg == "-e") - op = opUninstall; - else if (arg == "--upgrade" || arg == "-u") - op = opUpgrade; - else if (arg == "--set-flag") - op = opSetFlag; - else if (arg == "--set") - op = opSet; - else if (arg == "--query" || arg == "-q") - op = opQuery; - else if (arg == "--profile" || arg == "-p") - globals.profile = absPath(needArg(i, args, arg)); - else if (arg == "--file" || arg == "-f") - globals.instSource.nixExprPath = lookupFileArg(globals.state, needArg(i, args, arg)); - else if (arg == "--switch-profile" || arg == "-S") - op = opSwitchProfile; - else if (arg == "--switch-generation" || arg == "-G") - op = opSwitchGeneration; - else if (arg == "--rollback") - op = opRollback; - else if (arg == "--list-generations") - op = opListGenerations; - else if (arg == "--delete-generations") - op = opDeleteGenerations; - else if (arg == "--dry-run") { - printMsg(lvlInfo, "(dry run; not doing anything)"); - globals.dryRun = true; - } - else if (arg == "--system-filter") - globals.instSource.systemFilter = needArg(i, args, arg); - else if (arg == "--prebuilt-only" || arg == "-b") - globals.prebuiltOnly = true; - else if (arg == "--repair") - globals.state.repair = true; - else { - remaining.push_back(arg); - if (arg[0] == '-') { - opFlags.push_back(arg); - if (arg == "--from-profile") { /* !!! hack */ - if (i != args.end()) opFlags.push_back(*i++); - } - } else opArgs.push_back(arg); - } + globals.state = std::shared_ptr<EvalState>(new EvalState(searchPath)); + globals.state->repair = repair; - if (oldOp && oldOp != op) - throw UsageError("only one operation may be specified"); - } + if (file != "") + globals.instSource.nixExprPath = lookupFileArg(*globals.state, file); - if (!op) throw UsageError("no operation specified"); + evalAutoArgs(*globals.state, autoArgs_, globals.instSource.autoArgs); - if (globals.profile == "") - globals.profile = getEnv("NIX_PROFILE", ""); + if (globals.profile == "") + globals.profile = getEnv("NIX_PROFILE", ""); - if (globals.profile == "") { - Path profileLink = getHomeDir() + "/.nix-profile"; - globals.profile = pathExists(profileLink) - ? absPath(readLink(profileLink), dirOf(profileLink)) - : canonPath(settings.nixStateDir + "/profiles/default"); - } + if (globals.profile == "") { + Path profileLink = getHomeDir() + "/.nix-profile"; + globals.profile = pathExists(profileLink) + ? absPath(readLink(profileLink), dirOf(profileLink)) + : canonPath(settings.nixStateDir + "/profiles/default"); + } - store = openStore(); + store = openStore(); - op(globals, remaining, opFlags, opArgs); + op(globals, opFlags, opArgs); - globals.state.printStats(); + globals.state->printStats(); + }); } - - -string programId = "nix-env"; |