* 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,
|
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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue