From 633518628f48fb9c06bfd570eeca6f62696aba05 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 29 Nov 2007 16:18:24 +0000 Subject: * nix-env -e: support uninstalling by path, so that one can say $ nix-env -e $(which firefox) or $ nix-env -e /nix/store/nywzlygrkfcgz7dfmhm5xixlx1l0m60v-pan-0.132 * nix-env -i: if an argument contains a slash anywhere, treat it as a path and follow it through symlinks into the Nix store. This allows things like $ nix-build -A firefox $ nix-env -i ./result * nix-env -q/-i/-e: don't complain when the `*' selector doesn't match anything. In particular, `nix-env -q \*' doesn't fail anymore on an empty profile. --- src/nix-env/nix-env.cc | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'src/nix-env') diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 3396b191fd..1af1a2f536 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -410,7 +410,7 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems, /* Check that all selectors have been used. */ for (DrvNames::iterator i = selectors.begin(); i != selectors.end(); ++i) - if (i->hits == 0) + if (i->hits == 0 && i->fullName != "*") throw Error(format("selector `%1%' matches no derivations") % i->fullName); @@ -418,12 +418,18 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems, } +static bool isPath(const string & s) +{ + return s.find('/') != string::npos; +} + + static void queryInstSources(EvalState & state, const InstallSourceInfo & instSource, const Strings & args, DrvInfos & elems, bool newestOnly) { InstallSourceType type = instSource.type; - if (type == srcUnknown && args.size() > 0 && args.front()[0] == '/') + if (type == srcUnknown && args.size() > 0 && isPath(args.front())) type = srcStorePaths; switch (type) { @@ -475,23 +481,23 @@ static void queryInstSources(EvalState & state, for (Strings::const_iterator i = args.begin(); i != args.end(); ++i) { - assertStorePath(*i); + Path path = followLinksToStorePath(*i); DrvInfo elem; elem.attrs = boost::shared_ptr(new ATermMap(0)); /* ugh... */ - string name = baseNameOf(*i); + string name = baseNameOf(path); string::size_type dash = name.find('-'); if (dash != string::npos) name = string(name, dash + 1); - if (isDerivation(*i)) { - elem.setDrvPath(*i); - elem.setOutPath(findOutput(derivationFromPath(*i), "out")); + if (isDerivation(path)) { + elem.setDrvPath(path); + elem.setOutPath(findOutput(derivationFromPath(path), "out")); if (name.size() >= drvExtension.size() && string(name, name.size() - drvExtension.size()) == drvExtension) name = string(name, 0, name.size() - drvExtension.size()); } - else elem.setOutPath(*i); + else elem.setOutPath(path); elem.name = name; @@ -811,7 +817,7 @@ static void opSet(Globals & globals, } -static void uninstallDerivations(Globals & globals, DrvNames & selectors, +static void uninstallDerivations(Globals & globals, Strings & selectors, Path & profile) { PathLocks lock; @@ -824,11 +830,13 @@ static void uninstallDerivations(Globals & globals, DrvNames & selectors, { DrvName drvName(i->name); bool found = false; - for (DrvNames::iterator j = selectors.begin(); - j != selectors.end(); ++j) - if (j->matches(drvName)) { - printMsg(lvlInfo, - format("uninstalling `%1%'") % i->name); + for (Strings::iterator j = selectors.begin(); j != selectors.end(); ++j) + /* !!! the repeated calls to followLinksToStorePath() are + expensive, should pre-compute them. */ + if ((isPath(*j) && i->queryOutPath(globals.state) == followLinksToStorePath(*j)) + || DrvName(*j).matches(drvName)) + { + printMsg(lvlInfo, format("uninstalling `%1%'") % i->name); found = true; break; } @@ -847,11 +855,7 @@ static void opUninstall(Globals & globals, { if (opFlags.size() > 0) throw UsageError(format("unknown flag `%1%'") % opFlags.front()); - - DrvNames drvNames = drvNamesFromArgs(opArgs); - - uninstallDerivations(globals, drvNames, - globals.profile); + uninstallDerivations(globals, opArgs, globals.profile); } -- cgit 1.4.1