From 949c4fa1a863a804bdf1f985b55d5259f18838ae Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 28 Jul 2003 12:19:23 +0000 Subject: [PATCH] * `nix --help'. * `nix --query --graph' to print a dot dependency graph of derive expressions. --- src/Makefile.am | 9 +++- src/nix-help.txt | 36 ++++++++++++++++ src/nix.cc | 108 +++++++++++++++++++++++++++++++---------------- 3 files changed, 116 insertions(+), 37 deletions(-) create mode 100644 src/nix-help.txt diff --git a/src/Makefile.am b/src/Makefile.am index 98d76b753..23e242919 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,6 +33,13 @@ libshared_a_CXXFLAGS = \ -DNIX_LOG_DIR=\"$(localstatedir)/log/nix\" \ $(AM_CXXFLAGS) +nix.o: nix-help.txt.hh + +%.hh: % + echo -n '"' > $@ + sed 's|\(.*\)|\1\\n\\|' < $< >> $@ + echo '"' >> $@ + install-data-local: $(INSTALL) -d $(localstatedir)/nix $(INSTALL) -d $(localstatedir)/nix/links @@ -40,4 +47,4 @@ install-data-local: $(INSTALL) -d $(prefix)/store $(bindir)/nix --init -EXTRA_DIST = *.hh *.h \ No newline at end of file +EXTRA_DIST = *.hh *.h diff --git a/src/nix-help.txt b/src/nix-help.txt new file mode 100644 index 000000000..ecf9b5c16 --- /dev/null +++ b/src/nix-help.txt @@ -0,0 +1,36 @@ +nix [OPTIONS...] [ARGUMENTS...] + +Operations: + + --install / -i: realise an fstate + --delete / -d: delete paths from the Nix store + --add / -A: copy a path to the Nix store + --query / -q: query information + + --successor: register a successor expression + --substitute: register a substitute expression + + --dump: dump a path as a Nix archive + --restore: restore a path from a Nix archive + + --init: initialise the Nix database + --verify: verify Nix structures + + --version: output version information + --help: display help + +Source selection for --install, --dump: + + --path / -p: by file name !!! -> path + +Query flags: + + --list / -l: query the output paths (roots) of an fstate (default) + --refs / -r: query paths referenced by an fstate + --generators / -g: find expressions producing a subset of given ids + --expansion / -e: print a path containing id + --graph: print a dot graph rooted at given ids + +Options: + + --verbose / -v: verbose operation (may be repeated) diff --git a/src/nix.cc b/src/nix.cc index 3345f983f..9e62fa395 100644 --- a/src/nix.cc +++ b/src/nix.cc @@ -13,42 +13,14 @@ typedef void (* Operation) (Strings opFlags, Strings opArgs); static bool pathArgs = false; -/* Nix syntax: +static void printHelp() +{ + cout << +#include "nix-help.txt.hh" + ; + exit(0); +} - nix [OPTIONS...] [ARGUMENTS...] - - Operations: - - --install / -i: realise an fstate - --delete / -d: delete paths from the Nix store - --add / -A: copy a path to the Nix store - --query / -q: query information - - --successor: register a successor expression - --substitute: register a substitute expression - - --dump: dump a path as a Nix archive - --restore: restore a path from a Nix archive - - --init: initialise the Nix database - --verify: verify Nix structures - - --version: output version information - --help: display help - - Source selection for --install, --dump: - - --path / -p: by file name !!! -> path - - Query flags: - - --list / -l: query the output paths (roots) of an fstate - --refs / -r: query paths referenced by an fstate - - Options: - - --verbose / -v: verbose operation -*/ static FSId argToId(const string & arg) @@ -104,10 +76,17 @@ static void opAdd(Strings opFlags, Strings opArgs) } +string dotQuote(const string & s) +{ + return "\"" + s + "\""; +} + + /* Perform various sorts of queries. */ static void opQuery(Strings opFlags, Strings opArgs) { - enum { qList, qRefs, qGenerators, qExpansion } query = qList; + enum { qList, qRefs, qGenerators, qExpansion, qGraph + } query = qList; for (Strings::iterator i = opFlags.begin(); i != opFlags.end(); i++) @@ -115,6 +94,7 @@ static void opQuery(Strings opFlags, Strings opArgs) else if (*i == "--refs" || *i == "-r") query = qRefs; else if (*i == "--generators" || *i == "-g") query = qGenerators; else if (*i == "--expansion" || *i == "-e") query = qExpansion; + else if (*i == "--graph") query = qGraph; else throw UsageError(format("unknown flag `%1%'") % *i); switch (query) { @@ -170,6 +150,60 @@ static void opQuery(Strings opFlags, Strings opArgs) break; } + case qGraph: { + + FSIds workList; + + for (Strings::iterator i = opArgs.begin(); + i != opArgs.end(); i++) + workList.push_back(argToId(*i)); + + FSIdSet doneSet; + + cout << "digraph G {\n"; + + while (!workList.empty()) { + FSId id = workList.front(); + workList.pop_front(); + + if (doneSet.find(id) == doneSet.end()) { + doneSet.insert(id); + + FState fs = parseFState(termFromId(id)); + + string label; + + if (fs.type == FState::fsDerive) { + for (FSIds::iterator i = fs.derive.inputs.begin(); + i != fs.derive.inputs.end(); i++) + { + workList.push_back(*i); + cout << dotQuote(*i) << " -> " + << dotQuote(id) << ";\n"; + } + + label = "derive"; + for (StringPairs::iterator i = fs.derive.env.begin(); + i != fs.derive.env.end(); i++) + if (i->first == "name") label = i->second; + } + + else if (fs.type == FState::fsSlice) { + label = baseNameOf((*fs.slice.elems.begin()).path); + } + + else abort(); + + cout << dotQuote(id) << "[label = " + << dotQuote(label) + << "];\n"; + } + } + + cout << "}\n"; + break; + } + default: abort(); } @@ -309,6 +343,8 @@ void run(Strings args) pathArgs = true; else if (arg == "--verbose" || arg == "-v") verbosity = (Verbosity) ((int) verbosity + 1); + else if (arg == "--help") + printHelp(); else if (arg[0] == '-') opFlags.push_back(arg); else