@@ -5,10 +5,10 @@ import (
55 "context"
66 "crypto/sha256"
77 "encoding/json"
8- "fmt"
98 "io"
109 "os"
1110 "path/filepath"
11+ "strings"
1212 "time"
1313
1414 "github.com/fatih/color"
@@ -31,8 +31,9 @@ import (
3131)
3232
3333type Executor struct {
34- rootCmd * cobra.Command
35- runCmd * cobra.Command
34+ rootCmd * cobra.Command
35+ runCmd * cobra.Command
36+ lintersCmd * cobra.Command
3637
3738 exitCode int
3839 version , commit , date string
@@ -55,6 +56,7 @@ type Executor struct {
5556}
5657
5758func NewExecutor (version , commit , date string ) * Executor {
59+ startedAt := time .Now ()
5860 e := & Executor {
5961 cfg : config .NewDefault (),
6062 version : version ,
@@ -66,9 +68,6 @@ func NewExecutor(version, commit, date string) *Executor {
6668
6769 e .debugf ("Starting execution..." )
6870 e .log = report .NewLogWrapper (logutils .NewStderrLog ("" ), & e .reportData )
69- if ok := e .acquireFileLock (); ! ok {
70- e .log .Fatalf ("Parallel golangci-lint is running" )
71- }
7271
7372 // to setup log level early we need to parse config from command line extra time to
7473 // find `-v` option
@@ -121,6 +120,7 @@ func NewExecutor(version, commit, date string) *Executor {
121120
122121 // Slice options must be explicitly set for proper merging of config and command-line options.
123122 fixSlicesFlags (e .runCmd .Flags ())
123+ fixSlicesFlags (e .lintersCmd .Flags ())
124124
125125 e .EnabledLintersSet = lintersdb .NewEnabledSet (e .DBManager ,
126126 lintersdb .NewValidator (e .DBManager ), e .log .Child ("lintersdb" ), e .cfg )
@@ -139,7 +139,7 @@ func NewExecutor(version, commit, date string) *Executor {
139139 if err = e .initHashSalt (version ); err != nil {
140140 e .log .Fatalf ("Failed to init hash salt: %s" , err )
141141 }
142- e .debugf ("Initialized executor" )
142+ e .debugf ("Initialized executor in %s" , time . Since ( startedAt ) )
143143 return e
144144}
145145
@@ -191,27 +191,39 @@ func computeBinarySalt(version string) ([]byte, error) {
191191}
192192
193193func computeConfigSalt (cfg * config.Config ) ([]byte , error ) {
194- configBytes , err := json .Marshal (cfg )
194+ // We don't hash all config fields to reduce meaningless cache
195+ // invalidations. At least, it has a huge impact on tests speed.
196+
197+ lintersSettingsBytes , err := json .Marshal (cfg .LintersSettings )
195198 if err != nil {
196- return nil , errors .Wrap (err , "failed to json marshal config" )
199+ return nil , errors .Wrap (err , "failed to json marshal config linter settings " )
197200 }
198201
202+ var configData bytes.Buffer
203+ configData .WriteString ("linters-settings=" )
204+ configData .Write (lintersSettingsBytes )
205+ configData .WriteString ("\n build-tags=%s" + strings .Join (cfg .Run .BuildTags , "," ))
206+
199207 h := sha256 .New ()
200- if n , err := h .Write (configBytes ); n != len (configBytes ) {
201- return nil , fmt .Errorf ("failed to hash config bytes: wrote %d/%d bytes, error: %s" , n , len (configBytes ), err )
202- }
208+ h .Write (configData .Bytes ()) //nolint:errcheck
203209 return h .Sum (nil ), nil
204210}
205211
206212func (e * Executor ) acquireFileLock () bool {
213+ if e .cfg .Run .AllowParallelRunners {
214+ e .debugf ("Parallel runners are allowed, no locking" )
215+ return true
216+ }
217+
207218 lockFile := filepath .Join (os .TempDir (), "golangci-lint.lock" )
208219 e .debugf ("Locking on file %s..." , lockFile )
209220 f := flock .New (lockFile )
210- ctx , finish := context .WithTimeout (context .Background (), time .Minute )
221+ const totalTimeout = 5 * time .Second
222+ const retryDelay = time .Second
223+ ctx , finish := context .WithTimeout (context .Background (), totalTimeout )
211224 defer finish ()
212225
213- timeout := time .Second * 3
214- if ok , _ := f .TryLockContext (ctx , timeout ); ! ok {
226+ if ok , _ := f .TryLockContext (ctx , retryDelay ); ! ok {
215227 return false
216228 }
217229
@@ -220,6 +232,10 @@ func (e *Executor) acquireFileLock() bool {
220232}
221233
222234func (e * Executor ) releaseFileLock () {
235+ if e .cfg .Run .AllowParallelRunners {
236+ return
237+ }
238+
223239 if err := e .flock .Unlock (); err != nil {
224240 e .debugf ("Failed to unlock on file: %s" , err )
225241 }
0 commit comments