diff --git a/file.go b/file.go index 2aeca1d..f7d0e9b 100644 --- a/file.go +++ b/file.go @@ -3,6 +3,7 @@ package analysisutil import ( "go/ast" "go/token" + "regexp" "golang.org/x/tools/go/analysis" ) @@ -16,3 +17,14 @@ func File(pass *analysis.Pass, pos token.Pos) *ast.File { } return nil } + +var genCommentRegexp = regexp.MustCompile(`^// Code generated .* DO NOT EDIT\.$`) + +// IsGeneratedFile reports whether the file has been generated automatically. +// If file is nil, IsGeneratedFile will return false. +func IsGeneratedFile(file *ast.File) bool { + if file == nil || file.Doc == nil { + return false + } + return genCommentRegexp.MatchString(file.Doc.List[0].Text) +} diff --git a/file_test.go b/file_test.go new file mode 100644 index 0000000..341e7c5 --- /dev/null +++ b/file_test.go @@ -0,0 +1,46 @@ +package analysisutil_test + +import ( + "fmt" + "path/filepath" + "testing" + + "github.com/gostaticanalysis/analysisutil" + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/analysistest" +) + +func TestIsGeneratedFile(t *testing.T) { + t.Parallel() + + cases := map[string]struct { + src string + want bool + }{ + "true": {"// Code generated by test; DO NOT EDIT.", true}, + "false": {"//Code generated by test; DO NOT EDIT.", false}, + "empty": {"", false}, + } + + for name, tt := range cases { + name, tt := name, tt + t.Run(name, func(t *testing.T) { + t.Parallel() + a := &analysis.Analyzer{ + Name: name + "Analyzer", + Run: func(pass *analysis.Pass) (interface{}, error) { + got := analysisutil.IsGeneratedFile(pass.Files[0]) + if tt.want != got { + return nil, fmt.Errorf("want %v but got %v", tt.want, got) + } + return nil, nil + }, + } + path := filepath.Join(name, name+".go") + dir := WriteFiles(t, map[string]string{ + path: fmt.Sprintf("%s\npackage %s", tt.src, name), + }) + analysistest.Run(t, dir, a, name) + }) + } +}