cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.57.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/parser/read.go

162lines · modecode

1package parser
2
3import (
4 "bufio"
5 "errors"
6 "io"
7 "strings"
8
9 "github.com/cloudflare/pint/internal/comments"
10)
11
12type skipMode uint8
13
14const (
15 skipNone skipMode = iota
16 skipNextLine
17 skipBegin
18 skipEnd
19 skipCurrentLine
20 skipFile
21)
22
23func emptyLine(line string) (emptied string) {
24 preComment := strings.TrimSuffix(line, "\n")
25 var comment string
26 if commentStart := strings.IndexRune(line, '#'); commentStart >= 0 {
27 comment = preComment[commentStart:]
28 preComment = preComment[:commentStart]
29 }
30
31 emptied = strings.Repeat(" ", len(preComment)) + comment
32
33 if strings.HasSuffix(line, "\n") {
34 emptied += "\n"
35 }
36
37 return emptied
38}
39
40type Content struct {
41 Body []byte
42 TotalLines int
43 IgnoreLine int
44 Ignored bool
45}
46
47func ReadContent(r io.Reader) (out Content, fileComments []comments.Comment, err error) {
48 reader := bufio.NewReader(r)
49 var lineno int
50 var line string
51 var found bool
52 var skip skipMode
53
54 var skipNext bool
55 var autoReset bool
56 var skipAll bool
57 var inBegin bool
58 for {
59 lineno++
60 line, err = reader.ReadString('\n')
61 if err != nil && !errors.Is(err, io.EOF) {
62 break
63 }
64 if line != "" {
65 out.TotalLines++
66 }
67
68 if skipAll {
69 out.Body = append(out.Body, []byte(emptyLine(line))...)
70 } else {
71 skip = skipNone
72 found = false
73 for _, comment := range comments.Parse(lineno, line) {
74 // nolint:exhaustive
75 switch comment.Type {
76 case comments.IgnoreFileType:
77 skip = skipFile
78 found = true
79 case comments.IgnoreLineType:
80 skip = skipCurrentLine
81 found = true
82 case comments.IgnoreBeginType:
83 skip = skipBegin
84 found = true
85 case comments.IgnoreEndType:
86 skip = skipEnd
87 found = true
88 case comments.IgnoreNextLineType:
89 skip = skipNextLine
90 found = true
91 case comments.FileOwnerType:
92 fileComments = append(fileComments, comment)
93 case comments.RuleOwnerType:
94 // pass
95 case comments.FileDisableType:
96 fileComments = append(fileComments, comment)
97 case comments.DisableType:
98 // pass
99 case comments.FileSnoozeType:
100 fileComments = append(fileComments, comment)
101 case comments.SnoozeType:
102 // pass
103 case comments.RuleSetType:
104 // pass
105 case comments.InvalidComment:
106 fileComments = append(fileComments, comment)
107 }
108 }
109 switch {
110 case found:
111 switch skip {
112 case skipNone:
113 // no-op
114 case skipFile:
115 out.Ignored = true
116 out.IgnoreLine = lineno
117 out.Body = append(out.Body, []byte(emptyLine(line))...)
118 skipNext = true
119 autoReset = false
120 skipAll = true
121 case skipCurrentLine:
122 out.Body = append(out.Body, []byte(emptyLine(line))...)
123 if !inBegin {
124 skipNext = false
125 autoReset = true
126 }
127 case skipNextLine:
128 out.Body = append(out.Body, []byte(line)...)
129 skipNext = true
130 autoReset = true
131 case skipBegin:
132 out.Body = append(out.Body, []byte(line)...)
133 skipNext = true
134 autoReset = false
135 inBegin = true
136 case skipEnd:
137 out.Body = append(out.Body, []byte(line)...)
138 skipNext = false
139 autoReset = true
140 inBegin = false
141 }
142 case skipNext:
143 out.Body = append(out.Body, []byte(emptyLine(line))...)
144 if autoReset {
145 skipNext = false
146 }
147 default:
148 out.Body = append(out.Body, []byte(line)...)
149 }
150 }
151
152 if err != nil {
153 break
154 }
155 }
156
157 if !errors.Is(err, io.EOF) {
158 return out, fileComments, err
159 }
160
161 return out, fileComments, nil
162}
163