[tools] cmd/digraph: rename graph -> digraph

4 views
Skip to first unread message

Austin Clements (Gerrit)

unread,
Feb 19, 2026, 6:54:07 PM (5 days ago) Feb 19
to Alan Donovan, goph...@pubsubhelper.golang.org, Austin Clements, golang-co...@googlegroups.com
Attention needed from Alan Donovan

Austin Clements has uploaded the change for review

Austin Clements would like Alan Donovan to review this change.

Commit message

cmd/digraph: rename graph -> digraph

So we can import the graph package without an annoying name conflict.
Change-Id: Icd3abacee5f152d96edd39a4a4ae4aff1d714eb5

Change diff

diff --git a/cmd/digraph/digraph.go b/cmd/digraph/digraph.go
index f3811fe..3f9c767 100644
--- a/cmd/digraph/digraph.go
+++ b/cmd/digraph/digraph.go
@@ -47,7 +47,7 @@
usage()
}

- if err := digraph(args[0], args[1:]); err != nil {
+ if err := doDigraph(args[0], args[1:]); err != nil {
fmt.Fprintf(os.Stderr, "digraph: %s\n", err)
os.Exit(1)
}
@@ -86,10 +86,10 @@
}
}

-// A graph maps nodes to the non-nil set of their immediate successors.
-type graph map[string]nodeset
+// A digraph maps nodes to the non-nil set of their immediate successors.
+type digraph map[string]nodeset

-func (g graph) addNode(node string) nodeset {
+func (g digraph) addNode(node string) nodeset {
edges := g[node]
if edges == nil {
edges = make(nodeset)
@@ -98,7 +98,7 @@
return edges
}

-func (g graph) addEdges(from string, to ...string) {
+func (g digraph) addEdges(from string, to ...string) {
edges := g.addNode(from)
for _, to := range to {
g.addNode(to)
@@ -106,7 +106,7 @@
}
}

-func (g graph) nodelist() nodelist {
+func (g digraph) nodelist() nodelist {
nodes := make(nodeset)
for node := range g {
nodes[node] = true
@@ -114,7 +114,7 @@
return nodes.sort()
}

-func (g graph) reachableFrom(roots nodeset) nodeset {
+func (g digraph) reachableFrom(roots nodeset) nodeset {
seen := make(nodeset)
var visit func(node string)
visit = func(node string) {
@@ -131,8 +131,8 @@
return seen
}

-func (g graph) transpose() graph {
- rev := make(graph)
+func (g digraph) transpose() digraph {
+ rev := make(digraph)
for node, edges := range g {
rev.addNode(node)
for succ := range edges {
@@ -142,7 +142,7 @@
return rev
}

-func (g graph) sccs() []nodeset {
+func (g digraph) sccs() []nodeset {
// Kosaraju's algorithm---Tarjan is overkill here.

// Forward pass.
@@ -192,7 +192,7 @@
return sccs
}

-func (g graph) allpaths(from, to string) error {
+func (g digraph) allpaths(from, to string) error {
// We intersect the forward closure of 'from' with
// the reverse closure of 'to'. This is not the most
// efficient implementation, but it's the clearest,
@@ -224,7 +224,7 @@
return nil
}

-func (g graph) somepath(from, to string) error {
+func (g digraph) somepath(from, to string) error {
// Search breadth-first so that we return a minimal path.

// A path is a linked list whose head is a candidate "to" node
@@ -265,7 +265,7 @@
return fmt.Errorf("no path from %q to %q", from, to)
}

-func (g graph) toDot(w *bytes.Buffer) {
+func (g digraph) toDot(w *bytes.Buffer) {
fmt.Fprintln(w, "digraph {")
for _, src := range g.nodelist() {
for _, dst := range g[src].sort() {
@@ -279,8 +279,8 @@
fmt.Fprintln(w, "}")
}

-func parse(rd io.Reader) (graph, error) {
- g := make(graph)
+func parse(rd io.Reader) (digraph, error) {
+ g := make(digraph)

var linenum int
// We avoid bufio.Scanner as it imposes a (configurable) limit
@@ -314,7 +314,7 @@
var stdin io.Reader = os.Stdin
var stdout io.Writer = os.Stdout

-func digraph(cmd string, args []string) error {
+func doDigraph(cmd string, args []string) error {
// Parse the input graph.
g, err := parse(stdin)
if err != nil {
diff --git a/cmd/digraph/digraph_test.go b/cmd/digraph/digraph_test.go
index d244615..74e61ee 100644
--- a/cmd/digraph/digraph_test.go
+++ b/cmd/digraph/digraph_test.go
@@ -53,7 +53,7 @@
t.Run(test.name, func(t *testing.T) {
stdin = strings.NewReader(test.input)
stdout = new(bytes.Buffer)
- if err := digraph(test.cmd, test.args); err != nil {
+ if err := doDigraph(test.cmd, test.args); err != nil {
t.Fatal(err)
}

@@ -187,7 +187,7 @@
t.Run(test.name, func(t *testing.T) {
stdin = strings.NewReader(test.in)
stdout = new(bytes.Buffer)
- if err := digraph("allpaths", []string{"A", test.to}); err != nil {
+ if err := doDigraph("allpaths", []string{"A", test.to}); err != nil {
t.Fatal(err)
}

@@ -242,7 +242,7 @@
t.Run(test.name, func(t *testing.T) {
stdin = strings.NewReader(test.in)
stdout = new(bytes.Buffer)
- if err := digraph("somepath", []string{"A", test.to}); err != nil {
+ if err := doDigraph("somepath", []string{"A", test.to}); err != nil {
t.Fatal(err)
}

@@ -372,7 +372,7 @@
t.Run(test.name, func(t *testing.T) {
stdin = strings.NewReader(test.in)
stdout = new(bytes.Buffer)
- if err := digraph("focus", []string{test.focus}); err != nil {
+ if err := doDigraph("focus", []string{test.focus}); err != nil {
t.Fatal(err)
}
got := stdout.(fmt.Stringer).String()
@@ -397,7 +397,7 @@
defer func(in io.Reader, out io.Writer) { stdin, stdout = in, out }(stdin, stdout)
stdin = strings.NewReader(in)
stdout = new(bytes.Buffer)
- if err := digraph("to", []string{"dot"}); err != nil {
+ if err := doDigraph("to", []string{"dot"}); err != nil {
t.Fatal(err)
}
got := stdout.(fmt.Stringer).String()

Change information

Files:
  • M cmd/digraph/digraph.go
  • M cmd/digraph/digraph_test.go
Change size: S
Delta: 2 files changed, 21 insertions(+), 21 deletions(-)
Open in Gerrit

Related details

Attention is currently required from:
  • Alan Donovan
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Icd3abacee5f152d96edd39a4a4ae4aff1d714eb5
Gerrit-Change-Number: 747362
Gerrit-PatchSet: 1
Gerrit-Owner: Austin Clements <aus...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Austin Clements <aus...@google.com>
Gerrit-Attention: Alan Donovan <adon...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Austin Clements (Gerrit)

unread,
Feb 19, 2026, 6:58:09 PM (5 days ago) Feb 19
to Austin Clements, goph...@pubsubhelper.golang.org, Go LUCI, Alan Donovan, golang-co...@googlegroups.com
Attention needed from Alan Donovan

Austin Clements added 1 comment

Patchset-level comments
File-level comment, Patchset 1 (Latest):
Austin Clements . resolved

Starting from this commit, I mostly wanted to validate my new graph package by making sure cmd/digraph could be rewritten to use it. I don't have a strong feeling on whether it's worth the churn, but it's also not bad.

For the record, to do the algorithm ports, I used the following Gemini CLI prompt, followed by manual review and fairly minor cleanup:

I want to reimplement ./cmd/digraph to use the new ./internal/graph package. For each graph algorithm implemented in digraph as a method on its digraph type: 1. reimplement that algorithm in the graph package following the implementation strategy from digraph but operating on the graph.Graph interface, 2. modify digraph to use the graph package's version of the algorithm, 3. check that the digraph and graph tests pass, and 4. commit that algorithm as its own git commit for ease of review. Put each algorithm in its own source file in the graph package. Please copy over any relevant comments from the digraph implementation, particularly those about implementation strategy. The digraph algorithms are all done on string-identified nodes, so where it would be more efficient to use compactly numbered nodes, you can use graph.Compact in the algorithm (see graph.Postorder for an example of this), but this is not required. The output of the digraph command must remain determinsitic, but it doesn't have to stay in the same order it currently emits, so it's okay to do less sorting as long as the outcome is deterministic. You can use the tests in cmd/digraph to check your work, though you may need to update the order of output if that changes.

Open in Gerrit

Related details

Attention is currently required from:
  • Alan Donovan
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Icd3abacee5f152d96edd39a4a4ae4aff1d714eb5
Gerrit-Change-Number: 747362
Gerrit-PatchSet: 1
Gerrit-Owner: Austin Clements <aus...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Austin Clements <aus...@google.com>
Gerrit-Attention: Alan Donovan <adon...@google.com>
Gerrit-Comment-Date: Thu, 19 Feb 2026 23:58:06 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
unsatisfied_requirement
satisfied_requirement
open
diffy

Alan Donovan (Gerrit)

unread,
Feb 23, 2026, 2:04:05 PM (2 days ago) Feb 23
to Austin Clements, goph...@pubsubhelper.golang.org, Go LUCI, golang-co...@googlegroups.com
Attention needed from Austin Clements

Alan Donovan voted Code-Review+2

Code-Review+2
Open in Gerrit

Related details

Attention is currently required from:
  • Austin Clements
Submit Requirements:
  • requirement satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement satisfiedReview-Enforcement
  • requirement satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Icd3abacee5f152d96edd39a4a4ae4aff1d714eb5
Gerrit-Change-Number: 747362
Gerrit-PatchSet: 1
Gerrit-Owner: Austin Clements <aus...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Austin Clements <aus...@google.com>
Gerrit-Attention: Austin Clements <aus...@google.com>
Gerrit-Comment-Date: Mon, 23 Feb 2026 19:04:01 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
satisfied_requirement
open
diffy

Austin Clements (Gerrit)

unread,
Feb 24, 2026, 10:03:24 PM (7 hours ago) Feb 24
to Austin Clements, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Austin Clements

Austin Clements uploaded new patchset

Austin Clements uploaded patch set #2 to this change.
Following approvals got outdated and were removed:
  • TryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
Open in Gerrit

Related details

Attention is currently required from:
  • Austin Clements
Submit Requirements:
    • requirement satisfiedCode-Review
    • requirement satisfiedNo-Unresolved-Comments
    • requirement satisfiedReview-Enforcement
    • requirement is not satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: newpatchset
    Gerrit-Project: tools
    Gerrit-Branch: master
    Gerrit-Change-Id: Icd3abacee5f152d96edd39a4a4ae4aff1d714eb5
    Gerrit-Change-Number: 747362
    Gerrit-PatchSet: 2
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy
    Reply all
    Reply to author
    Forward
    0 new messages