github.com/shulhan/golangci-lint@v1.10.1/pkg/golinters/lll.go (about) 1 package golinters 2 3 import ( 4 "bufio" 5 "context" 6 "fmt" 7 "go/token" 8 "os" 9 "strings" 10 "unicode/utf8" 11 12 "github.com/golangci/golangci-lint/pkg/lint/linter" 13 "github.com/golangci/golangci-lint/pkg/result" 14 ) 15 16 type Lll struct{} 17 18 func (Lll) Name() string { 19 return "lll" 20 } 21 22 func (Lll) Desc() string { 23 return "Reports long lines" 24 } 25 26 func (lint Lll) getIssuesForFile(filename string, maxLineLen int, tabSpaces string) ([]result.Issue, error) { 27 var res []result.Issue 28 29 f, err := os.Open(filename) 30 if err != nil { 31 return nil, fmt.Errorf("can't open file %s: %s", filename, err) 32 } 33 defer f.Close() 34 35 lineNumber := 1 36 scanner := bufio.NewScanner(f) 37 for scanner.Scan() { 38 line := scanner.Text() 39 line = strings.Replace(line, "\t", tabSpaces, -1) 40 lineLen := utf8.RuneCountInString(line) 41 if lineLen > maxLineLen { 42 res = append(res, result.Issue{ 43 Pos: token.Position{ 44 Filename: filename, 45 Line: lineNumber, 46 }, 47 Text: fmt.Sprintf("line is %d characters", lineLen), 48 FromLinter: lint.Name(), 49 }) 50 } 51 lineNumber++ 52 } 53 54 if err := scanner.Err(); err != nil { 55 if err == bufio.ErrTooLong && maxLineLen < bufio.MaxScanTokenSize { 56 // scanner.Scan() might fail if the line is longer than bufio.MaxScanTokenSize 57 // In the case where the specified maxLineLen is smaller than bufio.MaxScanTokenSize 58 // we can return this line as a long line instead of returning an error. 59 // The reason for this change is that this case might happen with autogenerated files 60 // The go-bindata tool for instance might generate a file with a very long line. 61 // In this case, as it's a auto generated file, the warning returned by lll will 62 // be ignored. 63 // But if we return a linter error here, and this error happens for an autogenerated 64 // file the error will be discarded (fine), but all the subsequent errors for lll will 65 // be discarded for other files and we'll miss legit error. 66 res = append(res, result.Issue{ 67 Pos: token.Position{ 68 Filename: filename, 69 Line: lineNumber, 70 Column: 1, 71 }, 72 Text: fmt.Sprintf("line is more than %d characters", bufio.MaxScanTokenSize), 73 FromLinter: lint.Name(), 74 }) 75 } else { 76 return nil, fmt.Errorf("can't scan file %s: %s", filename, err) 77 } 78 } 79 80 return res, nil 81 } 82 83 func (lint Lll) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Issue, error) { 84 var res []result.Issue 85 spaces := strings.Repeat(" ", lintCtx.Settings().Lll.TabWidth) 86 for _, f := range lintCtx.PkgProgram.Files(lintCtx.Cfg.Run.AnalyzeTests) { 87 issues, err := lint.getIssuesForFile(f, lintCtx.Settings().Lll.LineLength, spaces) 88 if err != nil { 89 return nil, err 90 } 91 res = append(res, issues...) 92 } 93 94 return res, nil 95 }