Skip to content

Commit 0600733

Browse files
committed
add support for Go 1.25 ignore directives
Much like vendor and testdata directories, we still support formatting directories or files within them as long as they are given as explicit arguments. Fixes #250. Closes #329 as resolved.
1 parent d8f3fb6 commit 0600733

File tree

3 files changed

+55
-10
lines changed

3 files changed

+55
-10
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ The [added formatting rules](#Added-rules) are implemented in the `format` packa
2323
Similarly, the added rules do not apply to generated Go files unless they are
2424
given as explicit arguments.
2525

26+
[`ignore` directives](https://go.dev/ref/mod#go-mod-file-ignore) in `go.mod` files are obeyed as well,
27+
unless directories or files within them are given as explicit arguments.
28+
2629
Finally, note that the `-r` rewrite flag is removed in favor of `gofmt -r`,
2730
and the `-s` flag is hidden as it is always enabled.
2831

gofmt.go

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -521,11 +521,8 @@ func gofmtMain(s *sequencer) {
521521
case err != nil:
522522
return err
523523
case d.IsDir():
524-
if !explicit {
525-
switch filepath.Base(path) {
526-
case "vendor", "testdata":
527-
return filepath.SkipDir
528-
}
524+
if !explicit && shouldIgnore(path) {
525+
return filepath.SkipDir
529526
}
530527
return nil // simply recurse into directories
531528
case explicit:
@@ -547,6 +544,56 @@ func gofmtMain(s *sequencer) {
547544
}
548545
}
549546

547+
func shouldIgnore(path string) bool {
548+
switch filepath.Base(path) {
549+
case "vendor", "testdata":
550+
return true
551+
}
552+
path, err := filepath.Abs(path)
553+
if err != nil {
554+
return false // unclear how this could happen; don't ignore in any case
555+
}
556+
mod := loadModule(path)
557+
if mod == nil {
558+
return false // no module file to declare ignore paths
559+
}
560+
relPath, err := filepath.Rel(mod.absDir, path)
561+
if err != nil {
562+
return false // unclear how this could happen; don't ignore in any case
563+
}
564+
relPath = normalizePath(relPath)
565+
for _, ignore := range mod.file.Ignore {
566+
if matchIgnore(ignore.Path, relPath) {
567+
return true
568+
}
569+
}
570+
return false
571+
}
572+
573+
// normalizePath adds slashes to the front and end of the given path.
574+
func normalizePath(path string) string {
575+
path = filepath.ToSlash(path) // ensure Windows support
576+
if !strings.HasPrefix(path, "/") {
577+
path = "/" + path
578+
}
579+
if !strings.HasSuffix(path, "/") {
580+
path += "/"
581+
}
582+
return path
583+
}
584+
585+
func matchIgnore(ignore, relPath string) bool {
586+
ignore, rooted := strings.CutPrefix(ignore, "./")
587+
ignore = normalizePath(ignore)
588+
// Note that we only match the directory to be ignored itself,
589+
// and not any directories underneath it.
590+
// This way, using `gofumpt -w ignored` allows `ignored/subdir` to be formatted.
591+
if rooted {
592+
return relPath == ignore
593+
}
594+
return strings.HasSuffix(relPath, ignore)
595+
}
596+
550597
// A nil entry means the directory is not part of a Go module,
551598
// or a go.mod file was found but it's invalid.
552599
// A non-nil entry means this directory, or a parent, is in a valid Go module.

testdata/script/ignore.txtar

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,10 @@ testdata${/}foo${/}foo.go
3131
module${/}ignore${/}dir${/}ignore.go
3232
-- implicit-dot.stdout --
3333
ignore${/}dir${/}outsidemodule.go
34-
module${/}ignore${/}dir${/}ignore.go
35-
module${/}ignore${/}dir${/}subdir${/}ignore.go
3634
module${/}ignore${/}dirsuffix${/}nomatch.go
3735
module${/}ignore${/}nomatch.go
38-
module${/}ignoreroot${/}dir${/}ignore.go
39-
module${/}ignoreroot${/}dir${/}subdir${/}ignore.go
4036
module${/}ignoreroot${/}nomatch.go
4137
module${/}prefixignore${/}dir${/}nomatch.go
42-
module${/}subdir${/}ignore${/}dir${/}ignore.go
4338
module${/}subdir${/}ignoreroot${/}dir${/}notatroot.go
4439
-- explicit-dirs-unclean.stdout --
4540
${WORK}${/}vendor${/}bar${/}bar.go

0 commit comments

Comments
 (0)