11package errcheck
22
33import (
4- "bufio"
54 "cmp"
65 "fmt"
7- "os"
8- "os/user"
9- "path/filepath"
106 "regexp"
11- "strings"
127 "sync"
138
149 "github.com/kisielk/errcheck/errcheck"
1510 "golang.org/x/tools/go/analysis"
1611 "golang.org/x/tools/go/packages"
1712
1813 "github.com/golangci/golangci-lint/pkg/config"
19- "github.com/golangci/golangci-lint/pkg/fsutils"
2014 "github.com/golangci/golangci-lint/pkg/goanalysis"
2115 "github.com/golangci/golangci-lint/pkg/golinters/internal"
2216 "github.com/golangci/golangci-lint/pkg/lint/linter"
@@ -43,19 +37,12 @@ func New(settings *config.ErrcheckSettings) *goanalysis.Linter {
4337 nil ,
4438 ).WithContextSetter (func (lintCtx * linter.Context ) {
4539 // copied from errcheck
46- checker , err := getChecker (settings )
47- if err != nil {
48- lintCtx .Log .Errorf ("failed to get checker: %v" , err )
49- return
50- }
40+ checker := getChecker (settings )
5141
5242 checker .Tags = lintCtx .Cfg .Run .BuildTags
5343
5444 analyzer .Run = func (pass * analysis.Pass ) (any , error ) {
5545 issues := runErrCheck (lintCtx , pass , checker )
56- if err != nil {
57- return nil , err
58- }
5946
6047 if len (issues ) == 0 {
6148 return nil , nil
@@ -109,41 +96,7 @@ func runErrCheck(lintCtx *linter.Context, pass *analysis.Pass, checker *errcheck
10996 return issues
11097}
11198
112- // parseIgnoreConfig was taken from errcheck in order to keep the API identical.
113- // https://github.com/kisielk/errcheck/blob/1787c4bee836470bf45018cfbc783650db3c6501/main.go#L25-L60
114- func parseIgnoreConfig (s string ) (map [string ]* regexp.Regexp , error ) {
115- if s == "" {
116- return nil , nil
117- }
118-
119- cfg := map [string ]* regexp.Regexp {}
120-
121- for _ , pair := range strings .Split (s , "," ) {
122- colonIndex := strings .Index (pair , ":" )
123- var pkg , re string
124- if colonIndex == - 1 {
125- pkg = ""
126- re = pair
127- } else {
128- pkg = pair [:colonIndex ]
129- re = pair [colonIndex + 1 :]
130- }
131- regex , err := regexp .Compile (re )
132- if err != nil {
133- return nil , err
134- }
135- cfg [pkg ] = regex
136- }
137-
138- return cfg , nil
139- }
140-
141- func getChecker (errCfg * config.ErrcheckSettings ) (* errcheck.Checker , error ) {
142- ignoreConfig , err := parseIgnoreConfig (errCfg .Ignore )
143- if err != nil {
144- return nil , fmt .Errorf ("failed to parse 'ignore' directive: %w" , err )
145- }
146-
99+ func getChecker (errCfg * config.ErrcheckSettings ) * errcheck.Checker {
147100 checker := errcheck.Checker {
148101 Exclusions : errcheck.Exclusions {
149102 BlankAssignments : ! errCfg .CheckAssignToBlank ,
@@ -156,114 +109,7 @@ func getChecker(errCfg *config.ErrcheckSettings) (*errcheck.Checker, error) {
156109 checker .Exclusions .Symbols = append (checker .Exclusions .Symbols , errcheck .DefaultExcludedSymbols ... )
157110 }
158111
159- for pkg , re := range ignoreConfig {
160- checker .Exclusions .SymbolRegexpsByPackage [pkg ] = re
161- }
162-
163- if errCfg .Exclude != "" {
164- exclude , err := readExcludeFile (errCfg .Exclude )
165- if err != nil {
166- return nil , err
167- }
168-
169- checker .Exclusions .Symbols = append (checker .Exclusions .Symbols , exclude ... )
170- }
171-
172112 checker .Exclusions .Symbols = append (checker .Exclusions .Symbols , errCfg .ExcludeFunctions ... )
173113
174- return & checker , nil
175- }
176-
177- func getFirstPathArg () string {
178- args := os .Args
179-
180- // skip all args ([golangci-lint, run/linters]) before files/dirs list
181- for len (args ) != 0 {
182- if args [0 ] == "run" {
183- args = args [1 :]
184- break
185- }
186-
187- args = args [1 :]
188- }
189-
190- // find first file/dir arg
191- firstArg := "./..."
192- for _ , arg := range args {
193- if ! strings .HasPrefix (arg , "-" ) {
194- firstArg = arg
195- break
196- }
197- }
198-
199- return firstArg
200- }
201-
202- func setupConfigFileSearch (name string ) []string {
203- if strings .HasPrefix (name , "~" ) {
204- if u , err := user .Current (); err == nil {
205- name = strings .Replace (name , "~" , u .HomeDir , 1 )
206- }
207- }
208-
209- if filepath .IsAbs (name ) {
210- return []string {name }
211- }
212-
213- firstArg := getFirstPathArg ()
214-
215- absStartPath , err := filepath .Abs (firstArg )
216- if err != nil {
217- absStartPath = filepath .Clean (firstArg )
218- }
219-
220- // start from it
221- var curDir string
222- if fsutils .IsDir (absStartPath ) {
223- curDir = absStartPath
224- } else {
225- curDir = filepath .Dir (absStartPath )
226- }
227-
228- // find all dirs from it up to the root
229- configSearchPaths := []string {filepath .Join ("." , name )}
230- for {
231- configSearchPaths = append (configSearchPaths , filepath .Join (curDir , name ))
232- newCurDir := filepath .Dir (curDir )
233- if curDir == newCurDir || newCurDir == "" {
234- break
235- }
236- curDir = newCurDir
237- }
238-
239- return configSearchPaths
240- }
241-
242- func readExcludeFile (name string ) ([]string , error ) {
243- var err error
244- var fh * os.File
245-
246- for _ , path := range setupConfigFileSearch (name ) {
247- if fh , err = os .Open (path ); err == nil {
248- break
249- }
250- }
251-
252- if fh == nil {
253- return nil , fmt .Errorf ("failed reading exclude file: %s: %w" , name , err )
254- }
255- defer func () { _ = fh .Close () }()
256-
257- scanner := bufio .NewScanner (fh )
258-
259- var excludes []string
260- for scanner .Scan () {
261- excludes = append (excludes , scanner .Text ())
262- }
263-
264- if err := scanner .Err (); err != nil {
265- return nil , fmt .Errorf ("failed scanning file: %s: %w" , name , err )
266- }
267-
268- return excludes , nil
114+ return & checker
269115}
0 commit comments