cmd/viewcore: fix commandPath recursion commandPath recursively called itself with the same command when the command had a parent. The recursion therefore never reached the root command and eventually caused a stack overflow. Recurse with c.Parent() so each call advances toward the root. Add table-driven tests covering root, one-level, and two-level command paths. Change-Id: I8d258a9f2d4d2c42c1cd66df0873fa99185a8aa9 Reviewed-on: https://go-review.googlesource.com/c/debug/+/811640 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Keith Randall <khr@golang.org>
diff --git a/cmd/viewcore/main.go b/cmd/viewcore/main.go index 0244589..509cf3b 100644 --- a/cmd/viewcore/main.go +++ b/cmd/viewcore/main.go
@@ -204,7 +204,7 @@ // with viewcore's unusual command structure. func commandPath(c *cobra.Command) string { if c.HasParent() { - return commandPath(c) + " " + c.Name() + return commandPath(c.Parent()) + " " + c.Name() } return c.Use }
diff --git a/cmd/viewcore/main_test.go b/cmd/viewcore/main_test.go new file mode 100644 index 0000000..8c77213 --- /dev/null +++ b/cmd/viewcore/main_test.go
@@ -0,0 +1,39 @@ +// Copyright 2026 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !aix && !plan9 && !wasm + +package main + +import ( + "testing" + + "github.com/spf13/cobra" +) + +func TestCommandPath(t *testing.T) { + root := &cobra.Command{Use: "root <arg>"} + child := &cobra.Command{Use: "child"} + grandchild := &cobra.Command{Use: "grandchild"} + root.AddCommand(child) + child.AddCommand(grandchild) + + tests := []struct { + name string + cmd *cobra.Command + want string + }{ + {name: "root", cmd: root, want: "root <arg>"}, + {name: "child", cmd: child, want: "root <arg> child"}, + {name: "grandchild", cmd: grandchild, want: "root <arg> child grandchild"}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := commandPath(test.cmd); got != test.want { + t.Errorf("commandPath() = %q, want %q", got, test.want) + } + }) + } +}