Skip to content

Commit

Permalink
Merge pull request #83 from gostaticanalysis/add-no-testmodfile
Browse files Browse the repository at this point in the history
Add -copy-parent-gomod flag
  • Loading branch information
tenntenn authored Nov 17, 2024
2 parents 04d7eb7 + 2e5d714 commit 3a51956
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 8 deletions.
5 changes: 5 additions & 0 deletions v2/skeleton/_template/inspect/@@.Pkg@@_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import (

// TestAnalyzer is a test for Analyzer.
func TestAnalyzer(t *testing.T) {
@@if .CopyParentGoMod -@@
modfile := testutil.ModFile(t, ".", nil)
testdata := testutil.WithModules(t, analysistest.TestData(), modfile)
@@else -@@
testdata := testutil.WithModules(t, analysistest.TestData(), nil)
@@end -@@
analysistest.Run(t, testdata, @@.Pkg@@.Analyzer, "a")
}
5 changes: 5 additions & 0 deletions v2/skeleton/_template/ssa/@@.Pkg@@_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import (

// TestAnalyzer is a test for Analyzer.
func TestAnalyzer(t *testing.T) {
@@if .CopyParentGoMod -@@
modfile := testutil.ModFile(t, ".", nil)
testdata := testutil.WithModules(t, analysistest.TestData(), modfile)
@@else -@@
testdata := testutil.WithModules(t, analysistest.TestData(), nil)
@@end -@@
analysistest.Run(t, testdata, @@.Pkg@@.Analyzer, "a")
}
17 changes: 9 additions & 8 deletions v2/skeleton/info.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package skeleton

type Info struct {
Kind Kind
Checker Checker
Pkg string
Path string
Cmd bool
Plugin bool
GoMod bool
GoVersion string
Kind Kind
Checker Checker
Pkg string
Path string
Cmd bool
Plugin bool
GoMod bool
GoVersion string
CopyParentGoMod bool
}
1 change: 1 addition & 0 deletions v2/skeleton/skeleton.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func (s *Skeleton) parseFlag(args []string, info *Info) (*flag.FlagSet, error) {
flags.BoolVar(&info.Plugin, "plugin", false, "create golangci-lint plugin")
flags.StringVar(&info.Pkg, "pkg", "", "package name")
flags.BoolVar(&info.GoMod, "gomod", true, "create a go.mod file")
flags.BoolVar(&info.CopyParentGoMod, "copy-parent-gomod", false, "copy parent go.mod file to testdata")

if err := flags.Parse(args); err != nil {
return nil, err
Expand Down
2 changes: 2 additions & 0 deletions v2/skeleton/skeleton_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ func TestSkeletonRun(t *testing.T) {
"kind-packages": {"", "", "", "-kind packages", "example.com/example", "", skeleton.ExitSuccess, "", true},
"parent-module": {"", "", F(t, "go.mod", "module example.com/example"), "-gomod=false", "sub", "", skeleton.ExitSuccess, "", true},
"parent-module-deep": {"", "sub", F(t, "go.mod", "module example.com/example", "sub/sub.go", "package sub"), "-gomod=false", "subsub", "", skeleton.ExitSuccess, "", true},
"kind-inspect-copy-parent-gomod-to-testdata": {"", "", "", "-kind inspect -copy-parent-gomod", "example.com/example", "", skeleton.ExitSuccess, "", true},
"kind-ssa-copy-parent-gomod-to-testdata": {"", "", "", "-kind ssa -copy-parent-gomod", "example.com/example", "", skeleton.ExitSuccess, "", true},
}

if flagUpdate {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
--- FAIL: TestAnalyzer (0000s)
analysistest.go:550: a/a.go:6: diagnostic "identifier is gopher" does not match pattern `pattern`
analysistest.go:614: a/a.go:6: no diagnostic was reported matching `pattern`
FAIL
exit status 1
FAIL example.com/example 0000s
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
-- example/cmd/example/main.go --
package main

import (
"example.com/example"
"golang.org/x/tools/go/analysis/unitchecker"
)

func main() { unitchecker.Main(example.Analyzer) }
-- example/example.go --
package example

import (
"go/ast"

"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
)

const doc = "example is ..."

// Analyzer is ...
var Analyzer = &analysis.Analyzer{
Name: "example",
Doc: doc,
Run: run,
Requires: []*analysis.Analyzer{
inspect.Analyzer,
},
}

func run(pass *analysis.Pass) (any, error) {
inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)

nodeFilter := []ast.Node{
(*ast.Ident)(nil),
}

inspect.Preorder(nodeFilter, func(n ast.Node) {
switch n := n.(type) {
case *ast.Ident:
if n.Name == "gopher" {
pass.Reportf(n.Pos(), "identifier is gopher")
}
}
})

return nil, nil
}
-- example/example_test.go --
package example_test

import (
"testing"

"example.com/example"
"github.com/gostaticanalysis/testutil"
"golang.org/x/tools/go/analysis/analysistest"
)

// TestAnalyzer is a test for Analyzer.
func TestAnalyzer(t *testing.T) {
modfile := testutil.ModFile(t, ".", nil)
testdata := testutil.WithModules(t, analysistest.TestData(), modfile)
analysistest.Run(t, testdata, example.Analyzer, "a")
}
-- example/go.mod --
module example.com/example

go 1.23.3

-- example/testdata/src/a/a.go --
package a

func f() {
// The pattern can be written in regular expression.
var gopher int // want "pattern"
print(gopher) // want "identifier is gopher"
}
-- example/testdata/src/a/go.mod --
module a

go 1.23.3

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
a.f
Block 0
*ssa.Call print(0:int)
*ssa.Builtin builtin print
*ssa.Const 0:int
*ssa.Return return
--- FAIL: TestAnalyzer (0000s)
analysistest.go:614: a/a.go:6: no diagnostic was reported matching `pattern`
analysistest.go:614: a/a.go:7: no diagnostic was reported matching `identifier is gopher`
FAIL
exit status 1
FAIL example.com/example 0000s
84 changes: 84 additions & 0 deletions v2/skeleton/testdata/kind-ssa-copy-parent-gomod-to-testdata.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
-- example/cmd/example/main.go --
package main

import (
"example.com/example"
"golang.org/x/tools/go/analysis/unitchecker"
)

func main() { unitchecker.Main(example.Analyzer) }
-- example/example.go --
package example

import (
"fmt"

"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/buildssa"
)

const doc = "example is ..."

// Analyzer is ...
var Analyzer = &analysis.Analyzer{
Name: "example",
Doc: doc,
Run: run,
Requires: []*analysis.Analyzer{
buildssa.Analyzer,
},
}

func run(pass *analysis.Pass) (any, error) {
s := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
for _, f := range s.SrcFuncs {
fmt.Println(f)
for _, b := range f.Blocks {
fmt.Printf("\tBlock %d\n", b.Index)
for _, instr := range b.Instrs {
fmt.Printf("\t\t%[1]T\t%[1]v\n", instr)
for _, v := range instr.Operands(nil) {
if v != nil {
fmt.Printf("\t\t\t%[1]T\t%[1]v\n", *v)
}
}
}
}
}
return nil, nil
}
-- example/example_test.go --
package example_test

import (
"testing"

"example.com/example"
"github.com/gostaticanalysis/testutil"
"golang.org/x/tools/go/analysis/analysistest"
)

// TestAnalyzer is a test for Analyzer.
func TestAnalyzer(t *testing.T) {
modfile := testutil.ModFile(t, ".", nil)
testdata := testutil.WithModules(t, analysistest.TestData(), modfile)
analysistest.Run(t, testdata, example.Analyzer, "a")
}
-- example/go.mod --
module example.com/example

go 1.23.3

-- example/testdata/src/a/a.go --
package a

func f() {
// The pattern can be written in regular expression.
var gopher int // want "pattern"
print(gopher) // want "identifier is gopher"
}
-- example/testdata/src/a/go.mod --
module a

go 1.23.3

0 comments on commit 3a51956

Please sign in to comment.