gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/github.com/walle/lll/lll.go (about) 1 // Package lll provides validation functions regarding line length 2 package lll 3 4 import ( 5 "bufio" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "net/http" 10 "os" 11 "path/filepath" 12 "regexp" 13 "strings" 14 "unicode/utf8" 15 ) 16 17 // ShouldSkip checks the input and determines if the path should be skipped. 18 // Use the SkipList to quickly skip paths. 19 // All directories are skipped, only files are processed. 20 // If GoOnly is supplied check that the file is a go file. 21 // Otherwise check so the file is a "text file". 22 func ShouldSkip(path string, isDir bool, skipList []string, 23 goOnly bool) (bool, error) { 24 25 name := filepath.Base(path) 26 for _, d := range skipList { 27 if name == d { 28 if isDir { 29 return true, filepath.SkipDir 30 } 31 return true, nil 32 } 33 } 34 if isDir { 35 return true, nil 36 } 37 38 if goOnly { 39 if !strings.HasSuffix(path, ".go") { 40 return true, nil 41 } 42 } else { 43 b, err := ioutil.ReadFile(path) 44 if err != nil { 45 return true, err 46 } 47 m := http.DetectContentType(b) 48 if !strings.Contains(m, "text/") { 49 return true, nil 50 } 51 } 52 53 return false, nil 54 } 55 56 // ProcessFile checks all lines in the file and writes an error if the line 57 // length is greater than MaxLength. 58 func ProcessFile(w io.Writer, path string, maxLength, tabWidth int, 59 exclude *regexp.Regexp) error { 60 f, err := os.Open(path) 61 if err != nil { 62 return err 63 } 64 defer func() { 65 err := f.Close() 66 if err != nil { 67 fmt.Printf("Error closing file: %s\n", err) 68 } 69 }() 70 71 return Process(f, w, path, maxLength, tabWidth, exclude) 72 } 73 74 // Process checks all lines in the reader and writes an error if the line length 75 // is greater than MaxLength. 76 func Process(r io.Reader, w io.Writer, path string, maxLength, tabWidth int, 77 exclude *regexp.Regexp) error { 78 spaces := strings.Repeat(" ", tabWidth) 79 l := 1 80 s := bufio.NewScanner(r) 81 for s.Scan() { 82 t := s.Text() 83 t = strings.Replace(t, "\t", spaces, -1) 84 c := utf8.RuneCountInString(t) 85 if c > maxLength { 86 if exclude != nil { 87 if exclude.MatchString(t) { 88 continue 89 } 90 } 91 fmt.Fprintf(w, "%s:%d: line is %d characters\n", path, l, c) 92 } 93 l++ 94 } 95 96 if err := s.Err(); err != nil { 97 return err 98 } 99 100 return nil 101 }