goodcheck 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 95c2a7244c21b8436b9b3069df313871905d2544
4
- data.tar.gz: e2137ec229279936f5abed87dabff5a8dcd083ad
3
+ metadata.gz: bbd50cb641f78725c89b7543fad72cc682f89212
4
+ data.tar.gz: 3bfa5512cdd20c4401e6ebfbb25d32e471bb1bbe
5
5
  SHA512:
6
- metadata.gz: 77025fef5bebc19bf8638f3aee6f9777e4bc6cfbb1b41ab0dd0e04b60190c33947d0b6a06ed053e136e80573bb05f71c240e0d036699544c53ab65e323fa5b7e
7
- data.tar.gz: 93d155f4a8cbd50ec80412713c80ec7093a00de0635cad25db8451a37970ab20609ffc0b14d851e523d8a7a6480d30f71628873fd152c7968738ed4fc3c75473
6
+ metadata.gz: 9c9f1ae3060429088686d073c579e24b675c0e4e03461e9ccdc8b7b230e9f1c09f2f78c471cc7fe2f233ae58bc5d21fc6caadfdd94bd75b44529bc248a8abbe9
7
+ data.tar.gz: 860f1810b61143bb3f3a7a09fff042919c8e82876e9c4cfb5e0f2131f4993d36d324b3a64aa20493dca3497e56e671300cb26a33ba6848672d6ffec06eca7c21
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.6.0 (2019-05-08)
6
+
7
+ * Add `not` pattern rule [#49](https://github.com/sider/goodcheck/pull/49)
8
+
5
9
  ## 1.5.1 (2019-05-08)
6
10
 
7
11
  * Regexp matching improvements
@@ -10,23 +10,30 @@ module Goodcheck
10
10
 
11
11
  def scan(&block)
12
12
  if block_given?
13
- issues = []
14
-
15
13
  regexp = Regexp.union(*rule.patterns.map(&:regexp))
16
- scanner = StringScanner.new(buffer.content)
17
14
 
18
- while true
19
- case
20
- when scanner.scan_until(regexp)
21
- text = scanner.matched
22
- range = (scanner.pos - text.bytesize) .. scanner.pos
23
- issues << Issue.new(buffer: buffer, range: range, rule: rule, text: text)
24
- else
25
- break
15
+ unless rule.negated?
16
+ issues = []
17
+
18
+ scanner = StringScanner.new(buffer.content)
19
+
20
+ while true
21
+ case
22
+ when scanner.scan_until(regexp)
23
+ text = scanner.matched
24
+ range = (scanner.pos - text.bytesize) .. scanner.pos
25
+ issues << Issue.new(buffer: buffer, range: range, rule: rule, text: text)
26
+ else
27
+ break
28
+ end
26
29
  end
27
- end
28
30
 
29
- issues.each(&block)
31
+ issues.each(&block)
32
+ else
33
+ unless regexp =~ buffer.content
34
+ yield Issue.new(buffer: buffer, range: nil, rule: rule, text: text)
35
+ end
36
+ end
30
37
  else
31
38
  enum_for(:scan)
32
39
  end
@@ -20,7 +20,7 @@ module Goodcheck
20
20
  let :encoding, enum(*Encoding.name_list.map {|name| literal(name) })
21
21
  let :glob, object(pattern: string, encoding: optional(encoding))
22
22
 
23
- let :rule, object(
23
+ let :positive_rule, object(
24
24
  id: string,
25
25
  pattern: enum(array(pattern), pattern),
26
26
  message: string,
@@ -30,6 +30,18 @@ module Goodcheck
30
30
  fail: optional(enum(array(string), string))
31
31
  )
32
32
 
33
+ let :negative_rule, object(
34
+ id: string,
35
+ not: object(pattern: enum(array(pattern), pattern)),
36
+ message: string,
37
+ justification: optional(enum(array(string), string)),
38
+ glob: optional(enum(array(enum(glob, string)), glob, string)),
39
+ pass: optional(enum(array(string), string)),
40
+ fail: optional(enum(array(string), string))
41
+ )
42
+
43
+ let :rule, enum(positive_rule, negative_rule)
44
+
33
45
  let :rules, array(rule)
34
46
 
35
47
  let :import_target, string
@@ -99,20 +111,25 @@ module Goodcheck
99
111
  Goodcheck.logger.debug "Loading rule: #{hash[:id]}"
100
112
 
101
113
  id = hash[:id]
102
- patterns = retrieve_patterns(hash)
114
+ patterns, negated = retrieve_patterns(hash)
103
115
  justifications = array(hash[:justification])
104
116
  globs = load_globs(array(hash[:glob]))
105
117
  message = hash[:message].chomp
106
118
  passes = array(hash[:pass])
107
119
  fails = array(hash[:fail])
108
120
 
109
- Rule.new(id: id, patterns: patterns, justifications: justifications, globs: globs, message: message, passes: passes, fails: fails)
121
+ Rule.new(id: id, patterns: patterns, justifications: justifications, globs: globs, message: message, passes: passes, fails: fails, negated: negated)
110
122
  end
111
123
 
112
124
  def retrieve_patterns(hash)
113
- array(hash[:pattern]).map do |pat|
114
- load_pattern(pat)
125
+ if hash.is_a?(Hash) && hash.key?(:not)
126
+ negated = true
127
+ hash = hash[:not]
128
+ else
129
+ negated = false
115
130
  end
131
+
132
+ [array(hash[:pattern]).map {|pat| load_pattern(pat) }, negated]
116
133
  end
117
134
 
118
135
  def load_globs(globs)
@@ -17,13 +17,15 @@ module Goodcheck
17
17
  end
18
18
 
19
19
  def location
20
- unless @location
21
- start_line, start_column = buffer.location_for_position(range.begin)
22
- end_line, end_column = buffer.location_for_position(range.end)
23
- @location = Location.new(start_line: start_line, start_column: start_column, end_line: end_line, end_column: end_column)
24
- end
20
+ if range
21
+ unless @location
22
+ start_line, start_column = buffer.location_for_position(range.begin)
23
+ end_line, end_column = buffer.location_for_position(range.end)
24
+ @location = Location.new(start_line: start_line, start_column: start_column, end_line: end_line, end_column: end_column)
25
+ end
25
26
 
26
- @location
27
+ @location
28
+ end
27
29
  end
28
30
  end
29
31
  end
@@ -15,14 +15,15 @@ module Goodcheck
15
15
  yield
16
16
 
17
17
  json = issues.map do |issue|
18
+ location = issue.location
18
19
  {
19
20
  rule_id: issue.rule.id,
20
21
  path: issue.path,
21
- location: {
22
- start_line: issue.location.start_line,
23
- start_column: issue.location.start_column,
24
- end_line: issue.location.end_line,
25
- end_column: issue.location.end_column
22
+ location: location && {
23
+ start_line: location.start_line,
24
+ start_column: location.start_column,
25
+ end_line: location.end_line,
26
+ end_column: location.end_column
26
27
  },
27
28
  message: issue.rule.message,
28
29
  justifications: issue.rule.justifications
@@ -20,14 +20,18 @@ module Goodcheck
20
20
  end
21
21
 
22
22
  def issue(issue)
23
- line = issue.buffer.line(issue.location.start_line)
24
- end_column = if issue.location.start_line == issue.location.end_line
25
- issue.location.end_column
26
- else
27
- line.bytesize
28
- end
29
- colored_line = line.byteslice(0, issue.location.start_column) + Rainbow(line.byteslice(issue.location.start_column, end_column - issue.location.start_column)).red + line.byteslice(end_column, line.bytesize)
30
- stdout.puts "#{issue.path}:#{issue.location.start_line}:#{colored_line.chomp}:\t#{issue.rule.message.lines.first.chomp}"
23
+ if issue.location
24
+ line = issue.buffer.line(issue.location.start_line)
25
+ end_column = if issue.location.start_line == issue.location.end_line
26
+ issue.location.end_column
27
+ else
28
+ line.bytesize
29
+ end
30
+ colored_line = line.byteslice(0, issue.location.start_column) + Rainbow(line.byteslice(issue.location.start_column, end_column - issue.location.start_column)).red + line.byteslice(end_column, line.bytesize)
31
+ stdout.puts "#{issue.path}:#{issue.location.start_line}:#{colored_line.chomp}:\t#{issue.rule.message.lines.first.chomp}"
32
+ else
33
+ stdout.puts "#{issue.path}:-:#{issue.buffer.line(1).chomp}:\t#{issue.rule.message.lines.first.chomp}"
34
+ end
31
35
  end
32
36
  end
33
37
  end
@@ -8,7 +8,7 @@ module Goodcheck
8
8
  attr_reader :passes
9
9
  attr_reader :fails
10
10
 
11
- def initialize(id:, patterns:, message:, justifications:, globs:, fails:, passes:)
11
+ def initialize(id:, patterns:, message:, justifications:, globs:, fails:, passes:, negated:)
12
12
  @id = id
13
13
  @patterns = patterns
14
14
  @message = message
@@ -16,6 +16,11 @@ module Goodcheck
16
16
  @globs = globs
17
17
  @passes = passes
18
18
  @fails = fails
19
+ @negated = negated
20
+ end
21
+
22
+ def negated?
23
+ @negated
19
24
  end
20
25
  end
21
26
  end
@@ -1,3 +1,3 @@
1
1
  module Goodcheck
2
- VERSION = "1.5.1"
2
+ VERSION = "1.6.0"
3
3
  end
data/sample.yml CHANGED
@@ -10,6 +10,7 @@ rules:
10
10
  Maybe, you are misspelling.
11
11
  pass: GitHub
12
12
  fail: Github
13
+
13
14
  - id: sample.debug_print
14
15
  pattern:
15
16
  - token: pp
@@ -22,5 +23,35 @@ rules:
22
23
  fail:
23
24
  - pp("Hello World")
24
25
 
26
+ - id: sample.html
27
+ not:
28
+ pattern:
29
+ - token: <meta charset="utf-8"
30
+ - token: <meta charset="UTF-8"
31
+ message: |
32
+ Use UTF-8 (no BOM).
33
+ glob: "**/*.html"
34
+ pass:
35
+ - |
36
+ <html>
37
+ <meta charset="utf-8"/>
38
+ </html>
39
+ - |
40
+ <html>
41
+ <meta charset="utf-8"></meta>
42
+ </html>
43
+ - |
44
+ <html>
45
+ <meta charset="UTF-8"></meta>
46
+ </html>
47
+ fail:
48
+ - |
49
+ <html>
50
+ <meta charset="iso-8859-1">
51
+ </html>
52
+ - |
53
+ <html>
54
+ </html>
55
+
25
56
  import:
26
57
  - https://gist.githubusercontent.com/soutaro/6362c89acd7d6771ae6ebfc615be402d/raw/7f04b973c2c8df70783cd7deb955ab95d1375b2d/sample.yml
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: goodcheck
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Soutaro Matsumoto