Optionally ignore null-valued derivation attributes
This allows adding attributes like attr = if stdenv.system == "bla" then something else null; without changing the resulting derivation on non-<bla> platforms. We once considered adding a special "ignore" value for this purpose, but using null seems more elegant.
This commit is contained in:
		
							parent
							
								
									8b8ee53bc7
								
							
						
					
					
						commit
						6c98e6a5de
					
				
					 3 changed files with 24 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -139,6 +139,7 @@ EvalState::EvalState()
 | 
			
		|||
    , sSystem(symbols.create("system"))
 | 
			
		||||
    , sOverrides(symbols.create("__overrides"))
 | 
			
		||||
    , sOutputName(symbols.create("outputName"))
 | 
			
		||||
    , sIgnoreNulls(symbols.create("__ignoreNulls"))
 | 
			
		||||
    , baseEnv(allocEnv(128))
 | 
			
		||||
    , baseEnvDispl(0)
 | 
			
		||||
    , staticBaseEnv(false, 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -93,7 +93,7 @@ public:
 | 
			
		|||
    SymbolTable symbols;
 | 
			
		||||
 | 
			
		||||
    const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName,
 | 
			
		||||
        sSystem, sOverrides, sOutputName;
 | 
			
		||||
        sSystem, sOverrides, sOutputName, sIgnoreNulls;
 | 
			
		||||
 | 
			
		||||
    /* If set, force copying files to the Nix store even if they
 | 
			
		||||
       already exist there. */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -310,16 +310,22 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
 | 
			
		|||
        throw EvalError("required attribute `name' missing");
 | 
			
		||||
    string drvName;
 | 
			
		||||
    Pos & posDrvName(*attr->pos);
 | 
			
		||||
    try {        
 | 
			
		||||
    try {
 | 
			
		||||
        drvName = state.forceStringNoCtx(*attr->value);
 | 
			
		||||
    } catch (Error & e) {
 | 
			
		||||
        e.addPrefix(format("while evaluating the derivation attribute `name' at %1%:\n") % posDrvName);
 | 
			
		||||
        throw;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /* Check whether null attributes should be ignored. */
 | 
			
		||||
    bool ignoreNulls = false;
 | 
			
		||||
    attr = args[0]->attrs->find(state.sIgnoreNulls);
 | 
			
		||||
    if (attr != args[0]->attrs->end())
 | 
			
		||||
        ignoreNulls = state.forceBool(*attr->value);
 | 
			
		||||
 | 
			
		||||
    /* Build the derivation expression by processing the attributes. */
 | 
			
		||||
    Derivation drv;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    PathSet context;
 | 
			
		||||
 | 
			
		||||
    string outputHash, outputHashAlgo;
 | 
			
		||||
| 
						 | 
				
			
			@ -329,11 +335,17 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
 | 
			
		|||
    outputs.insert("out");
 | 
			
		||||
 | 
			
		||||
    foreach (Bindings::iterator, i, *args[0]->attrs) {
 | 
			
		||||
        if (i->name == state.sIgnoreNulls) continue;
 | 
			
		||||
        string key = i->name;
 | 
			
		||||
        startNest(nest, lvlVomit, format("processing attribute `%1%'") % key);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
 | 
			
		||||
            if (ignoreNulls) {
 | 
			
		||||
                state.forceValue(*i->value);
 | 
			
		||||
                if (i->value->type == tNull) continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* The `args' attribute is special: it supplies the
 | 
			
		||||
               command-line arguments to the builder. */
 | 
			
		||||
            if (key == "args") {
 | 
			
		||||
| 
						 | 
				
			
			@ -358,7 +370,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
 | 
			
		|||
                else if (key == "outputHash") outputHash = s;
 | 
			
		||||
                else if (key == "outputHashAlgo") outputHashAlgo = s;
 | 
			
		||||
                else if (key == "outputHashMode") {
 | 
			
		||||
                    if (s == "recursive") outputHashRecursive = true; 
 | 
			
		||||
                    if (s == "recursive") outputHashRecursive = true;
 | 
			
		||||
                    else if (s == "flat") outputHashRecursive = false;
 | 
			
		||||
                    else throw EvalError(format("invalid value `%1%' for `outputHashMode' attribute") % s);
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -390,13 +402,13 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
 | 
			
		|||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /* Everything in the context of the strings in the derivation
 | 
			
		||||
       attributes should be added as dependencies of the resulting
 | 
			
		||||
       derivation. */
 | 
			
		||||
    foreach (PathSet::iterator, i, context) {
 | 
			
		||||
        Path path = *i;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        /* Paths marked with `=' denote that the path of a derivation
 | 
			
		||||
           is explicitly passed to the builder.  Since that allows the
 | 
			
		||||
           builder to gain access to every path in the dependency
 | 
			
		||||
| 
						 | 
				
			
			@ -433,7 +445,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
 | 
			
		|||
        else
 | 
			
		||||
            drv.inputSrcs.insert(path);
 | 
			
		||||
    }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
    /* Do we have all required attributes? */
 | 
			
		||||
    if (drv.builder == "")
 | 
			
		||||
        throw EvalError("required attribute `builder' missing");
 | 
			
		||||
| 
						 | 
				
			
			@ -450,14 +462,14 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
 | 
			
		|||
        /* Handle fixed-output derivations. */
 | 
			
		||||
        if (outputs.size() != 1 || *(outputs.begin()) != "out")
 | 
			
		||||
            throw Error("multiple outputs are not supported in fixed-output derivations");
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        HashType ht = parseHashType(outputHashAlgo);
 | 
			
		||||
        if (ht == htUnknown)
 | 
			
		||||
            throw EvalError(format("unknown hash algorithm `%1%'") % outputHashAlgo);
 | 
			
		||||
        Hash h = parseHash16or32(ht, outputHash);
 | 
			
		||||
        outputHash = printHash(h);
 | 
			
		||||
        if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        Path outPath = makeFixedOutputPath(outputHashRecursive, ht, h, drvName);
 | 
			
		||||
        drv.env["out"] = outPath;
 | 
			
		||||
        drv.outputs["out"] = DerivationOutput(outPath, outputHashAlgo, outputHash);
 | 
			
		||||
| 
						 | 
				
			
			@ -477,7 +489,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
 | 
			
		|||
        /* Use the masked derivation expression to compute the output
 | 
			
		||||
           path. */
 | 
			
		||||
        Hash h = hashDerivationModulo(*store, drv);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        foreach (DerivationOutputs::iterator, i, drv.outputs)
 | 
			
		||||
            if (i->second.path == "") {
 | 
			
		||||
                Path outPath = makeOutputPath(i->first, h, drvName);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue