Skip to content

Commit d38f860

Browse files
committed
Add a way to get all the outputs of a derivation with their label
Generalize `queryDerivationOutputNames` and `queryDerivationOutputs` by adding a `queryDerivationOutputMap` that returns the map `outputName=>outputPath` (not that this is not equivalent to merging the results of `queryDerivationOutputs` and `queryDerivationOutputNames` as sets don't preserve the order, so we would end up with an incorrect mapping). squash! Add a way to get all the outputs of a derivation with their label Rename StorePathMap to OutputPathMap
1 parent 3c50e84 commit d38f860

File tree

10 files changed

+78
-11
lines changed

10 files changed

+78
-11
lines changed

src/libstore/build.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2750,8 +2750,8 @@ struct RestrictedStore : public LocalFSStore
27502750
void queryReferrers(const StorePath & path, StorePathSet & referrers) override
27512751
{ }
27522752

2753-
StorePathSet queryDerivationOutputs(const StorePath & path) override
2754-
{ throw Error("queryDerivationOutputs"); }
2753+
OutputPathMap queryDerivationOutputMap(const StorePath & path) override
2754+
{ throw Error("queryDerivationOutputMap"); }
27552755

27562756
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override
27572757
{ throw Error("queryPathFromHashPart"); }

src/libstore/daemon.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,15 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
347347
break;
348348
}
349349

350+
case wopQueryDerivationOutputMap: {
351+
auto path = store->parseStorePath(readString(from));
352+
logger->startWork();
353+
OutputPathMap outputs = store->queryDerivationOutputMap(path);
354+
logger->stopWork();
355+
writeOutputPathMap(*store, to, outputs);
356+
break;
357+
}
358+
350359
case wopQueryDeriver: {
351360
auto path = store->parseStorePath(readString(from));
352361
logger->startWork();

src/libstore/local-store.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -774,17 +774,20 @@ StorePathSet LocalStore::queryValidDerivers(const StorePath & path)
774774
}
775775

776776

777-
StorePathSet LocalStore::queryDerivationOutputs(const StorePath & path)
777+
OutputPathMap LocalStore::queryDerivationOutputMap(const StorePath & path)
778778
{
779-
return retrySQLite<StorePathSet>([&]() {
779+
return retrySQLite<OutputPathMap>([&]() {
780780
auto state(_state.lock());
781781

782782
auto useQueryDerivationOutputs(state->stmtQueryDerivationOutputs.use()
783783
(queryValidPathId(*state, path)));
784784

785-
StorePathSet outputs;
785+
OutputPathMap outputs;
786786
while (useQueryDerivationOutputs.next())
787-
outputs.insert(parseStorePath(useQueryDerivationOutputs.getStr(1)));
787+
outputs.emplace(
788+
useQueryDerivationOutputs.getStr(0),
789+
parseStorePath(useQueryDerivationOutputs.getStr(1))
790+
);
788791

789792
return outputs;
790793
});

src/libstore/local-store.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public:
133133

134134
StorePathSet queryValidDerivers(const StorePath & path) override;
135135

136-
StorePathSet queryDerivationOutputs(const StorePath & path) override;
136+
OutputPathMap queryDerivationOutputMap(const StorePath & path) override;
137137

138138
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override;
139139

src/libstore/path.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public:
6262

6363
typedef std::set<StorePath> StorePathSet;
6464
typedef std::vector<StorePath> StorePaths;
65+
typedef std::map<string, StorePath> OutputPathMap;
6566

6667
/* Extension of derivations in the Nix store. */
6768
const std::string drvExtension = ".drv";

src/libstore/remote-store.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,32 @@ void writeStorePaths(const Store & store, Sink & out, const StorePathSet & paths
3838
out << store.printStorePath(i);
3939
}
4040

41+
std::map<string, StorePath> readOutputPathMap(const Store & store, Source & from)
42+
{
43+
std::map<string, StorePath> pathMap;
44+
auto rawInput = readStrings<Strings>(from);
45+
auto curInput = rawInput.begin();
46+
while (curInput != rawInput.end()) {
47+
string thisKey = *curInput;
48+
curInput = std::next(curInput);
49+
if (curInput == rawInput.end()) {
50+
throw Error("Got an odd number of elements from the daemon when trying to read a map… that's odd");
51+
}
52+
string thisValue = *curInput;
53+
curInput = std::next(curInput);
54+
pathMap.emplace(thisKey, store.parseStorePath(thisValue));
55+
}
56+
return pathMap;
57+
}
58+
59+
void writeOutputPathMap(const Store & store, Sink & out, const std::map<string, StorePath> & pathMap)
60+
{
61+
out << 2*pathMap.size();
62+
for (auto & i : pathMap) {
63+
out << i.first;
64+
out << store.printStorePath(i.second);
65+
}
66+
}
4167

4268
/* TODO: Separate these store impls into different files, give them better names */
4369
RemoteStore::RemoteStore(const Params & params)
@@ -412,12 +438,24 @@ StorePathSet RemoteStore::queryValidDerivers(const StorePath & path)
412438
StorePathSet RemoteStore::queryDerivationOutputs(const StorePath & path)
413439
{
414440
auto conn(getConnection());
441+
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 0x16) {
442+
return Store::queryDerivationOutputs(path);
443+
}
415444
conn->to << wopQueryDerivationOutputs << printStorePath(path);
416445
conn.processStderr();
417446
return readStorePaths<StorePathSet>(*this, conn->from);
418447
}
419448

420449

450+
OutputPathMap RemoteStore::queryDerivationOutputMap(const StorePath & path)
451+
{
452+
auto conn(getConnection());
453+
conn->to << wopQueryDerivationOutputMap << printStorePath(path);
454+
conn.processStderr();
455+
return readOutputPathMap(*this, conn->from);
456+
457+
}
458+
421459
std::optional<StorePath> RemoteStore::queryPathFromHashPart(const std::string & hashPart)
422460
{
423461
auto conn(getConnection());

src/libstore/remote-store.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public:
5151

5252
StorePathSet queryDerivationOutputs(const StorePath & path) override;
5353

54+
OutputPathMap queryDerivationOutputMap(const StorePath & path) override;
5455
std::optional<StorePath> queryPathFromHashPart(const std::string & hashPart) override;
5556

5657
StorePathSet querySubstitutablePaths(const StorePathSet & paths) override;

src/libstore/store-api.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,16 @@ bool Store::PathInfoCacheValue::isKnownNow()
242242
return std::chrono::steady_clock::now() < time_point + ttl;
243243
}
244244

245+
StorePathSet Store::queryDerivationOutputs(const StorePath & path)
246+
{
247+
auto outputMap = this->queryDerivationOutputMap(path);
248+
StorePathSet outputPaths;
249+
for (auto & i: outputMap) {
250+
outputPaths.emplace(std::move(i.second));
251+
}
252+
return outputPaths;
253+
}
254+
245255
bool Store::isValidPath(const StorePath & storePath)
246256
{
247257
std::string hashPart(storePath.hashPart());

src/libstore/store-api.hh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,11 @@ public:
418418
virtual StorePathSet queryValidDerivers(const StorePath & path) { return {}; };
419419

420420
/* Query the outputs of the derivation denoted by `path'. */
421-
virtual StorePathSet queryDerivationOutputs(const StorePath & path)
422-
{ unsupported("queryDerivationOutputs"); }
421+
virtual StorePathSet queryDerivationOutputs(const StorePath & path);
422+
423+
/* Query the mapping outputName=>outputPath for the given derivation */
424+
virtual OutputPathMap queryDerivationOutputMap(const StorePath & path)
425+
{ unsupported("queryDerivationOutputMap"); }
423426

424427
/* Query the full store path given the hash part of a valid store
425428
path, or empty if the path doesn't exist. */

src/libstore/worker-protocol.hh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace nix {
66
#define WORKER_MAGIC_1 0x6e697863
77
#define WORKER_MAGIC_2 0x6478696f
88

9-
#define PROTOCOL_VERSION 0x115
9+
#define PROTOCOL_VERSION 0x116
1010
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
1111
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
1212

@@ -30,7 +30,7 @@ typedef enum {
3030
wopSetOptions = 19,
3131
wopCollectGarbage = 20,
3232
wopQuerySubstitutablePathInfo = 21,
33-
wopQueryDerivationOutputs = 22,
33+
wopQueryDerivationOutputs = 22, // obsolete
3434
wopQueryAllValidPaths = 23,
3535
wopQueryFailedPaths = 24,
3636
wopClearFailedPaths = 25,
@@ -49,6 +49,7 @@ typedef enum {
4949
wopNarFromPath = 38,
5050
wopAddToStoreNar = 39,
5151
wopQueryMissing = 40,
52+
wopQueryDerivationOutputMap = 41,
5253
} WorkerOp;
5354

5455

@@ -69,5 +70,6 @@ template<class T> T readStorePaths(const Store & store, Source & from);
6970

7071
void writeStorePaths(const Store & store, Sink & out, const StorePathSet & paths);
7172

73+
void writeOutputPathMap(const Store & store, Sink & out, const OutputPathMap & paths);
7274

7375
}

0 commit comments

Comments
 (0)