* Support multiple outputs in nix-store (specifically the ‘--query’
and ‘--realise’ actions).
This commit is contained in:
parent
a71d02440b
commit
93b56acb2d
1 changed files with 63 additions and 43 deletions
|
@ -50,26 +50,30 @@ static Path useDeriver(Path path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Realisation the given path. For a derivation that means build it;
|
/* Realise the given path. For a derivation that means build it; for
|
||||||
for other paths it means ensure their validity. */
|
other paths it means ensure their validity. */
|
||||||
static Path realisePath(const Path & path)
|
static PathSet realisePath(const Path & path)
|
||||||
{
|
{
|
||||||
if (isDerivation(path)) {
|
if (isDerivation(path)) {
|
||||||
PathSet paths;
|
store->buildDerivations(singleton<PathSet>(path));
|
||||||
paths.insert(path);
|
Derivation drv = derivationFromPath(*store, path);
|
||||||
store->buildDerivations(paths);
|
|
||||||
Path outPath = findOutput(derivationFromPath(*store, path), "out");
|
|
||||||
|
|
||||||
|
PathSet outputs;
|
||||||
|
foreach (DerivationOutputs::iterator, i, drv.outputs) {
|
||||||
|
Path outPath = i->second.path;
|
||||||
if (gcRoot == "")
|
if (gcRoot == "")
|
||||||
printGCWarning();
|
printGCWarning();
|
||||||
else
|
else
|
||||||
outPath = addPermRoot(*store, outPath,
|
outPath = addPermRoot(*store, outPath,
|
||||||
makeRootName(gcRoot, rootNr), indirectRoot);
|
makeRootName(gcRoot, rootNr), indirectRoot);
|
||||||
|
outputs.insert(outPath);
|
||||||
|
}
|
||||||
|
return outputs;
|
||||||
|
}
|
||||||
|
|
||||||
return outPath;
|
else {
|
||||||
} else {
|
|
||||||
store->ensurePath(path);
|
store->ensurePath(path);
|
||||||
return path;
|
return singleton<PathSet>(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,8 +100,11 @@ static void opRealise(Strings opFlags, Strings opArgs)
|
||||||
if (isDerivation(*i)) drvPaths.insert(*i);
|
if (isDerivation(*i)) drvPaths.insert(*i);
|
||||||
store->buildDerivations(drvPaths);
|
store->buildDerivations(drvPaths);
|
||||||
|
|
||||||
foreach (Strings::iterator, i, opArgs)
|
foreach (Strings::iterator, i, opArgs) {
|
||||||
cout << format("%1%\n") % realisePath(*i);
|
PathSet paths = realisePath(*i);
|
||||||
|
foreach (PathSet::iterator, j, paths)
|
||||||
|
cout << format("%1%\n") % *j;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,14 +164,17 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Path maybeUseOutput(const Path & storePath, bool useOutput, bool forceRealise)
|
static PathSet maybeUseOutputs(const Path & storePath, bool useOutput, bool forceRealise)
|
||||||
{
|
{
|
||||||
if (forceRealise) realisePath(storePath);
|
if (forceRealise) realisePath(storePath);
|
||||||
if (useOutput && isDerivation(storePath)) {
|
if (useOutput && isDerivation(storePath)) {
|
||||||
Derivation drv = derivationFromPath(*store, storePath);
|
Derivation drv = derivationFromPath(*store, storePath);
|
||||||
return findOutput(drv, "out");
|
PathSet outputs;
|
||||||
|
foreach (DerivationOutputs::iterator, i, drv.outputs)
|
||||||
|
outputs.insert(i->second.path);
|
||||||
|
return outputs;
|
||||||
}
|
}
|
||||||
else return storePath;
|
else return singleton<PathSet>(storePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -257,7 +267,8 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
*i = followLinksToStorePath(*i);
|
*i = followLinksToStorePath(*i);
|
||||||
if (forceRealise) realisePath(*i);
|
if (forceRealise) realisePath(*i);
|
||||||
Derivation drv = derivationFromPath(*store, *i);
|
Derivation drv = derivationFromPath(*store, *i);
|
||||||
cout << format("%1%\n") % findOutput(drv, "out");
|
foreach (DerivationOutputs::iterator, j, drv.outputs)
|
||||||
|
cout << format("%1%\n") % j->second.path;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -268,11 +279,13 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
case qReferrersClosure: {
|
case qReferrersClosure: {
|
||||||
PathSet paths;
|
PathSet paths;
|
||||||
foreach (Strings::iterator, i, opArgs) {
|
foreach (Strings::iterator, i, opArgs) {
|
||||||
Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
|
PathSet ps = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise);
|
||||||
if (query == qRequisites) computeFSClosure(*store, path, paths, false, includeOutputs);
|
foreach (PathSet::iterator, j, ps) {
|
||||||
else if (query == qReferences) store->queryReferences(path, paths);
|
if (query == qRequisites) computeFSClosure(*store, *j, paths, false, includeOutputs);
|
||||||
else if (query == qReferrers) store->queryReferrers(path, paths);
|
else if (query == qReferences) store->queryReferences(*j, paths);
|
||||||
else if (query == qReferrersClosure) computeFSClosure(*store, path, paths, true);
|
else if (query == qReferrers) store->queryReferrers(*j, paths);
|
||||||
|
else if (query == qReferrersClosure) computeFSClosure(*store, *j, paths, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Paths sorted = topoSortPaths(*store, paths);
|
Paths sorted = topoSortPaths(*store, paths);
|
||||||
for (Paths::reverse_iterator i = sorted.rbegin();
|
for (Paths::reverse_iterator i = sorted.rbegin();
|
||||||
|
@ -304,14 +317,16 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
case qHash:
|
case qHash:
|
||||||
case qSize:
|
case qSize:
|
||||||
foreach (Strings::iterator, i, opArgs) {
|
foreach (Strings::iterator, i, opArgs) {
|
||||||
Path path = maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise);
|
PathSet paths = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise);
|
||||||
ValidPathInfo info = store->queryPathInfo(path);
|
foreach (PathSet::iterator, j, paths) {
|
||||||
|
ValidPathInfo info = store->queryPathInfo(*j);
|
||||||
if (query == qHash) {
|
if (query == qHash) {
|
||||||
assert(info.hash.type == htSHA256);
|
assert(info.hash.type == htSHA256);
|
||||||
cout << format("sha256:%1%\n") % printHash32(info.hash);
|
cout << format("sha256:%1%\n") % printHash32(info.hash);
|
||||||
} else if (query == qSize)
|
} else if (query == qSize)
|
||||||
cout << format("%1%\n") % info.narSize;
|
cout << format("%1%\n") % info.narSize;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case qTree: {
|
case qTree: {
|
||||||
|
@ -323,16 +338,20 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
case qGraph: {
|
case qGraph: {
|
||||||
PathSet roots;
|
PathSet roots;
|
||||||
foreach (Strings::iterator, i, opArgs)
|
foreach (Strings::iterator, i, opArgs) {
|
||||||
roots.insert(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise));
|
PathSet paths = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise);
|
||||||
|
roots.insert(paths.begin(), paths.end());
|
||||||
|
}
|
||||||
printDotGraph(roots);
|
printDotGraph(roots);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case qXml: {
|
case qXml: {
|
||||||
PathSet roots;
|
PathSet roots;
|
||||||
foreach (Strings::iterator, i, opArgs)
|
foreach (Strings::iterator, i, opArgs) {
|
||||||
roots.insert(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise));
|
PathSet paths = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise);
|
||||||
|
roots.insert(paths.begin(), paths.end());
|
||||||
|
}
|
||||||
printXmlGraph(roots);
|
printXmlGraph(roots);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -345,10 +364,11 @@ 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(*store,
|
PathSet paths = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise);
|
||||||
maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise),
|
foreach (PathSet::iterator, j, paths)
|
||||||
referrers, true);
|
computeFSClosure(*store, *j, referrers, true);
|
||||||
|
}
|
||||||
Roots roots = store->findRoots();
|
Roots roots = store->findRoots();
|
||||||
foreach (Roots::iterator, i, roots)
|
foreach (Roots::iterator, i, roots)
|
||||||
if (referrers.find(i->second) != referrers.end())
|
if (referrers.find(i->second) != referrers.end())
|
||||||
|
|
Loading…
Reference in a new issue