aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/fix
diff options
context:
space:
mode:
authorAlan Donovan <adonovan@google.com>2025-09-26 13:33:09 -0400
committerAlan Donovan <adonovan@google.com>2025-10-10 13:10:21 -0700
commit6f4c63ba63fdec6e4a42e2e19ac71937973dedef (patch)
tree07de0c3fbb30da98e2f5ad260b06d1a7110449b6 /src/cmd/fix
parent955a5a0dc5dd68ed89200a08f17590c0a94c1e09 (diff)
downloadgo-6f4c63ba63fdec6e4a42e2e19ac71937973dedef.tar.xz
cmd/go: unify "go fix" and "go vet"
This change unifies the fix and vet subcommands; they use the same run function, action graph, and external tool (-vettool for go vet and -fixtool for go fix). go fix runs the tool with the -fix flag, whereas although go vet also supports -fix, it is not the default. The two tools have different (overlapping) suites of analyzers. The high-level parts are fully parameterized over the vet/fix distinction; the lower-level parts (the action graph) continue to use only the "vet" terminology. The cmd/{vet,fix} executable is referred to as the "tool". The tool is generally invoked in -json mode, regardless of whether -json was requested, so that the tool produces a cacheable JSON blob on stdout. When the go user did not request -json, this blob is parsed and printed to stderr by logic in the go vet command. (Formerly the tool would print diagnostics to stderr, but this interacts poorly with the build cache.) go fix's legacy -fix=fixer,... flag is now a no-op that prints a warning that the flag is obsolete. The unitchecker's -c=n flag (to display n lines of context around each diagnostic) is reimplemented in go vet based on the JSON information, to avoid reliance on the stderr output of the tool. cmd/fix is added to dist's prebuilt set of tools since go fix cannot build it dynamically (though ideally it would). Updates #71859 For #75432 Change-Id: I0a84746720b59d05d662ed57826747c5598dca44 Reviewed-on: https://go-review.googlesource.com/c/go/+/700795 Reviewed-by: Michael Matloob <matloob@google.com> Auto-Submit: Alan Donovan <adonovan@google.com> Reviewed-by: Michael Matloob <matloob@golang.org> TryBot-Bypass: Alan Donovan <adonovan@google.com>
Diffstat (limited to 'src/cmd/fix')
-rw-r--r--src/cmd/fix/doc.go20
-rw-r--r--src/cmd/fix/main.go66
2 files changed, 47 insertions, 39 deletions
diff --git a/src/cmd/fix/doc.go b/src/cmd/fix/doc.go
deleted file mode 100644
index b3d6914471..0000000000
--- a/src/cmd/fix/doc.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2011 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.
-
-/*
-Fix finds Go programs that use old APIs and rewrites them to use
-newer ones. After you update to a new Go release, fix helps make
-the necessary changes to your programs.
-
-Usage:
-
- go tool fix [ignored...]
-
-This tool is currently in transition. All its historical fixers were
-long obsolete and have been removed, so it is currently a no-op. In
-due course the tool will integrate with the Go analysis framework
-(golang.org/x/tools/go/analysis) and run a modern suite of fix
-algorithms; see https://go.dev/issue/71859.
-*/
-package main
diff --git a/src/cmd/fix/main.go b/src/cmd/fix/main.go
index 87cc0d6414..422fa82745 100644
--- a/src/cmd/fix/main.go
+++ b/src/cmd/fix/main.go
@@ -1,31 +1,59 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// Copyright 2025 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.
+/*
+Fix is a tool executed by "go fix" to update Go programs that use old
+features of the language and library and rewrite them to use newer
+ones. After you update to a new Go release, fix helps make the
+necessary changes to your programs.
+
+See the documentation for "go fix" for how to run this command.
+You can provide an alternative tool using "go fix -fixtool=..."
+
+Run "go tool fix help" to see the list of analyzers supported by this
+program.
+
+See [golang.org/x/tools/go/analysis] for information on how to write
+an analyzer that can suggest fixes.
+*/
package main
import (
- "flag"
- "fmt"
- "os"
-)
+ "cmd/internal/objabi"
+ "cmd/internal/telemetry/counter"
-var (
- _ = flag.Bool("diff", false, "obsolete, no effect")
- _ = flag.String("go", "", "obsolete, no effect")
- _ = flag.String("r", "", "obsolete, no effect")
- _ = flag.String("force", "", "obsolete, no effect")
+ "golang.org/x/tools/go/analysis"
+ "golang.org/x/tools/go/analysis/passes/buildtag"
+ "golang.org/x/tools/go/analysis/passes/hostport"
+ "golang.org/x/tools/go/analysis/unitchecker"
)
-func usage() {
- fmt.Fprintf(os.Stderr, "usage: go tool fix [-diff] [-r ignored] [-force ignored] ...\n")
- flag.PrintDefaults()
- os.Exit(2)
-}
-
func main() {
- flag.Usage = usage
- flag.Parse()
+ // Keep consistent with cmd/vet/main.go!
+ counter.Open()
+ objabi.AddVersionFlag()
+ counter.Inc("fix/invocations")
+
+ unitchecker.Main(suite...) // (never returns)
+}
- os.Exit(0)
+// The fix suite analyzers produce fixes that are safe to apply.
+// (Diagnostics may not describe actual problems,
+// but their fixes must be unambiguously safe to apply.)
+var suite = []*analysis.Analyzer{
+ buildtag.Analyzer,
+ hostport.Analyzer,
+ // TODO(adonovan): now the modernize (proposal #75266) and
+ // inline (proposal #75267) analyzers are published, revendor
+ // x/tools and add them here.
+ //
+ // TODO(adonovan):add any other vet analyzers whose fixes are always safe.
+ // Candidates to audit: sigchanyzer, printf, assign, unreachable.
+ // Rejected:
+ // - composites: some types (e.g. PointXY{1,2}) don't want field names.
+ // - timeformat: flipping MM/DD is a behavior change, but the code
+ // could potentially be a workaround for another bug.
+ // - stringintconv: offers two fixes, user input required to choose.
+ // - fieldalignment: poor signal/noise; fix could be a regression.
}