gopls/internal/tool: rename Application to Command This relands 0fdde844a (CL 791980), which was reverted in 0602b3093 (CL 793700) to stabilize the release. Rename tool.Application to tool.Command and embed it in tool.Subcommand to clarify the structure, addressing a TODO left in Gerrit CL 788640. References to tool.Application are updated to tool.Command throughout gopls/internal/cmd and gopls/internal/tool. Updates golang/go#79906 Change-Id: I839a0d126dcf8d687b2271f86ea443995b176b2a Reviewed-on: https://go-review.googlesource.com/c/tools/+/794461 Reviewed-by: Alan Donovan <adonovan@google.com> Auto-Submit: Hyang-Ah Hana Kim <hyangah@gmail.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/gopls/internal/cmd/cmd.go b/gopls/internal/cmd/cmd.go index 1f1cf79..fb38663 100644 --- a/gopls/internal/cmd/cmd.go +++ b/gopls/internal/cmd/cmd.go
@@ -136,18 +136,18 @@ return app } -// Name implements tool.Application returning the binary name. +// Name implements tool.Command returning the binary name. func (app *Application) Name() string { return "gopls" } -// Usage implements tool.Application returning empty extra argument usage. +// Usage implements tool.Command returning empty extra argument usage. func (app *Application) Usage() string { return "" } -// ShortHelp implements tool.Application returning the main binary help. +// ShortHelp implements tool.Command returning the main binary help. func (app *Application) ShortHelp() string { return "" } -// DetailedHelp implements tool.Application returning the main binary help. +// DetailedHelp implements tool.Command returning the main binary help. // This includes the short help for all the sub commands. func (app *Application) DetailedHelp(f *flag.FlagSet) { w := tabwriter.NewWriter(f.Output(), 0, 0, 2, ' ', 0) @@ -287,16 +287,16 @@ // Commands returns the set of commands supported by the gopls tool on the // command line. // The command is specified by the first non flag argument. -func (app *Application) Commands() []tool.Application { - var commands []tool.Application +func (app *Application) Commands() []tool.Command { + var commands []tool.Command commands = append(commands, app.mainCommands()...) commands = append(commands, app.featureCommands()...) commands = append(commands, app.internalCommands()...) return commands } -func (app *Application) mainCommands() []tool.Application { - return []tool.Application{ +func (app *Application) mainCommands() []tool.Command { + return []tool.Command{ &app.serve, &version{app: app}, &help{app: app}, @@ -305,14 +305,14 @@ } } -func (app *Application) internalCommands() []tool.Application { - return []tool.Application{ +func (app *Application) internalCommands() []tool.Command { + return []tool.Command{ &vulncheck{app: app}, } } -func (app *Application) featureCommands() []tool.Application { - return []tool.Application{ +func (app *Application) featureCommands() []tool.Command { + return []tool.Command{ &callHierarchy{app: app}, &check{app: app, Severity: "warning"}, &codeaction{app: app},
diff --git a/gopls/internal/cmd/info.go b/gopls/internal/cmd/info.go index b099046..dd4f991 100644 --- a/gopls/internal/cmd/info.go +++ b/gopls/internal/cmd/info.go
@@ -43,7 +43,7 @@ // Run prints help information about a subcommand. func (h *help) Run(ctx context.Context, args ...string) error { - find := func(cmds []tool.Application, name string) tool.Application { + find := func(cmds []tool.Command, name string) tool.Command { for _, cmd := range cmds { if cmd.Name() == name { return cmd @@ -53,7 +53,7 @@ } // Find the subcommand denoted by args (empty => h.app). - var cmd tool.Application = h.app + var cmd tool.Command = h.app for i, arg := range args { cmd = find(getSubcommands(cmd), arg) if cmd == nil {
diff --git a/gopls/internal/cmd/subcommands.go b/gopls/internal/cmd/subcommands.go index 47d577b..22034b9 100644 --- a/gopls/internal/cmd/subcommands.go +++ b/gopls/internal/cmd/subcommands.go
@@ -15,7 +15,7 @@ // subcommands is a helper that may be embedded for commands that delegate to // subcommands. -type subcommands []tool.Application +type subcommands []tool.Command func (s subcommands) DetailedHelp(f *flag.FlagSet) { w := tabwriter.NewWriter(f.Output(), 0, 0, 2, ' ', 0) @@ -43,14 +43,14 @@ return tool.CommandLineErrorf("unknown subcommand %v", command) } -func (s subcommands) Commands() []tool.Application { return s } +func (s subcommands) Commands() []tool.Command { return s } -// getSubcommands returns the subcommands of a given Application. -func getSubcommands(a tool.Application) []tool.Application { - // This interface is satisfied both by tool.Applications +// getSubcommands returns the subcommands of a given Command. +func getSubcommands(a tool.Command) []tool.Command { + // This interface is satisfied both by tool.Commands // that embed subcommands, and by *cmd.Application. type hasCommands interface { - Commands() []tool.Application + Commands() []tool.Command } if sub, ok := a.(hasCommands); ok { return sub.Commands()
diff --git a/gopls/internal/tool/tool.go b/gopls/internal/tool/tool.go index 70a6291..53031ea 100644 --- a/gopls/internal/tool/tool.go +++ b/gopls/internal/tool/tool.go
@@ -21,17 +21,11 @@ // This file is a harness for writing your main function. // -// It adds a method to the Application type -// Main(name, usage string, args []string) -// which should normally be invoked from a true main as follows: -// func main() { -// (&Application{}).Main("myapp", "non-flag-command-line-arg-help", os.Args[1:]) -// } -// It recursively scans the application object for fields with a tag containing +// It recursively scans the command object for fields with a tag containing // `flag:"flagnames" help:"short help text"` // uses all those fields to build command line flags. It will split flagnames on // commas and add a flag per name. -// It expects the Application type to have a method +// It expects the Command type to have a method // Run(context.Context, args...string) error // which it invokes only after all command line flag processing has been finished. // If Run returns an error, the error will be printed to stderr and the @@ -47,9 +41,9 @@ Block string `flag:"profile.block" help:"write block profile to this file"` } -// Application is the interface that must be satisfied by an object passed to Main. -type Application interface { - // Name returns the application's name. It is used in help and error messages. +// Command is the interface that must be satisfied by an object passed to Main. +type Command interface { + // Name returns the command's name. It is used in help and error messages. Name() string // Most of the help usage is automatically generated, this string should only // describe the contents of non flag arguments. @@ -67,7 +61,8 @@ Run(ctx context.Context, args ...string) error } -type SubCommand interface { +type Subcommand interface { + Command Parent() string } @@ -88,7 +83,7 @@ // It will only return if there was no error. If an error // was encountered it is printed to standard error and the // application exits with an exit code of 2. -func Main(ctx context.Context, app Application, args []string) { +func Main(ctx context.Context, app Command, args []string) { s := flag.NewFlagSet(app.Name(), flag.ExitOnError) if err := Run(ctx, s, app, args); err != nil { fmt.Fprintf(s.Output(), "%s: %v\n", app.Name(), err) @@ -106,11 +101,11 @@ // Run is the inner loop for Main; invoked by Main, recursively by // Run, and by various tests. It runs the application and returns an // error. -func Run(ctx context.Context, s *flag.FlagSet, app Application, args []string) (resultErr error) { +func Run(ctx context.Context, s *flag.FlagSet, app Command, args []string) (resultErr error) { s.Usage = func() { if app.ShortHelp() != "" { fmt.Fprintf(s.Output(), "%s\n\nUsage:\n ", app.ShortHelp()) - if sub, ok := app.(SubCommand); ok && sub.Parent() != "" { + if sub, ok := app.(Subcommand); ok && sub.Parent() != "" { fmt.Fprintf(s.Output(), "%s [flags] %s", sub.Parent(), app.Name()) } else { fmt.Fprintf(s.Output(), "%s [flags]", app.Name())