about summary refs log tree commit diff
path: root/src/nix-env
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2006-02-17T17·47+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2006-02-17T17·47+0000
commit7a3e715980c3fcd84b6d12f54a18a920ebba208d (patch)
treedd936690c8fa0e8397db3253adc1d8c302ce5072 /src/nix-env
parent58fc420b365b8f8d6faaa332ab3ba4e97ad584e0 (diff)
* Fix for NIX-31: "nix-env -i foo" installing all derivations named
  foo.  Now it will only install the one with the highest version
  number.

Diffstat (limited to 'src/nix-env')
-rw-r--r--src/nix-env/main.cc70
1 files changed, 62 insertions, 8 deletions
diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc
index 4acbb6db0320..985918c47094 100644
--- a/src/nix-env/main.cc
+++ b/src/nix-env/main.cc
@@ -208,13 +208,16 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
 }
 
 
-static DrvInfos filterBySelector(const DrvInfos & allElems,
-    const Strings & args)
+static DrvInfos filterBySelector(EvalState & state,
+    const DrvInfos & allElems,
+    const Strings & args, bool newestOnly)
 {
     DrvNames selectors = drvNamesFromArgs(args);
 
     DrvInfos elems;
+    PathSet done;
 
+#if 0    
     /* Filter out the ones we're not interested in. */
     for (DrvInfos::const_iterator i = allElems.begin();
          i != allElems.end(); ++i)
@@ -229,6 +232,56 @@ static DrvInfos filterBySelector(const DrvInfos & allElems,
             }
         }
     }
+#endif
+
+    for (DrvNames::iterator i = selectors.begin();
+         i != selectors.end(); ++i)
+    {
+        DrvInfos matches;
+        for (DrvInfos::const_iterator j = allElems.begin();
+             j != allElems.end(); ++j)
+        {
+            DrvName drvName(j->name);
+            if (i->matches(drvName)) {
+                i->hits++;
+                matches.push_back(*j);
+            }
+        }
+
+        if (newestOnly) {
+
+            /* Map from package names to derivations. */
+            map<string, DrvInfo> newest;
+
+            for (DrvInfos::const_iterator j = matches.begin();
+                 j != matches.end(); ++j)
+            {
+                DrvName drvName(j->name);
+                map<string, DrvInfo>::iterator k = newest.find(drvName.name);
+                if (k != newest.end())
+                    if (compareVersions(drvName.version, DrvName(k->second.name).version) > 0)
+                        newest[drvName.name] = *j;
+                    else
+                        ;
+                else
+                    newest[drvName.name] = *j;
+            }
+
+            matches.clear();
+            for (map<string, DrvInfo>::iterator j = newest.begin();
+                 j != newest.end(); ++j)
+                matches.push_back(j->second);
+        }
+
+        /* Insert only those elements in the final list that we
+           haven't inserted before. */
+        for (DrvInfos::const_iterator j = matches.begin();
+             j != matches.end(); ++j)
+            if (done.find(j->queryOutPath(state)) == done.end()) {
+                done.insert(j->queryOutPath(state));
+                elems.push_back(*j);
+            }
+    }
             
     /* Check that all selectors have been used. */
     for (DrvNames::iterator i = selectors.begin();
@@ -243,7 +296,7 @@ static DrvInfos filterBySelector(const DrvInfos & allElems,
 
 static void queryInstSources(EvalState & state,
     const InstallSourceInfo & instSource, const Strings & args,
-    DrvInfos & elems)
+    DrvInfos & elems, bool newestOnly)
 {
     InstallSourceType type = instSource.type;
     if (type == srcUnknown && args.size() > 0 && args.front()[0] == '/')
@@ -263,7 +316,7 @@ static void queryInstSources(EvalState & state,
             loadDerivations(state, instSource.nixExprPath,
                 instSource.systemFilter, allElems);
 
-            elems = filterBySelector(allElems, args);
+            elems = filterBySelector(state, allElems, args, newestOnly);
     
             break;
         }
@@ -328,8 +381,9 @@ static void queryInstSources(EvalState & state,
            user environment.  These are then filtered as in the
            `srcNixExprDrvs' case. */
         case srcProfile: {
-            elems = filterBySelector(
-                queryInstalled(state, instSource.profile), args);
+            elems = filterBySelector(state,
+                queryInstalled(state, instSource.profile),
+                args, newestOnly);
             break;
         }
     }
@@ -343,7 +397,7 @@ static void installDerivations(Globals & globals,
 
     /* Get the set of user environment elements to be installed. */
     DrvInfos newElems;
-    queryInstSources(globals.state, globals.instSource, args, newElems);
+    queryInstSources(globals.state, globals.instSource, args, newElems, true);
 
     StringSet newNames;
     for (DrvInfos::iterator i = newElems.begin(); i != newElems.end(); ++i)
@@ -406,7 +460,7 @@ static void upgradeDerivations(Globals & globals,
 
     /* Fetch all derivations from the input file. */
     DrvInfos availElems;
-    queryInstSources(globals.state, globals.instSource, args, availElems);
+    queryInstSources(globals.state, globals.instSource, args, availElems, false);
 
     /* Go through all installed derivations. */
     DrvInfos newElems;