about summary refs log tree commit diff
path: root/src/nix-env
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2007-11-29T16·18+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2007-11-29T16·18+0000
commit633518628f48fb9c06bfd570eeca6f62696aba05 (patch)
tree33313707305a011265e30d4670264a9b7979d298 /src/nix-env
parent12d0a1eb753567bb2083aadb4ee3d325d3f29c70 (diff)
* 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.

Diffstat (limited to 'src/nix-env')
-rw-r--r--src/nix-env/nix-env.cc42
1 files changed, 23 insertions, 19 deletions
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index 3396b191fd62..1af1a2f536d1 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<ATermMap>(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);
 }