about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/dotgraph.cc99
-rw-r--r--src/nix.cc2
2 files changed, 86 insertions, 15 deletions
diff --git a/src/dotgraph.cc b/src/dotgraph.cc
index 9f0182e53096..1b352e3ff384 100644
--- a/src/dotgraph.cc
+++ b/src/dotgraph.cc
@@ -7,6 +7,84 @@ static string dotQuote(const string & s)
 }
 
 
+static string nextColour()
+{
+    static int n = 0;
+    static string colours[] =
+	{ "black", "red", "green", "blue"
+	, "magenta", "burlywood" };
+    return colours[n++ % (sizeof(colours) / sizeof(string))];
+}
+
+
+static string makeEdge(const string & src, const string & dst)
+{
+    format f = format("%1% -> %2% [color = %3%];\n")
+	% dotQuote(src) % dotQuote(dst) % dotQuote(nextColour());
+    return f.str();
+}
+
+
+static string makeNode(const string & id, const string & label,
+    const string & colour)
+{
+    format f = format("%1% [label = %2%, shape = box, "
+	"style = filled, fillcolor = %3%];\n")
+	% dotQuote(id) % dotQuote(label) % dotQuote(colour);
+    return f.str();
+}
+
+
+static string symbolicName(const string & path)
+{
+    string p = baseNameOf(path);
+    if (isHash(string(p, 0, Hash::hashSize * 2)) && 
+	p[Hash::hashSize * 2] == '-')
+	p = string(p, Hash::hashSize * 2 + 1);
+    return p;
+}
+
+
+string pathLabel(const FSId & id, const string & path)
+{
+    return (string) id + "-" + path;
+}
+
+
+void printSlice(const FSId & id, const FState & fs)
+{
+    Strings workList(fs.slice.roots.begin(), fs.slice.roots.end());
+    StringSet doneSet;
+
+    for (Strings::iterator i = workList.begin(); i != workList.end(); i++) {
+	cout << makeEdge(pathLabel(id, *i), id);
+    }
+
+    while (!workList.empty()) {
+	string path = workList.front();
+	workList.pop_front();
+
+	if (doneSet.find(path) == doneSet.end()) {
+	    doneSet.insert(path);
+
+	    SliceElems::const_iterator elem = fs.slice.elems.find(path);
+	    if (elem == fs.slice.elems.end())
+		throw Error(format("bad slice, missing path `%1%'") % path);
+
+	    for (StringSet::const_iterator i = elem->second.refs.begin();
+		 i != elem->second.refs.end(); i++)
+	    {
+		workList.push_back(*i);
+		cout << makeEdge(pathLabel(id, *i), pathLabel(id, path));
+	    }
+
+	    cout << makeNode(pathLabel(id, path), 
+		symbolicName(path), "#ff0000");
+	}
+    }
+}
+
+
 void printDotGraph(const FSIds & roots)
 {
     FSIds workList(roots.begin(), roots.end());
@@ -23,41 +101,34 @@ void printDotGraph(const FSIds & roots)
                     
 	    FState fs = parseFState(termFromId(id));
 
-	    string label, shape;
+	    string label, colour;
                     
 	    if (fs.type == FState::fsDerive) {
 		for (FSIdSet::iterator i = fs.derive.inputs.begin();
 		     i != fs.derive.inputs.end(); i++)
 		{
 		    workList.push_back(*i);
-		    cout << dotQuote(*i) << " -> "
-			 << dotQuote(id) << ";\n";
+		    cout << makeEdge(*i, id);
 		}
 
 		label = "derive";
-		shape = "box";
+		colour = "#00ff00";
 		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()).first);
-		shape = "ellipse";
-		if (isHash(string(label, 0, Hash::hashSize * 2)) && 
-		    label[Hash::hashSize * 2] == '-')
-		    label = string(label, Hash::hashSize * 2 + 1);
+		label = "<slice>";
+		colour = "#00ffff";
+		printSlice(id, fs);
 	    }
 
 	    else abort();
 
-	    cout << dotQuote(id) << "[label = "
-		 << dotQuote(label)
-		 << ", shape = " << shape
-		 << "];\n";
+	    cout << makeNode(id, label, colour);
 	}
     }
 
     cout << "}\n";
-
 }
diff --git a/src/nix.cc b/src/nix.cc
index 41ed16839725..12a01fd3616e 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -168,7 +168,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
             FSIds roots;
             for (Strings::iterator i = opArgs.begin();
                  i != opArgs.end(); i++)
-                roots.push_back(argToId(*i));
+                roots.push_back(maybeNormalise(argToId(*i), normalise));
 	    printDotGraph(roots);
             break;
         }