aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThéophane Hufschmitt <7226587+thufschmitt@users.noreply.github.com>2022-03-17 10:55:22 +0100
committerGitHub <noreply@github.com>2022-03-17 10:55:22 +0100
commita0b517de5796d9a82b18242ecc63f507869237b1 (patch)
treeca111de239053f6aafccf78cd7ddb56ca1e79192 /src
parentfe1ad9613561ea78b6d97cf82c03d2dd77e43f69 (diff)
parentc20e07763d84c9dc6f8d06993335c765ba514aca (diff)
Merge pull request #6242 from ncfavier/print-output-names
nix-env: always print output names in JSON and XML
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/get-drvs.cc30
-rw-r--r--src/libexpr/get-drvs.hh7
-rw-r--r--src/nix-env/nix-env.cc137
-rw-r--r--src/nix-env/user-env.cc10
4 files changed, 97 insertions, 87 deletions
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index 7630c5ff4..7f2ecb4f7 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -102,7 +102,7 @@ StorePath DrvInfo::queryOutPath() const
}
-DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
+DrvInfo::Outputs DrvInfo::queryOutputs(bool withPaths, bool onlyOutputsToInstall)
{
if (outputs.empty()) {
/* Get the ‘outputs’ list. */
@@ -112,20 +112,24 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
/* For each output... */
for (auto elem : i->value->listItems()) {
- /* Evaluate the corresponding set. */
- std::string name(state->forceStringNoCtx(*elem, *i->pos));
- Bindings::iterator out = attrs->find(state->symbols.create(name));
- if (out == attrs->end()) continue; // FIXME: throw error?
- state->forceAttrs(*out->value, *i->pos);
-
- /* And evaluate its ‘outPath’ attribute. */
- Bindings::iterator outPath = out->value->attrs->find(state->sOutPath);
- if (outPath == out->value->attrs->end()) continue; // FIXME: throw error?
- PathSet context;
- outputs.emplace(name, state->coerceToStorePath(*outPath->pos, *outPath->value, context));
+ std::string output(state->forceStringNoCtx(*elem, *i->pos));
+
+ if (withPaths) {
+ /* Evaluate the corresponding set. */
+ Bindings::iterator out = attrs->find(state->symbols.create(output));
+ if (out == attrs->end()) continue; // FIXME: throw error?
+ state->forceAttrs(*out->value, *i->pos);
+
+ /* And evaluate its ‘outPath’ attribute. */
+ Bindings::iterator outPath = out->value->attrs->find(state->sOutPath);
+ if (outPath == out->value->attrs->end()) continue; // FIXME: throw error?
+ PathSet context;
+ outputs.emplace(output, state->coerceToStorePath(*outPath->pos, *outPath->value, context));
+ } else
+ outputs.emplace(output, std::nullopt);
}
} else
- outputs.emplace("out", queryOutPath());
+ outputs.emplace("out", withPaths ? std::optional{queryOutPath()} : std::nullopt);
}
if (!onlyOutputsToInstall || !attrs)
return outputs;
diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh
index 3ca6f1fca..7cc1abef2 100644
--- a/src/libexpr/get-drvs.hh
+++ b/src/libexpr/get-drvs.hh
@@ -13,7 +13,7 @@ namespace nix {
struct DrvInfo
{
public:
- typedef std::map<std::string, StorePath> Outputs;
+ typedef std::map<std::string, std::optional<StorePath>> Outputs;
private:
EvalState * state;
@@ -46,8 +46,9 @@ public:
StorePath requireDrvPath() const;
StorePath queryOutPath() const;
std::string queryOutputName() const;
- /** Return the list of outputs. The "outputs to install" are determined by `meta.outputsToInstall`. */
- Outputs queryOutputs(bool onlyOutputsToInstall = false);
+ /** Return the unordered map of output names to (optional) output paths.
+ * The "outputs to install" are determined by `meta.outputsToInstall`. */
+ Outputs queryOutputs(bool withPaths = true, bool onlyOutputsToInstall = false);
StringSet queryMetaNames();
Value * queryMeta(const std::string & name);
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index eb5fbc08f..9a68899cd 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -923,12 +923,17 @@ static void queryJSON(Globals & globals, std::vector<DrvInfo> & elems, bool prin
pkgObj.attr("pname", drvName.name);
pkgObj.attr("version", drvName.version);
pkgObj.attr("system", i.querySystem());
+ pkgObj.attr("outputName", i.queryOutputName());
- if (printOutPath) {
- DrvInfo::Outputs outputs = i.queryOutputs();
+ {
+ DrvInfo::Outputs outputs = i.queryOutputs(printOutPath);
JSONObject outputObj = pkgObj.object("outputs");
- for (auto & j : outputs)
- outputObj.attr(j.first, globals.state->store->printStorePath(j.second));
+ for (auto & j : outputs) {
+ if (j.second)
+ outputObj.attr(j.first, globals.state->store->printStorePath(*j.second));
+ else
+ outputObj.attr(j.first, nullptr);
+ }
}
if (printMeta) {
@@ -1057,6 +1062,7 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
/* Print the desired columns, or XML output. */
if (jsonOutput) {
queryJSON(globals, elems, printOutPath, printMeta);
+ cout << '\n';
return;
}
@@ -1159,13 +1165,16 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
columns.push_back(drvPath ? store.printStorePath(*drvPath) : "-");
}
+ if (xmlOutput)
+ attrs["outputName"] = i.queryOutputName();
+
if (printOutPath && !xmlOutput) {
DrvInfo::Outputs outputs = i.queryOutputs();
std::string s;
for (auto & j : outputs) {
if (!s.empty()) s += ';';
if (j.first != "out") { s += j.first; s += "="; }
- s += store.printStorePath(j.second);
+ s += store.printStorePath(*j.second);
}
columns.push_back(s);
}
@@ -1179,71 +1188,67 @@ static void opQuery(Globals & globals, Strings opFlags, Strings opArgs)
}
if (xmlOutput) {
- if (printOutPath || printMeta) {
- XMLOpenElement item(xml, "item", attrs);
- if (printOutPath) {
- DrvInfo::Outputs outputs = i.queryOutputs();
- for (auto & j : outputs) {
- XMLAttrs attrs2;
- attrs2["name"] = j.first;
- attrs2["path"] = store.printStorePath(j.second);
- xml.writeEmptyElement("output", attrs2);
- }
- }
- if (printMeta) {
- StringSet metaNames = i.queryMetaNames();
- for (auto & j : metaNames) {
- XMLAttrs attrs2;
- attrs2["name"] = j;
- Value * v = i.queryMeta(j);
- if (!v)
- printError(
- "derivation '%s' has invalid meta attribute '%s'",
- i.queryName(), j);
- else {
- if (v->type() == nString) {
- attrs2["type"] = "string";
- attrs2["value"] = v->string.s;
- xml.writeEmptyElement("meta", attrs2);
- } else if (v->type() == nInt) {
- attrs2["type"] = "int";
- attrs2["value"] = (format("%1%") % v->integer).str();
- xml.writeEmptyElement("meta", attrs2);
- } else if (v->type() == nFloat) {
- attrs2["type"] = "float";
- attrs2["value"] = (format("%1%") % v->fpoint).str();
- xml.writeEmptyElement("meta", attrs2);
- } else if (v->type() == nBool) {
- attrs2["type"] = "bool";
- attrs2["value"] = v->boolean ? "true" : "false";
- xml.writeEmptyElement("meta", attrs2);
- } else if (v->type() == nList) {
- attrs2["type"] = "strings";
- XMLOpenElement m(xml, "meta", attrs2);
- for (auto elem : v->listItems()) {
- if (elem->type() != nString) continue;
- XMLAttrs attrs3;
- attrs3["value"] = elem->string.s;
- xml.writeEmptyElement("string", attrs3);
- }
- } else if (v->type() == nAttrs) {
- attrs2["type"] = "strings";
- XMLOpenElement m(xml, "meta", attrs2);
- Bindings & attrs = *v->attrs;
- for (auto &i : attrs) {
- Attr & a(*attrs.find(i.name));
- if(a.value->type() != nString) continue;
- XMLAttrs attrs3;
- attrs3["type"] = i.name;
- attrs3["value"] = a.value->string.s;
- xml.writeEmptyElement("string", attrs3);
+ XMLOpenElement item(xml, "item", attrs);
+ DrvInfo::Outputs outputs = i.queryOutputs(printOutPath);
+ for (auto & j : outputs) {
+ XMLAttrs attrs2;
+ attrs2["name"] = j.first;
+ if (j.second)
+ attrs2["path"] = store.printStorePath(*j.second);
+ xml.writeEmptyElement("output", attrs2);
+ }
+ if (printMeta) {
+ StringSet metaNames = i.queryMetaNames();
+ for (auto & j : metaNames) {
+ XMLAttrs attrs2;
+ attrs2["name"] = j;
+ Value * v = i.queryMeta(j);
+ if (!v)
+ printError(
+ "derivation '%s' has invalid meta attribute '%s'",
+ i.queryName(), j);
+ else {
+ if (v->type() == nString) {
+ attrs2["type"] = "string";
+ attrs2["value"] = v->string.s;
+ xml.writeEmptyElement("meta", attrs2);
+ } else if (v->type() == nInt) {
+ attrs2["type"] = "int";
+ attrs2["value"] = (format("%1%") % v->integer).str();
+ xml.writeEmptyElement("meta", attrs2);
+ } else if (v->type() == nFloat) {
+ attrs2["type"] = "float";
+ attrs2["value"] = (format("%1%") % v->fpoint).str();
+ xml.writeEmptyElement("meta", attrs2);
+ } else if (v->type() == nBool) {
+ attrs2["type"] = "bool";
+ attrs2["value"] = v->boolean ? "true" : "false";
+ xml.writeEmptyElement("meta", attrs2);
+ } else if (v->type() == nList) {
+ attrs2["type"] = "strings";
+ XMLOpenElement m(xml, "meta", attrs2);
+ for (auto elem : v->listItems()) {
+ if (elem->type() != nString) continue;
+ XMLAttrs attrs3;
+ attrs3["value"] = elem->string.s;
+ xml.writeEmptyElement("string", attrs3);
}
- }
+ } else if (v->type() == nAttrs) {
+ attrs2["type"] = "strings";
+ XMLOpenElement m(xml, "meta", attrs2);
+ Bindings & attrs = *v->attrs;
+ for (auto &i : attrs) {
+ Attr & a(*attrs.find(i.name));
+ if(a.value->type() != nString) continue;
+ XMLAttrs attrs3;
+ attrs3["type"] = i.name;
+ attrs3["value"] = a.value->string.s;
+ xml.writeEmptyElement("string", attrs3);
+ }
}
}
}
- } else
- xml.writeEmptyElement("item", attrs);
+ }
} else
table.push_back(columns);
diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc
index af4f350ff..bcc7736ac 100644
--- a/src/nix-env/user-env.cc
+++ b/src/nix-env/user-env.cc
@@ -56,7 +56,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
output paths, and optionally the derivation path, as well
as the meta attributes. */
std::optional<StorePath> drvPath = keepDerivations ? i.queryDrvPath() : std::nullopt;
- DrvInfo::Outputs outputs = i.queryOutputs(true);
+ DrvInfo::Outputs outputs = i.queryOutputs(true, true);
StringSet metaNames = i.queryMetaNames();
auto attrs = state.buildBindings(7 + outputs.size());
@@ -76,15 +76,15 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
for (const auto & [m, j] : enumerate(outputs)) {
(vOutputs.listElems()[m] = state.allocValue())->mkString(j.first);
auto outputAttrs = state.buildBindings(2);
- outputAttrs.alloc(state.sOutPath).mkString(state.store->printStorePath(j.second));
+ outputAttrs.alloc(state.sOutPath).mkString(state.store->printStorePath(*j.second));
attrs.alloc(j.first).mkAttrs(outputAttrs);
/* This is only necessary when installing store paths, e.g.,
`nix-env -i /nix/store/abcd...-foo'. */
- state.store->addTempRoot(j.second);
- state.store->ensurePath(j.second);
+ state.store->addTempRoot(*j.second);
+ state.store->ensurePath(*j.second);
- references.insert(j.second);
+ references.insert(*j.second);
}
// Copy the meta attributes.