1 : #include "misc.hh"
2 : #include "store-api.hh"
3 : #include "local-store.hh"
4 :
5 : #include <aterm2.h>
6 :
7 :
8 : namespace nix {
9 :
10 :
11 440 : Derivation derivationFromPath(const Path & drvPath)
12 : {
13 440 : assertStorePath(drvPath);
14 440 : store->ensurePath(drvPath);
15 440 : ATerm t = ATreadFromNamedFile(drvPath.c_str());
16 440 : if (!t) throw Error(format("cannot read aterm from `%1%'") % drvPath);
17 440 : return parseDerivation(t);
18 : }
19 :
20 :
21 : void computeFSClosure(const Path & storePath,
22 406 : PathSet & paths, bool flipDirection)
23 : {
24 406 : if (paths.find(storePath) != paths.end()) return;
25 353 : paths.insert(storePath);
26 :
27 353 : PathSet references;
28 353 : if (flipDirection)
29 2 : store->queryReferrers(storePath, references);
30 : else
31 351 : store->queryReferences(storePath, references);
32 :
33 512 : for (PathSet::iterator i = references.begin();
34 : i != references.end(); ++i)
35 512 : computeFSClosure(*i, paths, flipDirection);
36 : }
37 :
38 :
39 57 : Path findOutput(const Derivation & drv, string id)
40 : {
41 57 : for (DerivationOutputs::const_iterator i = drv.outputs.begin();
42 : i != drv.outputs.end(); ++i)
43 57 : if (i->first == id) return i->second.path;
44 0 : throw Error(format("derivation has no output `%1%'") % id);
45 : }
46 :
47 :
48 : void queryMissing(const PathSet & targets,
49 : PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
50 64 : unsigned long long & downloadSize)
51 : {
52 64 : downloadSize = 0;
53 :
54 64 : PathSet todo(targets.begin(), targets.end()), done;
55 :
56 351 : while (!todo.empty()) {
57 223 : Path p = *(todo.begin());
58 223 : todo.erase(p);
59 321 : if (done.find(p) != done.end()) continue;
60 218 : done.insert(p);
61 :
62 218 : if (isDerivation(p)) {
63 118 : if (!store->isValidPath(p)) {
64 1 : unknown.insert(p);
65 : continue;
66 : }
67 117 : Derivation drv = derivationFromPath(p);
68 :
69 117 : bool mustBuild = false;
70 234 : for (DerivationOutputs::iterator i = drv.outputs.begin();
71 : i != drv.outputs.end(); ++i)
72 117 : if (!store->isValidPath(i->second.path) && !store->hasSubstitutes(i->second.path))
73 89 : mustBuild = true;
74 :
75 117 : if (mustBuild) {
76 89 : willBuild.insert(p);
77 89 : todo.insert(drv.inputSrcs.begin(), drv.inputSrcs.end());
78 143 : for (DerivationInputs::iterator i = drv.inputDrvs.begin();
79 : i != drv.inputDrvs.end(); ++i)
80 54 : todo.insert(i->first);
81 : } else
82 56 : for (DerivationOutputs::iterator i = drv.outputs.begin();
83 : i != drv.outputs.end(); ++i)
84 145 : todo.insert(i->second.path);
85 : }
86 :
87 : else {
88 100 : if (store->isValidPath(p)) continue;
89 8 : SubstitutablePathInfo info;
90 8 : if (store->querySubstitutablePathInfo(p, info)) {
91 8 : willSubstitute.insert(p);
92 8 : downloadSize += info.downloadSize;
93 8 : todo.insert(info.references.begin(), info.references.end());
94 : } else
95 0 : unknown.insert(p);
96 : }
97 64 : }
98 64 : }
99 :
100 0 :
101 1106 : }
|