#45: fix no results for gocyclo
This commit is contained in:
parent
80a5ff2eff
commit
ef81b998ed
@ -1,16 +1,21 @@
|
||||
package astcache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/tools/go/loader"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
F *ast.File
|
||||
Fset *token.FileSet
|
||||
Name string
|
||||
err error
|
||||
}
|
||||
|
||||
@ -34,22 +39,40 @@ func (c *Cache) prepareValidFiles() {
|
||||
c.s = files
|
||||
}
|
||||
|
||||
func LoadFromProgram(prog *loader.Program) *Cache {
|
||||
func LoadFromProgram(prog *loader.Program) (*Cache, error) {
|
||||
c := &Cache{
|
||||
m: map[string]*File{},
|
||||
}
|
||||
|
||||
root, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get working dir: %s", err)
|
||||
}
|
||||
|
||||
for _, pkg := range prog.InitialPackages() {
|
||||
for _, f := range pkg.Files {
|
||||
pos := prog.Fset.Position(0)
|
||||
c.m[pos.Filename] = &File{
|
||||
pos := prog.Fset.Position(f.Pos())
|
||||
if pos.Filename == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
relPath, err := filepath.Rel(root, pos.Filename)
|
||||
if err != nil {
|
||||
logrus.Warnf("Can't get relative path for %s and %s: %s",
|
||||
root, pos.Filename, err)
|
||||
continue
|
||||
}
|
||||
|
||||
c.m[relPath] = &File{
|
||||
F: f,
|
||||
Fset: prog.Fset,
|
||||
Name: relPath,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.prepareValidFiles()
|
||||
return c
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func LoadFromFiles(files []string) *Cache {
|
||||
@ -63,6 +86,7 @@ func LoadFromFiles(files []string) *Cache {
|
||||
F: f,
|
||||
Fset: fset,
|
||||
err: err,
|
||||
Name: filePath,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,50 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func (e *Executor) persistentPostRun(cmd *cobra.Command, args []string) {
|
||||
if e.cfg.Run.PrintVersion {
|
||||
fmt.Fprintf(printers.StdOut, "golangci-lint has version %s built from %s on %s\n", e.version, e.commit, e.date)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
runtime.GOMAXPROCS(e.cfg.Run.Concurrency)
|
||||
|
||||
log.SetFlags(0) // don't print time
|
||||
if e.cfg.Run.IsVerbose {
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
} else {
|
||||
logrus.SetLevel(logrus.WarnLevel)
|
||||
}
|
||||
|
||||
if e.cfg.Run.CPUProfilePath != "" {
|
||||
f, err := os.Create(e.cfg.Run.CPUProfilePath)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
if err := pprof.StartCPUProfile(f); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Executor) persistentPreRun(cmd *cobra.Command, args []string) {
|
||||
if e.cfg.Run.CPUProfilePath != "" {
|
||||
pprof.StopCPUProfile()
|
||||
}
|
||||
if e.cfg.Run.MemProfilePath != "" {
|
||||
f, err := os.Create(e.cfg.Run.MemProfilePath)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
runtime.GC() // get up-to-date statistics
|
||||
if err := pprof.WriteHeapProfile(f); err != nil {
|
||||
logrus.Fatal("could not write memory profile: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
os.Exit(e.exitCode)
|
||||
}
|
||||
|
||||
func (e *Executor) initRoot() {
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "golangci-lint",
|
||||
@ -22,48 +66,8 @@ func (e *Executor) initRoot() {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
},
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
if e.cfg.Run.PrintVersion {
|
||||
fmt.Fprintf(printers.StdOut, "golangci-lint has version %s built from %s on %s\n", e.version, e.commit, e.date)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
runtime.GOMAXPROCS(e.cfg.Run.Concurrency)
|
||||
|
||||
log.SetFlags(0) // don't print time
|
||||
if e.cfg.Run.IsVerbose {
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
} else {
|
||||
logrus.SetLevel(logrus.WarnLevel)
|
||||
}
|
||||
|
||||
if e.cfg.Run.CPUProfilePath != "" {
|
||||
f, err := os.Create(e.cfg.Run.CPUProfilePath)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
if err := pprof.StartCPUProfile(f); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
},
|
||||
PersistentPostRun: func(cmd *cobra.Command, args []string) {
|
||||
if e.cfg.Run.CPUProfilePath != "" {
|
||||
pprof.StopCPUProfile()
|
||||
}
|
||||
if e.cfg.Run.MemProfilePath != "" {
|
||||
f, err := os.Create(e.cfg.Run.MemProfilePath)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
runtime.GC() // get up-to-date statistics
|
||||
if err := pprof.WriteHeapProfile(f); err != nil {
|
||||
logrus.Fatal("could not write memory profile: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
os.Exit(e.exitCode)
|
||||
},
|
||||
PersistentPreRun: e.persistentPostRun,
|
||||
PersistentPostRun: e.persistentPreRun,
|
||||
}
|
||||
rootCmd.PersistentFlags().BoolVarP(&e.cfg.Run.IsVerbose, "verbose", "v", false, "verbose output")
|
||||
rootCmd.PersistentFlags().StringVar(&e.cfg.Run.CPUProfilePath, "cpu-profile-path", "", "Path to CPU profile output file")
|
||||
|
@ -254,7 +254,10 @@ func buildLintCtx(ctx context.Context, linters []pkg.Linter, cfg *config.Config)
|
||||
|
||||
var astCache *astcache.Cache
|
||||
if prog != nil {
|
||||
astCache = astcache.LoadFromProgram(prog)
|
||||
astCache, err = astcache.LoadFromProgram(prog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
astCache = astcache.LoadFromFiles(paths.Files)
|
||||
}
|
||||
|
54
pkg/commands/run_test.go
Normal file
54
pkg/commands/run_test.go
Normal file
@ -0,0 +1,54 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/golangci/golangci-lint/pkg"
|
||||
"github.com/golangci/golangci-lint/pkg/astcache"
|
||||
"github.com/golangci/golangci-lint/pkg/config"
|
||||
"github.com/golangci/golangci-lint/pkg/fsutils"
|
||||
"github.com/golangci/golangci-lint/pkg/golinters"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestASTCacheLoading(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
linters := []pkg.Linter{golinters.Errcheck{}}
|
||||
|
||||
inputPaths := []string{"./...", "./", "./run.go", "run.go"}
|
||||
for _, inputPath := range inputPaths {
|
||||
paths, err := fsutils.GetPathsForAnalysis(ctx, []string{inputPath}, true)
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, paths.Files)
|
||||
|
||||
prog, _, err := loadWholeAppIfNeeded(ctx, linters, &config.Run{
|
||||
AnalyzeTests: true,
|
||||
}, paths)
|
||||
assert.NoError(t, err)
|
||||
|
||||
astCacheFromProg, err := astcache.LoadFromProgram(prog)
|
||||
assert.NoError(t, err)
|
||||
|
||||
astCacheFromFiles := astcache.LoadFromFiles(paths.Files)
|
||||
|
||||
filesFromProg := astCacheFromProg.GetAllValidFiles()
|
||||
filesFromFiles := astCacheFromFiles.GetAllValidFiles()
|
||||
if len(filesFromProg) != len(filesFromFiles) {
|
||||
t.Logf("files: %s", paths.Files)
|
||||
t.Logf("from prog:")
|
||||
for _, f := range filesFromProg {
|
||||
t.Logf("%+v", *f)
|
||||
}
|
||||
t.Logf("from files:")
|
||||
for _, f := range filesFromFiles {
|
||||
t.Logf("%+v", *f)
|
||||
}
|
||||
t.Fatalf("lengths differ")
|
||||
}
|
||||
|
||||
if len(filesFromProg) != len(paths.Files) {
|
||||
t.Fatalf("filesFromProg differ from path.Files")
|
||||
}
|
||||
}
|
||||
}
|
@ -294,9 +294,7 @@ func GetAllLintersForPreset(p string) []Linter {
|
||||
return ret
|
||||
}
|
||||
|
||||
func getEnabledLintersSet(cfg *config.Config) map[string]Linter { // nolint:gocyclo
|
||||
lcfg := &cfg.Linters
|
||||
|
||||
func getEnabledLintersSet(lcfg *config.Linters, enabledByDefaultLinters []Linter) map[string]Linter { // nolint:gocyclo
|
||||
resultLintersSet := map[string]Linter{}
|
||||
switch {
|
||||
case len(lcfg.Presets) != 0:
|
||||
@ -306,7 +304,7 @@ func getEnabledLintersSet(cfg *config.Config) map[string]Linter { // nolint:gocy
|
||||
case lcfg.DisableAll:
|
||||
break
|
||||
default:
|
||||
resultLintersSet = lintersToMap(getAllEnabledByDefaultLinters())
|
||||
resultLintersSet = lintersToMap(enabledByDefaultLinters)
|
||||
}
|
||||
|
||||
// --presets can only add linters to default set
|
||||
@ -332,12 +330,24 @@ func getEnabledLintersSet(cfg *config.Config) map[string]Linter { // nolint:gocy
|
||||
}
|
||||
|
||||
for _, name := range lcfg.Disable {
|
||||
if name == "megacheck" {
|
||||
for _, ln := range getAllMegacheckSubLinterNames() {
|
||||
delete(resultLintersSet, ln)
|
||||
}
|
||||
}
|
||||
delete(resultLintersSet, name)
|
||||
}
|
||||
|
||||
return resultLintersSet
|
||||
}
|
||||
|
||||
func getAllMegacheckSubLinterNames() []string {
|
||||
unusedName := golinters.Megacheck{UnusedEnabled: true}.Name()
|
||||
gosimpleName := golinters.Megacheck{GosimpleEnabled: true}.Name()
|
||||
staticcheckName := golinters.Megacheck{StaticcheckEnabled: true}.Name()
|
||||
return []string{unusedName, gosimpleName, staticcheckName}
|
||||
}
|
||||
|
||||
func optimizeLintersSet(linters map[string]Linter) {
|
||||
unusedName := golinters.Megacheck{UnusedEnabled: true}.Name()
|
||||
gosimpleName := golinters.Megacheck{GosimpleEnabled: true}.Name()
|
||||
@ -375,7 +385,7 @@ func GetEnabledLinters(cfg *config.Config) ([]Linter, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resultLintersSet := getEnabledLintersSet(cfg)
|
||||
resultLintersSet := getEnabledLintersSet(&cfg.Linters, getAllEnabledByDefaultLinters())
|
||||
optimizeLintersSet(resultLintersSet)
|
||||
|
||||
var resultLinters []Linter
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -370,3 +371,48 @@ func BenchmarkWithGometalinter(b *testing.B) {
|
||||
compare(b, runGometalinter, runGolangciLint, bc.name, "", lc/1000)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetEnabledLintersSet(t *testing.T) {
|
||||
type cs struct {
|
||||
cfg config.Linters
|
||||
name string // test case name
|
||||
def []string // enabled by default linters
|
||||
exp []string // alphabetically ordered enabled linter names
|
||||
}
|
||||
cases := []cs{
|
||||
{
|
||||
cfg: config.Linters{
|
||||
Disable: []string{"megacheck"},
|
||||
},
|
||||
name: "disable all linters from megacheck",
|
||||
def: getAllMegacheckSubLinterNames(),
|
||||
},
|
||||
{
|
||||
cfg: config.Linters{
|
||||
Disable: []string{"staticcheck"},
|
||||
},
|
||||
name: "disable only staticcheck",
|
||||
def: getAllMegacheckSubLinterNames(),
|
||||
exp: []string{"gosimple", "unused"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
defaultLinters := []Linter{}
|
||||
for _, ln := range c.def {
|
||||
defaultLinters = append(defaultLinters, getLinterByName(ln))
|
||||
}
|
||||
els := getEnabledLintersSet(&c.cfg, defaultLinters)
|
||||
var enabledLinters []string
|
||||
for ln := range els {
|
||||
enabledLinters = append(enabledLinters, ln)
|
||||
}
|
||||
|
||||
sort.Strings(enabledLinters)
|
||||
sort.Strings(c.exp)
|
||||
|
||||
assert.Equal(t, c.exp, enabledLinters)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user