cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.29.2

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/discovery/glob.go

114lines · modecode

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