1
1
package commands
2
2
3
3
import (
4
+ "bytes"
5
+ "crypto/sha256"
4
6
"fmt"
7
+ "io"
5
8
"os"
6
9
"path/filepath"
10
+ "strings"
7
11
8
12
"github.com/spf13/cobra"
13
+ "gopkg.in/yaml.v3"
9
14
10
15
"github.com/golangci/golangci-lint/internal/cache"
16
+ "github.com/golangci/golangci-lint/pkg/config"
11
17
"github.com/golangci/golangci-lint/pkg/fsutils"
12
18
"github.com/golangci/golangci-lint/pkg/logutils"
13
19
)
@@ -21,14 +27,13 @@ func (e *Executor) initCache() {
21
27
return cmd .Help ()
22
28
},
23
29
}
24
- e .rootCmd .AddCommand (cacheCmd )
25
30
26
31
cacheCmd .AddCommand (& cobra.Command {
27
32
Use : "clean" ,
28
33
Short : "Clean cache" ,
29
34
Args : cobra .NoArgs ,
30
35
ValidArgsFunction : cobra .NoFileCompletions ,
31
- RunE : e .executeCleanCache ,
36
+ RunE : e .executeCacheClean ,
32
37
})
33
38
cacheCmd .AddCommand (& cobra.Command {
34
39
Use : "status" ,
@@ -39,9 +44,11 @@ func (e *Executor) initCache() {
39
44
})
40
45
41
46
// TODO: add trim command?
47
+
48
+ e .rootCmd .AddCommand (cacheCmd )
42
49
}
43
50
44
- func (e * Executor ) executeCleanCache (_ * cobra.Command , _ []string ) error {
51
+ func (e * Executor ) executeCacheClean (_ * cobra.Command , _ []string ) error {
45
52
cacheDir := cache .DefaultDir ()
46
53
if err := os .RemoveAll (cacheDir ); err != nil {
47
54
return fmt .Errorf ("failed to remove dir %s: %w" , cacheDir , err )
@@ -70,3 +77,68 @@ func dirSizeBytes(path string) (int64, error) {
70
77
})
71
78
return size , err
72
79
}
80
+
81
+ // --- Related to cache but not used directly by the cache command.
82
+
83
+ func initHashSalt (version string , cfg * config.Config ) error {
84
+ binSalt , err := computeBinarySalt (version )
85
+ if err != nil {
86
+ return fmt .Errorf ("failed to calculate binary salt: %w" , err )
87
+ }
88
+
89
+ configSalt , err := computeConfigSalt (cfg )
90
+ if err != nil {
91
+ return fmt .Errorf ("failed to calculate config salt: %w" , err )
92
+ }
93
+
94
+ b := bytes .NewBuffer (binSalt )
95
+ b .Write (configSalt )
96
+ cache .SetSalt (b .Bytes ())
97
+ return nil
98
+ }
99
+
100
+ func computeBinarySalt (version string ) ([]byte , error ) {
101
+ if version != "" && version != "(devel)" {
102
+ return []byte (version ), nil
103
+ }
104
+
105
+ if logutils .HaveDebugTag (logutils .DebugKeyBinSalt ) {
106
+ return []byte ("debug" ), nil
107
+ }
108
+
109
+ p , err := os .Executable ()
110
+ if err != nil {
111
+ return nil , err
112
+ }
113
+ f , err := os .Open (p )
114
+ if err != nil {
115
+ return nil , err
116
+ }
117
+ defer f .Close ()
118
+ h := sha256 .New ()
119
+ if _ , err := io .Copy (h , f ); err != nil {
120
+ return nil , err
121
+ }
122
+ return h .Sum (nil ), nil
123
+ }
124
+
125
+ // computeConfigSalt computes configuration hash.
126
+ // We don't hash all config fields to reduce meaningless cache invalidations.
127
+ // At least, it has a huge impact on tests speed.
128
+ // Fields: `LintersSettings` and `Run.BuildTags`.
129
+ func computeConfigSalt (cfg * config.Config ) ([]byte , error ) {
130
+ lintersSettingsBytes , err := yaml .Marshal (cfg .LintersSettings )
131
+ if err != nil {
132
+ return nil , fmt .Errorf ("failed to json marshal config linter settings: %w" , err )
133
+ }
134
+
135
+ configData := bytes .NewBufferString ("linters-settings=" )
136
+ configData .Write (lintersSettingsBytes )
137
+ configData .WriteString ("\n build-tags=%s" + strings .Join (cfg .Run .BuildTags , "," ))
138
+
139
+ h := sha256 .New ()
140
+ if _ , err := h .Write (configData .Bytes ()); err != nil {
141
+ return nil , err
142
+ }
143
+ return h .Sum (nil ), nil
144
+ }
0 commit comments