1
0
mirror of https://github.com/golang/go synced 2024-10-01 12:48:33 -06:00
go/internal/lsp/cmd/query.go
hartzell 5adc211bf7 tools/internal/tool: refactor tool.Main() for testabilty
In it previous implementation, tool.Main was meant to be called from
an applications main().  If it encountered an error it would print the
error to standard error and exit with a non-zero status (2).

It is also called recursively and in various test functions.

Exiting on an error makes testing difficult, unnecessarily.

This change breaks the functionality into to parts: an outer
tool.MustMain() that is intended to be called by main() functions and
an inner Main that is used by MustMain() and by test functions.

None of the existing test functions use Main()'s error value, but the
failure case tests for the command line invocation of rename (#194878)
require it.

Fixes #34291

Change-Id: Id0d80fc4670d56c87398b86b1ad9fdf7a676c95b
GitHub-Last-Rev: cd64995c91c94b997754c8d8b1004afc488bf8b7
GitHub-Pull-Request: golang/tools#159
Reviewed-on: https://go-review.googlesource.com/c/tools/+/195338
Reviewed-by: Ian Cottrell <iancottrell@google.com>
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-09-19 22:27:22 +00:00

71 lines
1.9 KiB
Go

// Copyright 2019 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.
package cmd
import (
"context"
"flag"
"fmt"
"golang.org/x/tools/internal/tool"
)
const (
// The set of possible options that can be passed through the -emulate flag,
// which causes query to adjust its output to match that of the binary being
// emulated.
// emulateGuru tells query to emulate the output format of the guru tool.
emulateGuru = "guru"
)
// query implements the query command.
type query struct {
JSON bool `flag:"json" help:"emit output in JSON format"`
Emulate string `flag:"emulate" help:"compatibility mode, causes gopls to emulate another tool.\nvalues depend on the operation being performed"`
app *Application
}
func (q *query) Name() string { return "query" }
func (q *query) Usage() string { return "<mode> <mode args>" }
func (q *query) ShortHelp() string {
return "answer queries about go source code"
}
func (q *query) DetailedHelp(f *flag.FlagSet) {
fmt.Fprint(f.Output(), `
The mode argument determines the query to perform:
`)
for _, m := range q.modes() {
fmt.Fprintf(f.Output(), " %s : %v\n", m.Name(), m.ShortHelp())
}
fmt.Fprint(f.Output(), `
query flags are:
`)
f.PrintDefaults()
}
// Run takes the args after command flag processing, and invokes the correct
// query mode as specified by the first argument.
func (q *query) Run(ctx context.Context, args ...string) error {
if len(args) == 0 {
return tool.CommandLineErrorf("query must be supplied a mode")
}
mode, args := args[0], args[1:]
for _, m := range q.modes() {
if m.Name() == mode {
return tool.Run(ctx, m, args) // pass errors up the chain
}
}
return tool.CommandLineErrorf("unknown command %v", mode)
}
// modes returns the set of modes supported by the query command.
func (q *query) modes() []tool.Application {
return []tool.Application{
&definition{query: q},
}
}