From 8bcdd36f10c5adfd312493c822c95c6fa5fbd110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Mon, 31 May 2010 16:36:24 +0000 Subject: [PATCH] Add XML output to `nix-store'. * src/nix-store/Makefile.am (nix_store_SOURCES): Add `xmlgraph.cc' and `xmlgraph.hh'. * src/nix-store/help.txt (Operations): Document `--xml'. * src/nix-store/nix-store.cc (opQuery): Handle `--xml'. * src/nix-store/xmlgraph.cc, src/nix-store/xmlgraph.hh: New files. --- src/nix-store/Makefile.am | 5 ++- src/nix-store/help.txt | 1 + src/nix-store/nix-store.cc | 14 ++++++-- src/nix-store/xmlgraph.cc | 71 ++++++++++++++++++++++++++++++++++++++ src/nix-store/xmlgraph.hh | 12 +++++++ 5 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 src/nix-store/xmlgraph.cc create mode 100644 src/nix-store/xmlgraph.hh diff --git a/src/nix-store/Makefile.am b/src/nix-store/Makefile.am index 9a439dd92..b6dd37a61 100644 --- a/src/nix-store/Makefile.am +++ b/src/nix-store/Makefile.am @@ -1,6 +1,9 @@ bin_PROGRAMS = nix-store -nix_store_SOURCES = nix-store.cc dotgraph.cc dotgraph.hh help.txt +nix_store_SOURCES = \ + nix-store.cc dotgraph.cc dotgraph.hh help.txt \ + xmlgraph.cc xmlgraph.hh + nix_store_LDADD = ../libmain/libmain.la ../libstore/libstore.la ../libutil/libutil.la \ ../boost/format/libformat.la @ADDITIONAL_NETWORK_LIBS@ diff --git a/src/nix-store/help.txt b/src/nix-store/help.txt index 7576e3ef5..071934b20 100644 --- a/src/nix-store/help.txt +++ b/src/nix-store/help.txt @@ -39,6 +39,7 @@ Query flags: --referrers-closure: print all paths (in)directly refering to the path --tree: print a tree showing the dependency graph of the path --graph: print a dot graph rooted at given path + --xml: emit an XML representation of the graph rooted at the given path --hash: print the SHA-256 hash of the contents of the path --roots: print the garbage collector roots that point to the path diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 22effc65d..e22ef7efc 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -6,6 +6,7 @@ #include "archive.hh" #include "shared.hh" #include "dotgraph.hh" +#include "xmlgraph.hh" #include "local-store.hh" #include "util.hh" #include "help.txt.hh" @@ -226,7 +227,7 @@ static void opQuery(Strings opFlags, Strings opArgs) { enum { qOutputs, qRequisites, qReferences, qReferrers , qReferrersClosure, qDeriver, qBinding, qHash - , qTree, qGraph, qResolve, qRoots } query = qOutputs; + , qTree, qGraph, qXml, qResolve, qRoots } query = qOutputs; bool useOutput = false; bool includeOutputs = false; bool forceRealise = false; @@ -249,6 +250,7 @@ static void opQuery(Strings opFlags, Strings opArgs) else if (*i == "--hash") query = qHash; else if (*i == "--tree") query = qTree; else if (*i == "--graph") query = qGraph; + else if (*i == "--xml") query = qXml; else if (*i == "--resolve") query = qResolve; else if (*i == "--roots") query = qRoots; else if (*i == "--use-output" || *i == "-u") useOutput = true; @@ -327,7 +329,15 @@ static void opQuery(Strings opFlags, Strings opArgs) PathSet roots; foreach (Strings::iterator, i, opArgs) roots.insert(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise)); - printDotGraph(roots); + printDotGraph(roots); + break; + } + + case qXml: { + PathSet roots; + foreach (Strings::iterator, i, opArgs) + roots.insert(maybeUseOutput(followLinksToStorePath(*i), useOutput, forceRealise)); + printXmlGraph(roots); break; } diff --git a/src/nix-store/xmlgraph.cc b/src/nix-store/xmlgraph.cc new file mode 100644 index 000000000..1b3ad3d28 --- /dev/null +++ b/src/nix-store/xmlgraph.cc @@ -0,0 +1,71 @@ +#include "xmlgraph.hh" +#include "util.hh" +#include "store-api.hh" + +#include + + +using std::cout; + +namespace nix { + + +static inline const string & xmlQuote(const string & s) +{ + // Luckily, store paths shouldn't contain any character that needs to be + // quoted. + return s; +} + + +static string makeEdge(const string & src, const string & dst) +{ + format f = format(" \n") + % xmlQuote(src) % xmlQuote(dst); + return f.str(); +} + + +static string makeNode(const string & id) +{ + format f = format(" \n") % xmlQuote(id); + return f.str(); +} + + +void printXmlGraph(const PathSet & roots) +{ + PathSet workList(roots); + PathSet doneSet; + + cout << "\n" + << "\n"; + + while (!workList.empty()) { + Path path = *(workList.begin()); + workList.erase(path); + + if (doneSet.find(path) != doneSet.end()) continue; + doneSet.insert(path); + + cout << makeNode(path); + + PathSet references; + store->queryReferences(path, references); + + for (PathSet::iterator i = references.begin(); + i != references.end(); ++i) + { + if (*i != path) { + workList.insert(*i); + cout << makeEdge(*i, path); + } + } + + } + + cout << "\n"; +} + + +} diff --git a/src/nix-store/xmlgraph.hh b/src/nix-store/xmlgraph.hh new file mode 100644 index 000000000..2f9908c43 --- /dev/null +++ b/src/nix-store/xmlgraph.hh @@ -0,0 +1,12 @@ +#ifndef __XMLGRAPH_H +#define __XMLGRAPH_H + +#include "types.hh" + +namespace nix { + +void printXmlGraph(const PathSet & roots); + +} + +#endif /* !__XMLGRAPH_H */