* Unify the treatment of sources copied to the store, and recursive
SHA-256 outputs of fixed-output derivations.  I.e. they now produce
  the same store path:
  $ nix-store --add x
  /nix/store/j2fq9qxvvxgqymvpszhs773ncci45xsj-x
  $ nix-store --add-fixed --recursive sha256 x
  /nix/store/j2fq9qxvvxgqymvpszhs773ncci45xsj-x
  the latter being the same as the path that a derivation
    derivation {
      name = "x";
      outputHashAlgo = "sha256";
      outputHashMode = "recursive";
      outputHash = "...";
      ...
    };
  produces.
  This does change the output path for such fixed-output derivations.
  Fortunately they are quite rare.  The most common use is fetchsvn
  calls with SHA-256 hashes.  (There are a handful of those is
  Nixpkgs, mostly unstable development packages.)
  
* Documented the computation of store paths (in store-api.cc).
			
			
This commit is contained in:
		
							parent
							
								
									09bc0c502c
								
							
						
					
					
						commit
						64519cfd65
					
				
					 12 changed files with 191 additions and 79 deletions
				
			
		|  | @ -215,6 +215,14 @@ static Expr prim_trace(EvalState & state, const ATermVector & args) | |||
|  *************************************************************/ | ||||
| 
 | ||||
| 
 | ||||
| static bool isFixedOutput(const Derivation & drv) | ||||
| { | ||||
|     return drv.outputs.size() == 1 && | ||||
|         drv.outputs.begin()->first == "out" && | ||||
|         drv.outputs.begin()->second.hash != ""; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Returns the hash of a derivation modulo fixed-output
 | ||||
|    subderivations.  A fixed-output derivation is a derivation with one | ||||
|    output (`out') for which an expected hash and hash algorithm are | ||||
|  | @ -227,27 +235,23 @@ static Expr prim_trace(EvalState & state, const ATermVector & args) | |||
|    function, we do not want to rebuild everything depending on it | ||||
|    (after all, (the hash of) the file being downloaded is unchanged). | ||||
|    So the *output paths* should not change.  On the other hand, the | ||||
|    *derivation store expression paths* should change to reflect the | ||||
|    new dependency graph. | ||||
|    *derivation paths* should change to reflect the new dependency | ||||
|    graph. | ||||
| 
 | ||||
|    That's what this function does: it returns a hash which is just the | ||||
|    of the derivation ATerm, except that any input store expression | ||||
|    hash of the derivation ATerm, except that any input derivation | ||||
|    paths have been replaced by the result of a recursive call to this | ||||
|    function, and that for fixed-output derivations we return | ||||
|    (basically) its outputHash. */ | ||||
|    function, and that for fixed-output derivations we return a hash of | ||||
|    its output path. */ | ||||
| static Hash hashDerivationModulo(EvalState & state, Derivation drv) | ||||
| { | ||||
|     /* Return a fixed hash for fixed-output derivations. */ | ||||
|     if (drv.outputs.size() == 1) { | ||||
|     if (isFixedOutput(drv)) { | ||||
|         DerivationOutputs::const_iterator i = drv.outputs.begin(); | ||||
|         if (i->first == "out" && | ||||
|             i->second.hash != "") | ||||
|         { | ||||
|             return hashString(htSHA256, "fixed:out:" | ||||
|                 + i->second.hashAlgo + ":" | ||||
|                 + i->second.hash + ":" | ||||
|                 + i->second.path); | ||||
|         } | ||||
|         return hashString(htSHA256, "fixed:out:" | ||||
|             + i->second.hashAlgo + ":" | ||||
|             + i->second.hash + ":" | ||||
|             + i->second.path); | ||||
|     } | ||||
| 
 | ||||
|     /* For other derivations, replace the inputs paths with recursive
 | ||||
|  | @ -304,8 +308,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) | |||
|      | ||||
|     PathSet context; | ||||
| 
 | ||||
|     string outputHash; | ||||
|     string outputHashAlgo; | ||||
|     string outputHash, outputHashAlgo; | ||||
|     bool outputHashRecursive = false; | ||||
| 
 | ||||
|     for (ATermMap::const_iterator i = attrs.begin(); i != attrs.end(); ++i) { | ||||
|  | @ -380,6 +383,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) | |||
|         throw EvalError("required attribute `system' missing"); | ||||
| 
 | ||||
|     /* If an output hash was given, check it. */ | ||||
|     Path outPath; | ||||
|     if (outputHash == "") | ||||
|         outputHashAlgo = ""; | ||||
|     else { | ||||
|  | @ -398,6 +402,7 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) | |||
|                 % outputHash % outputHashAlgo); | ||||
|         string s = outputHash; | ||||
|         outputHash = printHash(h); | ||||
|         outPath = makeFixedOutputPath(outputHashRecursive, outputHashAlgo, h, drvName); | ||||
|         if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo; | ||||
|     } | ||||
| 
 | ||||
|  | @ -413,13 +418,12 @@ static Expr prim_derivationStrict(EvalState & state, const ATermVector & args) | |||
|        have an empty value.  This ensures that changes in the set of | ||||
|        output names do get reflected in the hash. */ | ||||
|     drv.env["out"] = ""; | ||||
|     drv.outputs["out"] = | ||||
|         DerivationOutput("", outputHashAlgo, outputHash); | ||||
|     drv.outputs["out"] = DerivationOutput("", outputHashAlgo, outputHash); | ||||
|          | ||||
|     /* Use the masked derivation expression to compute the output
 | ||||
|        path. */ | ||||
|     Path outPath = makeStorePath("output:out", | ||||
|         hashDerivationModulo(state, drv), drvName); | ||||
|     if (outPath == "") | ||||
|         outPath = makeStorePath("output:out", hashDerivationModulo(state, drv), drvName); | ||||
| 
 | ||||
|     /* Construct the final derivation store expression. */ | ||||
|     drv.env["out"] = outPath; | ||||
|  | @ -632,8 +636,8 @@ static Expr prim_filterSource(EvalState & state, const ATermVector & args) | |||
|     FilterFromExpr filter(state, args[0]); | ||||
| 
 | ||||
|     Path dstPath = readOnlyMode | ||||
|         ? computeStorePathForPath(path, false, false, "", filter).first | ||||
|         : store->addToStore(path, false, false, "", filter); | ||||
|         ? computeStorePathForPath(path, true, "sha256", filter).first | ||||
|         : store->addToStore(path, true, "sha256", filter); | ||||
| 
 | ||||
|     return makeStr(dstPath, singleton<PathSet>(dstPath)); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue