forked from lix-project/lix
* `nix-env -q --xml': show query result in XML format for easier
automated processing.
This commit is contained in:
parent
0e267e2625
commit
339e6f0e1d
|
@ -45,7 +45,7 @@ void XMLWriter::closeElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLWriter::writeShortElement(const string & name,
|
void XMLWriter::writeEmptyElement(const string & name,
|
||||||
const XMLAttrs & attrs)
|
const XMLAttrs & attrs)
|
||||||
{
|
{
|
||||||
assert(!closed);
|
assert(!closed);
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
const XMLAttrs & attrs = XMLAttrs());
|
const XMLAttrs & attrs = XMLAttrs());
|
||||||
void closeElement();
|
void closeElement();
|
||||||
|
|
||||||
void writeShortElement(const string & name,
|
void writeEmptyElement(const string & name,
|
||||||
const XMLAttrs & attrs = XMLAttrs());
|
const XMLAttrs & attrs = XMLAttrs());
|
||||||
|
|
||||||
void writeCharData(const string & data);
|
void writeCharData(const string & data);
|
||||||
|
|
|
@ -12,11 +12,13 @@
|
||||||
#include "get-drvs.hh"
|
#include "get-drvs.hh"
|
||||||
#include "attr-path.hh"
|
#include "attr-path.hh"
|
||||||
#include "pathlocks.hh"
|
#include "pathlocks.hh"
|
||||||
|
#include "xml-writer.hh"
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -724,6 +726,8 @@ static string colorString(const string & s)
|
||||||
static void opQuery(Globals & globals,
|
static void opQuery(Globals & globals,
|
||||||
Strings opFlags, Strings opArgs)
|
Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
|
typedef vector< map<string, string> > ResultSet;
|
||||||
|
|
||||||
bool printStatus = false;
|
bool printStatus = false;
|
||||||
bool printName = true;
|
bool printName = true;
|
||||||
bool printAttrPath = false;
|
bool printAttrPath = false;
|
||||||
|
@ -732,6 +736,7 @@ static void opQuery(Globals & globals,
|
||||||
bool printOutPath = false;
|
bool printOutPath = false;
|
||||||
bool printDescription = false;
|
bool printDescription = false;
|
||||||
bool compareVersions = false;
|
bool compareVersions = false;
|
||||||
|
bool xmlOutput = false;
|
||||||
|
|
||||||
enum { sInstalled, sAvailable } source = sInstalled;
|
enum { sInstalled, sAvailable } source = sInstalled;
|
||||||
|
|
||||||
|
@ -748,6 +753,7 @@ static void opQuery(Globals & globals,
|
||||||
else if (*i == "--out-path") printOutPath = true;
|
else if (*i == "--out-path") printOutPath = true;
|
||||||
else if (*i == "--installed") source = sInstalled;
|
else if (*i == "--installed") source = sInstalled;
|
||||||
else if (*i == "--available" || *i == "-a") source = sAvailable;
|
else if (*i == "--available" || *i == "-a") source = sAvailable;
|
||||||
|
else if (*i == "--xml") xmlOutput = true;
|
||||||
else throw UsageError(format("unknown flag `%1%'") % *i);
|
else throw UsageError(format("unknown flag `%1%'") % *i);
|
||||||
|
|
||||||
if (globals.instSource.type == srcAttrPath) printAttrPath = true; /* hack */
|
if (globals.instSource.type == srcAttrPath) printAttrPath = true; /* hack */
|
||||||
|
@ -795,28 +801,47 @@ static void opQuery(Globals & globals,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Print the desired columns. */
|
/* Print the desired columns, or XML output. */
|
||||||
Table table;
|
Table table;
|
||||||
|
ostringstream dummy;
|
||||||
|
XMLWriter xml(xmlOutput ? cout : dummy);
|
||||||
|
XMLOpenElement xmlRoot(xml, "items");
|
||||||
|
|
||||||
for (vector<DrvInfo>::iterator i = elems2.begin();
|
for (vector<DrvInfo>::iterator i = elems2.begin();
|
||||||
i != elems2.end(); ++i)
|
i != elems2.end(); ++i)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
/* For table output. */
|
||||||
Strings columns;
|
Strings columns;
|
||||||
|
|
||||||
|
/* For XML output. */
|
||||||
|
XMLAttrs attrs;
|
||||||
|
|
||||||
if (printStatus) {
|
if (printStatus) {
|
||||||
Substitutes subs = querySubstitutes(noTxn, i->queryOutPath(globals.state));
|
Substitutes subs = querySubstitutes(noTxn, i->queryOutPath(globals.state));
|
||||||
|
bool isInstalled = installed.find(i->queryOutPath(globals.state)) != installed.end();
|
||||||
|
bool isValid = isValidPath(i->queryOutPath(globals.state));
|
||||||
|
if (xmlOutput) {
|
||||||
|
attrs["installed"] = isInstalled ? "1" : "0";
|
||||||
|
attrs["valid"] = isValid ? "1" : "0";
|
||||||
|
attrs["substitutable"] = !subs.empty() ? "1" : "0";
|
||||||
|
} else
|
||||||
columns.push_back(
|
columns.push_back(
|
||||||
(string) (installed.find(i->queryOutPath(globals.state))
|
(string) (isInstalled ? "I" : "-")
|
||||||
!= installed.end() ? "I" : "-")
|
+ (isValid ? "P" : "-")
|
||||||
+ (isValidPath(i->queryOutPath(globals.state)) ? "P" : "-")
|
+ (!subs.empty() ? "S" : "-"));
|
||||||
+ (subs.size() > 0 ? "S" : "-"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (printAttrPath) columns.push_back(i->attrPath);
|
if (xmlOutput)
|
||||||
|
attrs["attrPath"] = i->attrPath;
|
||||||
|
else if (printAttrPath)
|
||||||
|
columns.push_back(i->attrPath);
|
||||||
|
|
||||||
if (printName) columns.push_back(i->name);
|
if (xmlOutput)
|
||||||
|
attrs["name"] = i->name;
|
||||||
|
else if (printName)
|
||||||
|
columns.push_back(i->name);
|
||||||
|
|
||||||
if (compareVersions) {
|
if (compareVersions) {
|
||||||
/* Compare this element against the versions of the
|
/* Compare this element against the versions of the
|
||||||
|
@ -825,6 +850,7 @@ static void opQuery(Globals & globals,
|
||||||
This is O(N * M), should be O(N * lg M). */
|
This is O(N * M), should be O(N * lg M). */
|
||||||
string version;
|
string version;
|
||||||
VersionDiff diff = compareVersionAgainstSet(*i, otherElems, version);
|
VersionDiff diff = compareVersionAgainstSet(*i, otherElems, version);
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
switch (diff) {
|
switch (diff) {
|
||||||
case cvLess: ch = '>'; break;
|
case cvLess: ch = '>'; break;
|
||||||
|
@ -833,31 +859,62 @@ static void opQuery(Globals & globals,
|
||||||
case cvUnavail: ch = '-'; break;
|
case cvUnavail: ch = '-'; break;
|
||||||
default: abort();
|
default: abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xmlOutput) {
|
||||||
|
if (diff != cvUnavail) {
|
||||||
|
attrs["versionDiff"] = ch;
|
||||||
|
attrs["maxComparedVersion"] = version;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
string column = (string) "" + ch + " " + version;
|
string column = (string) "" + ch + " " + version;
|
||||||
if (diff == cvGreater) column = colorString(column);
|
if (diff == cvGreater) column = colorString(column);
|
||||||
columns.push_back(column);
|
columns.push_back(column);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (printSystem) columns.push_back(i->system);
|
if (xmlOutput) {
|
||||||
|
if (i->system != "") attrs["system"] = i->system;
|
||||||
|
}
|
||||||
|
else if (printSystem)
|
||||||
|
columns.push_back(i->system);
|
||||||
|
|
||||||
if (printDrvPath) columns.push_back(
|
if (printDrvPath) {
|
||||||
i->queryDrvPath(globals.state) == ""
|
string drvPath = i->queryDrvPath(globals.state);
|
||||||
? "-" : i->queryDrvPath(globals.state));
|
if (xmlOutput) {
|
||||||
|
if (drvPath != "") attrs["drvPath"] = drvPath;
|
||||||
|
} else
|
||||||
|
columns.push_back(drvPath == "" ? "-" : drvPath);
|
||||||
|
}
|
||||||
|
|
||||||
if (printOutPath) columns.push_back(i->queryOutPath(globals.state));
|
if (printOutPath) {
|
||||||
|
string outPath = i->queryOutPath(globals.state);
|
||||||
|
if (xmlOutput) {
|
||||||
|
if (outPath != "") attrs["outPath"] = outPath;
|
||||||
|
} else
|
||||||
|
columns.push_back(outPath);
|
||||||
|
}
|
||||||
|
|
||||||
if (printDescription) {
|
if (printDescription) {
|
||||||
MetaInfo meta = i->queryMetaInfo(globals.state);
|
MetaInfo meta = i->queryMetaInfo(globals.state);
|
||||||
columns.push_back(meta["description"]);
|
string descr = meta["description"];
|
||||||
|
if (xmlOutput) {
|
||||||
|
if (descr != "") attrs["description"] = descr;
|
||||||
|
} else
|
||||||
|
columns.push_back(descr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xmlOutput) {
|
||||||
|
xml.writeEmptyElement("item", attrs);
|
||||||
|
xml.writeCharData("\n");
|
||||||
|
} else
|
||||||
table.push_back(columns);
|
table.push_back(columns);
|
||||||
}
|
|
||||||
catch (AssertionError & e) {
|
} catch (AssertionError & e) {
|
||||||
|
/* !!! hm, maybe we should give some sort of warning here? */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printTable(table);
|
if (!xmlOutput) printTable(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue