goodcheck 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bbd50cb641f78725c89b7543fad72cc682f89212
4
- data.tar.gz: 3bfa5512cdd20c4401e6ebfbb25d32e471bb1bbe
3
+ metadata.gz: 941c25a76e1e8d433dabf11a05e9881251666ea6
4
+ data.tar.gz: af4c6b7a6f0c7de3318efd540a9031127a6eab22
5
5
  SHA512:
6
- metadata.gz: 9c9f1ae3060429088686d073c579e24b675c0e4e03461e9ccdc8b7b230e9f1c09f2f78c471cc7fe2f233ae58bc5d21fc6caadfdd94bd75b44529bc248a8abbe9
7
- data.tar.gz: 860f1810b61143bb3f3a7a09fff042919c8e82876e9c4cfb5e0f2131f4993d36d324b3a64aa20493dca3497e56e671300cb26a33ba6848672d6ffec06eca7c21
6
+ metadata.gz: 30d772081204a902869971bded0ba16b779500d3cad31a0857b75a10979c0cacbe7ce5be45b6b4c0520bd587649394bb54cf0873ea18dccba1896cedcdd20a5a
7
+ data.tar.gz: a3020566b156d0a23f3ca4b1a2ac590d39182bf47597dcc6fb89bcd861198821f671967925fcf37e0e56f01c39a388e45d9237181f2d2bb4a9b1467083c2d156
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.7.0 (2019-05-28)
6
+
7
+ * Support a rule without `pattern` [#52](https://github.com/sider/goodcheck/pull/52)
8
+ * Let each `pattern` have `glob` [#50](https://github.com/sider/goodcheck/pull/50)
9
+
5
10
  ## 1.6.0 (2019-05-08)
6
11
 
7
12
  * Add `not` pattern rule [#49](https://github.com/sider/goodcheck/pull/49)
data/README.md CHANGED
@@ -63,7 +63,7 @@ rules:
63
63
  The *rule* hash contains the following keys.
64
64
 
65
65
  * `id`: a string to identify rules (required)
66
- * `pattern`: a *pattern* or a sequence of *pattern*s (required)
66
+ * `pattern`: a *pattern* or a sequence of *pattern*s
67
67
  * `message`: a string to tell writers why the code piece should be revised (required)
68
68
  * `justification`: a sequence of strings to tell writers when a exception can be allowed (optional)
69
69
  * `glob`: a *glob* or a sequence of *glob*s (optional)
@@ -84,11 +84,13 @@ id: com.sample.GitHub
84
84
  pattern:
85
85
  literal: Github
86
86
  case_sensitive: true
87
+ glob: []
87
88
  message: Write GitHub, not Github
88
89
  ```
89
90
 
90
91
  All regexp meta characters included in the `literal` value will be escaped.
91
92
  `case_sensitive` is an optional key and the default is `true`.
93
+ `glob` is an optional key and the default is empty.
92
94
 
93
95
  #### *regexp pattern*
94
96
 
@@ -100,12 +102,13 @@ pattern:
100
102
  regexp: \d{4,}
101
103
  case_sensitive: false
102
104
  multiline: false
105
+ glob: []
103
106
  message: Insert delimiters when writing large numbers
104
107
  justification:
105
108
  - When you are not writing numbers, including phone numbers, zip code, ...
106
109
  ```
107
110
 
108
- It accepts two optional attributes, `case_sensitive` and `multiline`.
111
+ It accepts two optional attributes, `case_sensitive`, `multiline`, and `glob`.
109
112
  The default values of `case_sensitive` and `multiline` are `true` and `false` respectively.
110
113
 
111
114
  The regexp will be passed to `Regexp.compile`.
@@ -120,6 +123,7 @@ id: com.sample.no-blink
120
123
  pattern:
121
124
  token: "<blink"
122
125
  case_sensitive: false
126
+ glob: []
123
127
  message: Stop using <blink> tag
124
128
  glob: "**/*.html"
125
129
  justification:
@@ -133,7 +137,7 @@ In that case, try using *regexp pattern*.
133
137
  The generated regexp of `<blink` is `<\s*blink\b/m`.
134
138
  It matches with `<blink />` and `< BLINK>`, but does not match with `https://www.chromium.org/blink`.
135
139
 
136
- It accepts one optional attribute, `case_sensitive`.
140
+ It accepts one optional attributes, `case_sensitive` and `glob`.
137
141
  The default value of `case_sensitive` is `true`.
138
142
  Note that the generated regexp is in multiline mode.
139
143
 
@@ -156,6 +160,54 @@ If you write a string as a `glob`, the string value can be the `pattern` of the
156
160
 
157
161
  If you omit `glob` attribute in a rule, the rule will be applied to all files given to `goodcheck`.
158
162
 
163
+ If both of your rule and its pattern has `glob`, Goodcheck will scan the pattern from the `glob` files in the pattern.
164
+
165
+ ```yaml
166
+ rules:
167
+ - id: glob_test
168
+ pattern:
169
+ - literal: 123 # This pattern applies to .css files
170
+ glob: "*.css"
171
+ - literal: abc # This pattern applies to .txt files
172
+ glob: "*.txt"
173
+ ```
174
+
175
+ ### A rule without _negated_ pattern
176
+
177
+ Goodcheck rules are usually to detect _something is included in a file_.
178
+ You can define the _negated_ rules for the opposite, _something is missing in a file_.
179
+
180
+ ```yaml
181
+ rules:
182
+ - id: negated
183
+ not:
184
+ pattern:
185
+ <!DOCTYPE html>
186
+ message: Write a doctype on HTML files.
187
+ glob: "**/*.html"
188
+ ```
189
+
190
+ ### A rule without `pattern`
191
+
192
+ You can define a rule without `pattern`.
193
+ The rule emits a issue on each file specified with `glob`.
194
+ You cannot omit `glob` from a rule definition without `pattern`.
195
+
196
+ ```yaml
197
+ rules:
198
+ - id: without_pattern
199
+ message: |
200
+ Read the operation manual for DB migration: https://example.com/guides/123
201
+ glob: db/schema.rb
202
+ ```
203
+
204
+ The output will be something like:
205
+
206
+ ```
207
+ $ goodcheck check
208
+ db/schema.rb:-:# This file is auto-generated from the current state of the database. Instead: Read the operation manual for DB migration: https://example.com/guides/123
209
+ ```
210
+
159
211
  ## Importing rules
160
212
 
161
213
  `goodcheck.yml` can have optional `import` attribute.
@@ -25,9 +25,10 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "bundler", ">= 1.16"
26
26
  spec.add_development_dependency "rake", "~> 10.0"
27
27
  spec.add_development_dependency "minitest", "~> 5.0"
28
+ spec.add_development_dependency "minitest-reporters", "~> 1.3.6"
28
29
 
29
30
  spec.add_runtime_dependency "activesupport", ">= 4.0", "< 6.0"
30
- spec.add_runtime_dependency "strong_json", "~> 0.7.1"
31
+ spec.add_runtime_dependency "strong_json", "~> 1.0.0"
31
32
  spec.add_runtime_dependency "rainbow", "~> 3.0.0"
32
33
  spec.add_runtime_dependency "httpclient", "~> 2.8.3"
33
34
  end
@@ -8,30 +8,55 @@ module Goodcheck
8
8
  @buffer = buffer
9
9
  end
10
10
 
11
+ def use_all_patterns!
12
+ @use_all_patterns = true
13
+ end
14
+
15
+ def patterns
16
+ if @use_all_patterns
17
+ rule.patterns
18
+ else
19
+ rule.patterns.select do |pattern|
20
+ case
21
+ when pattern.globs.empty? && rule.globs.empty?
22
+ true
23
+ when pattern.globs.empty?
24
+ rule.globs.any? {|glob| glob.test(buffer.path) }
25
+ else
26
+ pattern.globs.any? {|glob| glob.test(buffer.path) }
27
+ end
28
+ end
29
+ end
30
+ end
31
+
11
32
  def scan(&block)
12
33
  if block_given?
13
- regexp = Regexp.union(*rule.patterns.map(&:regexp))
34
+ if rule.patterns.empty?
35
+ yield Issue.new(buffer: buffer, range: nil, rule: rule, text: nil)
36
+ else
37
+ regexp = Regexp.union(*patterns.map(&:regexp))
14
38
 
15
- unless rule.negated?
16
- issues = []
39
+ unless rule.negated?
40
+ issues = []
17
41
 
18
- scanner = StringScanner.new(buffer.content)
42
+ scanner = StringScanner.new(buffer.content)
19
43
 
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
44
+ while true
45
+ case
46
+ when scanner.scan_until(regexp)
47
+ text = scanner.matched
48
+ range = (scanner.pos - text.bytesize) .. scanner.pos
49
+ issues << Issue.new(buffer: buffer, range: range, rule: rule, text: text)
50
+ else
51
+ break
52
+ end
28
53
  end
29
- end
30
54
 
31
- issues.each(&block)
32
- else
33
- unless regexp =~ buffer.content
34
- yield Issue.new(buffer: buffer, range: nil, rule: rule, text: text)
55
+ issues.each(&block)
56
+ else
57
+ unless regexp =~ buffer.content
58
+ yield Issue.new(buffer: buffer, range: nil, rule: rule, text: nil)
59
+ end
35
60
  end
36
61
  end
37
62
  else
@@ -45,8 +45,10 @@ module Goodcheck
45
45
  stderr.puts " #{trace_loc}"
46
46
  end
47
47
  1
48
- rescue StrongJSON::Type::Error => exn
49
- stderr.puts "Invalid config at #{exn.path.map {|x| "[#{x}]" }.join}"
48
+ rescue StrongJSON::Type::TypeError, StrongJSON::Type::UnexpectedAttributeError => exn
49
+ stderr.puts "Invalid config: #{exn.message}"
50
+ stderr.puts StrongJSON::ErrorReporter.new(path: exn.path).to_s
51
+
50
52
  1
51
53
  rescue Errno::ENOENT => exn
52
54
  stderr.puts "#{exn}"
@@ -3,7 +3,8 @@ module Goodcheck
3
3
  class Init
4
4
  CONFIG = <<-EOC
5
5
  rules:
6
- - id: com.example.1
6
+ # id, pattern, message are required attributes.
7
+ - id: example.github
7
8
  pattern: Github
8
9
  message: Do you want to write GitHub?
9
10
  glob:
@@ -15,9 +16,46 @@ rules:
15
16
  pass:
16
17
  - Signup via GitHub
17
18
 
18
- exclude:
19
- - node_modules
20
- - vendor
19
+ # You can have *justification* to explain the exceptional cases.
20
+ - id: example.localStorage
21
+ pattern:
22
+ token: localStorage
23
+ message: |
24
+ Using localStorage may raise error (example: with Safari in private mode)
25
+ justification:
26
+ - If you catch the errors.
27
+ - When you implement admin console, where end users won't access.
28
+ glob:
29
+ - "**/*.js"
30
+ fail:
31
+ - |
32
+ localStorage.setItem(key, value);
33
+
34
+ # You can put `not` pattern to detect something is missing.
35
+ - id: example.strict-mode
36
+ not:
37
+ pattern: use strict
38
+ message: Use *strict mode* if possible.
39
+ glob: "**/*.js"
40
+ fail:
41
+ - |
42
+ const var = "This is *sloppy* mode."
43
+
44
+ # You can omit pattern, which prints the message on the files specified by glob.
45
+ - id: example.package-lock.json
46
+ message: Some of the packages are updated!
47
+ justification:
48
+ - If you update some of the packages.
49
+ glob: "package-lock.json"
50
+
51
+ # You can import rules.
52
+ # import:
53
+ # - https://example.com/example-rules.yml
54
+
55
+ # You can skip checking files.
56
+ # exclude:
57
+ # - node_modules
58
+ # - vendor
21
59
  EOC
22
60
 
23
61
  attr_reader :stdout
@@ -93,6 +93,7 @@ module Goodcheck
93
93
  def rule_matches_example?(rule, example)
94
94
  buffer = Buffer.new(path: Pathname("-"), content: example)
95
95
  analyzer = Analyzer.new(rule: rule, buffer: buffer)
96
+ analyzer.use_all_patterns!
96
97
  analyzer.scan.count > 0
97
98
  end
98
99
  end
@@ -8,17 +8,33 @@ module Goodcheck
8
8
  @exclude_paths = exclude_paths
9
9
  end
10
10
 
11
+ def each_rule(filter:, &block)
12
+ if block_given?
13
+ if filter.empty?
14
+ rules.each(&block)
15
+ else
16
+ rules.each do |rule|
17
+ if filter.any? {|rule_id| rule.id == rule_id || rule.id.start_with?("#{rule_id}.") }
18
+ yield rule
19
+ end
20
+ end
21
+ end
22
+ else
23
+ enum_for :each_rule, filter: filter
24
+ end
25
+ end
26
+
11
27
  def rules_for_path(path, rules_filter:, &block)
12
28
  if block_given?
13
- rules.map do |rule|
14
- if rules_filter.empty? || rules_filter.any? {|filter| /\A#{Regexp.escape(filter)}\.?/ =~ rule.id }
15
- if rule.globs.empty?
16
- [rule, nil]
17
- else
18
- glob = rule.globs.find {|glob| path.fnmatch?(glob.pattern, File::FNM_PATHNAME | File::FNM_EXTGLOB) }
19
- if glob
20
- [rule, glob]
21
- end
29
+ each_rule(filter: rules_filter).map do |rule|
30
+ globs = rule.patterns.flat_map(&:globs).push(*rule.globs)
31
+
32
+ if globs.empty?
33
+ [rule, nil]
34
+ else
35
+ glob = globs.find {|glob| glob.test(path) }
36
+ if glob
37
+ [rule, glob]
22
38
  end
23
39
  end
24
40
  end.compact.each(&block)
@@ -5,48 +5,117 @@ module Goodcheck
5
5
  class InvalidPattern < StandardError; end
6
6
 
7
7
  Schema = StrongJSON.new do
8
+ def self.array_or(type)
9
+ a = array(type)
10
+ enum(a, type, detector: -> (value) {
11
+ case value
12
+ when Array
13
+ a
14
+ else
15
+ type
16
+ end
17
+ })
18
+ end
19
+
8
20
  let :deprecated_regexp_pattern, object(regexp: string, case_insensitive: boolean?, multiline: boolean?)
9
21
  let :deprecated_literal_pattern, object(literal: string, case_insensitive: boolean?)
10
22
  let :deprecated_token_pattern, object(token: string, case_insensitive: boolean?)
11
23
 
12
- let :regexp_pattern, object(regexp: string, case_sensitive: boolean?, multiline: boolean?)
13
- let :literal_pattern, object(literal: string, case_sensitive: boolean?)
14
- let :token_pattern, object(token: string, case_sensitive: boolean?)
15
-
16
- let :pattern, enum(regexp_pattern, literal_pattern, token_pattern,
17
- deprecated_regexp_pattern, deprecated_literal_pattern, deprecated_token_pattern,
18
- string)
19
-
20
24
  let :encoding, enum(*Encoding.name_list.map {|name| literal(name) })
21
- let :glob, object(pattern: string, encoding: optional(encoding))
25
+ let :glob_obj, object(pattern: string, encoding: optional(encoding))
26
+ let :one_glob, enum(glob_obj,
27
+ string,
28
+ detector: -> (value) {
29
+ case value
30
+ when Hash
31
+ glob_obj
32
+ when String
33
+ string
34
+ end
35
+ })
36
+ let :glob, array_or(one_glob)
37
+
38
+ let :regexp_pattern, object(regexp: string, case_sensitive: boolean?, multiline: boolean?, glob: optional(glob))
39
+ let :literal_pattern, object(literal: string, case_sensitive: boolean?, glob: optional(glob))
40
+ let :token_pattern, object(token: string, case_sensitive: boolean?, glob: optional(glob))
41
+
42
+ let :pattern, enum(regexp_pattern,
43
+ literal_pattern,
44
+ token_pattern,
45
+ deprecated_regexp_pattern,
46
+ deprecated_literal_pattern,
47
+ deprecated_token_pattern,
48
+ string,
49
+ detector: -> (value) {
50
+ case value
51
+ when Hash
52
+ case
53
+ when value.key?(:regexp) && value.key?(:case_insensitive)
54
+ deprecated_regexp_pattern
55
+ when value.key?(:regexp)
56
+ regexp_pattern
57
+ when value.key?(:literal) && value.key?(:case_insensitive)
58
+ deprecated_literal_pattern
59
+ when value.key?(:literal)
60
+ literal_pattern
61
+ when value.key?(:token) && value.key?(:case_insensitive)
62
+ deprecated_token_pattern
63
+ when value.key?(:token)
64
+ token_pattern
65
+ end
66
+ when String
67
+ string
68
+ end
69
+ })
22
70
 
23
71
  let :positive_rule, object(
24
72
  id: string,
25
- pattern: enum(array(pattern), pattern),
73
+ pattern: array_or(pattern),
26
74
  message: string,
27
- justification: optional(enum(array(string), string)),
28
- glob: optional(enum(array(enum(glob, string)), glob, string)),
29
- pass: optional(enum(array(string), string)),
30
- fail: optional(enum(array(string), string))
75
+ justification: optional(array_or(string)),
76
+ glob: optional(glob),
77
+ pass: optional(array_or(string)),
78
+ fail: optional(array_or(string))
31
79
  )
32
80
 
33
81
  let :negative_rule, object(
34
82
  id: string,
35
- not: object(pattern: enum(array(pattern), pattern)),
83
+ not: object(pattern: array_or(pattern)),
84
+ message: string,
85
+ justification: optional(array_or(string)),
86
+ glob: optional(glob),
87
+ pass: optional(array_or(string)),
88
+ fail: optional(array_or(string))
89
+ )
90
+
91
+ let :nopattern_rule, object(
92
+ id: string,
36
93
  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))
94
+ justification: optional(array_or(string)),
95
+ glob: glob
41
96
  )
42
97
 
43
- let :rule, enum(positive_rule, negative_rule)
98
+ let :rule, enum(positive_rule,
99
+ negative_rule,
100
+ nopattern_rule,
101
+ detector: -> (hash) {
102
+ if hash.is_a?(Hash)
103
+ case
104
+ when hash[:pattern]
105
+ positive_rule
106
+ when hash[:not]
107
+ negative_rule
108
+ when hash.key?(:glob) && !hash.key?(:pattern) && !hash.key?(:not)
109
+ nopattern_rule
110
+ end
111
+ end
112
+ })
44
113
 
45
114
  let :rules, array(rule)
46
115
 
47
116
  let :import_target, string
48
117
  let :imports, array(import_target)
49
- let :exclude, enum(array(string), string)
118
+ let :exclude, array_or(string)
50
119
 
51
120
  let :config, object(
52
121
  rules: rules,
@@ -129,7 +198,11 @@ module Goodcheck
129
198
  negated = false
130
199
  end
131
200
 
132
- [array(hash[:pattern]).map {|pat| load_pattern(pat) }, negated]
201
+ if hash.key?(:pattern)
202
+ [array(hash[:pattern]).map {|pat| load_pattern(pat) }, negated]
203
+ else
204
+ [[], false]
205
+ end
133
206
  end
134
207
 
135
208
  def load_globs(globs)
@@ -148,20 +221,21 @@ module Goodcheck
148
221
  when String
149
222
  Pattern.literal(pattern, case_sensitive: true)
150
223
  when Hash
224
+ globs = load_globs(array(pattern[:glob]))
151
225
  case
152
226
  when pattern[:literal]
153
227
  cs = case_sensitive?(pattern)
154
228
  literal = pattern[:literal]
155
- Pattern.literal(literal, case_sensitive: cs)
229
+ Pattern.literal(literal, case_sensitive: cs, globs: globs)
156
230
  when pattern[:regexp]
157
231
  regexp = pattern[:regexp]
158
232
  cs = case_sensitive?(pattern)
159
233
  multiline = pattern[:multiline]
160
- Pattern.regexp(regexp, case_sensitive: cs, multiline: multiline)
234
+ Pattern.regexp(regexp, case_sensitive: cs, multiline: multiline, globs: globs)
161
235
  when pattern[:token]
162
236
  tok = pattern[:token]
163
237
  cs = case_sensitive?(pattern)
164
- Pattern.token(tok, case_sensitive: cs)
238
+ Pattern.token(tok, case_sensitive: cs, globs: globs)
165
239
  end
166
240
  end
167
241
  end
@@ -7,5 +7,9 @@ module Goodcheck
7
7
  @pattern = pattern
8
8
  @encoding = encoding
9
9
  end
10
+
11
+ def test(path)
12
+ path.fnmatch?(pattern, File::FNM_PATHNAME | File::FNM_EXTGLOB)
13
+ end
10
14
  end
11
15
  end
@@ -2,26 +2,40 @@ module Goodcheck
2
2
  class Pattern
3
3
  attr_reader :source
4
4
  attr_reader :regexp
5
+ attr_reader :globs
5
6
 
6
- def initialize(source:, regexp:)
7
+ def initialize(source:, regexp:, globs:)
7
8
  @source = source
8
9
  @regexp = regexp
10
+ @globs = globs
9
11
  end
10
12
 
11
- def self.literal(literal, case_sensitive:)
12
- new(source: literal, regexp: Regexp.compile(Regexp.escape(literal), !case_sensitive))
13
+ def self.literal(literal, case_sensitive:, globs: [])
14
+ new(
15
+ source: literal,
16
+ regexp: Regexp.compile(Regexp.escape(literal), !case_sensitive),
17
+ globs: globs
18
+ )
13
19
  end
14
20
 
15
- def self.regexp(regexp, case_sensitive:, multiline:)
21
+ def self.regexp(regexp, case_sensitive:, multiline:, globs: [])
16
22
  options = 0
17
23
  options |= Regexp::IGNORECASE unless case_sensitive
18
24
  options |= Regexp::MULTILINE if multiline
19
25
 
20
- new(source: regexp, regexp: Regexp.compile(regexp, options))
26
+ new(
27
+ source: regexp,
28
+ regexp: Regexp.compile(regexp, options),
29
+ globs: globs
30
+ )
21
31
  end
22
32
 
23
- def self.token(tokens, case_sensitive:)
24
- new(source: tokens, regexp: compile_tokens(tokens, case_sensitive: case_sensitive))
33
+ def self.token(tokens, case_sensitive:, globs: [])
34
+ new(
35
+ source: tokens,
36
+ regexp: compile_tokens(tokens, case_sensitive: case_sensitive),
37
+ globs: globs
38
+ )
25
39
  end
26
40
 
27
41
  def self.compile_tokens(source, case_sensitive:)
@@ -1,3 +1,3 @@
1
1
  module Goodcheck
2
- VERSION = "1.6.0"
2
+ VERSION = "1.7.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: goodcheck
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Soutaro Matsumoto
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-08 00:00:00.000000000 Z
11
+ date: 2019-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-reporters
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.3.6
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.3.6
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: activesupport
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -78,14 +92,14 @@ dependencies:
78
92
  requirements:
79
93
  - - "~>"
80
94
  - !ruby/object:Gem::Version
81
- version: 0.7.1
95
+ version: 1.0.0
82
96
  type: :runtime
83
97
  prerelease: false
84
98
  version_requirements: !ruby/object:Gem::Requirement
85
99
  requirements:
86
100
  - - "~>"
87
101
  - !ruby/object:Gem::Version
88
- version: 0.7.1
102
+ version: 1.0.0
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: rainbow
91
105
  requirement: !ruby/object:Gem::Requirement