Skip to content

proposal: cmd/go: fix: apply fixes from modernizers and gofix analyzers #71859

@jba

Description

@jba

(Rewritten by @adonovan after prototyping.)

This proposal is the second of a sequence of two; #73605 is the first.

Background: gopls includes a number of analyzers in the Go analysis framework whose purpose is to modernize Go code to take advantage of newer features of the language and library. For example, the modernize suite, and the //go:fix inline analyzer. We would like to make these available through go fix, in much the same way that analyzers for reporting diagnostics are available through go vet.

Proposal: We propose to eliminate cmd/fix, and to restructure go fix to follow the approach of go vet, executing the same "vet tool", cmd/vet by default. The only differences between them would be (a) that go vet reports diagnostics whereas go fix applies their fixes and (b) that they invoke different subsets of analyzers.

The proposed new CLI is shown below. Here is a brief summary of changes:

  1. go fix now behaves almost exactly like go vet, and uses the same -vettool extension mechanism based on the Go analysis framework. The only difference is that it runs the vet tool (default cmd/vet) with the -fix flag, to apply fixes, and with GOVET=fix, to allow the vet tool to select a different analyzer suite. (This happens before the call to unitchecker.Main, which does flag parsing, hence the unfortunate need for an environment variable.) The go vet and go fix both dynamically query the vet tool for the set of analyzers and thus the dynamic set of feature flags.
  2. go fix and go vet both accept a -diff flag, which they pass through to the vet tool. The go command reports an error on go vet -diff without -fix.
  3. The obsolete go fix -fix=name,... flag is now a no-op, and results in a warning.
  4. The unitchecker CLI now accepts the -fix and -diff flags.
  5. We will remove from go fix the set of legacy cmd/fix passes, and their flags each of the form -name. Though this is technically a breaking change, it seems unlikely that anyone would be explicitly relying on specific passes that have no value at all. (Alternatively, we could add a specific check for these names and report a specific error.)
  6. The modernizer suite and the //go:fix inline analyzer will be added to the go fix suite. See these related proposals for those subtasks:

See https://go.dev/cl/700795 for the go fix implementation, which can be submitted once this is approved.

$ go help fix
usage: go fix [build flags] [-vettool prog] [fix flags] [packages]

Fix runs the Go vet command (cmd/vet) on the named packages
and applies suggested fixes.

It supports these flags:

  -json
	instead of applying each fix, emit JSON output
  -diff
	instead of applying each fix, print the patch as a unified diff

Use the -vettool to specify an alternative checking tool.
See 'go doc vet' for details.

For more about specifying packages, see 'go help packages'.

For a list of checkers and their flags, see 'GOVET=fix go tool vet help'.
(The set of checkers may differ from those run by "go vet".)

For details of a specific checker such as 'hostport',
see 'GOVET=fix go tool vet help hostport'.

The build flags supported by go vet are those that control package resolution
and execution, such as -C, -n, -x, -v, -tags, and -toolexec.
For more about these flags, see 'go help build'.

See also: go fmt, go vet.
$ go help vet
usage: go vet [build flags] [-vettool prog] [vet flags] [packages]

Vet runs the Go vet command (cmd/vet) on the named packages
and reports diagnostics.

It supports these flags:

  -c int
    	display offending line with this many lines of context (default -1)
  -json
    	emit JSON output
  -fix
	instead of printing each diagnostic, apply its first fix (if any)
  -diff
	instead of applying each fix, print the patch as a unified diff

The -vettool=prog flag selects a different analysis tool with
alternative or additional checks. For example, the 'shadow' analyzer
can be built and run using these commands:

  go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
  go vet -vettool=$(which shadow)

Alternative vet tools should be built atop golang.org/x/tools/go/analysis/unitchecker,
which handles the interaction with go vet.

For more about specifying packages, see 'go help packages'.
For a list of checkers and their flags, see 'go tool vet help'.
For details of a specific checker such as 'printf', see 'go tool vet help printf'.

The build flags supported by go vet are those that control package resolution
and execution, such as -C, -n, -x, -v, -tags, and -toolexec.
For more about these flags, see 'go help build'.

See also: go fmt, go fix.

Metadata

Metadata

Assignees

Labels

AnalysisIssues related to static analysis (vet, x/tools/go/analysis)ProposalRefactoringIssues related to refactoring toolsToolProposalIssues describing a requested change to a Go tool or command-line program.

Type

No type

Projects

Status

Active

Relationships

None yet

Development

No branches or pull requests

Issue actions