github.com/ferretdb/golangci-lint@v1.10.1/pkg/commands/root.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"runtime"
     7  	"runtime/pprof"
     8  
     9  	"github.com/golangci/golangci-lint/pkg/config"
    10  	"github.com/golangci/golangci-lint/pkg/logutils"
    11  	"github.com/spf13/cobra"
    12  	"github.com/spf13/pflag"
    13  )
    14  
    15  func (e *Executor) persistentPreRun(cmd *cobra.Command, args []string) {
    16  	if e.cfg.Run.PrintVersion {
    17  		fmt.Fprintf(logutils.StdOut, "golangci-lint has version %s built from %s on %s\n", e.version, e.commit, e.date)
    18  		os.Exit(0)
    19  	}
    20  
    21  	runtime.GOMAXPROCS(e.cfg.Run.Concurrency)
    22  
    23  	logutils.SetupVerboseLog(e.log, e.cfg.Run.IsVerbose)
    24  
    25  	if e.cfg.Run.CPUProfilePath != "" {
    26  		f, err := os.Create(e.cfg.Run.CPUProfilePath)
    27  		if err != nil {
    28  			e.log.Fatalf("Can't create file %s: %s", e.cfg.Run.CPUProfilePath, err)
    29  		}
    30  		if err := pprof.StartCPUProfile(f); err != nil {
    31  			e.log.Fatalf("Can't start CPU profiling: %s", err)
    32  		}
    33  	}
    34  }
    35  
    36  func (e *Executor) persistentPostRun(cmd *cobra.Command, args []string) {
    37  	if e.cfg.Run.CPUProfilePath != "" {
    38  		pprof.StopCPUProfile()
    39  	}
    40  	if e.cfg.Run.MemProfilePath != "" {
    41  		f, err := os.Create(e.cfg.Run.MemProfilePath)
    42  		if err != nil {
    43  			e.log.Fatalf("Can't create file %s: %s", e.cfg.Run.MemProfilePath, err)
    44  		}
    45  		runtime.GC() // get up-to-date statistics
    46  		if err := pprof.WriteHeapProfile(f); err != nil {
    47  			e.log.Fatalf("Can't write heap profile: %s", err)
    48  		}
    49  	}
    50  
    51  	os.Exit(e.exitCode)
    52  }
    53  
    54  func getDefaultConcurrency() int {
    55  	if os.Getenv("HELP_RUN") == "1" {
    56  		return 8 // to make stable concurrency for README help generating builds
    57  	}
    58  
    59  	return runtime.NumCPU()
    60  }
    61  
    62  func (e *Executor) initRoot() {
    63  	rootCmd := &cobra.Command{
    64  		Use:   "golangci-lint",
    65  		Short: "golangci-lint is a smart linters runner.",
    66  		Long:  `Smart, fast linters runner. Run it in cloud for every GitHub pull request on https://golangci.com`,
    67  		Run: func(cmd *cobra.Command, args []string) {
    68  			if err := cmd.Help(); err != nil {
    69  				e.log.Fatalf("Can't run help: %s", err)
    70  			}
    71  		},
    72  		PersistentPreRun:  e.persistentPreRun,
    73  		PersistentPostRun: e.persistentPostRun,
    74  	}
    75  
    76  	initRootFlagSet(rootCmd.PersistentFlags(), e.cfg, e.needVersionOption())
    77  	e.rootCmd = rootCmd
    78  }
    79  
    80  func (e *Executor) needVersionOption() bool {
    81  	return e.date != ""
    82  }
    83  
    84  func initRootFlagSet(fs *pflag.FlagSet, cfg *config.Config, needVersionOption bool) {
    85  	fs.BoolVarP(&cfg.Run.IsVerbose, "verbose", "v", false, wh("verbose output"))
    86  
    87  	var silent bool
    88  	fs.BoolVarP(&silent, "silent", "s", false, wh("disables congrats outputs"))
    89  	if err := fs.MarkHidden("silent"); err != nil {
    90  		panic(err)
    91  	}
    92  	err := fs.MarkDeprecated("silent",
    93  		"now golangci-lint by default is silent: it doesn't print Congrats message")
    94  	if err != nil {
    95  		panic(err)
    96  	}
    97  
    98  	fs.StringVar(&cfg.Run.CPUProfilePath, "cpu-profile-path", "", wh("Path to CPU profile output file"))
    99  	fs.StringVar(&cfg.Run.MemProfilePath, "mem-profile-path", "", wh("Path to memory profile output file"))
   100  	fs.IntVarP(&cfg.Run.Concurrency, "concurrency", "j", getDefaultConcurrency(), wh("Concurrency (default NumCPU)"))
   101  	if needVersionOption {
   102  		fs.BoolVar(&cfg.Run.PrintVersion, "version", false, wh("Print version"))
   103  	}
   104  }