* 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.
This commit is contained in:
Eelco Dolstra 2006-02-17 17:47:54 +00:00
parent 58fc420b36
commit 7a3e715980
2 changed files with 64 additions and 10 deletions

View file

@ -208,13 +208,16 @@ static void createUserEnv(EvalState & state, const DrvInfos & elems,
} }
static DrvInfos filterBySelector(const DrvInfos & allElems, static DrvInfos filterBySelector(EvalState & state,
const Strings & args) const DrvInfos & allElems,
const Strings & args, bool newestOnly)
{ {
DrvNames selectors = drvNamesFromArgs(args); DrvNames selectors = drvNamesFromArgs(args);
DrvInfos elems; DrvInfos elems;
PathSet done;
#if 0
/* Filter out the ones we're not interested in. */ /* Filter out the ones we're not interested in. */
for (DrvInfos::const_iterator i = allElems.begin(); for (DrvInfos::const_iterator i = allElems.begin();
i != allElems.end(); ++i) 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. */ /* Check that all selectors have been used. */
for (DrvNames::iterator i = selectors.begin(); for (DrvNames::iterator i = selectors.begin();
@ -243,7 +296,7 @@ static DrvInfos filterBySelector(const DrvInfos & allElems,
static void queryInstSources(EvalState & state, static void queryInstSources(EvalState & state,
const InstallSourceInfo & instSource, const Strings & args, const InstallSourceInfo & instSource, const Strings & args,
DrvInfos & elems) DrvInfos & elems, bool newestOnly)
{ {
InstallSourceType type = instSource.type; InstallSourceType type = instSource.type;
if (type == srcUnknown && args.size() > 0 && args.front()[0] == '/') if (type == srcUnknown && args.size() > 0 && args.front()[0] == '/')
@ -263,7 +316,7 @@ static void queryInstSources(EvalState & state,
loadDerivations(state, instSource.nixExprPath, loadDerivations(state, instSource.nixExprPath,
instSource.systemFilter, allElems); instSource.systemFilter, allElems);
elems = filterBySelector(allElems, args); elems = filterBySelector(state, allElems, args, newestOnly);
break; break;
} }
@ -328,8 +381,9 @@ static void queryInstSources(EvalState & state,
user environment. These are then filtered as in the user environment. These are then filtered as in the
`srcNixExprDrvs' case. */ `srcNixExprDrvs' case. */
case srcProfile: { case srcProfile: {
elems = filterBySelector( elems = filterBySelector(state,
queryInstalled(state, instSource.profile), args); queryInstalled(state, instSource.profile),
args, newestOnly);
break; break;
} }
} }
@ -343,7 +397,7 @@ static void installDerivations(Globals & globals,
/* Get the set of user environment elements to be installed. */ /* Get the set of user environment elements to be installed. */
DrvInfos newElems; DrvInfos newElems;
queryInstSources(globals.state, globals.instSource, args, newElems); queryInstSources(globals.state, globals.instSource, args, newElems, true);
StringSet newNames; StringSet newNames;
for (DrvInfos::iterator i = newElems.begin(); i != newElems.end(); ++i) 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. */ /* Fetch all derivations from the input file. */
DrvInfos availElems; DrvInfos availElems;
queryInstSources(globals.state, globals.instSource, args, availElems); queryInstSources(globals.state, globals.instSource, args, availElems, false);
/* Go through all installed derivations. */ /* Go through all installed derivations. */
DrvInfos newElems; DrvInfos newElems;

View file

@ -82,7 +82,7 @@ test "$($nixenv -p $profiles/test -q | wc -l)" -eq 0
# Installing "foo" should only install the newest foo. # Installing "foo" should only install the newest foo.
$nixenv -p $profiles/test -f ./user-envs.nix -i 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 $nixenv -p $profiles/test -q | grep -q foo-2.0
# On the other hand, this should install both (and should fail due to # 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. # 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 -e '*'
$nixenv -p $profiles/test -f ./user-envs.nix -i '*' $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 foo-2.0
$nixenv -p $profiles/test -q | grep -q bar-0.1.1 $nixenv -p $profiles/test -q | grep -q bar-0.1.1