* 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue