From af2e53fd481994cca46b9c003a6a8eae50cf951c Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sun, 6 Nov 2011 06:28:20 +0000 Subject: [PATCH] Include all outputs of derivations in the closure of explicitly-passed derivation paths This required adding a queryOutputDerivationNames function in the store API --- src/libexpr/primops.cc | 10 ++++++++-- src/libstore/local-store.cc | 22 ++++++++++++++++++++++ src/libstore/local-store.hh | 2 ++ src/libstore/remote-store.cc | 10 ++++++++++ src/libstore/remote-store.hh | 2 ++ src/libstore/store-api.hh | 3 +++ src/libstore/worker-protocol.hh | 1 + src/nix-worker/nix-worker.cc | 10 ++++++++++ 8 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 2a3f1e2c3..ce0b9e8b0 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -347,6 +347,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) derivation. */ foreach (PathSet::iterator, i, context) { Path path = *i; + bool explicitlyPassed = false; /* Paths marked with `=' denote that the path of a derivation is explicitly passed to the builder. Since that allows the @@ -361,8 +362,10 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) foreach (PathSet::iterator, j, refs) { drv.inputSrcs.insert(*j); if (isDerivation(*j)) - drv.inputDrvs[*j] = singleton("out"); + drv.inputDrvs[*j] = store -> queryDerivationOutputNames(*j); } + + explicitlyPassed = true; } /* See prim_unsafeDiscardOutputDependency. */ @@ -376,7 +379,10 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) debug(format("derivation uses `%1%'") % path); if (!useDrvAsSrc && isDerivation(path)) - drv.inputDrvs[path] = singleton("out"); + if (explicitlyPassed) + drv.inputDrvs[path] = store -> queryDerivationOutputNames(path); + else + drv.inputDrvs[path] = singleton("out"); else drv.inputSrcs.insert(path); } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 702ff67e7..8ca5daa9f 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -820,6 +820,28 @@ PathSet LocalStore::queryDerivationOutputs(const Path & path) } +StringSet LocalStore::queryDerivationOutputNames(const Path & path) +{ + SQLiteTxn txn(db); + + SQLiteStmtUse use(stmtQueryDerivationOutputs); + stmtQueryDerivationOutputs.bind(queryValidPathId(path)); + + StringSet outputNames; + int r; + while ((r = sqlite3_step(stmtQueryDerivationOutputs)) == SQLITE_ROW) { + const char * s = (const char *) sqlite3_column_text(stmtQueryDerivationOutputs, 0); + assert(s); + outputNames.insert(s); + } + + if (r != SQLITE_DONE) + throwSQLiteError(db, format("error getting output names of `%1%'") % path); + + return outputNames; +} + + void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & run) { if (run.pid != -1) return; diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 7ef01b264..b97e2f406 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -118,6 +118,8 @@ public: PathSet queryValidDerivers(const Path & path); PathSet queryDerivationOutputs(const Path & path); + + StringSet queryDerivationOutputNames(const Path & path); PathSet querySubstitutablePaths(); diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 568a6aa58..84c87246f 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -322,6 +322,16 @@ PathSet RemoteStore::queryDerivationOutputs(const Path & path) } +PathSet RemoteStore::queryDerivationOutputNames(const Path & path) +{ + openConnection(); + writeInt(wopQueryDerivationOutputNames, to); + writeString(path, to); + processStderr(); + return readStringSet(from); +} + + Path RemoteStore::addToStore(const Path & _srcPath, bool recursive, HashType hashAlgo, PathFilter & filter) { diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 519f46fd1..3be9e315a 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -41,6 +41,8 @@ public: PathSet queryDerivationOutputs(const Path & path); + StringSet queryDerivationOutputNames(const Path & path); + bool hasSubstitutes(const Path & path); bool querySubstitutablePathInfo(const Path & path, diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index b3e67436c..038465749 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -140,6 +140,9 @@ public: /* Query the outputs of the derivation denoted by `path'. */ virtual PathSet queryDerivationOutputs(const Path & path) = 0; + + /* Query the output names of the derivation denoted by `path'. */ + virtual StringSet queryDerivationOutputNames(const Path & path) = 0; /* Query whether a path has substitutes. */ virtual bool hasSubstitutes(const Path & path) = 0; diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh index acb8bc8b2..576e754d2 100644 --- a/src/libstore/worker-protocol.hh +++ b/src/libstore/worker-protocol.hh @@ -39,6 +39,7 @@ typedef enum { wopQueryFailedPaths = 24, wopClearFailedPaths = 25, wopQueryPathInfo = 26, + wopQueryDerivationOutputNames = 27, } WorkerOp; diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc index 0fa1b40ae..3587bd7fd 100644 --- a/src/nix-worker/nix-worker.cc +++ b/src/nix-worker/nix-worker.cc @@ -331,6 +331,16 @@ static void performOp(unsigned int clientVersion, break; } + case wopQueryDerivationOutputNames: { + Path path = readStorePath(from); + startWork(); + StringSet names; + names = store->queryDerivationOutputNames(path); + stopWork(); + writeStringSet(names, to); + break; + } + case wopQueryDeriver: { Path path = readStorePath(from); startWork();