aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nix-env/main.cc70
-rw-r--r--tests/user-envs.sh4
2 files changed, 64 insertions, 10 deletions
diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc
index 4acbb6db0..985918c47 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;
diff --git a/tests/user-envs.sh b/tests/user-envs.sh
index bd14f5108..59565cff0 100644
--- a/tests/user-envs.sh
+++ b/tests/user-envs.sh
@@ -82,7 +82,7 @@ test "$($nixenv -p $profiles/test -q | wc -l)" -eq 0
# Installing "foo" should only install the newest foo.
$nixenv -p $profiles/test -f ./user-envs.nix -i foo
-test "$($nixenv -p $profiles/test -q | grep foo- | wc)" -eq 1
+test "$($nixenv -p $profiles/test -q | grep foo- | wc -l)" -eq 1
$nixenv -p $profiles/test -q | grep -q foo-2.0
# On the other hand, this should install both (and should fail due to
@@ -93,6 +93,6 @@ if $nixenv -p $profiles/test -f ./user-envs.nix -i foo-1.0 foo-2.0; then false;
# Installing "*" should install one foo and one bar.
$nixenv -p $profiles/test -f ./user-envs.nix -e '*'
$nixenv -p $profiles/test -f ./user-envs.nix -i '*'
-test "$($nixenv -p $profiles/test -q | wc)" -eq 2
+test "$($nixenv -p $profiles/test -q | wc -l)" -eq 2
$nixenv -p $profiles/test -q | grep -q foo-2.0
$nixenv -p $profiles/test -q | grep -q bar-0.1.1