2 #include "store-api.hh"
3 #include "local-store.hh"
10 Derivation
derivationFromPath(StoreAPI
& store
, const Path
& drvPath
)
12 assertStorePath(drvPath
);
13 store
.ensurePath(drvPath
);
14 return readDerivation(drvPath
);
18 void computeFSClosure(StoreAPI
& store
, const Path
& path
,
19 PathSet
& paths
, bool flipDirection
, bool includeOutputs
, bool includeDerivers
)
21 if (paths
.find(path
) != paths
.end()) return;
27 store
.queryReferrers(path
, edges
);
30 PathSet derivers
= store
.queryValidDerivers(path
);
31 foreach (PathSet::iterator
, i
, derivers
)
35 if (includeDerivers
&& isDerivation(path
)) {
36 PathSet outputs
= store
.queryDerivationOutputs(path
);
37 foreach (PathSet::iterator
, i
, outputs
)
38 if (store
.isValidPath(*i
) && store
.queryDeriver(*i
) == path
)
43 store
.queryReferences(path
, edges
);
45 if (includeOutputs
&& isDerivation(path
)) {
46 PathSet outputs
= store
.queryDerivationOutputs(path
);
47 foreach (PathSet::iterator
, i
, outputs
)
48 if (store
.isValidPath(*i
)) edges
.insert(*i
);
51 if (includeDerivers
) {
52 Path deriver
= store
.queryDeriver(path
);
53 if (store
.isValidPath(deriver
)) edges
.insert(deriver
);
57 foreach (PathSet::iterator
, i
, edges
)
58 computeFSClosure(store
, *i
, paths
, flipDirection
, includeOutputs
, includeDerivers
);
62 Path
findOutput(const Derivation
& drv
, string id
)
64 foreach (DerivationOutputs::const_iterator
, i
, drv
.outputs
)
65 if (i
->first
== id
) return i
->second
.path
;
66 throw Error(format("derivation has no output `%1%'") % id
);
70 static void dfsVisit(StoreAPI
& store
, const PathSet
& paths
,
71 const Path
& path
, PathSet
& visited
, Paths
& sorted
,
74 if (parents
.find(path
) != parents
.end())
75 throw BuildError(format("cycle detected in the references of `%1%'") % path
);
77 if (visited
.find(path
) != visited
.end()) return;
82 if (store
.isValidPath(path
))
83 store
.queryReferences(path
, references
);
85 foreach (PathSet::iterator
, i
, references
)
86 /* Don't traverse into paths that don't exist. That can
87 happen due to substitutes for non-existent paths. */
88 if (*i
!= path
&& paths
.find(*i
) != paths
.end())
89 dfsVisit(store
, paths
, *i
, visited
, sorted
, parents
);
91 sorted
.push_front(path
);
96 Paths
topoSortPaths(StoreAPI
& store
, const PathSet
& paths
)
99 PathSet visited
, parents
;
100 foreach (PathSet::const_iterator
, i
, paths
)
101 dfsVisit(store
, paths
, *i
, visited
, sorted
, parents
);