+
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 22 additions & 16 deletions grit/cmd/plot/subcommands/churncomplexity.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,27 @@ import (
)

var (
outputFile string
since string
until string
churnType git.ChurnType
outputFile string
since string
until string
churnType git.ChurnType
excludeRegex string
)

var churnOpts = &git.ChurnOptions{
SortBy: git.Changes,
Top: 0,
Extensions: nil,
Since: time.Time{},
Until: time.Time{},
Path: "",
ExcludePath: "",
SortBy: git.Changes,
Top: 0,
Extensions: nil,
Since: time.Time{},
Until: time.Time{},
Path: "",
ExcludeRegex: nil,
}

var complexityOpts = complexity.Options{
Engine: complexity.Gocyclo,
ExcludePath: "",
Top: 0, //nolint:mnd // default value
var complexityOpts = &complexity.Options{
Engine: complexity.Gocyclo,
ExcludeRegex: nil,
Top: 0, //nolint:mnd // default value
}

var ChurnComplexityCmd = &cobra.Command{
Expand All @@ -53,7 +54,7 @@ Open generated file '.html' in a browser to view the graph.`,

flag.LogIfVerbose("Processing directory: %s\n", repoPath)

if err := git.PopulateOpts(churnOpts, []string{"go"}, since, until, repoPath); err != nil {
if err := git.PopulateOpts(churnOpts, []string{"go"}, since, until, repoPath, excludeRegex); err != nil {
return fmt.Errorf("failed to create options: %w", err)
}

Expand All @@ -68,6 +69,10 @@ Open generated file '.html' in a browser to view the graph.`,

flag.LogIfVerbose("Analyzing complexity data...\n")

if err := complexity.PopulateOpts(complexityOpts, excludeRegex); err != nil {
return fmt.Errorf("failed to create options: %w", err)
}

complexityStats, err := complexity.RunComplexity(repoPath, complexityOpts)
if err != nil {
return fmt.Errorf("error running complexity analysis: %w", err)
Expand All @@ -93,6 +98,7 @@ func init() {
// Common flags
flags.BoolVarP(&flag.Verbose, flag.LongVerbose, flag.ShortVerbose, false, "Show detailed progress")
flags.StringVarP(&outputFile, "output", "o", "complexity_churn.html", "Output graph file name")
flags.StringVar(&excludeRegex, flag.LongExclude, "", "Exclude files matching regex pattern")

flags.StringVarP(&churnType, "churn-type", "t", git.Commits,
fmt.Sprintf("Specify churn type for plotting: [%s, %s]", git.Changes, git.Commits))
Expand Down
28 changes: 14 additions & 14 deletions grit/cmd/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,25 @@ var (
)

var churnOpts = &git.ChurnOptions{
SortBy: git.Changes,
Top: 0,
Extensions: nil,
Since: time.Time{},
Until: time.Time{},
Path: "",
ExcludePath: "",
SortBy: git.Changes,
Top: 0,
Extensions: nil,
Since: time.Time{},
Until: time.Time{},
Path: "",
ExcludeRegex: nil,
}

var complexityOpts = complexity.Options{
Engine: complexity.Gocyclo,
ExcludePath: "",
Top: 0, //nolint:mnd // default value
var complexityOpts = &complexity.Options{
Engine: complexity.Gocyclo,
ExcludeRegex: nil,
Top: 0, //nolint:mnd // default value
}

var coverageOpts = coverage.Options{
var coverageOpts = &coverage.Options{
SortBy: coverage.Worst,
Top: 0, //nolint:mnd // default value
ExcludePath: "",
ExcludeRegex: nil,
RunCoverage: flag.Auto,
CoverageFilename: "coverage.out",
}
Expand Down Expand Up @@ -85,7 +85,7 @@ var ReportCmd = &cobra.Command{
flag.LogIfVerbose("Processing directory: %s\n", repoPath)

flag.LogIfVerbose("Analyzing churn data...\n")
if err := git.PopulateOpts(churnOpts, []string{"go"}, since, until, repoPath); err != nil {
if err := git.PopulateOpts(churnOpts, []string{"go"}, since, until, repoPath, excludeRegex); err != nil {
return fmt.Errorf("failed to create options: %w", err)
}

Expand Down
27 changes: 14 additions & 13 deletions grit/cmd/stat/subcommands/churn.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,21 @@ import (
)

var churnOpts = &git.ChurnOptions{
SortBy: git.Changes,
Top: git.DefaultTop,
Extensions: nil,
Since: time.Time{},
Until: time.Time{},
Path: "",
ExcludePath: "",
SortBy: git.Changes,
Top: git.DefaultTop,
Extensions: nil,
Since: time.Time{},
Until: time.Time{},
Path: "",
ExcludeRegex: nil,
}

var (
extensionList []string
since string
until string
repoPath string
extensionList []string
since string
until string
repoPath string
excludeChurnRegex string
)

var ChurnCmd = &cobra.Command{ //nolint:exhaustruct // no need to set all fields
Expand All @@ -41,7 +42,7 @@ var ChurnCmd = &cobra.Command{ //nolint:exhaustruct // no need to set all fields

flag.LogIfVerbose("Processing repository: %s\n", repoPath)

if err := git.PopulateOpts(churnOpts, extensionList, since, until, repoPath); err != nil {
if err := git.PopulateOpts(churnOpts, extensionList, since, until, repoPath, excludeChurnRegex); err != nil {
return fmt.Errorf("failed to create options: %w", err)
}

Expand All @@ -63,7 +64,7 @@ func init() {
fmt.Sprintf("Specify churn sort type: [%s, %s, %s, %s]", git.Changes, git.Additions, git.Deletions, git.Commits))
flags.IntVarP(&churnOpts.Top, flag.LongTop, flag.ShortTop, git.DefaultTop, "Number of top files to display")
flags.BoolVarP(&flag.Verbose, flag.LongVerbose, flag.ShortVerbose, false, "Show detailed progress")
flags.StringVar(&churnOpts.ExcludePath, flag.LongExclude, "", "Exclude files matching regex pattern")
flags.StringVar(&excludeChurnRegex, flag.LongExclude, "", "Exclude files matching regex pattern")
flags.StringSliceVarP(&extensionList, flag.LongExtensions, flag.ShortExt, nil,
"Only include files with given extensions in comma-separated list, e.g. 'go,h,c'")
flags.StringVarP(&since, flag.LongSince, flag.ShortSince, "", "Start date for analysis in format 'YYYY-MM-DD'")
Expand Down
16 changes: 11 additions & 5 deletions grit/cmd/stat/subcommands/complexity.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ import (
)

var complexityOpts = complexity.Options{
Engine: complexity.Gocyclo,
ExcludePath: "",
Top: 10, //nolint:mnd // default value
Engine: complexity.Gocyclo,
ExcludeRegex: nil,
Top: 10, //nolint:mnd // default value
}

var excludeComplexityRegex string

var ComplexityCmd = &cobra.Command{ //nolint:exhaustruct // no need to set all fields
Use: "complexity [flags] <path>",
Short: "Finds the most complex files",
Expand All @@ -29,7 +31,11 @@ var ComplexityCmd = &cobra.Command{ //nolint:exhaustruct // no need to set all f

flag.LogIfVerbose("Processing repository: %s\n", repoPath)

fileStat, err := complexity.RunComplexity(repoPath, complexityOpts)
if err := complexity.PopulateOpts(&complexityOpts, excludeComplexityRegex); err != nil {
return fmt.Errorf("failed to create options: %w", err)
}

fileStat, err := complexity.RunComplexity(repoPath, &complexityOpts)
if err != nil {
return fmt.Errorf("error running complexity analysis: %w", err)
}
Expand All @@ -49,5 +55,5 @@ func init() {
fmt.Sprintf("Specify complexity calculation engine: [%s, %s]", complexity.Gocyclo, complexity.Gocognit))
flags.IntVarP(&complexityOpts.Top, flag.LongTop, flag.ShortTop, git.DefaultTop, "Number of top files to display")
flags.BoolVarP(&flag.Verbose, flag.LongVerbose, flag.ShortVerbose, false, "Show detailed progress")
flags.StringVar(&complexityOpts.ExcludePath, flag.LongExclude, "", "Exclude files matching regex pattern")
flags.StringVar(&excludeComplexityRegex, flag.LongExclude, "", "Exclude files matching regex pattern")
}
11 changes: 9 additions & 2 deletions grit/cmd/stat/subcommands/coverage.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ import (
"github.com/vbvictor/grit/pkg/coverage"
)

var coverageOpts = coverage.Options{
var coverageOpts = &coverage.Options{
SortBy: coverage.Worst,
Top: 10, //nolint:mnd // default value
ExcludePath: "",
ExcludeRegex: nil,
RunCoverage: "",
CoverageFilename: "coverage.out",
}

var excludeCoverageRegex string

var CoverageCmd = &cobra.Command{ //nolint:exhaustruct // no need to set all fields
Use: "coverage [flags] <path>",
Short: "Finds files with the least unit-test coverage",
Expand All @@ -31,6 +33,10 @@ var CoverageCmd = &cobra.Command{ //nolint:exhaustruct // no need to set all fie

flag.LogIfVerbose("Processing directory: %s\n", repoPath)

if err := coverage.PopulateOpts(coverageOpts, excludeCoverageRegex); err != nil {
return fmt.Errorf("failed to create options: %w", err)
}

covData, err := coverage.GetCoverageData(repoPath, coverageOpts)
if err != nil {
return fmt.Errorf("failed to get coverage data: %w", err)
Expand Down Expand Up @@ -59,4 +65,5 @@ func init() {
"Name of code coverage file to read or create")
flags.BoolVarP(&flag.Verbose, flag.LongVerbose, flag.ShortVerbose, false, "Enable verbose output")
flags.IntVarP(&coverageOpts.Top, flag.LongTop, flag.ShortTop, flag.DefaultTop, "Number of top files to display")
flags.StringVar(&excludeCoverageRegex, flag.LongExclude, "", "Exclude files matching regex pattern")
}
16 changes: 2 additions & 14 deletions pkg/complexity/gocognit.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,20 @@ import (
"go/token"
"os"
"path/filepath"
"regexp"
"strings"

"github.com/uudashr/gocognit"
)

func RunGocognit(repoPath string, opts Options) ([]*FileStat, error) { //nolint:funlen,cyclop // TODO: refactor later
var excludeRegex *regexp.Regexp

if opts.ExcludePath != "" {
var err error

excludeRegex, err = regexp.Compile(opts.ExcludePath)
if err != nil {
return nil, fmt.Errorf("invalid exclude pattern: %w", err)
}
}

func RunGocognit(repoPath string, opts *Options) ([]*FileStat, error) { //nolint:funlen,cyclop // TODO: refactor later
fileMap := make(map[string][]FunctionStat)

err := filepath.Walk(repoPath, func(path string, _ os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("failed to walk path: %w", err)
}

if excludeRegex != nil && excludeRegex.MatchString(path) {
if opts.ExcludeRegex != nil && opts.ExcludeRegex.MatchString(path) {
return nil
}

Expand Down
32 changes: 31 additions & 1 deletion pkg/complexity/gocognit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package complexity

import (
"path/filepath"
"regexp"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -25,6 +26,7 @@ func TestRunGocognit(t *testing.T) {
name string
directory string
expectedFiles map[string]ExpectedFile
excludeRegex *regexp.Regexp
}{
{
name: "Empty directory",
Expand Down Expand Up @@ -106,6 +108,34 @@ func TestRunGocognit(t *testing.T) {
},
},
},
{
name: "Exclude regex",
directory: "nested",
excludeRegex: regexp.MustCompile(`file1\.go$|morelevel2`),
expectedFiles: map[string]ExpectedFile{
"main.go": {
Functions: map[string]TestFunction{
"BaseFunction": {0, 3, "nested", "main.go"},
"SimpleCondition": {1, 7, "nested", "main.go"},
},
AvgComplexity: 0.5,
},
filepath.Join("level1", "level2", "file2.go"): {
Functions: map[string]TestFunction{
"Func3": {6, 3, "level2", filepath.Join("level1", "level2", "file2.go")},
"Func4": {10, 15, "level2", filepath.Join("level1", "level2", "file2.go")},
},
AvgComplexity: 8.0,
},
filepath.Join("level1", "level2", "file3.go"): {
Functions: map[string]TestFunction{
"NestedLoopsWithConditions": {10, 3, "level2", filepath.Join("level1", "level2", "file3.go")},
"SwitchWithLoops": {9, 17, "level2", filepath.Join("level1", "level2", "file3.go")},
},
AvgComplexity: 9.5,
},
},
},
{
name: "Special cases",
directory: "special",
Expand All @@ -124,7 +154,7 @@ func TestRunGocognit(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
testPath := filepath.Join("..", "..", "testdata", "complexity", "gocode", tt.directory)
result, err := RunGocognit(testPath, Options{})
result, err := RunGocognit(testPath, &Options{ExcludeRegex: tt.excludeRegex})

require.NoError(t, err)
assert.Len(t, result, len(tt.expectedFiles))
Expand Down
16 changes: 2 additions & 14 deletions pkg/complexity/gocyclo.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,13 @@ package complexity
import (
"fmt"
"path/filepath"
"regexp"

"github.com/fzipp/gocyclo"
)

func RunGocyclo(repoPath string, opts Options) ([]*FileStat, error) {
var excludeRegex *regexp.Regexp

if opts.ExcludePath != "" {
var err error

excludeRegex, err = regexp.Compile(opts.ExcludePath)
if err != nil {
return nil, fmt.Errorf("invalid exclude pattern: %w", err)
}
}

func RunGocyclo(repoPath string, opts *Options) ([]*FileStat, error) {
paths := []string{repoPath}
stats := gocyclo.Analyze(paths, excludeRegex)
stats := gocyclo.Analyze(paths, opts.ExcludeRegex)

result := make([]*FileStat, 0)
fileMap := make(map[string][]FunctionStat)
Expand Down
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载