Share code between scopedImport and import
In addition to reducing duplication, this fixes both import from derivation and import of derivation for scopedImport
This commit is contained in:
		
							parent
							
								
									61c464f252
								
							
						
					
					
						commit
						a8fb575c98
					
				
					 1 changed files with 45 additions and 43 deletions
				
			
		|  | @ -39,28 +39,31 @@ std::pair<string, string> decodeContext(const string & s) | ||||||
| 
 | 
 | ||||||
| /* 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_import(EvalState & state, const Pos & pos, Value * * args, Value & v) | static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args, Value & v) | ||||||
| { | { | ||||||
|     PathSet context; |     PathSet context; | ||||||
|     Path path = state.coerceToPath(pos, *args[0], context); |     Path path = state.coerceToPath(pos, *args[1], context); | ||||||
| 
 | 
 | ||||||
|     foreach (PathSet::iterator, i, context) { |     PathSet drvs; | ||||||
|         Path ctx = decodeContext(*i).first; |     for (auto & i : context) { | ||||||
|  |         std::pair<string, string> decoded = decodeContext(i); | ||||||
|  |         Path ctx = decoded.first; | ||||||
|         assert(isStorePath(ctx)); |         assert(isStorePath(ctx)); | ||||||
|         if (!store->isValidPath(ctx)) |         if (!store->isValidPath(ctx)) | ||||||
|             throw EvalError(format("cannot import `%1%', since path `%2%' is not valid, at %3%") |             throw EvalError(format("cannot import `%1%', since path `%2%' is not valid, at %3%") | ||||||
|                 % path % ctx % pos); |                 % path % ctx % pos); | ||||||
|         if (isDerivation(ctx)) |         if (isDerivation(ctx)) | ||||||
|  |             drvs.insert(decoded.first + "!" + decoded.second); | ||||||
|  |     } | ||||||
|  |     if (!drvs.empty()) { | ||||||
|         try { |         try { | ||||||
|             /* For performance, prefetch all substitute info. */ |             /* For performance, prefetch all substitute info. */ | ||||||
|             PathSet willBuild, willSubstitute, unknown; |             PathSet willBuild, willSubstitute, unknown; | ||||||
|             unsigned long long downloadSize, narSize; |             unsigned long long downloadSize, narSize; | ||||||
|                 queryMissing(*store, singleton<PathSet>(ctx), |             queryMissing(*store, drvs, | ||||||
|                 willBuild, willSubstitute, unknown, downloadSize, narSize); |                 willBuild, willSubstitute, unknown, downloadSize, narSize); | ||||||
| 
 | 
 | ||||||
|                 /* !!! If using a substitute, we only need to fetch
 |             store->buildPaths(drvs); | ||||||
|                    the selected output of this derivation. */ |  | ||||||
|                 store->buildPaths(singleton<PathSet>(ctx)); |  | ||||||
|         } catch (Error & e) { |         } catch (Error & e) { | ||||||
|             throw ImportError(e.msg()); |             throw ImportError(e.msg()); | ||||||
|         } |         } | ||||||
|  | @ -88,17 +91,10 @@ static void prim_import(EvalState & state, const Pos & pos, Value * * args, Valu | ||||||
|         mkApp(v, fun, w); |         mkApp(v, fun, w); | ||||||
|         state.forceAttrs(v, pos); |         state.forceAttrs(v, pos); | ||||||
|     } else { |     } else { | ||||||
|         state.evalFile(path, v); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args, Value & v) |  | ||||||
| { |  | ||||||
|     PathSet context; |  | ||||||
|         state.forceAttrs(*args[0]); |         state.forceAttrs(*args[0]); | ||||||
|     Path path = resolveExprPath(state.coerceToPath(pos, *args[1], context)); |         if (args[0]->attrs->empty()) | ||||||
| 
 |             state.evalFile(path, v); | ||||||
|  |         else { | ||||||
|             Env * env = &state.allocEnv(args[0]->attrs->size()); |             Env * env = &state.allocEnv(args[0]->attrs->size()); | ||||||
|             env->up = &state.baseEnv; |             env->up = &state.baseEnv; | ||||||
| 
 | 
 | ||||||
|  | @ -111,9 +107,11 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path); |             startNest(nest, lvlTalkative, format("evaluating file `%1%'") % path); | ||||||
|     Expr * e = state.parseExprFromFile(path, staticEnv); |             Expr * e = state.parseExprFromFile(resolveExprPath(path), staticEnv); | ||||||
| 
 | 
 | ||||||
|             e->eval(state, *env, v); |             e->eval(state, *env, v); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -1301,8 +1299,12 @@ void EvalState::createBaseEnv() | ||||||
|     addConstant("__langVersion", v); |     addConstant("__langVersion", v); | ||||||
| 
 | 
 | ||||||
|     // Miscellaneous
 |     // Miscellaneous
 | ||||||
|     addPrimOp("import", 1, prim_import); |  | ||||||
|     addPrimOp("scopedImport", 2, prim_scopedImport); |     addPrimOp("scopedImport", 2, prim_scopedImport); | ||||||
|  |     Value * v2 = allocValue(); | ||||||
|  |     mkAttrs(*v2, 0); | ||||||
|  |     mkApp(v, *baseEnv.values[baseEnvDispl - 1], *v2); | ||||||
|  |     forceValue(v); | ||||||
|  |     addConstant("import", v); | ||||||
|     addPrimOp("__typeOf", 1, prim_typeOf); |     addPrimOp("__typeOf", 1, prim_typeOf); | ||||||
|     addPrimOp("isNull", 1, prim_isNull); |     addPrimOp("isNull", 1, prim_isNull); | ||||||
|     addPrimOp("__isFunction", 1, prim_isFunction); |     addPrimOp("__isFunction", 1, prim_isFunction); | ||||||
|  | @ -1388,7 +1390,7 @@ void EvalState::createBaseEnv() | ||||||
|     mkList(v, searchPath.size()); |     mkList(v, searchPath.size()); | ||||||
|     int n = 0; |     int n = 0; | ||||||
|     for (auto & i : searchPath) { |     for (auto & i : searchPath) { | ||||||
|         Value * v2 = v.list.elems[n++] = allocValue(); |         v2 = v.list.elems[n++] = allocValue(); | ||||||
|         mkAttrs(*v2, 2); |         mkAttrs(*v2, 2); | ||||||
|         mkString(*allocAttr(*v2, symbols.create("path")), i.second); |         mkString(*allocAttr(*v2, symbols.create("path")), i.second); | ||||||
|         mkString(*allocAttr(*v2, symbols.create("prefix")), i.first); |         mkString(*allocAttr(*v2, symbols.create("prefix")), i.first); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue