// dotDump dumps the given image stream tree in DOT syntax func dotDump(root *Node, g *dot.Graph, graphName string) (string, error) { if root == nil { return "", nil } // Add current node rootNamespace, rootName, err := split(root.FullName) if err != nil { return "", err } attrs := make(map[string]string) for _, tag := range root.Tags { setTag(tag, attrs) } var tag string // Inject tag into root's name once.Do(func() { tag = root.Tags[0] }) setLabel(rootName, rootNamespace, attrs, tag) rootName = validDOT(rootName) g.AddNode(graphName, rootName, attrs) // Add edges between current node and its children for _, child := range root.Children { for _, edge := range root.Edges { if child.FullName == edge.To { _, childName, err := split(child.FullName) if err != nil { return "", err } childName = validDOT(childName) edgeNamespace, edgeName, err := split(edge.FullName) if err != nil { return "", err } edgeName = validDOT(edgeName) edgeAttrs := make(map[string]string) setLabel(edgeName, edgeNamespace, edgeAttrs, "") g.AddEdge(rootName, childName, true, edgeAttrs) } } // Recursively add every child and their children as nodes if _, err := dotDump(child, g, graphName); err != nil { return "", err } } dotOutput := g.String() // Parse DOT output for validation if _, err := dot.Parse([]byte(dotOutput)); err != nil { return "", fmt.Errorf("cannot parse DOT output: %v", err) } return dotOutput, nil }
func ParseTasks(topologyDot []byte) *TaskGraphStructure { parsed, err := gographviz.Parse(topologyDot) if err != nil { panic(err) } // Display the graph var topology *TaskGraphStructure topology = NewTaskGraphStructure() gographviz.Analyse(parsed, topology) return topology }