gitlab-exporter 11.1.0 → 11.5.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
  SHA256:
3
- metadata.gz: b3eef01acf595b16deb86b2578776e3487b513865fca93ede7684ba982932706
4
- data.tar.gz: e5194e0230ac9672b9c30fbd1bf1be3b11333d894a21505dd97e39891f72b960
3
+ metadata.gz: 29e350149b9ffdf7a61ddf79b266992fb0acec022e83c30f0dec627d8222569d
4
+ data.tar.gz: e3d3f1e9f38ab27199b6048fe29cfde62380422f03c5dc681257f5f6c1804044
5
5
  SHA512:
6
- metadata.gz: 60c79e4a4e550adf557129aa278986726370e21f77ca5f67864f23fbb181f5c904d02f5015d51d8317c748b9a72b74cfd59a5f14b4a0af0ffce6b03883ceef4a
7
- data.tar.gz: 5bd99ea95151fd95a5f72597474ec6c81e3fd9e1f0284f5d85b7595257f24cddde5b0a315a6705a6258b8b7d0ebcbe5178f6816978ebc3b2c47a435578d58ee0
6
+ metadata.gz: 4e98d5ac89e78c049235f1419eaebeedd36e109e52e398cbf15d28f4c229a1420753ce2105eba24967de4b2a3d3fb69f3b51912f743f0c5f9b58e95ba3e3719e
7
+ data.tar.gz: a474f550f66341ee303fbabe0319e4876f42c7ca5220fe2414da06b44b7da02bcad8fac9c0d38eebf51b68a40be1077e5faf4136919e73fb8ce787cec7a2ea30
data/.gitlab-ci.yml CHANGED
@@ -6,12 +6,15 @@ include:
6
6
  - template: Security/SAST.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
7
7
  - template: Security/Secret-Detection.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml
8
8
 
9
+ variables:
10
+ RUBY_VERSION: "2.7"
11
+
9
12
  stages:
10
13
  - test
11
14
  - dast
12
15
 
13
16
  default:
14
- image: ruby:2.7
17
+ image: ruby:${RUBY_VERSION}
15
18
  cache:
16
19
  paths:
17
20
  - vendor
@@ -36,6 +39,10 @@ rspec:
36
39
  script:
37
40
  - bundle exec rspec spec -f d -c
38
41
  before_script: *before_scripts
42
+ parallel:
43
+ matrix:
44
+ - RUBY_VERSION: "2.7"
45
+ - RUBY_VERSION: "3.0"
39
46
 
40
47
  rubocop:
41
48
  script:
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.2
1
+ 2.7.4
data/Gemfile CHANGED
@@ -2,6 +2,8 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
+ gem "webrick", "~> 1.7"
6
+
5
7
  group :test do
6
8
  gem "rspec", "~>3.5"
7
9
  gem "rubocop", "~>0.42"
data/Gemfile.lock CHANGED
@@ -1,15 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-exporter (11.1.0)
4
+ gitlab-exporter (11.5.0)
5
5
  connection_pool (= 2.2.5)
6
6
  pg (= 1.2.3)
7
7
  puma (= 5.3.2)
8
8
  quantile (= 0.2.1)
9
- redis (= 4.1.4)
9
+ redis (= 4.4.0)
10
10
  redis-namespace (= 1.6.0)
11
- sidekiq (= 5.2.9)
12
- sinatra (= 2.0.8.1)
11
+ sidekiq (= 6.2.2)
12
+ sinatra (~> 2.1.0)
13
13
 
14
14
  GEM
15
15
  remote: https://rubygems.org/
@@ -19,7 +19,7 @@ GEM
19
19
  diff-lcs (1.3)
20
20
  mustermann (1.1.1)
21
21
  ruby2_keywords (~> 0.0.1)
22
- nio4r (2.5.7)
22
+ nio4r (2.5.8)
23
23
  parallel (1.20.1)
24
24
  parser (3.0.0.0)
25
25
  ast (~> 2.4.1)
@@ -28,10 +28,10 @@ GEM
28
28
  nio4r (~> 2.0)
29
29
  quantile (0.2.1)
30
30
  rack (2.2.3)
31
- rack-protection (2.0.8.1)
31
+ rack-protection (2.1.0)
32
32
  rack
33
33
  rainbow (3.0.0)
34
- redis (4.1.4)
34
+ redis (4.4.0)
35
35
  redis-namespace (1.6.0)
36
36
  redis (>= 3.0.4)
37
37
  regexp_parser (2.0.3)
@@ -61,19 +61,19 @@ GEM
61
61
  rubocop-ast (1.4.0)
62
62
  parser (>= 2.7.1.5)
63
63
  ruby-progressbar (1.11.0)
64
- ruby2_keywords (0.0.4)
65
- sidekiq (5.2.9)
66
- connection_pool (~> 2.2, >= 2.2.2)
64
+ ruby2_keywords (0.0.5)
65
+ sidekiq (6.2.2)
66
+ connection_pool (>= 2.2.2)
67
67
  rack (~> 2.0)
68
- rack-protection (>= 1.5.0)
69
- redis (>= 3.3.5, < 4.2)
70
- sinatra (2.0.8.1)
68
+ redis (>= 4.2.0)
69
+ sinatra (2.1.0)
71
70
  mustermann (~> 1.0)
72
- rack (~> 2.0)
73
- rack-protection (= 2.0.8.1)
71
+ rack (~> 2.2)
72
+ rack-protection (= 2.1.0)
74
73
  tilt (~> 2.0)
75
74
  tilt (2.0.10)
76
75
  unicode-display_width (1.7.0)
76
+ webrick (1.7.0)
77
77
 
78
78
  PLATFORMS
79
79
  ruby
@@ -83,6 +83,7 @@ DEPENDENCIES
83
83
  rspec (~> 3.5)
84
84
  rspec-expectations (~> 3.7.0)
85
85
  rubocop (~> 0.42)
86
+ webrick (~> 1.7)
86
87
 
87
88
  BUNDLED WITH
88
- 2.1.4
89
+ 2.2.22
@@ -24,10 +24,10 @@ Gem::Specification.new do |s|
24
24
  s.add_runtime_dependency "pg", "1.2.3"
25
25
  s.add_runtime_dependency "puma", "5.3.2"
26
26
  s.add_runtime_dependency "quantile", "0.2.1"
27
- s.add_runtime_dependency "redis", "4.1.4"
27
+ s.add_runtime_dependency "redis", "4.4.0"
28
28
  s.add_runtime_dependency "redis-namespace", "1.6.0"
29
- s.add_runtime_dependency "sidekiq", "5.2.9"
30
- s.add_runtime_dependency "sinatra", "2.0.8.1"
29
+ s.add_runtime_dependency "sidekiq", "6.2.2"
30
+ s.add_runtime_dependency "sinatra", "~> 2.1.0"
31
31
 
32
32
  s.add_development_dependency "rspec", "~> 3.7.0"
33
33
  s.add_development_dependency "rspec-expectations", "~> 3.7.0"
@@ -41,8 +41,8 @@ module GitLab
41
41
  conn.type_map_for_results = tm
42
42
  end
43
43
 
44
- def initialize(args, logger: nil)
45
- @connection_string = args[:connection_string]
44
+ def initialize(connection_string:, logger: nil, **opts) # rubocop:disable Lint/UnusedMethodArgument
45
+ @connection_string = connection_string
46
46
  @logger = logger
47
47
  end
48
48
 
@@ -39,12 +39,11 @@ module GitLab
39
39
 
40
40
  attr_reader :metrics, :collector, :bloat_types
41
41
 
42
- def initialize(opts,
43
- metrics: PrometheusMetrics.new,
44
- collector: BloatCollector.new(connection_string: opts[:connection_string]),
45
- logger: nil)
42
+ def initialize(metrics: PrometheusMetrics.new,
43
+ logger: nil,
44
+ **opts)
46
45
  @metrics = metrics
47
- @collector = collector
46
+ @collector = opts[:collector] || BloatCollector.new(**opts)
48
47
  @collector.logger = logger
49
48
  @bloat_types = opts[:bloat_types] || %i[btree table]
50
49
  end
@@ -168,8 +168,8 @@ module GitLab
168
168
 
169
169
  DEFAULT_UNARCHIVED_TRACES_OFFSET_MINUTES = 1440
170
170
 
171
- def initialize(opts, logger: nil)
172
- super(opts, logger: logger)
171
+ def initialize(**opts)
172
+ super
173
173
 
174
174
  @created_builds_counting_disabled = opts[:created_builds_counting_disabled]
175
175
  @unarchived_traces_offset_minutes = opts[:unarchived_traces_offset_minutes]
@@ -294,13 +294,9 @@ module GitLab
294
294
 
295
295
  # The prober which is called when gathering metrics
296
296
  class CiBuildsProber
297
- def initialize(opts, metrics: PrometheusMetrics.new, logger: nil)
297
+ def initialize(metrics: PrometheusMetrics.new, **opts)
298
298
  @metrics = metrics
299
-
300
- collector_opts = { connection_string: opts[:connection_string],
301
- created_builds_counting_disabled: opts[:created_builds_counting_disabled],
302
- unarchived_traces_offset_minutes: opts[:unarchived_traces_offset_minutes] }
303
- @collector = CiBuildsCollector.new(collector_opts, logger: logger)
299
+ @collector = CiBuildsCollector.new(**opts)
304
300
  end
305
301
 
306
302
  def probe_db
@@ -391,7 +387,7 @@ module GitLab
391
387
  labels[:namespace] = "" unless labels[:namespace]
392
388
 
393
389
  selected_labels = labels.select { |k, _| allowed_labels.include?(k) }.sort.to_h
394
- @metrics.add(metric_name, value.to_f, selected_labels)
390
+ @metrics.add(metric_name, value.to_f, **selected_labels)
395
391
  end
396
392
 
397
393
  def unarchived_traces_metrics
@@ -10,8 +10,8 @@ module GitLab
10
10
  FROM remote_mirrors WHERE project_id IN (%s) AND enabled = 't'
11
11
  SQL
12
12
 
13
- def initialize(args)
14
- super(args)
13
+ def initialize(**args)
14
+ super(**args)
15
15
 
16
16
  @project_ids = args[:project_ids]
17
17
  end
@@ -35,7 +35,7 @@ module GitLab
35
35
 
36
36
  # The prober which is called when gathering metrics
37
37
  class RemoteMirrorsProber
38
- def initialize(opts, metrics: PrometheusMetrics.new, logger: nil) # rubocop:disable Lint/UnusedMethodArgument
38
+ def initialize(metrics: PrometheusMetrics.new, **opts)
39
39
  @metrics = metrics
40
40
  @collector = RemoteMirrorsCollector.new(
41
41
  connection_string: opts[:connection_string],
@@ -131,13 +131,29 @@ module GitLab
131
131
  visibility_level: {},
132
132
  root: { definition: "(parent_id IS NULL)" }
133
133
  }
134
- }
134
+ },
135
+ registry_gc_manifest_review_queue: { select: :gc_manifest_review_queue },
136
+ registry_gc_manifest_review_queue_overdue: {
137
+ select: :gc_manifest_review_queue,
138
+ where: "review_after < NOW()"
139
+ },
140
+ registry_gc_blob_review_queue: { select: :gc_blob_review_queue },
141
+ registry_gc_blob_review_queue_overdue: {
142
+ select: :gc_blob_review_queue,
143
+ where: "review_after < NOW()"
144
+ },
145
+ registry_top_level_namespaces: { select: :top_level_namespaces },
146
+ # Please note that the tables below are partitioned, so a SELECT COUNT(*)
147
+ # will scale poorly. Avoid using these in production:
148
+ registry_repositories: { select: :repositories },
149
+ registry_manifests: { select: :manifests },
150
+ registry_blobs: { select: :blobs }
135
151
  }.freeze
136
152
 
137
- def initialize(args)
138
- super(args)
153
+ def initialize(selected_queries: nil, **args)
154
+ super(**args)
139
155
 
140
- @selected_queries = Set.new(args[:selected_queries].map(&:to_sym)) unless args[:selected_queries].nil?
156
+ @selected_queries = Set.new(selected_queries.map(&:to_sym)) unless selected_queries.nil?
141
157
  end
142
158
 
143
159
  def run
@@ -200,12 +216,9 @@ module GitLab
200
216
 
201
217
  # The prober which is called when gathering metrics
202
218
  class RowCountProber
203
- def initialize(opts, metrics: PrometheusMetrics.new, logger: nil) # rubocop:disable Lint/UnusedMethodArgument
219
+ def initialize(metrics: PrometheusMetrics.new, **opts)
204
220
  @metrics = metrics
205
- @collector = RowCountCollector.new(
206
- connection_string: opts[:connection_string],
207
- selected_queries: opts[:selected_queries]
208
- )
221
+ @collector = RowCountCollector.new(**opts)
209
222
  end
210
223
 
211
224
  def probe_db
@@ -25,9 +25,9 @@ module GitLab
25
25
 
26
26
  # Probes the DB specified by opts[:connection_string] for tuple stats, then converts them to metrics
27
27
  class TuplesProber
28
- def initialize(opts, metrics: PrometheusMetrics.new, logger: nil)
28
+ def initialize(metrics: PrometheusMetrics.new, **opts)
29
29
  @metrics = metrics
30
- @collector = TupleStatsCollector.new(connection_string: opts[:connection_string], logger: logger)
30
+ @collector = TupleStatsCollector.new(**opts)
31
31
  end
32
32
 
33
33
  def probe_db
@@ -64,10 +64,10 @@ module GitLab
64
64
  # Optionally takes a metrics object which by default is a PrometheusMetrics, useful to change the
65
65
  # metrics writer to something else.
66
66
  class GitProber
67
- def initialize(opts, metrics: PrometheusMetrics.new, logger: nil) # rubocop:disable Lint/UnusedMethodArgument
67
+ def initialize(source:, metrics: PrometheusMetrics.new, labels: {}, **opts) # rubocop:disable Lint/UnusedMethodArgument
68
68
  @metrics = metrics
69
- @labels = opts[:labels] || {}
70
- @git = Git.new(opts[:source])
69
+ @labels = labels
70
+ @git = Git.new(source)
71
71
  end
72
72
 
73
73
  def probe_pull
@@ -87,9 +87,9 @@ module GitLab
87
87
 
88
88
  # A special prober for git processes
89
89
  class GitProcessProber
90
- def initialize(opts, metrics: PrometheusMetrics.new, logger: nil) # rubocop:disable Lint/UnusedMethodArgument
91
- @opts = opts
90
+ def initialize(metrics: PrometheusMetrics.new, quantiles: nil, **opts) # rubocop:disable Lint/UnusedMethodArgument
92
91
  @metrics = metrics
92
+ @quantiles = quantiles
93
93
  end
94
94
 
95
95
  def probe_git # rubocop:disable Metrics/MethodLength
@@ -115,7 +115,7 @@ module GitLab
115
115
  {
116
116
  name: name,
117
117
  pid_or_pattern: pid,
118
- quantiles: @opts[:quantiles]
118
+ quantiles: @quantiles
119
119
  },
120
120
  metrics: @metrics
121
121
  )
@@ -2,7 +2,7 @@ module GitLab
2
2
  module Exporter
3
3
  # A class to combine multiple probers into one
4
4
  class Prober
5
- def initialize(prober_opts, metrics: PrometheusMetrics.new, logger: nil)
5
+ def initialize(metrics: PrometheusMetrics.new, logger: nil, **prober_opts)
6
6
  @prober_opts = prober_opts
7
7
  @metrics = metrics
8
8
  @logger = logger
@@ -13,7 +13,7 @@ module GitLab
13
13
  def probe_all
14
14
  @prober_opts.each do |_probe_name, params|
15
15
  Utils.wrap_in_array(params[:opts]).each do |opts|
16
- prober = params[:class].new(opts, metrics: @metrics, logger: @logger)
16
+ prober = params[:class].new(metrics: @metrics, logger: @logger, **opts)
17
17
  params[:methods].each do |meth|
18
18
  prober.send(meth)
19
19
  end
@@ -59,15 +59,15 @@ module GitLab
59
59
 
60
60
  # Probes a process for info then writes metrics to a target
61
61
  class ProcessProber
62
- def initialize(options, metrics: PrometheusMetrics.new, logger: nil) # rubocop:disable Lint/UnusedMethodArgument
62
+ def initialize(name:, metrics: PrometheusMetrics.new, quantiles: false, **options)
63
63
  @metrics = metrics
64
- @name = options[:name]
64
+ @name = name
65
65
  @pids = if options[:pid_or_pattern] =~ /^\d+$/
66
66
  [options[:pid_or_pattern]]
67
67
  else
68
68
  Utils.pgrep(options[:pid_or_pattern])
69
69
  end
70
- @use_quantiles = options.fetch(:quantiles, false)
70
+ @use_quantiles = quantiles
71
71
  end
72
72
 
73
73
  def probe_stat
@@ -4,9 +4,9 @@ module GitLab
4
4
  module Exporter
5
5
  # Probes a current process GC for info then writes metrics to a target
6
6
  class RubyProber
7
- def initialize(options, metrics: PrometheusMetrics.new, logger: nil) # rubocop:disable Lint/UnusedMethodArgument
7
+ def initialize(metrics: PrometheusMetrics.new, quantiles: false, **opts) # rubocop:disable Lint/UnusedMethodArgument
8
8
  @metrics = metrics
9
- @use_quantiles = options.fetch(:quantiles, false)
9
+ @use_quantiles = quantiles
10
10
  end
11
11
 
12
12
  def probe_gc
@@ -33,7 +33,7 @@ module GitLab
33
33
  end
34
34
  end
35
35
 
36
- def initialize(opts, metrics: PrometheusMetrics.new, logger: nil)
36
+ def initialize(metrics: PrometheusMetrics.new, logger: nil, **opts)
37
37
  @opts = opts
38
38
  @metrics = metrics
39
39
  @logger = logger
@@ -1,5 +1,5 @@
1
1
  module GitLab
2
2
  module Exporter
3
- VERSION = "11.1.0".freeze
3
+ VERSION = "11.5.0".freeze
4
4
  end
5
5
  end
@@ -89,7 +89,7 @@ module GitLab
89
89
 
90
90
  get "/#{probe_name}" do
91
91
  content_type "text/plain; version=0.0.4"
92
- prober = Prober.new(opts, metrics: PrometheusMetrics.new(include_timestamp: false), logger: logger)
92
+ prober = Prober.new(metrics: PrometheusMetrics.new(include_timestamp: false), logger: logger, **opts)
93
93
 
94
94
  prober.probe_all
95
95
  prober.write_to(response)
@@ -26,7 +26,7 @@ describe GitLab::Exporter::Database::BloatCollector do
26
26
  end
27
27
 
28
28
  describe GitLab::Exporter::Database::BloatProber do
29
- let(:opts) { { bloat_types: %i[btree table] } }
29
+ let(:opts) { { bloat_types: %i[btree table], connection_string: "" } }
30
30
  let(:metrics) { double("PrometheusMetrics", add: nil) }
31
31
  let(:collector) { double("BloatCollector", run: data) }
32
32
 
@@ -43,7 +43,7 @@ describe GitLab::Exporter::Database::BloatProber do
43
43
  end
44
44
 
45
45
  describe "#probe_db" do
46
- subject { described_class.new(opts, metrics: metrics, collector: collector, logger: STDOUT).probe_db }
46
+ subject { described_class.new(metrics: metrics, collector: collector, logger: STDOUT, **opts).probe_db }
47
47
 
48
48
  before do
49
49
  expect(collector).to receive(:logger=).with(STDOUT)
@@ -92,7 +92,7 @@ describe GitLab::Exporter::Database::BloatProber do
92
92
  describe "#write_to" do
93
93
  let(:target) { double }
94
94
  let(:metrics) { double("PrometheusMetrics", to_s: double) }
95
- subject { described_class.new(opts, metrics: metrics).write_to(target) }
95
+ subject { described_class.new(metrics: metrics, **opts).write_to(target) }
96
96
 
97
97
  it "writes to given target" do
98
98
  expect(target).to receive(:write).with(metrics.to_s)
@@ -216,11 +216,12 @@ describe GitLab::Exporter::Database do
216
216
  describe GitLab::Exporter::Database::CiBuildsProber do
217
217
  let(:writer) { StringIO.new }
218
218
  let(:prober) do
219
- opts = { connection_string: "host=localhost",
220
- created_builds_counting_disabled: created_builds_counting_disabled,
221
- unarchived_traces_offset_minutes: unarchived_traces_offset_minutes }
222
- described_class.new(opts,
223
- metrics: GitLab::Exporter::PrometheusMetrics.new(include_timestamp: false))
219
+ described_class.new(
220
+ connection_string: "host=localhost",
221
+ created_builds_counting_disabled: created_builds_counting_disabled,
222
+ unarchived_traces_offset_minutes: unarchived_traces_offset_minutes,
223
+ metrics: GitLab::Exporter::PrometheusMetrics.new(include_timestamp: false)
224
+ )
224
225
  end
225
226
 
226
227
  before do
data/spec/git_spec.rb CHANGED
@@ -34,17 +34,17 @@ context "With valid pair of repositories" do
34
34
  end
35
35
 
36
36
  describe GitLab::Exporter::GitProber do
37
- let(:options) { GitProberOptions.new(repos.cloned_repo, {}) }
37
+ let(:options) { { source: repos.cloned_repo, labels: {} } }
38
38
  let(:output) { StringIO.new }
39
39
 
40
40
  it "probes and monitors a pull" do
41
- prober = GitLab::Exporter::GitProber.new(options)
41
+ prober = GitLab::Exporter::GitProber.new(**options)
42
42
  prober.probe_pull.write_to(output)
43
43
  expect(output.string).to match(/git_pull_time_milliseconds \d+ \d+/)
44
44
  end
45
45
 
46
46
  it "probes and monitors a push" do
47
- prober = GitLab::Exporter::GitProber.new(options)
47
+ prober = GitLab::Exporter::GitProber.new(**options)
48
48
  prober.probe_push.write_to(output)
49
49
  expect(output.string).to match(/git_push_time_milliseconds \d+ \d+/)
50
50
  end
data/spec/ruby_spec.rb CHANGED
@@ -3,7 +3,7 @@ require "gitlab_exporter/ruby"
3
3
  require "gitlab_exporter/prober"
4
4
 
5
5
  describe GitLab::Exporter::RubyProber do
6
- let(:prober) { GitLab::Exporter::Prober.new(options) }
6
+ let(:prober) { GitLab::Exporter::Prober.new(**options) }
7
7
 
8
8
  let(:options) do
9
9
  {
data/spec/spec_helper.rb CHANGED
@@ -40,8 +40,6 @@ class GitRepoBuilder
40
40
  end
41
41
  end
42
42
 
43
- GitProberOptions = Struct.new(:source, :labels)
44
-
45
43
  class CLIArgs
46
44
  def initialize(args)
47
45
  @arguments = args
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-exporter
3
3
  version: !ruby/object:Gem::Version
4
- version: 11.1.0
4
+ version: 11.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pablo Carranza
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 4.1.4
75
+ version: 4.4.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 4.1.4
82
+ version: 4.4.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: redis-namespace
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -100,28 +100,28 @@ dependencies:
100
100
  requirements:
101
101
  - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: 5.2.9
103
+ version: 6.2.2
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: 5.2.9
110
+ version: 6.2.2
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: sinatra
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '='
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 2.0.8.1
117
+ version: 2.1.0
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '='
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 2.0.8.1
124
+ version: 2.1.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rspec
127
127
  requirement: !ruby/object:Gem::Requirement