Skip to content

Commit d74ca43

Browse files
committed
fully format generated files if given explicitly
Otherwise it's very hard to apply gofumpt rules to generated code. It still makes sense to skip the added rules with "gofumpt -w .", because more often than not code generators only obey gofmt, and it's often unnecessary to force generated code to follow gofumpt. The behavior is similar to how we treat vendor directories, with the difference that we do fully skip vendor directories by default, whereas for generated Go files we still apply gofmt. The difference is that changing vendored files may upset cmd/go, and walking the vendor directory can unnecessarily waste time. While here, tweak the README to better explain these special cases. Fixes #180.
1 parent 9685193 commit d74ca43

File tree

4 files changed

+50
-42
lines changed

4 files changed

+50
-42
lines changed

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ replacement. Running `gofmt` after `gofumpt` should be a no-op. For example:
1111
gofumpt -l -w .
1212

1313
Some of the Go source files in this repository belong to the Go project.
14-
The added formatting rules are in the `format` package.
14+
The [added formatting rules](#Added-rules) are implemented in the `format` package.
1515

16-
Beyond the [added rules below](#Added-rules), the tool differs from gofmt in the
17-
following ways:
16+
Note that vendor directories are skipped unless given as explicit arguments.
17+
Similarly, the added rules do not apply to generated Go files unless they are
18+
given as explicit arguments.
1819

19-
* Vendor directories are skipped unless given as explicit arguments
20-
* The added rules are not applied to generated Go files
21-
* The `-r` rewrite feature is removed in favor of `gofmt -r`
20+
Finally, note that the `-r` rewrite flag is removed in favor of `gofmt -r`,
21+
and the `-s` flag is hidden as it is always enabled.
2222

2323
### Added rules
2424

format/format.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,25 +69,12 @@ func Source(src []byte, opts Options) ([]byte, error) {
6969
return buf.Bytes(), nil
7070
}
7171

72-
var rxCodeGenerated = regexp.MustCompile(`^// Code generated .* DO NOT EDIT\.$`)
73-
7472
// File modifies a file and fset in place to follow gofumpt's format. The
7573
// changes might include manipulating adding or removing newlines in fset,
7674
// modifying the position of nodes, or modifying literal values.
7775
func File(fset *token.FileSet, file *ast.File, opts Options) {
7876
simplify(file)
7977

80-
for _, cg := range file.Comments {
81-
if cg.Pos() > file.Package {
82-
break
83-
}
84-
for _, line := range cg.List {
85-
if rxCodeGenerated.MatchString(line.Text) {
86-
return
87-
}
88-
}
89-
}
90-
9178
if opts.LangVersion == "" {
9279
opts.LangVersion = "v1"
9380
} else if opts.LangVersion[0] != 'v' {

gofmt.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"io/fs"
1919
"os"
2020
"path/filepath"
21+
"regexp"
2122
"runtime"
2223
"runtime/pprof"
2324
"strings"
@@ -103,8 +104,24 @@ func isGoFile(f fs.DirEntry) bool {
103104
return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
104105
}
105106

107+
var rxCodeGenerated = regexp.MustCompile(`^// Code generated .* DO NOT EDIT\.$`)
108+
109+
func isGenerated(file *ast.File) bool {
110+
for _, cg := range file.Comments {
111+
if cg.Pos() > file.Package {
112+
return false
113+
}
114+
for _, line := range cg.List {
115+
if rxCodeGenerated.MatchString(line.Text) {
116+
return true
117+
}
118+
}
119+
}
120+
return false
121+
}
122+
106123
// If in == nil, the source is the contents of the file with the given filename.
107-
func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error {
124+
func processFile(filename string, in io.Reader, out io.Writer, stdin, explicit bool) error {
108125
var perm os.FileMode = 0o644
109126
if in == nil {
110127
f, err := os.Open(filename)
@@ -143,10 +160,12 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error
143160
}
144161
}
145162

146-
gformat.File(fileSet, file, gformat.Options{
147-
LangVersion: *langVersion,
148-
ExtraRules: *extraRules,
149-
})
163+
if explicit || !isGenerated(file) {
164+
gformat.File(fileSet, file, gformat.Options{
165+
LangVersion: *langVersion,
166+
ExtraRules: *extraRules,
167+
})
168+
}
150169

151170
res, err := format(fileSet, file, sourceAdj, indentAdj, src, printer.Config{Mode: printerMode, Tabwidth: tabWidth})
152171
if err != nil {
@@ -198,7 +217,7 @@ func visitFile(path string, f fs.DirEntry, err error) error {
198217
if err != nil || !isGoFile(f) {
199218
return err
200219
}
201-
if err := processFile(path, nil, os.Stdout, false); err != nil {
220+
if err := processFile(path, nil, os.Stdout, false, false); err != nil {
202221
report(err)
203222
}
204223
return nil
@@ -255,7 +274,7 @@ func gofumptMain() {
255274
exitCode = 2
256275
return
257276
}
258-
if err := processFile("<standard input>", os.Stdin, os.Stdout, true); err != nil {
277+
if err := processFile("<standard input>", os.Stdin, os.Stdout, true, true); err != nil {
259278
report(err)
260279
}
261280
return
@@ -267,7 +286,7 @@ func gofumptMain() {
267286
report(err)
268287
case !info.IsDir():
269288
// Non-directory arguments are always formatted.
270-
if err := processFile(arg, nil, os.Stdout, false); err != nil {
289+
if err := processFile(arg, nil, os.Stdout, false, true); err != nil {
271290
report(err)
272291
}
273292
default:

testdata/scripts/generated.txt

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
1-
cp foo.go foo.go.orig
2-
cp foo.go foo.go.golden
3-
exec gofmt -w foo.go.golden
1+
gofumpt foo.go
2+
cmp stdout foo.go.golden
43

5-
gofumpt -w foo.go
6-
cmp foo.go foo.go.golden
7-
8-
cp foo.go.orig foo.go
9-
gofumpt -w .
10-
cmp foo.go foo.go.golden
4+
gofumpt -l .
5+
! stdout .
6+
! stderr .
117

128
-- foo.go --
139
// foo is a package about bar.
1410

1511
// Code generated by foo. DO NOT EDIT.
16-
// versions:
17-
// foo v1.26.0
12+
1813
package foo
1914

20-
type i interface {
15+
func f() {
16+
17+
println("body")
18+
19+
}
20+
-- foo.go.golden --
21+
// foo is a package about bar.
2122

22-
a(x int) int
23+
// Code generated by foo. DO NOT EDIT.
2324

24-
b(x int) int
25+
package foo
2526

26-
c(x int) int
27+
func f() {
28+
println("body")
2729
}

0 commit comments

Comments
 (0)