cmd/gofmt: change -d to exit 1 if diffs exist

When using the -d flag, set the exit code to 1 if there is a diff.

Fixes #46289

Change-Id: I802e8ccd1798ed7f4448696bec4bc82835ec71a2
GitHub-Last-Rev: db2207fba9
GitHub-Pull-Request: golang/go#75649
Reviewed-on: https://go-review.googlesource.com/c/go/+/707635
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Sean Liao <sean@liao.dev>
Auto-Submit: Sean Liao <sean@liao.dev>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Robbie McMichael 2025-10-06 12:47:34 +00:00 committed by Gopher Robot
parent d4830c6130
commit d945600d06
4 changed files with 64 additions and 5 deletions

View file

@ -41,6 +41,9 @@ var (
// debugging // debugging
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to this file") cpuprofile = flag.String("cpuprofile", "", "write cpu profile to this file")
// errors
errFormattingDiffers = fmt.Errorf("formatting differs from gofmt's")
) )
// Keep these in sync with go/format/format.go. // Keep these in sync with go/format/format.go.
@ -218,8 +221,12 @@ func (r *reporter) Report(err error) {
panic("Report with nil error") panic("Report with nil error")
} }
st := r.getState() st := r.getState()
scanner.PrintError(st.err, err) if err == errFormattingDiffers {
st.exitCode = 2 st.exitCode = 1
} else {
scanner.PrintError(st.err, err)
st.exitCode = 2
}
} }
func (r *reporter) ExitCode() int { func (r *reporter) ExitCode() int {
@ -281,6 +288,7 @@ func processFile(filename string, info fs.FileInfo, in io.Reader, r *reporter) e
newName := filepath.ToSlash(filename) newName := filepath.ToSlash(filename)
oldName := newName + ".orig" oldName := newName + ".orig"
r.Write(diff.Diff(oldName, src, newName, res)) r.Write(diff.Diff(oldName, src, newName, res))
return errFormattingDiffers
} }
} }

View file

@ -53,10 +53,19 @@ func gofmtFlags(filename string, maxLines int) string {
return "" return ""
} }
func runTest(t *testing.T, in, out string) { // Reset global variables for all flags to their default value.
// process flags func resetFlags() {
*simplifyAST = false *list = false
*write = false
*rewriteRule = "" *rewriteRule = ""
*simplifyAST = false
*doDiff = false
*allErrors = false
*cpuprofile = ""
}
func runTest(t *testing.T, in, out string) {
resetFlags()
info, err := os.Lstat(in) info, err := os.Lstat(in)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
@ -159,6 +168,46 @@ func TestRewrite(t *testing.T) {
} }
} }
// TestDiff runs gofmt with the -d flag on the input files and checks that the
// expected exit code is set.
func TestDiff(t *testing.T) {
tests := []struct {
in string
exitCode int
}{
{in: "testdata/exitcode.input", exitCode: 1},
{in: "testdata/exitcode.golden", exitCode: 0},
}
for _, tt := range tests {
resetFlags()
*doDiff = true
initParserMode()
initRewrite()
info, err := os.Lstat(tt.in)
if err != nil {
t.Error(err)
return
}
const maxWeight = 2 << 20
var buf, errBuf bytes.Buffer
s := newSequencer(maxWeight, &buf, &errBuf)
s.Add(fileWeight(tt.in, info), func(r *reporter) error {
return processFile(tt.in, info, nil, r)
})
if errBuf.Len() > 0 {
t.Logf("%q", errBuf.Bytes())
}
if s.GetExitCode() != tt.exitCode {
t.Errorf("%s: expected exit code %d, got %d", tt.in, tt.exitCode, s.GetExitCode())
}
}
}
// Test case for issue 3961. // Test case for issue 3961.
func TestCRLF(t *testing.T) { func TestCRLF(t *testing.T) {
const input = "testdata/crlf.input" // must contain CR/LF's const input = "testdata/crlf.input" // must contain CR/LF's

View file

@ -0,0 +1 @@
package main

1
src/cmd/gofmt/testdata/exitcode.input vendored Normal file
View file

@ -0,0 +1 @@
package main