need any info on substitutable paths, we just call the substituters (such as download-using-manifests.pl) directly. This means that it's no longer necessary for nix-pull to register substitutes or for nix-channel to clear them, which makes those operations much faster (NIX-95). Also, we don't have to worry about keeping nix-pull manifests (in /nix/var/nix/manifests) and the database in sync with each other. The downside is that there is some overhead in calling an external program to get the substitutes info. For instance, "nix-env -qas" takes a bit longer. Abolishing the substitutes table also makes the logic in local-store.cc simpler, as we don't need to store info for invalid paths. On the downside, you cannot do things like "nix-store -qR" on a substitutable but invalid path (but nobody did that anyway). * Never catch interrupts (the Interrupted exception).
		
			
				
	
	
		
			92 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "misc.hh"
 | |
| #include "store-api.hh"
 | |
| #include "db.hh"
 | |
| 
 | |
| #include <aterm2.h>
 | |
| 
 | |
| 
 | |
| namespace nix {
 | |
| 
 | |
| 
 | |
| Derivation derivationFromPath(const Path & drvPath)
 | |
| {
 | |
|     assertStorePath(drvPath);
 | |
|     store->ensurePath(drvPath);
 | |
|     ATerm t = ATreadFromNamedFile(drvPath.c_str());
 | |
|     if (!t) throw Error(format("cannot read aterm from `%1%'") % drvPath);
 | |
|     return parseDerivation(t);
 | |
| }
 | |
| 
 | |
| 
 | |
| void computeFSClosure(const Path & storePath,
 | |
|     PathSet & paths, bool flipDirection)
 | |
| {
 | |
|     if (paths.find(storePath) != paths.end()) return;
 | |
|     paths.insert(storePath);
 | |
| 
 | |
|     PathSet references;
 | |
|     if (flipDirection)
 | |
|         store->queryReferrers(storePath, references);
 | |
|     else
 | |
|         store->queryReferences(storePath, references);
 | |
| 
 | |
|     for (PathSet::iterator i = references.begin();
 | |
|          i != references.end(); ++i)
 | |
|         computeFSClosure(*i, paths, flipDirection);
 | |
| }
 | |
| 
 | |
| 
 | |
| Path findOutput(const Derivation & drv, string id)
 | |
| {
 | |
|     for (DerivationOutputs::const_iterator i = drv.outputs.begin();
 | |
|          i != drv.outputs.end(); ++i)
 | |
|         if (i->first == id) return i->second.path;
 | |
|     throw Error(format("derivation has no output `%1%'") % id);
 | |
| }
 | |
| 
 | |
| 
 | |
| void queryMissing(const PathSet & targets,
 | |
|     PathSet & willBuild, PathSet & willSubstitute)
 | |
| {
 | |
|     PathSet todo(targets.begin(), targets.end()), done;
 | |
| 
 | |
|     while (!todo.empty()) {
 | |
|         Path p = *(todo.begin());
 | |
|         todo.erase(p);
 | |
|         if (done.find(p) != done.end()) continue;
 | |
|         done.insert(p);
 | |
| 
 | |
|         if (isDerivation(p)) {
 | |
|             if (!store->isValidPath(p)) continue;
 | |
|             Derivation drv = derivationFromPath(p);
 | |
| 
 | |
|             bool mustBuild = false;
 | |
|             for (DerivationOutputs::iterator i = drv.outputs.begin();
 | |
|                  i != drv.outputs.end(); ++i)
 | |
|                 if (!store->isValidPath(i->second.path) && !store->hasSubstitutes(i->second.path))
 | |
|                     mustBuild = true;
 | |
| 
 | |
|             if (mustBuild) {
 | |
|                 willBuild.insert(p);
 | |
|                 todo.insert(drv.inputSrcs.begin(), drv.inputSrcs.end());
 | |
|                 for (DerivationInputs::iterator i = drv.inputDrvs.begin();
 | |
|                      i != drv.inputDrvs.end(); ++i)
 | |
|                     todo.insert(i->first);
 | |
|             } else 
 | |
|                 for (DerivationOutputs::iterator i = drv.outputs.begin();
 | |
|                      i != drv.outputs.end(); ++i)
 | |
|                     todo.insert(i->second.path);
 | |
|         }
 | |
| 
 | |
|         else {
 | |
|             if (store->isValidPath(p)) continue;
 | |
|             if (store->hasSubstitutes(p))
 | |
|                 willSubstitute.insert(p);
 | |
|             // XXX call the substituters
 | |
|             // store->queryReferences(p, todo);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
|  
 | |
| }
 |