* Eliminate all uses of the global variable ‘store’ from libstore.

This should also fix:

    nix-instantiate: ./../boost/shared_ptr.hpp:254: T* boost::shared_ptr<T>::operator->() const [with T = nix::StoreAPI]: Assertion `px != 0' failed.

  which was caused by hashDerivationModulo() calling the ‘store’
  object (during store upgrades) before openStore() assigned it.
This commit is contained in:
Eelco Dolstra 2011-08-31 21:11:50 +00:00
parent 5bcdc7e351
commit 93227ff65c
15 changed files with 95 additions and 89 deletions

View file

@ -357,7 +357,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
runs. */ runs. */
if (path.at(0) == '=') { if (path.at(0) == '=') {
path = string(path, 1); path = string(path, 1);
PathSet refs; computeFSClosure(path, refs); PathSet refs; computeFSClosure(*store, path, refs);
foreach (PathSet::iterator, j, refs) { foreach (PathSet::iterator, j, refs) {
drv.inputSrcs.insert(*j); drv.inputSrcs.insert(*j);
if (isDerivation(*j)) if (isDerivation(*j))
@ -433,7 +433,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
/* Use the masked derivation expression to compute the output /* Use the masked derivation expression to compute the output
path. */ path. */
Hash h = hashDerivationModulo(drv); Hash h = hashDerivationModulo(*store, drv);
foreach (DerivationOutputs::iterator, i, drv.outputs) foreach (DerivationOutputs::iterator, i, drv.outputs)
if (i->second.path == "") { if (i->second.path == "") {
@ -444,7 +444,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
} }
/* Write the resulting term into the Nix store directory. */ /* Write the resulting term into the Nix store directory. */
Path drvPath = writeDerivation(drv, drvName); Path drvPath = writeDerivation(*store, drv, drvName);
printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'") printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'")
% drvName % drvPath); % drvName % drvPath);
@ -452,7 +452,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
/* Optimisation, but required in read-only mode! because in that /* Optimisation, but required in read-only mode! because in that
case we don't actually write store derivations, so we can't case we don't actually write store derivations, so we can't
read them later. */ read them later. */
drvHashes[drvPath] = hashDerivationModulo(drv); drvHashes[drvPath] = hashDerivationModulo(*store, drv);
state.mkAttrs(v, 1 + drv.outputs.size()); state.mkAttrs(v, 1 + drv.outputs.size());
mkString(*state.allocAttr(v, state.sDrvPath), drvPath, singleton<PathSet>("=" + drvPath)); mkString(*state.allocAttr(v, state.sDrvPath), drvPath, singleton<PathSet>("=" + drvPath));

View file

@ -52,11 +52,11 @@ void printGCWarning()
} }
void printMissing(const PathSet & paths) void printMissing(StoreAPI & store, const PathSet & paths)
{ {
unsigned long long downloadSize, narSize; unsigned long long downloadSize, narSize;
PathSet willBuild, willSubstitute, unknown; PathSet willBuild, willSubstitute, unknown;
queryMissing(paths, willBuild, willSubstitute, unknown, downloadSize, narSize); queryMissing(store, paths, willBuild, willSubstitute, unknown, downloadSize, narSize);
if (!willBuild.empty()) { if (!willBuild.empty()) {
printMsg(lvlInfo, format("these derivations will be built:")); printMsg(lvlInfo, format("these derivations will be built:"));

View file

@ -24,11 +24,13 @@ namespace nix {
MakeError(UsageError, nix::Error); MakeError(UsageError, nix::Error);
class StoreAPI;
/* Ugh. No better place to put this. */ /* Ugh. No better place to put this. */
Path makeRootName(const Path & gcRoot, int & counter); Path makeRootName(const Path & gcRoot, int & counter);
void printGCWarning(); void printGCWarning();
void printMissing(const PathSet & paths); void printMissing(StoreAPI & store, const PathSet & paths);
template<class N> N getIntArg(const string & opt, template<class N> N getIntArg(const string & opt,
Strings::iterator & i, const Strings::iterator & end) Strings::iterator & i, const Strings::iterator & end)

View file

@ -934,7 +934,7 @@ void DerivationGoal::haveDerivation()
assert(worker.store.isValidPath(drvPath)); assert(worker.store.isValidPath(drvPath));
/* Get the derivation. */ /* Get the derivation. */
drv = derivationFromPath(drvPath); drv = derivationFromPath(worker.store, drvPath);
foreach (DerivationOutputs::iterator, i, drv.outputs) foreach (DerivationOutputs::iterator, i, drv.outputs)
worker.store.addTempRoot(i->second.path); worker.store.addTempRoot(i->second.path);
@ -1030,10 +1030,10 @@ void DerivationGoal::inputsRealised()
`*i' as input paths. Only add the closures of output paths `*i' as input paths. Only add the closures of output paths
that are specified as inputs. */ that are specified as inputs. */
assert(worker.store.isValidPath(i->first)); assert(worker.store.isValidPath(i->first));
Derivation inDrv = derivationFromPath(i->first); Derivation inDrv = derivationFromPath(worker.store, i->first);
foreach (StringSet::iterator, j, i->second) foreach (StringSet::iterator, j, i->second)
if (inDrv.outputs.find(*j) != inDrv.outputs.end()) if (inDrv.outputs.find(*j) != inDrv.outputs.end())
computeFSClosure(inDrv.outputs[*j].path, inputPaths); computeFSClosure(worker.store, inDrv.outputs[*j].path, inputPaths);
else else
throw Error( throw Error(
format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'") format("derivation `%1%' requires non-existent output `%2%' from input derivation `%3%'")
@ -1042,7 +1042,7 @@ void DerivationGoal::inputsRealised()
/* Second, the input sources. */ /* Second, the input sources. */
foreach (PathSet::iterator, i, drv.inputSrcs) foreach (PathSet::iterator, i, drv.inputSrcs)
computeFSClosure(*i, inputPaths); computeFSClosure(worker.store, *i, inputPaths);
debug(format("added input paths %1%") % showPaths(inputPaths)); debug(format("added input paths %1%") % showPaths(inputPaths));
@ -1399,7 +1399,7 @@ HookReply DerivationGoal::tryBuildHook()
list it since the remote system *probably* already has it.) */ list it since the remote system *probably* already has it.) */
PathSet allInputs; PathSet allInputs;
allInputs.insert(inputPaths.begin(), inputPaths.end()); allInputs.insert(inputPaths.begin(), inputPaths.end());
computeFSClosure(drvPath, allInputs); computeFSClosure(worker.store, drvPath, allInputs);
string s; string s;
foreach (PathSet::iterator, i, allInputs) s += *i + " "; foreach (PathSet::iterator, i, allInputs) s += *i + " ";
@ -1545,14 +1545,14 @@ void DerivationGoal::startBuilder()
like passing all build-time dependencies of some path to a like passing all build-time dependencies of some path to a
derivation that builds a NixOS DVD image. */ derivation that builds a NixOS DVD image. */
PathSet paths, paths2; PathSet paths, paths2;
computeFSClosure(storePath, paths); computeFSClosure(worker.store, storePath, paths);
paths2 = paths; paths2 = paths;
foreach (PathSet::iterator, j, paths2) { foreach (PathSet::iterator, j, paths2) {
if (isDerivation(*j)) { if (isDerivation(*j)) {
Derivation drv = derivationFromPath(*j); Derivation drv = derivationFromPath(worker.store, *j);
foreach (DerivationOutputs::iterator, k, drv.outputs) foreach (DerivationOutputs::iterator, k, drv.outputs)
computeFSClosure(k->second.path, paths); computeFSClosure(worker.store, k->second.path, paths);
} }
} }

View file

@ -26,7 +26,8 @@ void DerivationOutput::parseHashInfo(bool & recursive, HashType & hashType, Hash
} }
Path writeDerivation(const Derivation & drv, const string & name) Path writeDerivation(StoreAPI & store,
const Derivation & drv, const string & name)
{ {
PathSet references; PathSet references;
references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end()); references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end());
@ -39,7 +40,7 @@ Path writeDerivation(const Derivation & drv, const string & name)
string contents = unparseDerivation(drv); string contents = unparseDerivation(drv);
return readOnlyMode return readOnlyMode
? computeStorePathForText(suffix, contents, references) ? computeStorePathForText(suffix, contents, references)
: store->addTextToStore(suffix, contents, references); : store.addTextToStore(suffix, contents, references);
} }
@ -221,7 +222,7 @@ DrvHashes drvHashes;
paths have been replaced by the result of a recursive call to this paths have been replaced by the result of a recursive call to this
function, and that for fixed-output derivations we return a hash of function, and that for fixed-output derivations we return a hash of
its output path. */ its output path. */
Hash hashDerivationModulo(Derivation drv) Hash hashDerivationModulo(StoreAPI & store, Derivation drv)
{ {
/* Return a fixed hash for fixed-output derivations. */ /* Return a fixed hash for fixed-output derivations. */
if (isFixedOutputDrv(drv)) { if (isFixedOutputDrv(drv)) {
@ -238,8 +239,8 @@ Hash hashDerivationModulo(Derivation drv)
foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) { foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) {
Hash h = drvHashes[i->first]; Hash h = drvHashes[i->first];
if (h.type == htUnknown) { if (h.type == htUnknown) {
Derivation drv2 = derivationFromPath(i->first); Derivation drv2 = derivationFromPath(store, i->first);
h = hashDerivationModulo(drv2); h = hashDerivationModulo(store, drv2);
drvHashes[i->first] = h; drvHashes[i->first] = h;
} }
inputs2[printHash(h)] = i->second; inputs2[printHash(h)] = i->second;

View file

@ -53,8 +53,12 @@ struct Derivation
}; };
class StoreAPI;
/* Write a derivation to the Nix store, and return its path. */ /* Write a derivation to the Nix store, and return its path. */
Path writeDerivation(const Derivation & drv, const string & name); Path writeDerivation(StoreAPI & store,
const Derivation & drv, const string & name);
/* Parse a derivation. */ /* Parse a derivation. */
Derivation parseDerivation(const string & s); Derivation parseDerivation(const string & s);
@ -69,7 +73,7 @@ bool isDerivation(const string & fileName);
/* Return true iff this is a fixed-output derivation. */ /* Return true iff this is a fixed-output derivation. */
bool isFixedOutputDrv(const Derivation & drv); bool isFixedOutputDrv(const Derivation & drv);
Hash hashDerivationModulo(Derivation drv); Hash hashDerivationModulo(StoreAPI & store, Derivation drv);
/* Memoisation of hashDerivationModulo(). */ /* Memoisation of hashDerivationModulo(). */
typedef std::map<Path, Hash> DrvHashes; typedef std::map<Path, Hash> DrvHashes;

View file

@ -90,8 +90,8 @@ void LocalStore::addIndirectRoot(const Path & path)
} }
Path addPermRoot(const Path & _storePath, const Path & _gcRoot, Path addPermRoot(StoreAPI & store, const Path & _storePath,
bool indirect, bool allowOutsideRootsDir) const Path & _gcRoot, bool indirect, bool allowOutsideRootsDir)
{ {
Path storePath(canonPath(_storePath)); Path storePath(canonPath(_storePath));
Path gcRoot(canonPath(_gcRoot)); Path gcRoot(canonPath(_gcRoot));
@ -104,7 +104,7 @@ Path addPermRoot(const Path & _storePath, const Path & _gcRoot,
if (indirect) { if (indirect) {
createSymlink(gcRoot, storePath, true); createSymlink(gcRoot, storePath, true);
store->addIndirectRoot(gcRoot); store.addIndirectRoot(gcRoot);
} }
else { else {
@ -127,7 +127,7 @@ Path addPermRoot(const Path & _storePath, const Path & _gcRoot,
check if the root is in a directory in or linked from the check if the root is in a directory in or linked from the
gcroots directory. */ gcroots directory. */
if (queryBoolSetting("gc-check-reachability", false)) { if (queryBoolSetting("gc-check-reachability", false)) {
Roots roots = store->findRoots(); Roots roots = store.findRoots();
if (roots.find(gcRoot) == roots.end()) if (roots.find(gcRoot) == roots.end())
printMsg(lvlError, printMsg(lvlError,
format( format(
@ -139,7 +139,7 @@ Path addPermRoot(const Path & _storePath, const Path & _gcRoot,
/* Grab the global GC root, causing us to block while a GC is in /* Grab the global GC root, causing us to block while a GC is in
progress. This prevents the set of permanent roots from progress. This prevents the set of permanent roots from
increasing while a GC is in progress. */ increasing while a GC is in progress. */
store->syncWithGC(); store.syncWithGC();
return gcRoot; return gcRoot;
} }
@ -275,8 +275,8 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
} }
static void findRoots(const Path & path, bool recurseSymlinks, static void findRoots(StoreAPI & store, const Path & path,
bool deleteStale, Roots & roots) bool recurseSymlinks, bool deleteStale, Roots & roots)
{ {
try { try {
@ -289,7 +289,7 @@ static void findRoots(const Path & path, bool recurseSymlinks,
if (S_ISDIR(st.st_mode)) { if (S_ISDIR(st.st_mode)) {
Strings names = readDirectory(path); Strings names = readDirectory(path);
foreach (Strings::iterator, i, names) foreach (Strings::iterator, i, names)
findRoots(path + "/" + *i, recurseSymlinks, deleteStale, roots); findRoots(store, path + "/" + *i, recurseSymlinks, deleteStale, roots);
} }
else if (S_ISLNK(st.st_mode)) { else if (S_ISLNK(st.st_mode)) {
@ -299,7 +299,7 @@ static void findRoots(const Path & path, bool recurseSymlinks,
debug(format("found root `%1%' in `%2%'") debug(format("found root `%1%' in `%2%'")
% target % path); % target % path);
Path storePath = toStorePath(target); Path storePath = toStorePath(target);
if (store->isValidPath(storePath)) if (store.isValidPath(storePath))
roots[path] = storePath; roots[path] = storePath;
else else
printMsg(lvlInfo, format("skipping invalid root from `%1%' to `%2%'") printMsg(lvlInfo, format("skipping invalid root from `%1%' to `%2%'")
@ -308,7 +308,7 @@ static void findRoots(const Path & path, bool recurseSymlinks,
else if (recurseSymlinks) { else if (recurseSymlinks) {
if (pathExists(target)) if (pathExists(target))
findRoots(target, false, deleteStale, roots); findRoots(store, target, false, deleteStale, roots);
else if (deleteStale) { else if (deleteStale) {
printMsg(lvlInfo, format("removing stale link from `%1%' to `%2%'") % path % target); printMsg(lvlInfo, format("removing stale link from `%1%' to `%2%'") % path % target);
/* Note that we only delete when recursing, i.e., /* Note that we only delete when recursing, i.e.,
@ -331,22 +331,22 @@ static void findRoots(const Path & path, bool recurseSymlinks,
} }
static Roots findRoots(bool deleteStale) static Roots findRoots(StoreAPI & store, bool deleteStale)
{ {
Roots roots; Roots roots;
Path rootsDir = canonPath((format("%1%/%2%") % nixStateDir % gcRootsDir).str()); Path rootsDir = canonPath((format("%1%/%2%") % nixStateDir % gcRootsDir).str());
findRoots(rootsDir, true, deleteStale, roots); findRoots(store, rootsDir, true, deleteStale, roots);
return roots; return roots;
} }
Roots LocalStore::findRoots() Roots LocalStore::findRoots()
{ {
return nix::findRoots(false); return nix::findRoots(*this, false);
} }
static void addAdditionalRoots(PathSet & roots) static void addAdditionalRoots(StoreAPI & store, PathSet & roots)
{ {
Path rootFinder = getEnv("NIX_ROOT_FINDER", Path rootFinder = getEnv("NIX_ROOT_FINDER",
nixLibexecDir + "/nix/find-runtime-roots.pl"); nixLibexecDir + "/nix/find-runtime-roots.pl");
@ -362,7 +362,7 @@ static void addAdditionalRoots(PathSet & roots)
foreach (Strings::iterator, i, paths) { foreach (Strings::iterator, i, paths) {
if (isInStore(*i)) { if (isInStore(*i)) {
Path path = toStorePath(*i); Path path = toStorePath(*i);
if (roots.find(path) == roots.end() && store->isValidPath(path)) { if (roots.find(path) == roots.end() && store.isValidPath(path)) {
debug(format("got additional root `%1%'") % path); debug(format("got additional root `%1%'") % path);
roots.insert(path); roots.insert(path);
} }
@ -371,32 +371,32 @@ static void addAdditionalRoots(PathSet & roots)
} }
static void dfsVisit(const PathSet & paths, const Path & path, static void dfsVisit(StoreAPI & store, const PathSet & paths,
PathSet & visited, Paths & sorted) const Path & path, PathSet & visited, Paths & sorted)
{ {
if (visited.find(path) != visited.end()) return; if (visited.find(path) != visited.end()) return;
visited.insert(path); visited.insert(path);
PathSet references; PathSet references;
if (store->isValidPath(path)) if (store.isValidPath(path))
store->queryReferences(path, references); store.queryReferences(path, references);
foreach (PathSet::iterator, i, references) foreach (PathSet::iterator, i, references)
/* Don't traverse into paths that don't exist. That can /* Don't traverse into paths that don't exist. That can
happen due to substitutes for non-existent paths. */ happen due to substitutes for non-existent paths. */
if (*i != path && paths.find(*i) != paths.end()) if (*i != path && paths.find(*i) != paths.end())
dfsVisit(paths, *i, visited, sorted); dfsVisit(store, paths, *i, visited, sorted);
sorted.push_front(path); sorted.push_front(path);
} }
Paths topoSortPaths(const PathSet & paths) Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
{ {
Paths sorted; Paths sorted;
PathSet visited; PathSet visited;
foreach (PathSet::const_iterator, i, paths) foreach (PathSet::const_iterator, i, paths)
dfsVisit(paths, *i, visited, sorted); dfsVisit(store, paths, *i, visited, sorted);
return sorted; return sorted;
} }
@ -582,7 +582,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
/* Find the roots. Since we've grabbed the GC lock, the set of /* Find the roots. Since we've grabbed the GC lock, the set of
permanent roots cannot increase now. */ permanent roots cannot increase now. */
printMsg(lvlError, format("finding garbage collector roots...")); printMsg(lvlError, format("finding garbage collector roots..."));
Roots rootMap = options.ignoreLiveness ? Roots() : nix::findRoots(true); Roots rootMap = options.ignoreLiveness ? Roots() : nix::findRoots(*this, true);
foreach (Roots::iterator, i, rootMap) state.roots.insert(i->second); foreach (Roots::iterator, i, rootMap) state.roots.insert(i->second);
@ -591,7 +591,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
to add running programs to the set of roots (to prevent them to add running programs to the set of roots (to prevent them
from being garbage collected). */ from being garbage collected). */
if (!options.ignoreLiveness) if (!options.ignoreLiveness)
addAdditionalRoots(state.roots); addAdditionalRoots(*this, state.roots);
/* Read the temporary roots. This acquires read locks on all /* Read the temporary roots. This acquires read locks on all
per-process temporary root files. So after this point no paths per-process temporary root files. So after this point no paths

View file

@ -497,7 +497,7 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
drvCopy.env[i->first] = ""; drvCopy.env[i->first] = "";
} }
Hash h = hashDerivationModulo(drvCopy); Hash h = hashDerivationModulo(*this, drvCopy);
foreach (DerivationOutputs::const_iterator, i, drv.outputs) { foreach (DerivationOutputs::const_iterator, i, drv.outputs) {
Path outPath = makeOutputPath(i->first, h, drvName); Path outPath = makeOutputPath(i->first, h, drvName);

View file

@ -6,15 +6,15 @@
namespace nix { namespace nix {
Derivation derivationFromPath(const Path & drvPath) Derivation derivationFromPath(StoreAPI & store, const Path & drvPath)
{ {
assertStorePath(drvPath); assertStorePath(drvPath);
store->ensurePath(drvPath); store.ensurePath(drvPath);
return parseDerivation(readFile(drvPath)); return parseDerivation(readFile(drvPath));
} }
void computeFSClosure(const Path & storePath, void computeFSClosure(StoreAPI & store, const Path & storePath,
PathSet & paths, bool flipDirection, bool includeOutputs) PathSet & paths, bool flipDirection, bool includeOutputs)
{ {
if (paths.find(storePath) != paths.end()) return; if (paths.find(storePath) != paths.end()) return;
@ -22,19 +22,19 @@ void computeFSClosure(const Path & storePath,
PathSet references; PathSet references;
if (flipDirection) if (flipDirection)
store->queryReferrers(storePath, references); store.queryReferrers(storePath, references);
else else
store->queryReferences(storePath, references); store.queryReferences(storePath, references);
if (includeOutputs && isDerivation(storePath)) { if (includeOutputs && isDerivation(storePath)) {
PathSet outputs = store->queryDerivationOutputs(storePath); PathSet outputs = store.queryDerivationOutputs(storePath);
foreach (PathSet::iterator, i, outputs) foreach (PathSet::iterator, i, outputs)
if (store->isValidPath(*i)) if (store.isValidPath(*i))
computeFSClosure(*i, paths, flipDirection, true); computeFSClosure(store, *i, paths, flipDirection, true);
} }
foreach (PathSet::iterator, i, references) foreach (PathSet::iterator, i, references)
computeFSClosure(*i, paths, flipDirection, includeOutputs); computeFSClosure(store, *i, paths, flipDirection, includeOutputs);
} }
@ -46,7 +46,7 @@ Path findOutput(const Derivation & drv, string id)
} }
void queryMissing(const PathSet & targets, void queryMissing(StoreAPI & store, const PathSet & targets,
PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown, PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
unsigned long long & downloadSize, unsigned long long & narSize) unsigned long long & downloadSize, unsigned long long & narSize)
{ {
@ -61,15 +61,15 @@ void queryMissing(const PathSet & targets,
done.insert(p); done.insert(p);
if (isDerivation(p)) { if (isDerivation(p)) {
if (!store->isValidPath(p)) { if (!store.isValidPath(p)) {
unknown.insert(p); unknown.insert(p);
continue; continue;
} }
Derivation drv = derivationFromPath(p); Derivation drv = derivationFromPath(store, p);
bool mustBuild = false; bool mustBuild = false;
foreach (DerivationOutputs::iterator, i, drv.outputs) foreach (DerivationOutputs::iterator, i, drv.outputs)
if (!store->isValidPath(i->second.path) && !store->hasSubstitutes(i->second.path)) if (!store.isValidPath(i->second.path) && !store.hasSubstitutes(i->second.path))
mustBuild = true; mustBuild = true;
if (mustBuild) { if (mustBuild) {
@ -83,9 +83,9 @@ void queryMissing(const PathSet & targets,
} }
else { else {
if (store->isValidPath(p)) continue; if (store.isValidPath(p)) continue;
SubstitutablePathInfo info; SubstitutablePathInfo info;
if (store->querySubstitutablePathInfo(p, info)) { if (store.querySubstitutablePathInfo(p, info)) {
willSubstitute.insert(p); willSubstitute.insert(p);
downloadSize += info.downloadSize; downloadSize += info.downloadSize;
narSize += info.narSize; narSize += info.narSize;

View file

@ -9,7 +9,7 @@ namespace nix {
/* Read a derivation, after ensuring its existence through /* Read a derivation, after ensuring its existence through
ensurePath(). */ ensurePath(). */
Derivation derivationFromPath(const Path & drvPath); Derivation derivationFromPath(StoreAPI & store, const Path & drvPath);
/* Place in `paths' the set of all store paths in the file system /* Place in `paths' the set of all store paths in the file system
closure of `storePath'; that is, all paths than can be directly or closure of `storePath'; that is, all paths than can be directly or
@ -18,7 +18,7 @@ Derivation derivationFromPath(const Path & drvPath);
`storePath' is returned; that is, the closures under the `storePath' is returned; that is, the closures under the
`referrers' relation instead of the `references' relation is `referrers' relation instead of the `references' relation is
returned. */ returned. */
void computeFSClosure(const Path & storePath, void computeFSClosure(StoreAPI & store, const Path & storePath,
PathSet & paths, bool flipDirection = false, PathSet & paths, bool flipDirection = false,
bool includeOutputs = false); bool includeOutputs = false);
@ -29,7 +29,7 @@ Path findOutput(const Derivation & drv, string id);
/* Given a set of paths that are to be built, return the set of /* Given a set of paths that are to be built, return the set of
derivations that will be built, and the set of output paths that derivations that will be built, and the set of output paths that
will be substituted. */ will be substituted. */
void queryMissing(const PathSet & targets, void queryMissing(StoreAPI & store, const PathSet & targets,
PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown, PathSet & willBuild, PathSet & willSubstitute, PathSet & unknown,
unsigned long long & downloadSize, unsigned long long & narSize); unsigned long long & downloadSize, unsigned long long & narSize);

View file

@ -314,13 +314,13 @@ void removeTempRoots();
/* Register a permanent GC root. */ /* Register a permanent GC root. */
Path addPermRoot(const Path & storePath, const Path & gcRoot, Path addPermRoot(StoreAPI & store, const Path & storePath,
bool indirect, bool allowOutsideRootsDir = false); const Path & gcRoot, bool indirect, bool allowOutsideRootsDir = false);
/* Sort a set of paths topologically under the references relation. /* Sort a set of paths topologically under the references relation.
If p refers to q, then p follows q in this list. */ If p refers to q, then p follows q in this list. */
Paths topoSortPaths(const PathSet & paths); Paths topoSortPaths(StoreAPI & store, const PathSet & paths);
/* For now, there is a single global store API object, but we'll /* For now, there is a single global store API object, but we'll

View file

@ -381,7 +381,7 @@ static void queryInstSources(EvalState & state,
if (isDerivation(path)) { if (isDerivation(path)) {
elem.setDrvPath(path); elem.setDrvPath(path);
elem.setOutPath(findOutput(derivationFromPath(path), "out")); elem.setOutPath(findOutput(derivationFromPath(*store, path), "out"));
if (name.size() >= drvExtension.size() && if (name.size() >= drvExtension.size() &&
string(name, name.size() - drvExtension.size()) == drvExtension) string(name, name.size() - drvExtension.size()) == drvExtension)
name = string(name, 0, name.size() - drvExtension.size()); name = string(name, 0, name.size() - drvExtension.size());
@ -430,7 +430,7 @@ static void printMissing(EvalState & state, const DrvInfos & elems)
targets.insert(i->queryOutPath(state)); targets.insert(i->queryOutPath(state));
} }
printMissing(targets); printMissing(*store, targets);
} }
@ -693,12 +693,12 @@ static void opSet(Globals & globals,
if (drv.queryDrvPath(globals.state) != "") { if (drv.queryDrvPath(globals.state) != "") {
PathSet paths = singleton<PathSet>(drv.queryDrvPath(globals.state)); PathSet paths = singleton<PathSet>(drv.queryDrvPath(globals.state));
printMissing(paths); printMissing(*store, paths);
if (globals.dryRun) return; if (globals.dryRun) return;
store->buildDerivations(paths); store->buildDerivations(paths);
} }
else { else {
printMissing(singleton<PathSet>(drv.queryOutPath(globals.state))); printMissing(*store, singleton<PathSet>(drv.queryOutPath(globals.state)));
if (globals.dryRun) return; if (globals.dryRun) return;
store->ensurePath(drv.queryOutPath(globals.state)); store->ensurePath(drv.queryOutPath(globals.state));
} }

View file

@ -91,7 +91,7 @@ Path createGeneration(Path profile, Path outPath)
user environment etc. we've just built. */ user environment etc. we've just built. */
Path generation; Path generation;
makeName(profile, num + 1, generation); makeName(profile, num + 1, generation);
addPermRoot(outPath, generation, false, true); addPermRoot(*store, outPath, generation, false, true);
return generation; return generation;
} }

View file

@ -64,9 +64,8 @@ void processExpr(EvalState & state, const Strings & attrPaths,
if (gcRoot == "") if (gcRoot == "")
printGCWarning(); printGCWarning();
else else
drvPath = addPermRoot(drvPath, drvPath = addPermRoot(*store, drvPath,
makeRootName(gcRoot, rootNr), makeRootName(gcRoot, rootNr), indirectRoot);
indirectRoot);
std::cout << format("%1%\n") % drvPath; std::cout << format("%1%\n") % drvPath;
} }
} }

View file

@ -58,14 +58,13 @@ static Path realisePath(const Path & path)
PathSet paths; PathSet paths;
paths.insert(path); paths.insert(path);
store->buildDerivations(paths); store->buildDerivations(paths);
Path outPath = findOutput(derivationFromPath(path), "out"); Path outPath = findOutput(derivationFromPath(*store, path), "out");
if (gcRoot == "") if (gcRoot == "")
printGCWarning(); printGCWarning();
else else
outPath = addPermRoot(outPath, outPath = addPermRoot(*store, outPath,
makeRootName(gcRoot, rootNr), makeRootName(gcRoot, rootNr), indirectRoot);
indirectRoot);
return outPath; return outPath;
} else { } else {
@ -87,7 +86,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
foreach (Strings::iterator, i, opArgs) foreach (Strings::iterator, i, opArgs)
*i = followLinksToStorePath(*i); *i = followLinksToStorePath(*i);
printMissing(PathSet(opArgs.begin(), opArgs.end())); printMissing(*store, PathSet(opArgs.begin(), opArgs.end()));
if (dryRun) return; if (dryRun) return;
@ -170,7 +169,7 @@ static Path maybeUseOutput(const Path & storePath, bool useOutput, bool forceRea
{ {
if (forceRealise) realisePath(storePath); if (forceRealise) realisePath(storePath);
if (useOutput && isDerivation(storePath)) { if (useOutput && isDerivation(storePath)) {
Derivation drv = derivationFromPath(storePath); Derivation drv = derivationFromPath(*store, storePath);
return findOutput(drv, "out"); return findOutput(drv, "out");
} }
else return storePath; else return storePath;
@ -210,7 +209,7 @@ static void printTree(const Path & path,
closure(B). That is, if derivation A is an (possibly indirect) closure(B). That is, if derivation A is an (possibly indirect)
input of B, then A is printed first. This has the effect of input of B, then A is printed first. This has the effect of
flattening the tree, preventing deeply nested structures. */ flattening the tree, preventing deeply nested structures. */
Paths sorted = topoSortPaths(references); Paths sorted = topoSortPaths(*store, references);
reverse(sorted.begin(), sorted.end()); reverse(sorted.begin(), sorted.end());
for (Paths::iterator i = sorted.begin(); i != sorted.end(); ++i) { for (Paths::iterator i = sorted.begin(); i != sorted.end(); ++i) {
@ -265,7 +264,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
foreach (Strings::iterator, i, opArgs) { foreach (Strings::iterator, i, opArgs) {
*i = followLinksToStorePath(*i); *i = followLinksToStorePath(*i);
if (forceRealise) realisePath(*i); if (forceRealise) realisePath(*i);
Derivation drv = derivationFromPath(*i); Derivation drv = derivationFromPath(*store, *i);
cout << format("%1%\n") % findOutput(drv, "out"); cout << format("%1%\n") % findOutput(drv, "out");
} }
break; break;
@ -278,12 +277,12 @@ static void opQuery(Strings opFlags, Strings opArgs)
PathSet paths; PathSet paths;
foreach (Strings::iterator, i, opArgs) { foreach (Strings::iterator, i, opArgs) {
Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise); Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
if (query == qRequisites) computeFSClosure(path, paths, false, includeOutputs); if (query == qRequisites) computeFSClosure(*store, path, paths, false, includeOutputs);
else if (query == qReferences) store->queryReferences(path, paths); else if (query == qReferences) store->queryReferences(path, paths);
else if (query == qReferrers) store->queryReferrers(path, paths); else if (query == qReferrers) store->queryReferrers(path, paths);
else if (query == qReferrersClosure) computeFSClosure(path, paths, true); else if (query == qReferrersClosure) computeFSClosure(*store, path, paths, true);
} }
Paths sorted = topoSortPaths(paths); Paths sorted = topoSortPaths(*store, paths);
for (Paths::reverse_iterator i = sorted.rbegin(); for (Paths::reverse_iterator i = sorted.rbegin();
i != sorted.rend(); ++i) i != sorted.rend(); ++i)
cout << format("%s\n") % *i; cout << format("%s\n") % *i;
@ -301,7 +300,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
case qBinding: case qBinding:
foreach (Strings::iterator, i, opArgs) { foreach (Strings::iterator, i, opArgs) {
Path path = useDeriver(followLinksToStorePath(*i)); Path path = useDeriver(followLinksToStorePath(*i));
Derivation drv = derivationFromPath(path); Derivation drv = derivationFromPath(*store, path);
StringPairs::iterator j = drv.env.find(bindingName); StringPairs::iterator j = drv.env.find(bindingName);
if (j == drv.env.end()) if (j == drv.env.end())
throw Error(format("derivation `%1%' has no environment binding named `%2%'") throw Error(format("derivation `%1%' has no environment binding named `%2%'")
@ -355,7 +354,8 @@ static void opQuery(Strings opFlags, Strings opArgs)
case qRoots: { case qRoots: {
PathSet referrers; PathSet referrers;
foreach (Strings::iterator, i, opArgs) foreach (Strings::iterator, i, opArgs)
computeFSClosure(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise), computeFSClosure(*store,
maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise),
referrers, true); referrers, true);
Roots roots = store->findRoots(); Roots roots = store->findRoots();
foreach (Roots::iterator, i, roots) foreach (Roots::iterator, i, roots)