cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.51.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/parser/read.go

154lines · 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 Ignored bool
43}
44
45func ReadContent(r io.Reader) (out Content, fileComments []comments.Comment, err error) {
46 reader := bufio.NewReader(r)
47 var line string
48 var found bool
49 var skip skipMode
50
51 var skipNext bool
52 var autoReset bool
53 var skipAll bool
54 var inBegin bool
55 for {
56 line, err = reader.ReadString('\n')
57 if err != nil && !errors.Is(err, io.EOF) {
58 break
59 }
60
61 if skipAll {
62 out.Body = append(out.Body, []byte(emptyLine(line))...)
63 } else {
64 skip = skipNone
65 found = false
66 for _, comment := range comments.Parse(line) {
67 // nolint:exhaustive
68 switch comment.Type {
69 case comments.IgnoreFileType:
70 skip = skipFile
71 found = true
72 case comments.IgnoreLineType:
73 skip = skipCurrentLine
74 found = true
75 case comments.IgnoreBeginType:
76 skip = skipBegin
77 found = true
78 case comments.IgnoreEndType:
79 skip = skipEnd
80 found = true
81 case comments.IgnoreNextLineType:
82 skip = skipNextLine
83 found = true
84 case comments.FileOwnerType:
85 fileComments = append(fileComments, comment)
86 case comments.RuleOwnerType:
87 // pass
88 case comments.FileDisableType:
89 fileComments = append(fileComments, comment)
90 case comments.DisableType:
91 // pass
92 case comments.FileSnoozeType:
93 fileComments = append(fileComments, comment)
94 case comments.SnoozeType:
95 // pass
96 case comments.RuleSetType:
97 // pass
98 case comments.InvalidComment:
99 fileComments = append(fileComments, comment)
100 }
101 }
102 switch {
103 case found:
104 switch skip {
105 case skipNone:
106 // no-op
107 case skipFile:
108 out.Ignored = true
109 out.Body = append(out.Body, []byte(emptyLine(line))...)
110 skipNext = true
111 autoReset = false
112 skipAll = true
113 case skipCurrentLine:
114 out.Body = append(out.Body, []byte(emptyLine(line))...)
115 if !inBegin {
116 skipNext = false
117 autoReset = true
118 }
119 case skipNextLine:
120 out.Body = append(out.Body, []byte(line)...)
121 skipNext = true
122 autoReset = true
123 case skipBegin:
124 out.Body = append(out.Body, []byte(line)...)
125 skipNext = true
126 autoReset = false
127 inBegin = true
128 case skipEnd:
129 out.Body = append(out.Body, []byte(line)...)
130 skipNext = false
131 autoReset = true
132 inBegin = false
133 }
134 case skipNext:
135 out.Body = append(out.Body, []byte(emptyLine(line))...)
136 if autoReset {
137 skipNext = false
138 }
139 default:
140 out.Body = append(out.Body, []byte(line)...)
141 }
142 }
143
144 if err != nil {
145 break
146 }
147 }
148
149 if !errors.Is(err, io.EOF) {
150 return out, fileComments, err
151 }
152
153 return out, fileComments, nil
154}
155