Merge remote-tracking branch 'origin/feature/initial-improvements'
This commit is contained in:
		
						commit
						ac1a976ee9
					
				@ -1,6 +1,4 @@
 | 
				
			|||||||
run:
 | 
					run:
 | 
				
			||||||
  args:
 | 
					 | 
				
			||||||
    - ./...
 | 
					 | 
				
			||||||
  verbose: true
 | 
					  verbose: true
 | 
				
			||||||
  concurrency: 4
 | 
					  concurrency: 4
 | 
				
			||||||
  deadline: 1m
 | 
					  deadline: 1m
 | 
				
			||||||
 | 
				
			|||||||
@ -2,11 +2,13 @@ package commands
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"go/build"
 | 
						"go/build"
 | 
				
			||||||
	"go/token"
 | 
						"go/token"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
						"runtime"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -21,6 +23,7 @@ import (
 | 
				
			|||||||
	"github.com/golangci/golangci-lint/pkg/result/processors"
 | 
						"github.com/golangci/golangci-lint/pkg/result/processors"
 | 
				
			||||||
	"github.com/sirupsen/logrus"
 | 
						"github.com/sirupsen/logrus"
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
 | 
						"github.com/spf13/pflag"
 | 
				
			||||||
	"github.com/spf13/viper"
 | 
						"github.com/spf13/viper"
 | 
				
			||||||
	"golang.org/x/tools/go/loader"
 | 
						"golang.org/x/tools/go/loader"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -51,6 +54,8 @@ func (e *Executor) initRun() {
 | 
				
			|||||||
	runCmd.Flags().StringSliceVar(&rc.BuildTags, "build-tags", []string{}, "Build tags (not all linters support them)")
 | 
						runCmd.Flags().StringSliceVar(&rc.BuildTags, "build-tags", []string{}, "Build tags (not all linters support them)")
 | 
				
			||||||
	runCmd.Flags().DurationVar(&rc.Deadline, "deadline", time.Minute, "Deadline for total work")
 | 
						runCmd.Flags().DurationVar(&rc.Deadline, "deadline", time.Minute, "Deadline for total work")
 | 
				
			||||||
	runCmd.Flags().BoolVar(&rc.AnalyzeTests, "tests", false, "Analyze tests (*_test.go)")
 | 
						runCmd.Flags().BoolVar(&rc.AnalyzeTests, "tests", false, "Analyze tests (*_test.go)")
 | 
				
			||||||
 | 
						runCmd.Flags().BoolVar(&rc.PrintResourcesUsage, "print-resources-usage", false, "Print avg and max memory usage of golangci-lint and total time")
 | 
				
			||||||
 | 
						runCmd.Flags().StringVarP(&rc.Config, "config", "c", "", "Read config from file path `PATH`")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Linters settings config
 | 
						// Linters settings config
 | 
				
			||||||
	lsc := &e.cfg.LintersSettings
 | 
						lsc := &e.cfg.LintersSettings
 | 
				
			||||||
@ -98,8 +103,6 @@ func (e *Executor) initRun() {
 | 
				
			|||||||
	runCmd.Flags().StringVar(&ic.DiffFromRevision, "new-from-rev", "", "Show only new issues created after git revision `REV`")
 | 
						runCmd.Flags().StringVar(&ic.DiffFromRevision, "new-from-rev", "", "Show only new issues created after git revision `REV`")
 | 
				
			||||||
	runCmd.Flags().StringVar(&ic.DiffPatchFilePath, "new-from-patch", "", "Show only new issues created in git patch with file path `PATH`")
 | 
						runCmd.Flags().StringVar(&ic.DiffPatchFilePath, "new-from-patch", "", "Show only new issues created in git patch with file path `PATH`")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	runCmd.Flags().StringVarP(&e.cfg.Run.Config, "config", "c", "", "Read config from file path `PATH`")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	e.parseConfig(runCmd)
 | 
						e.parseConfig(runCmd)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -240,19 +243,7 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (chan result.
 | 
				
			|||||||
	return runner.Run(ctx, linters, lintCtx), nil
 | 
						return runner.Run(ctx, linters, lintCtx), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *Executor) executeRun(cmd *cobra.Command, args []string) {
 | 
					func (e *Executor) runAndPrint(ctx context.Context, args []string) error {
 | 
				
			||||||
	ctx, cancel := context.WithTimeout(context.Background(), e.cfg.Run.Deadline)
 | 
					 | 
				
			||||||
	defer cancel()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	defer func(startedAt time.Time) {
 | 
					 | 
				
			||||||
		logrus.Infof("Run took %s", time.Since(startedAt))
 | 
					 | 
				
			||||||
	}(time.Now())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if e.cfg.Output.PrintWelcomeMessage {
 | 
					 | 
				
			||||||
		fmt.Println("Run this tool in cloud on every github pull request in https://golangci.com for free (public repos)")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f := func() error {
 | 
					 | 
				
			||||||
	issues, err := e.runAnalysis(ctx, args)
 | 
						issues, err := e.runAnalysis(ctx, args)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@ -276,9 +267,29 @@ func (e *Executor) executeRun(cmd *cobra.Command, args []string) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *Executor) executeRun(cmd *cobra.Command, args []string) {
 | 
				
			||||||
 | 
						needTrackResources := e.cfg.Run.IsVerbose || e.cfg.Run.PrintResourcesUsage
 | 
				
			||||||
 | 
						trackResourcesEndCh := make(chan struct{})
 | 
				
			||||||
 | 
						defer func() { // XXX: this defer must be before ctx.cancel defer
 | 
				
			||||||
 | 
							if needTrackResources { // wait until resource tracking finished to print properly
 | 
				
			||||||
 | 
								<-trackResourcesEndCh
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx, cancel := context.WithTimeout(context.Background(), e.cfg.Run.Deadline)
 | 
				
			||||||
 | 
						defer cancel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if needTrackResources {
 | 
				
			||||||
 | 
							go watchResources(ctx, trackResourcesEndCh)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := f(); err != nil {
 | 
						if e.cfg.Output.PrintWelcomeMessage {
 | 
				
			||||||
 | 
							fmt.Println("Run this tool in cloud on every github pull request in https://golangci.com for free (public repos)")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := e.runAndPrint(ctx, args); err != nil {
 | 
				
			||||||
		log.Print(err)
 | 
							log.Print(err)
 | 
				
			||||||
		if e.exitCode == 0 {
 | 
							if e.exitCode == 0 {
 | 
				
			||||||
			e.exitCode = exitCodeIfFailure
 | 
								e.exitCode = exitCodeIfFailure
 | 
				
			||||||
@ -289,7 +300,10 @@ func (e *Executor) executeRun(cmd *cobra.Command, args []string) {
 | 
				
			|||||||
func (e *Executor) parseConfig(cmd *cobra.Command) {
 | 
					func (e *Executor) parseConfig(cmd *cobra.Command) {
 | 
				
			||||||
	// XXX: hack with double parsing to acces "config" option here
 | 
						// XXX: hack with double parsing to acces "config" option here
 | 
				
			||||||
	if err := cmd.ParseFlags(os.Args); err != nil {
 | 
						if err := cmd.ParseFlags(os.Args); err != nil {
 | 
				
			||||||
		log.Fatalf("Can't parse agrs: %s", err)
 | 
							if err == pflag.ErrHelp {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							log.Fatalf("Can't parse args: %s", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := viper.BindPFlags(cmd.Flags()); err != nil {
 | 
						if err := viper.BindPFlags(cmd.Flags()); err != nil {
 | 
				
			||||||
@ -318,4 +332,63 @@ func (e *Executor) parseConfig(cmd *cobra.Command) {
 | 
				
			|||||||
	if err := viper.Unmarshal(&e.cfg); err != nil {
 | 
						if err := viper.Unmarshal(&e.cfg); err != nil {
 | 
				
			||||||
		log.Fatalf("Can't unmarshal config by viper: %s", err)
 | 
							log.Fatalf("Can't unmarshal config by viper: %s", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := e.validateConfig(); err != nil {
 | 
				
			||||||
 | 
							log.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *Executor) validateConfig() error {
 | 
				
			||||||
 | 
						c := e.cfg
 | 
				
			||||||
 | 
						if len(c.Run.Args) != 0 {
 | 
				
			||||||
 | 
							return errors.New("option run.args in config aren't supported now")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if c.Run.CPUProfilePath != "" {
 | 
				
			||||||
 | 
							return errors.New("option run.cpuprofilepath in config isn't allowed")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func watchResources(ctx context.Context, done chan struct{}) {
 | 
				
			||||||
 | 
						startedAt := time.Now()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rssValues := []uint64{}
 | 
				
			||||||
 | 
						ticker := time.NewTicker(100 * time.Millisecond)
 | 
				
			||||||
 | 
						defer ticker.Stop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							var m runtime.MemStats
 | 
				
			||||||
 | 
							runtime.ReadMemStats(&m)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							rssValues = append(rssValues, m.Sys)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							stop := false
 | 
				
			||||||
 | 
							select {
 | 
				
			||||||
 | 
							case <-ctx.Done():
 | 
				
			||||||
 | 
								stop = true
 | 
				
			||||||
 | 
							case <-ticker.C: // track every second
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if stop {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var avg, max uint64
 | 
				
			||||||
 | 
						for _, v := range rssValues {
 | 
				
			||||||
 | 
							avg += v
 | 
				
			||||||
 | 
							if v > max {
 | 
				
			||||||
 | 
								max = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						avg /= uint64(len(rssValues))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const MB = 1024 * 1024
 | 
				
			||||||
 | 
						maxMB := float64(max) / MB
 | 
				
			||||||
 | 
						logrus.Infof("Memory: %d samples, avg is %.1fMB, max is %.1fMB",
 | 
				
			||||||
 | 
							len(rssValues), float64(avg)/MB, maxMB)
 | 
				
			||||||
 | 
						logrus.Infof("Execution took %s", time.Since(startedAt))
 | 
				
			||||||
 | 
						close(done)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,7 @@ type Run struct {
 | 
				
			|||||||
	IsVerbose           bool `mapstructure:"verbose"`
 | 
						IsVerbose           bool `mapstructure:"verbose"`
 | 
				
			||||||
	CPUProfilePath      string
 | 
						CPUProfilePath      string
 | 
				
			||||||
	Concurrency         int
 | 
						Concurrency         int
 | 
				
			||||||
 | 
						PrintResourcesUsage bool `mapstructure:"print-resources-usage"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Config string
 | 
						Config string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user