* 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:
parent
58fc420b36
commit
7a3e715980
2 changed files with 64 additions and 10 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue