cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.30.1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/discovery/glob.go

139lines · modecode

1package discovery
2
3import (
4 "fmt"
5 "io/fs"
6 "os"
7 "path/filepath"
8 "regexp"
9)
10
11func NewGlobFinder(patterns []string, relaxed []*regexp.Regexp) GlobFinder {
12 return GlobFinder{
13 patterns: patterns,
14 relaxed: relaxed,
15 }
16}
17
18type GlobFinder struct {
19 patterns []string
20 relaxed []*regexp.Regexp
21}
22
23func (f GlobFinder) Find() (entries []Entry, err error) {
24 paths := filePaths{}
25 for _, p := range f.patterns {
26 matches, err := filepath.Glob(p)
27 if err != nil {
28 return nil, err
29 }
30
31 for _, path := range matches {
32 subpaths, err := findFiles(path)
33 if err != nil {
34 return nil, err
35 }
36 for _, subpath := range subpaths {
37 if !paths.hasPath(subpath.path) {
38 paths = append(paths, subpath)
39 }
40 }
41 }
42 }
43
44 if len(paths) == 0 {
45 return nil, fmt.Errorf("no matching files")
46 }
47
48 for _, fp := range paths {
49 el, err := readFile(fp.path, !matchesAny(f.relaxed, fp.target))
50 if err != nil {
51 return nil, fmt.Errorf("invalid file syntax: %w", err)
52 }
53 for _, e := range el {
54 if len(e.ModifiedLines) == 0 {
55 e.ModifiedLines = e.Rule.Lines()
56 }
57 e.SourcePath = fp.path
58 e.ReportedPath = fp.target
59 entries = append(entries, e)
60 }
61 }
62
63 return entries, nil
64}
65
66type filePath struct {
67 path string
68 target string
69}
70
71type filePaths []filePath
72
73func (fps filePaths) hasPath(p string) bool {
74 for _, fp := range fps {
75 if fp.path == p {
76 return true
77 }
78 }
79 return false
80}
81
82func findFiles(path string) (paths filePaths, err error) {
83 s, err := os.Stat(path)
84 if err != nil {
85 return nil, err
86 }
87
88 if s.IsDir() {
89 subpaths, err := walkDir(path)
90 if err != nil {
91 return nil, err
92 }
93 paths = append(paths, subpaths...)
94 } else {
95 paths = append(paths, filePath{path: path, target: path})
96 }
97
98 return paths, nil
99}
100
101func walkDir(dirname string) (paths filePaths, err error) {
102 err = filepath.WalkDir(dirname,
103 func(path string, d fs.DirEntry, err error) error {
104 if err != nil {
105 return err
106 }
107
108 // nolint: exhaustive
109 switch d.Type() {
110 case fs.ModeDir:
111 return nil
112 case fs.ModeSymlink:
113 dest, err := filepath.EvalSymlinks(path)
114 if err != nil {
115 return err
116 }
117
118 s, err := os.Stat(dest)
119 if err != nil {
120 return err
121 }
122 if s.IsDir() {
123 subpaths, err := findFiles(dest)
124 if err != nil {
125 return err
126 }
127 paths = append(paths, subpaths...)
128 } else {
129 paths = append(paths, filePath{path: path, target: dest})
130 }
131 default:
132 paths = append(paths, filePath{path: path, target: path})
133 }
134
135 return nil
136 })
137
138 return
139}