findFile: Realise the context of the path attributes
This commit is contained in:
		
							parent
							
								
									a8fb575c98
								
							
						
					
					
						commit
						718f20da6d
					
				
					 2 changed files with 51 additions and 24 deletions
				
			
		|  | @ -16,6 +16,7 @@ MakeError(ThrownError, AssertionError) | ||||||
| MakeError(Abort, EvalError) | MakeError(Abort, EvalError) | ||||||
| MakeError(TypeError, EvalError) | MakeError(TypeError, EvalError) | ||||||
| MakeError(ImportError, EvalError) // error building an imported derivation
 | MakeError(ImportError, EvalError) // error building an imported derivation
 | ||||||
|  | MakeError(FindError, EvalError) // error building a nix-path component
 | ||||||
| MakeError(UndefinedVarError, Error) | MakeError(UndefinedVarError, Error) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,6 +37,38 @@ std::pair<string, string> decodeContext(const string & s) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | struct InvalidPathError : EvalError | ||||||
|  | { | ||||||
|  |     Path path; | ||||||
|  |     InvalidPathError(const Path & path) : | ||||||
|  |         EvalError(format("path `%1%' is not valid") % path), path(path) {}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static void realiseContext(const PathSet & context) | ||||||
|  | { | ||||||
|  |     PathSet drvs; | ||||||
|  |     for (auto & i : context) { | ||||||
|  |         std::pair<string, string> decoded = decodeContext(i); | ||||||
|  |         Path ctx = decoded.first; | ||||||
|  |         assert(isStorePath(ctx)); | ||||||
|  |         if (!store->isValidPath(ctx)) | ||||||
|  |             throw InvalidPathError(ctx); | ||||||
|  |         if (isDerivation(ctx)) | ||||||
|  |             drvs.insert(decoded.first + "!" + decoded.second); | ||||||
|  |     } | ||||||
|  |     if (!drvs.empty()) { | ||||||
|  |         /* For performance, prefetch all substitute info. */ | ||||||
|  |         PathSet willBuild, willSubstitute, unknown; | ||||||
|  |         unsigned long long downloadSize, narSize; | ||||||
|  |         queryMissing(*store, drvs, | ||||||
|  |             willBuild, willSubstitute, unknown, downloadSize, narSize); | ||||||
|  | 
 | ||||||
|  |         store->buildPaths(drvs); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /* Load and evaluate an expression from path specified by the
 | /* Load and evaluate an expression from path specified by the
 | ||||||
|    argument. */ |    argument. */ | ||||||
| static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args, Value & v) | static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||||
|  | @ -44,29 +76,13 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     Path path = state.coerceToPath(pos, *args[1], context); |     Path path = state.coerceToPath(pos, *args[1], context); | ||||||
| 
 | 
 | ||||||
|     PathSet drvs; |     try { | ||||||
|     for (auto & i : context) { |         realiseContext(context); | ||||||
|         std::pair<string, string> decoded = decodeContext(i); |     } catch (InvalidPathError & e) { | ||||||
|         Path ctx = decoded.first; |         throw EvalError(format("cannot import `%1%', since path `%2%' is not valid, at %3%") | ||||||
|         assert(isStorePath(ctx)); |             % path % e.path % pos); | ||||||
|         if (!store->isValidPath(ctx)) |     } catch (Error & e) { | ||||||
|             throw EvalError(format("cannot import `%1%', since path `%2%' is not valid, at %3%") |         throw ImportError(e.msg()); | ||||||
|                 % path % ctx % pos); |  | ||||||
|         if (isDerivation(ctx)) |  | ||||||
|             drvs.insert(decoded.first + "!" + decoded.second); |  | ||||||
|     } |  | ||||||
|     if (!drvs.empty()) { |  | ||||||
|         try { |  | ||||||
|             /* For performance, prefetch all substitute info. */ |  | ||||||
|             PathSet willBuild, willSubstitute, unknown; |  | ||||||
|             unsigned long long downloadSize, narSize; |  | ||||||
|             queryMissing(*store, drvs, |  | ||||||
|                 willBuild, willSubstitute, unknown, downloadSize, narSize); |  | ||||||
| 
 |  | ||||||
|             store->buildPaths(drvs); |  | ||||||
|         } catch (Error & e) { |  | ||||||
|             throw ImportError(e.msg()); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (isStorePath(path) && store->isValidPath(path) && isDerivation(path)) { |     if (isStorePath(path) && store->isValidPath(path) && isDerivation(path)) { | ||||||
|  | @ -660,6 +676,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va | ||||||
| 
 | 
 | ||||||
|     SearchPath searchPath; |     SearchPath searchPath; | ||||||
| 
 | 
 | ||||||
|  |     PathSet context; | ||||||
|     for (unsigned int n = 0; n < args[0]->list.length; ++n) { |     for (unsigned int n = 0; n < args[0]->list.length; ++n) { | ||||||
|         Value & v2(*args[0]->list.elems[n]); |         Value & v2(*args[0]->list.elems[n]); | ||||||
|         state.forceAttrs(v2, pos); |         state.forceAttrs(v2, pos); | ||||||
|  | @ -672,13 +689,22 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va | ||||||
|         i = v2.attrs->find(state.symbols.create("path")); |         i = v2.attrs->find(state.symbols.create("path")); | ||||||
|         if (i == v2.attrs->end()) |         if (i == v2.attrs->end()) | ||||||
|             throw EvalError(format("attribute `path' missing, at %1%") % pos); |             throw EvalError(format("attribute `path' missing, at %1%") % pos); | ||||||
|         PathSet context; |  | ||||||
|         string path = state.coerceToPath(pos, *i->value, context); |         string path = state.coerceToPath(pos, *i->value, context); | ||||||
| 
 | 
 | ||||||
|         searchPath.push_back(std::pair<string, Path>(prefix, path)); |         searchPath.push_back(std::pair<string, Path>(prefix, path)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     string path = state.forceStringNoCtx(*args[1], pos); |     string path = state.forceStringNoCtx(*args[1], pos); | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |         realiseContext(context); | ||||||
|  |     } catch (InvalidPathError & e) { | ||||||
|  |         throw EvalError(format("cannot find `%1%', since path `%2%' is not valid, at %3%") | ||||||
|  |             % path % e.path % pos); | ||||||
|  |     } catch (Error & e) { | ||||||
|  |         throw FindError(e.msg()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     mkPath(v, state.findFile(searchPath, path).c_str()); |     mkPath(v, state.findFile(searchPath, path).c_str()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue