goodcheck 2.6.1 → 2.7.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
  SHA256:
3
- metadata.gz: 883ed31ce90c345b08d6b9e12b89a13c802baa1f6836d986f440a2eac816ec41
4
- data.tar.gz: 196cc57241e9fc0f1505122225d4f165930c9fed34cf30f58146f415c53eaeef
3
+ metadata.gz: 8c2de636a6040f67abd7f2a24da8cd3519d76490724c0897ec4da3e8594e9a88
4
+ data.tar.gz: 690af43e3de713f7185fe3d080d8d99b647423e389b941981d18c2a84e049169
5
5
  SHA512:
6
- metadata.gz: 857d4fb3c2048887c3c4e2809c17357e22eb968ad895a125db39059b52e81ccb9f7fb956827e3c4d0f927c052b8deb1f277f4183c2d0542f09fb45b016f14aed
7
- data.tar.gz: f306f2e95696190574f577b141bccefd641bc62171008cb0a47c8bd7fe9966dba0a9c92881f91c186dfafab49c3173519537017bf377579aecce686e275e1890
6
+ metadata.gz: 8e6d05a4a287d13d41fcb42af646d259aa50b1cb0c8b0c39d14aa09ce96fa97839331dbf192f1048737f56b5a253ef590187add746f82251c3acb8e45ceaaa7a
7
+ data.tar.gz: aeec81a86feffac3321ad616c10f5f319a37dd6efce177a446e0a316c35db1fdc8de405d5c2afd5a7e450a9faafb359578ea92a1283411bfc988f78722c35eb5
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## HEAD
4
4
 
5
+ ## 2.7.0 (2020-12-02)
6
+
7
+ * Goodbye ActiveSupport [#155](https://github.com/sider/goodcheck/pull/155)
8
+ * Fix zero column [#160](https://github.com/sider/goodcheck/pull/160)
9
+ * Improve text reporter [#161](https://github.com/sider/goodcheck/pull/161)
10
+
5
11
  ## 2.6.1 (2020-11-19)
6
12
 
7
13
  * Add missing doc for importing glob feature [#151](https://github.com/sider/goodcheck/pull/151)
@@ -4,9 +4,7 @@ require "set"
4
4
  require "strong_json"
5
5
  require "yaml"
6
6
  require "json"
7
- require "active_support/core_ext/hash/indifferent_access"
8
- require "active_support/core_ext/integer/inflections"
9
- require "active_support/tagged_logging"
7
+ require "logger"
10
8
  require "rainbow"
11
9
  require "digest/sha2"
12
10
  require "net/http"
@@ -13,7 +13,7 @@ module Goodcheck
13
13
  def scan(&block)
14
14
  if block_given?
15
15
  if trigger.patterns.empty?
16
- yield Issue.new(buffer: buffer, range: nil, rule: rule, text: nil)
16
+ yield Issue.new(buffer: buffer, rule: rule)
17
17
  else
18
18
  var_pats, novar_pats = trigger.patterns.partition {|pat|
19
19
  pat.is_a?(Pattern::Token) && !pat.variables.empty?
@@ -44,9 +44,7 @@ module Goodcheck
44
44
  while true
45
45
  case
46
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)
47
+ issues << new_issue_with_matched(scanner)
50
48
  else
51
49
  break
52
50
  end
@@ -55,7 +53,7 @@ module Goodcheck
55
53
  issues.each(&block)
56
54
  else
57
55
  unless regexp =~ buffer.content
58
- yield Issue.new(buffer: buffer, range: nil, rule: rule, text: nil)
56
+ yield Issue.new(buffer: buffer, rule: rule)
59
57
  end
60
58
  end
61
59
  end
@@ -68,9 +66,7 @@ module Goodcheck
68
66
  case
69
67
  when scanner.scan_until(pat.regexp)
70
68
  if pat.test_variables(scanner)
71
- text = scanner.matched
72
- range = (scanner.pos - text.bytesize) .. scanner.pos
73
- yield Issue.new(buffer: buffer, range: range, rule: rule, text: text)
69
+ yield new_issue_with_matched(scanner)
74
70
  end
75
71
  else
76
72
  break
@@ -84,11 +80,19 @@ module Goodcheck
84
80
  break
85
81
  end
86
82
  else
87
- yield Issue.new(buffer: buffer, range: nil, rule: rule, text: nil)
83
+ yield Issue.new(buffer: buffer, rule: rule)
88
84
  break
89
85
  end
90
86
  end
91
87
  end
92
88
  end
89
+
90
+ private
91
+
92
+ def new_issue_with_matched(scanner)
93
+ Issue.new(buffer: buffer, rule: rule,
94
+ text: scanner.matched,
95
+ text_begin_pos: scanner.pos - scanner.matched_size)
96
+ end
93
97
  end
94
98
  end
@@ -43,7 +43,7 @@ module Goodcheck
43
43
  start_position = 0
44
44
 
45
45
  content.split(/\n/, -1).each do |line|
46
- range = start_position...(start_position + line.bytesize)
46
+ range = start_position..(start_position + line.bytesize)
47
47
  @line_ranges << range
48
48
  start_position = range.end + 1
49
49
  end
@@ -51,10 +51,10 @@ module Goodcheck
51
51
 
52
52
  @line_ranges
53
53
  end
54
-
54
+
55
55
  def line_disabled?(line_number)
56
56
  if line_number > 1
57
- return true if DISABLE_NEXT_LINE_PATTERNS.any? { |pattern| line(line_number - 1).match?(pattern) }
57
+ return true if DISABLE_NEXT_LINE_PATTERNS.any? { |pattern| line(line_number - 1).match?(pattern) }
58
58
  end
59
59
 
60
60
  if line_number <= lines.length
@@ -70,7 +70,9 @@ module Goodcheck
70
70
  end
71
71
 
72
72
  if line_index
73
- [line_index + 1, position - line_ranges[line_index].begin]
73
+ line_number = line_index + 1
74
+ column_number = position - line_ranges[line_index].begin + 1
75
+ [line_number, column_number]
74
76
  end
75
77
  end
76
78
 
@@ -79,16 +81,7 @@ module Goodcheck
79
81
  end
80
82
 
81
83
  def line(line_number)
82
- lines[line_number-1]
83
- end
84
-
85
- def position_for_location(line, column)
86
- if (range = line_ranges[line-1])
87
- pos = range.begin + column
88
- if pos <= range.end
89
- pos
90
- end
91
- end
84
+ lines[line_number - 1]
92
85
  end
93
86
  end
94
87
  end
@@ -63,7 +63,7 @@ module Goodcheck
63
63
  rules = []
64
64
  formats = [:text, :json]
65
65
  format = :text
66
- loglevel = Logger::ERROR
66
+ loglevel = nil
67
67
  force_download = false
68
68
 
69
69
  OptionParser.new("Usage: goodcheck check [options] paths...") do |opts|
@@ -82,7 +82,7 @@ module Goodcheck
82
82
  end
83
83
  end.parse!(args)
84
84
 
85
- Goodcheck.logger.level = loglevel
85
+ Goodcheck.logger.level = loglevel if loglevel
86
86
 
87
87
  if args.empty?
88
88
  targets << Pathname(".")
@@ -57,6 +57,8 @@ module Goodcheck
57
57
  end
58
58
  end
59
59
 
60
+ reporter.summary
61
+
60
62
  issue_reported ? EXIT_MATCH : EXIT_SUCCESS
61
63
  end
62
64
  end
@@ -71,31 +73,27 @@ module Goodcheck
71
73
  def each_check
72
74
  targets.each do |target|
73
75
  Goodcheck.logger.info "Checking target: #{target}"
74
- Goodcheck.logger.tagged target.to_s do
75
- each_file target, immediate: true do |path|
76
- Goodcheck.logger.debug "Checking file: #{path}"
77
- Goodcheck.logger.tagged path.to_s do
78
- reporter.file(path) do
79
- buffers = {}
80
-
81
- config.rules_for_path(path, rules_filter: rules) do |rule, glob, trigger|
82
- Goodcheck.logger.debug "Checking rule: #{rule.id}"
83
- begin
84
- encoding = glob&.encoding || Encoding.default_external.name
85
-
86
- if buffers[encoding]
87
- buffer = buffers[encoding]
88
- else
89
- content = path.read(encoding: encoding).encode(Encoding.default_internal || Encoding::UTF_8)
90
- buffer = Buffer.new(path: path, content: content)
91
- buffers[encoding] = buffer
92
- end
93
-
94
- yield buffer, rule, trigger
95
- rescue ArgumentError => exn
96
- stderr.puts "#{path}: #{exn.inspect}"
97
- end
76
+ each_file target, immediate: true do |path|
77
+ Goodcheck.logger.debug "Checking file: #{path}"
78
+ reporter.file(path) do
79
+ buffers = {}
80
+
81
+ config.rules_for_path(path, rules_filter: rules) do |rule, glob, trigger|
82
+ Goodcheck.logger.debug "Checking rule: #{rule.id}"
83
+ begin
84
+ encoding = glob&.encoding || Encoding.default_external.name
85
+
86
+ if buffers[encoding]
87
+ buffer = buffers[encoding]
88
+ else
89
+ content = path.read(encoding: encoding).encode(Encoding.default_internal || Encoding::UTF_8)
90
+ buffer = Buffer.new(path: path, content: content)
91
+ buffers[encoding] = buffer
98
92
  end
93
+
94
+ yield buffer, rule, trigger
95
+ rescue ArgumentError => exn
96
+ stderr.puts "#{path}: #{exn.inspect}"
99
97
  end
100
98
  end
101
99
  end
@@ -112,7 +110,7 @@ module Goodcheck
112
110
  when DEFAULT_EXCLUSIONS.include?(path.basename.to_s)
113
111
  # noop
114
112
  when immediate || !excluded?(path)
115
- path.children.each do |child|
113
+ path.children.sort.each do |child|
116
114
  each_file(child, &block)
117
115
  end
118
116
  end
@@ -5,6 +5,7 @@ module Goodcheck
5
5
  attr_reader :path
6
6
 
7
7
  def initialize(path:)
8
+ super(path.to_s)
8
9
  @path = path
9
10
  end
10
11
  end
@@ -20,7 +21,7 @@ module Goodcheck
20
21
  end
21
22
 
22
23
  import_loader = ImportLoader.new(cache_path: cache_path, force_download: force_download, config_path: config_path)
23
- content = JSON.parse(JSON.dump(YAML.load(config_content, filename: config_path.to_s)), symbolize_names: true)
24
+ content = JSON.parse(JSON.dump(YAML.safe_load(config_content, filename: config_path.to_s)), symbolize_names: true)
24
25
  loader = ConfigLoader.new(path: config_path, content: content, stderr: stderr, import_loader: import_loader)
25
26
  @config = loader.load
26
27
  end
@@ -51,7 +51,8 @@ module Goodcheck
51
51
  true
52
52
  else
53
53
  count = duplicated_ids.size
54
- stdout.puts(Rainbow(" Found #{count} #{'duplication'.pluralize(count)}.😞").red)
54
+ duplication = count == 1 ? 'duplication' : 'duplications'
55
+ stdout.puts(Rainbow(" Found #{count} #{duplication}.😞").red)
55
56
  duplicated_ids.each do |id|
56
57
  stdout.puts " #{id}"
57
58
  end
@@ -76,7 +77,7 @@ module Goodcheck
76
77
  if trigger.by_pattern?
77
78
  stdout.puts " Testing pattern..."
78
79
  else
79
- stdout.puts " Testing #{(index+1).ordinalize} trigger..."
80
+ stdout.puts " #{index + 1}. Testing trigger..."
80
81
  end
81
82
 
82
83
  pass_errors = trigger.passes.each.with_index.select do |pass, _|
@@ -92,7 +93,7 @@ module Goodcheck
92
93
  rule_ok = false
93
94
 
94
95
  pass_errors.each do |_, index|
95
- stdout.puts " #{(index+1).ordinalize} #{Rainbow('pass').green} example matched.😱"
96
+ stdout.puts " #{index + 1}. #{Rainbow('pass').green} example matched.😱"
96
97
  failed_rule_ids << rule.id
97
98
  end
98
99
  end
@@ -102,7 +103,7 @@ module Goodcheck
102
103
  rule_ok = false
103
104
 
104
105
  fail_errors.each do |_, index|
105
- stdout.puts " #{(index+1).ordinalize} #{Rainbow('fail').red} example didn't match.😱"
106
+ stdout.puts " #{index + 1}. #{Rainbow('fail').red} example didn't match.😱"
106
107
  failed_rule_ids << rule.id
107
108
  end
108
109
  end
@@ -132,10 +133,11 @@ module Goodcheck
132
133
  end
133
134
 
134
135
  rule_count = success_count + failure_count
136
+ rule = rule_count == 1 ? "1 rule" : "#{rule_count} rules"
137
+ success = Rainbow(success_count == 1 ? "1 success" : "#{success_count} successes").green
138
+ failure = Rainbow(failure_count == 1 ? "1 failure" : "#{failure_count} failures").red
135
139
  stdout.puts ""
136
- stdout.puts ["Tested #{rule_count} #{'rule'.pluralize(rule_count)}",
137
- Rainbow("#{success_count} #{'success'.pluralize(success_count)}").green,
138
- Rainbow("#{failure_count} #{'failure'.pluralize(failure_count)}").red].join(", ")
140
+ stdout.puts "Tested #{rule}, #{success}, #{failure}"
139
141
 
140
142
  test_pass
141
143
  end
@@ -214,21 +214,19 @@ module Goodcheck
214
214
 
215
215
  def load
216
216
  Goodcheck.logger.info "Loading configuration: #{path}"
217
- Goodcheck.logger.tagged "#{path}" do
218
- Schema.config.coerce(content)
217
+ Schema.config.coerce(content)
219
218
 
220
- rules = []
219
+ rules = []
221
220
 
222
- load_rules(rules, array(content[:rules]))
221
+ load_rules(rules, array(content[:rules]))
223
222
 
224
- Array(content[:import]).each do |import|
225
- load_import rules, import
226
- end
223
+ Array(content[:import]).each do |import|
224
+ load_import rules, import
225
+ end
227
226
 
228
- exclude_paths = Array(content[:exclude])
227
+ exclude_paths = Array(content[:exclude])
229
228
 
230
- Config.new(rules: rules, exclude_paths: exclude_paths)
231
- end
229
+ Config.new(rules: rules, exclude_paths: exclude_paths)
232
230
  end
233
231
 
234
232
  def load_rules(rules, array)
@@ -240,13 +238,11 @@ module Goodcheck
240
238
  def load_import(rules, import)
241
239
  Goodcheck.logger.info "Importing rules from #{import}"
242
240
 
243
- Goodcheck.logger.tagged import do
244
- import_loader.load(import) do |content|
245
- json = JSON.parse(JSON.dump(YAML.load(content, filename: import)), symbolize_names: true)
241
+ import_loader.load(import) do |content|
242
+ json = JSON.parse(JSON.dump(YAML.load(content, filename: import)), symbolize_names: true)
246
243
 
247
- Schema.rules.coerce json
248
- load_rules(rules, json)
249
- end
244
+ Schema.rules.coerce json
245
+ load_rules(rules, json)
250
246
  end
251
247
  end
252
248
 
@@ -1,15 +1,15 @@
1
1
  module Goodcheck
2
2
  class Issue
3
3
  attr_reader :buffer
4
- attr_reader :range
5
4
  attr_reader :rule
6
5
  attr_reader :text
6
+ attr_reader :range
7
7
 
8
- def initialize(buffer:, range:, rule:, text:)
8
+ def initialize(buffer:, rule:, text: nil, text_begin_pos: nil)
9
9
  @buffer = buffer
10
- @range = range
11
10
  @rule = rule
12
11
  @text = text
12
+ @range = text ? text_begin_pos..(text_begin_pos + text.bytesize - 1) : nil
13
13
  @location = nil
14
14
  end
15
15
 
@@ -1,4 +1,18 @@
1
1
  module Goodcheck
2
+ # In the example below, each attribute is:
3
+ #
4
+ # - start_line: 2
5
+ # - start_column: 3
6
+ # - end_line: 2
7
+ # - end_column: 9
8
+ #
9
+ # @example
10
+ #
11
+ # 1 |
12
+ # 2 | A matched text
13
+ # 3 | ^~~~~~~
14
+ # 3456789
15
+ #
2
16
  class Location
3
17
  attr_reader :start_line
4
18
  attr_reader :start_column
@@ -12,6 +26,14 @@ module Goodcheck
12
26
  @end_column = end_column
13
27
  end
14
28
 
29
+ def one_line?
30
+ start_line == end_line
31
+ end
32
+
33
+ def column_size
34
+ end_column - start_column + 1
35
+ end
36
+
15
37
  def ==(other)
16
38
  other.is_a?(Location) &&
17
39
  other.start_line == start_line &&
@@ -19,5 +41,11 @@ module Goodcheck
19
41
  other.end_line == end_line &&
20
42
  other.end_column == end_column
21
43
  end
44
+
45
+ alias eql? ==
46
+
47
+ def hash
48
+ self.class.hash ^ start_line.hash ^ start_column.hash ^ end_line.hash ^ end_column.hash
49
+ end
22
50
  end
23
51
  end
@@ -1,8 +1,8 @@
1
1
  module Goodcheck
2
2
  def self.logger
3
- @logger ||= ActiveSupport::TaggedLogging.new(Logger.new(STDERR)).tap do |logger|
4
- logger.push_tags VERSION
5
- logger.level = Logger::ERROR
6
- end
3
+ @logger ||= Logger.new(
4
+ STDERR, level: Logger::ERROR,
5
+ formatter: ->(severity, time, progname, msg) { "[#{severity}] #{msg}\n" }
6
+ )
7
7
  end
8
8
  end
@@ -44,6 +44,10 @@ module Goodcheck
44
44
  def issue(issue)
45
45
  issues << issue
46
46
  end
47
+
48
+ def summary
49
+ # noop
50
+ end
47
51
  end
48
52
  end
49
53
  end
@@ -5,6 +5,8 @@ module Goodcheck
5
5
 
6
6
  def initialize(stdout:)
7
7
  @stdout = stdout
8
+ @file_count = 0
9
+ @issue_count = 0
8
10
  end
9
11
 
10
12
  def analysis
@@ -12,6 +14,7 @@ module Goodcheck
12
14
  end
13
15
 
14
16
  def file(path)
17
+ @file_count += 1
15
18
  yield
16
19
  end
17
20
 
@@ -20,21 +23,49 @@ module Goodcheck
20
23
  end
21
24
 
22
25
  def issue(issue)
26
+ @issue_count += 1
27
+
28
+ message = issue.rule.message.lines.first.chomp
29
+
23
30
  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}"
31
+ start_line = issue.location.start_line
32
+ start_column = issue.location.start_column
33
+ start_column_index = start_column - 1
34
+ line = issue.buffer.line(start_line)
35
+ column_size = if issue.location.one_line?
36
+ issue.location.column_size
37
+ else
38
+ line.bytesize - start_column
39
+ end
40
+ stdout.puts "#{Rainbow(issue.path).cyan}:#{start_line}:#{start_column}: #{message}"
41
+ stdout.puts line.chomp
42
+ stdout.puts (" " * start_column_index) + Rainbow("^" + "~" * (column_size - 1)).yellow
32
43
  else
33
- line = issue.buffer.line(1)&.chomp
34
- line = line ? Rainbow(line).red : '-'
35
- stdout.puts "#{issue.path}:-:#{line}:\t#{issue.rule.message.lines.first.chomp}"
44
+ stdout.puts "#{Rainbow(issue.path).cyan}:-:-: #{message}"
36
45
  end
37
46
  end
47
+
48
+ def summary
49
+ files = case @file_count
50
+ when 0
51
+ "no files"
52
+ when 1
53
+ "1 file"
54
+ else
55
+ "#{@file_count} files"
56
+ end
57
+ issues = case @issue_count
58
+ when 0
59
+ Rainbow("no issues").green
60
+ when 1
61
+ Rainbow("1 issue").red
62
+ else
63
+ Rainbow("#{@issue_count} issues").red
64
+ end
65
+
66
+ stdout.puts ""
67
+ stdout.puts "#{files} inspected, #{issues} detected"
68
+ end
38
69
  end
39
70
  end
40
71
  end
@@ -1,3 +1,3 @@
1
1
  module Goodcheck
2
- VERSION = "2.6.1".freeze
2
+ VERSION = "2.7.0".freeze
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: 2.6.1
4
+ version: 2.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: 2020-11-19 00:00:00.000000000 Z
11
+ date: 2020-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,64 +28,58 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '13.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '13.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '5.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: minitest-reporters
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 1.4.2
61
+ version: '1.4'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 1.4.2
68
+ version: '1.4'
69
69
  - !ruby/object:Gem::Dependency
70
- name: activesupport
70
+ name: simplecov
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '4.0'
76
- - - "<"
77
- - !ruby/object:Gem::Version
78
- version: '7.0'
79
- type: :runtime
75
+ version: '0.18'
76
+ type: :development
80
77
  prerelease: false
81
78
  version_requirements: !ruby/object:Gem::Requirement
82
79
  requirements:
83
80
  - - ">="
84
81
  - !ruby/object:Gem::Version
85
- version: '4.0'
86
- - - "<"
87
- - !ruby/object:Gem::Version
88
- version: '7.0'
82
+ version: '0.18'
89
83
  - !ruby/object:Gem::Dependency
90
84
  name: strong_json
91
85
  requirement: !ruby/object:Gem::Requirement
@@ -110,16 +104,22 @@ dependencies:
110
104
  name: rainbow
111
105
  requirement: !ruby/object:Gem::Requirement
112
106
  requirements:
113
- - - "~>"
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '3.0'
110
+ - - "<"
114
111
  - !ruby/object:Gem::Version
115
- version: 3.0.0
112
+ version: '4.0'
116
113
  type: :runtime
117
114
  prerelease: false
118
115
  version_requirements: !ruby/object:Gem::Requirement
119
116
  requirements:
120
- - - "~>"
117
+ - - ">="
121
118
  - !ruby/object:Gem::Version
122
- version: 3.0.0
119
+ version: '3.0'
120
+ - - "<"
121
+ - !ruby/object:Gem::Version
122
+ version: '4.0'
123
123
  - !ruby/object:Gem::Dependency
124
124
  name: psych
125
125
  requirement: !ruby/object:Gem::Requirement