berkshelf 2.0.5 → 2.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,8 @@
1
+ # 2.0.6
2
+
3
+ * Fix installation failures due to latest release of ActiveSupport
4
+ * --except and --only will now work with a lockfile present
5
+
1
6
  # 2.0.5
2
7
 
3
8
  * Improve speed of resolution when a lockfile is present
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
30
30
  s.required_ruby_version = '>= 1.9.1'
31
31
  s.required_rubygems_version = '>= 1.8.0'
32
32
 
33
- s.add_dependency 'activesupport', '>= 3.2.0'
33
+ s.add_dependency 'activesupport', '~> 3.2.0'
34
34
  s.add_dependency 'addressable', '~> 2.3.4'
35
35
  s.add_dependency 'buff-shell_out', '~> 0.1'
36
36
  s.add_dependency 'celluloid', '>= 0.14.0'
@@ -28,6 +28,41 @@ Feature: Installing specific groups
28
28
  And the output should not contain "Using notme (1.0.0)"
29
29
  And the exit status should be 0
30
30
 
31
+ Scenario: Using the --except option with a lockfile
32
+ Given the cookbook store has the cookbooks:
33
+ | default | 1.0.0 |
34
+ | takeme | 1.0.0 |
35
+ Given I write to "Berksfile" with:
36
+ """
37
+ group :notme do
38
+ cookbook 'notme', '1.0.0'
39
+ end
40
+
41
+ cookbook 'default', '1.0.0'
42
+
43
+ group :takeme do
44
+ cookbook 'takeme', '1.0.0'
45
+ end
46
+ """
47
+ And I write to "Berksfile.lock" with:
48
+ """
49
+ {
50
+ "sources": {
51
+ "notme": { "locked_version": "1.0.0"},
52
+ "takeme": { "locked_version": "1.0.0"},
53
+ "default": { "locked_version": "1.0.0"}
54
+ }
55
+ }
56
+ """
57
+ When I successfully run `berks install --except notme`
58
+ Then the output should contain:
59
+ """
60
+ Using default (1.0.0)
61
+ Using takeme (1.0.0)
62
+ """
63
+ And the output should not contain "Using notme (1.0.0)"
64
+ And the exit status should be 0
65
+
31
66
  Scenario: Using the --only option
32
67
  Given the cookbook store has the cookbooks:
33
68
  | takeme | 1.0.0 |
@@ -14,7 +14,6 @@ Feature: Creating and reading the Berkshelf lockfile
14
14
  Then the file "Berksfile.lock" should contain JSON:
15
15
  """
16
16
  {
17
- "sha":"80396ed07db133e0192593adebb360c27eed88c2",
18
17
  "sources":{
19
18
  "fake":{
20
19
  "locked_version":"1.0.0"
@@ -40,7 +39,6 @@ Feature: Creating and reading the Berkshelf lockfile
40
39
  Then the file "Berksfile.lock" should contain JSON:
41
40
  """
42
41
  {
43
- "sha": "374a3d22920abae4a6d620a14a32b90d8babda8f",
44
42
  "sources": {
45
43
  "fake": {
46
44
  "locked_version": "1.0.0"
@@ -64,7 +62,6 @@ Feature: Creating and reading the Berkshelf lockfile
64
62
  Then the file "Berksfile.lock" should contain JSON:
65
63
  """
66
64
  {
67
- "sha":"ebf27d476739b5aba7e7e8a61de23b3330e20a7d",
68
65
  "sources":{
69
66
  "fake":{
70
67
  "path":"./fake"
@@ -86,7 +83,6 @@ Feature: Creating and reading the Berkshelf lockfile
86
83
  Then the file "Berksfile.lock" should contain JSON:
87
84
  """
88
85
  {
89
- "sha":"80396ed07db133e0192593adebb360c27eed88c2",
90
86
  "sources":{
91
87
  "fake":{
92
88
  "locked_version":"1.0.0"
@@ -109,7 +105,6 @@ Feature: Creating and reading the Berkshelf lockfile
109
105
  And I write to "Berksfile.lock" with:
110
106
  """
111
107
  {
112
- "sha":"e42f8e41a5e646bd86591c5b7ec25442736b87fd",
113
108
  "sources":{
114
109
  "berkshelf-cookbook-fixture":{
115
110
  "locked_version":"1.0.0"
@@ -121,7 +116,6 @@ Feature: Creating and reading the Berkshelf lockfile
121
116
  Then the file "Berksfile.lock" should contain JSON:
122
117
  """
123
118
  {
124
- "sha":"e42f8e41a5e646bd86591c5b7ec25442736b87fd",
125
119
  "sources":{
126
120
  "berkshelf-cookbook-fixture":{
127
121
  "locked_version":"1.0.0"
@@ -142,7 +136,6 @@ Feature: Creating and reading the Berkshelf lockfile
142
136
  And I write to "Berksfile.lock" with:
143
137
  """
144
138
  {
145
- "sha":"3dced4fcd9c3f72b68e746190aaa1140bdc6cc3d",
146
139
  "sources":{
147
140
  "berkshelf-cookbook-fixture":{
148
141
  "locked_version":"0.1.0"
@@ -154,7 +147,6 @@ Feature: Creating and reading the Berkshelf lockfile
154
147
  Then the file "Berksfile.lock" should contain JSON:
155
148
  """
156
149
  {
157
- "sha":"b2714a4f9bdf500cb20267067160a0b3c1d8404c",
158
150
  "sources":{
159
151
  "berkshelf-cookbook-fixture":{
160
152
  "locked_version":"0.2.0"
@@ -174,7 +166,6 @@ Feature: Creating and reading the Berkshelf lockfile
174
166
  And I write to "Berksfile.lock" with:
175
167
  """
176
168
  {
177
- "sha":"c6438d7590f4d695d8abae83ff22586ba6d3a52e",
178
169
  "sources":{
179
170
  "berkshelf-cookbook-fixture":{
180
171
  "locked_version":"1.0.0"
@@ -186,7 +177,6 @@ Feature: Creating and reading the Berkshelf lockfile
186
177
  Then the file "Berksfile.lock" should contain JSON:
187
178
  """
188
179
  {
189
- "sha":"c6438d7590f4d695d8abae83ff22586ba6d3a52e",
190
180
  "sources":{
191
181
  "berkshelf-cookbook-fixture":{
192
182
  "locked_version":"1.0.0"
@@ -207,7 +197,6 @@ Feature: Creating and reading the Berkshelf lockfile
207
197
  Then the file "Berksfile.lock" should contain JSON:
208
198
  """
209
199
  {
210
- "sha": "b8e06c891c824b3e3481df024eb241e1c02572a6",
211
200
  "sources":{
212
201
  "berkshelf-cookbook-fixture":{
213
202
  "git":"git://github.com/RiotGames/berkshelf-cookbook-fixture.git",
@@ -230,7 +219,6 @@ Feature: Creating and reading the Berkshelf lockfile
230
219
  Then the file "Berksfile.lock" should contain JSON:
231
220
  """
232
221
  {
233
- "sha": "310f95bb86ba76b47eef28abc621d0e8de19bbb6",
234
222
  "sources":{
235
223
  "berkshelf-cookbook-fixture":{
236
224
  "git":"git://github.com/RiotGames/berkshelf-cookbook-fixture.git",
@@ -253,7 +241,6 @@ Feature: Creating and reading the Berkshelf lockfile
253
241
  Then the file "Berksfile.lock" should contain JSON:
254
242
  """
255
243
  {
256
- "sha": "ade51e222f569cc299f34ec1100d321f3b230c36",
257
244
  "sources":{
258
245
  "berkshelf-cookbook-fixture":{
259
246
  "git":"git://github.com/RiotGames/berkshelf-cookbook-fixture.git",
@@ -276,7 +263,6 @@ Feature: Creating and reading the Berkshelf lockfile
276
263
  Then the file "Berksfile.lock" should contain JSON:
277
264
  """
278
265
  {
279
- "sha": "3ac97aa503bcebb2b393410aebc176c3c5bed2d4",
280
266
  "sources":{
281
267
  "berkshelf-cookbook-fixture":{
282
268
  "git":"git://github.com/RiotGames/berkshelf-cookbook-fixture.git",
@@ -297,7 +283,6 @@ Feature: Creating and reading the Berkshelf lockfile
297
283
  Then the file "Berksfile.lock" should contain JSON:
298
284
  """
299
285
  {
300
- "sha": "f0b5a9c0230a3ff384badb0c40af1058cde75bee",
301
286
  "sources":{
302
287
  "berkshelf-cookbook-fixture":{
303
288
  "git":"git://github.com/RiotGames/berkshelf-cookbook-fixture.git",
@@ -320,7 +305,6 @@ Feature: Creating and reading the Berkshelf lockfile
320
305
  Then the file "Berksfile.lock" should contain JSON:
321
306
  """
322
307
  {
323
- "sha": "a148a5a75397588393801a2fd55df1325080868c",
324
308
  "sources":{
325
309
  "fake":{
326
310
  "path":"./fake"
@@ -341,7 +325,6 @@ Feature: Creating and reading the Berkshelf lockfile
341
325
  Then the file "Berksfile.lock" should contain JSON:
342
326
  """
343
327
  {
344
- "sha": "a7371143bae509b849bf94e5d65987581bf93133",
345
328
  "sources": {
346
329
  "fake": {
347
330
  "path": "."
@@ -360,7 +343,6 @@ Feature: Creating and reading the Berkshelf lockfile
360
343
  And the cookbook "fake" has the file "Berksfile.lock" with:
361
344
  """
362
345
  {
363
- "sha": "a7371143bae509b849bf94e5d65987581bf93133",
364
346
  "sources": {
365
347
  "fake": {
366
348
  "path": "."
@@ -373,7 +355,6 @@ Feature: Creating and reading the Berkshelf lockfile
373
355
  Then the file "Berksfile.lock" should contain JSON:
374
356
  """
375
357
  {
376
- "sha": "a7371143bae509b849bf94e5d65987581bf93133",
377
358
  "sources": {
378
359
  "fake": {
379
360
  "path": "."
@@ -393,7 +374,6 @@ Feature: Creating and reading the Berkshelf lockfile
393
374
  # Then the file "Berksfile.lock" should contain JSON:
394
375
  # """
395
376
  # {
396
- # "sha": "3232c5ae6f54aee3efc5fdcfce69249a2526822b",
397
377
  # "sources":{
398
378
  # "sudo":{
399
379
  # "site":"opscode",
@@ -20,7 +20,6 @@ Feature: Updating a cookbook defined by a Berksfile
20
20
  Then the file "Berksfile.lock" should contain JSON:
21
21
  """
22
22
  {
23
- "sha":"b2714a4f9bdf500cb20267067160a0b3c1d8404c",
24
23
  "sources":{
25
24
  "berkshelf-cookbook-fixture":{
26
25
  "locked_version":"0.1.0"
@@ -43,7 +42,6 @@ Feature: Updating a cookbook defined by a Berksfile
43
42
  And I write to "Berksfile.lock" with:
44
43
  """
45
44
  {
46
- "sha":"69b2e00e970d2bb6a9b1d09aeb3e6a17ef3df955",
47
45
  "sources":{
48
46
  "berkshelf-cookbook-fixture":{
49
47
  "locked_version":"0.1.0"
@@ -58,7 +56,6 @@ Feature: Updating a cookbook defined by a Berksfile
58
56
  Then the file "Berksfile.lock" should contain JSON:
59
57
  """
60
58
  {
61
- "sha":"69b2e00e970d2bb6a9b1d09aeb3e6a17ef3df955",
62
59
  "sources":{
63
60
  "berkshelf-cookbook-fixture":{
64
61
  "locked_version":"0.2.0"
@@ -84,7 +81,6 @@ Feature: Updating a cookbook defined by a Berksfile
84
81
  And I write to "Berksfile.lock" with:
85
82
  """
86
83
  {
87
- "sha":"69b2e00e970d2bb6a9b1d09aeb3e6a17ef3df955",
88
84
  "sources":{
89
85
  "berkshelf-cookbook-fixture":{
90
86
  "locked_version":"0.1.0"
@@ -99,7 +95,6 @@ Feature: Updating a cookbook defined by a Berksfile
99
95
  Then the file "Berksfile.lock" should contain JSON:
100
96
  """
101
97
  {
102
- "sha":"69b2e00e970d2bb6a9b1d09aeb3e6a17ef3df955",
103
98
  "sources":{
104
99
  "berkshelf-cookbook-fixture":{
105
100
  "locked_version":"0.2.0"
@@ -122,7 +117,6 @@ Feature: Updating a cookbook defined by a Berksfile
122
117
  Given I write to "Berksfile.lock" with:
123
118
  """
124
119
  {
125
- "sha":"23150cfe61b7b86882013c8664883058560b899d",
126
120
  "sources":{
127
121
  "berkshelf-cookbook-fixture":{
128
122
  "locked_version":"0.1.0"
@@ -293,3 +293,26 @@ Feature: Uploading cookbooks to a Chef Server
293
293
  And the Chef server should not have the cookbooks:
294
294
  | ekaf | 2.0.0 |
295
295
  And the exit status should be 0
296
+
297
+ @focus
298
+ Scenario: With unicode characters
299
+ Given a cookbook named "fake"
300
+ And the cookbook "fake" has the file "README.md" with:
301
+ """
302
+ Jamié Wiñsor
303
+ 赛斯瓦戈
304
+ Μιψηαελ Ιωευ
305
+ جوستين كامبل
306
+ """
307
+ And the cookbook "fake" has the file "Berksfile" with:
308
+ """
309
+ site :opscode
310
+ metadata
311
+ """
312
+ When I cd to "fake"
313
+ And I successfully run `berks upload fake`
314
+ Then the output should contain:
315
+ """
316
+ Uploading fake (0.0.0)
317
+ """
318
+ And the exit status should be 0
@@ -89,13 +89,7 @@ module Berkshelf
89
89
  @cached_cookbooks = nil
90
90
  end
91
91
 
92
- # @return [String]
93
- # the shasum for the sources in the Berksfile (or metadata/path locations)
94
- def sha
95
- @sha ||= Digest::SHA1.hexdigest(shaable_contents.join("\n"))
96
- end
97
-
98
- # Add a cookbook source to the Berksfile to be retrieved and have it's dependencies recursively retrieved
92
+ # Add a cookbook dependency to the Berksfile to be retrieved and have it's dependencies recursively retrieved
99
93
  # and resolved.
100
94
  #
101
95
  # @example a cookbook source that will be retrieved from one of the default locations
@@ -196,8 +190,6 @@ module Berkshelf
196
190
  metadata_path = File.expand_path(File.join(path, 'metadata.rb'))
197
191
  metadata = Ridley::Chef::Cookbook::Metadata.from_file(metadata_path)
198
192
 
199
- shaable_contents << File.read(metadata_path)
200
-
201
193
  name = metadata.name.presence || File.basename(File.expand_path(path))
202
194
 
203
195
  add_source(name, nil, { path: path, metadata: true })
@@ -267,7 +259,6 @@ module Berkshelf
267
259
 
268
260
  if options[:path]
269
261
  metadata_file = File.expand_path(File.join(options[:path], 'metadata.rb'))
270
- shaable_contents << File.read(metadata_file)
271
262
  end
272
263
 
273
264
  options[:constraint] = constraint
@@ -385,20 +376,14 @@ module Berkshelf
385
376
  # sources are considered to be "unlocked". If a lockfile is specified, a
386
377
  # definition is created via the following algorithm:
387
378
  #
388
- # - Compare the SHA of the current sources (as JSON) with the last-known
389
- # SHA of the sources.
390
- # - If the SHAs match, the sources have not been updated, so we can rely
391
- # solely on the locked ones.
392
- # - If the SHAs don't match, then the sources have diverged from the
393
- # lockfile, which means some sources are outdated. For each unlocked
394
- # source, see if there exists a locked version that still satisfies
395
- # the version constraint in the Berksfile. If there exists such a
396
- # source, remove it from the list of unlocked sources. If not, then
397
- # either a version constraint has changed, or a new source has been
398
- # added to the Berksfile. In the event that a locked_source exists,
399
- # but it no longer satisfies the constraint, this method will raise
400
- # a {Berkshelf::OutdatedCookbookSource}, and inform the user to run
401
- # <tt>berks update COOKBOOK</tt> to remedy the issue.
379
+ # - For each source, see if there exists a locked version that still
380
+ # satisfies the version constraint in the Berksfile. If
381
+ # there exists such a source, remove it from the list of unlocked
382
+ # sources. If not, then either a version constraint has changed,
383
+ # or a new source has been added to the Berksfile. In the event that
384
+ # a locked_source exists, but it no longer satisfies the constraint,
385
+ # this method will raise a {Berkshelf::OutdatedCookbookSource}, and
386
+ # inform the user to run <tt>berks update COOKBOOK</tt> to remedy the issue.
402
387
  # - Remove any locked sources that no longer exist in the Berksfile
403
388
  # (i.e. a cookbook source was removed from the Berksfile).
404
389
  #
@@ -423,11 +408,7 @@ module Berkshelf
423
408
  #
424
409
  # @return [Array<Berkshelf::CachedCookbook>]
425
410
  def install(options = {})
426
- if self.sha == lockfile.sha
427
- local_sources = locked_sources
428
- else
429
- local_sources = apply_lockfile(sources(options))
430
- end
411
+ local_sources = apply_lockfile(sources(options))
431
412
 
432
413
  resolver = resolve(local_sources)
433
414
  @cached_cookbooks = resolver[:solution]
@@ -437,7 +418,7 @@ module Berkshelf
437
418
 
438
419
  self.class.vendor(@cached_cookbooks, options[:path]) if options[:path]
439
420
 
440
- lockfile.update(local_sources, sha: self.sha)
421
+ lockfile.update(local_sources)
441
422
 
442
423
  self.cached_cookbooks
443
424
  end
@@ -456,8 +437,6 @@ module Berkshelf
456
437
  # Unlock any/all specified cookbooks
457
438
  sources(options).each { |source| lockfile.unlock(source) }
458
439
 
459
- lockfile.reset_sha!
460
-
461
440
  # NOTE: We intentionally do NOT pass options to the installer
462
441
  self.install
463
442
  end
@@ -823,12 +802,5 @@ module Berkshelf
823
802
  end
824
803
  end
825
804
 
826
- # The contents of the files that we want to SHA for caching against
827
- # the lockfile.
828
- #
829
- # @return [Array<String>]
830
- def shaable_contents
831
- @shaable_contents ||= [File.read(self.filepath)]
832
- end
833
805
  end
834
806
  end
@@ -13,10 +13,6 @@ module Berkshelf
13
13
  # the Berksfile for this Lockfile
14
14
  attr_reader :berksfile
15
15
 
16
- # @return [String]
17
- # the last known SHA of the Berksfile
18
- attr_accessor :sha
19
-
20
16
  # Create a new lockfile instance associated with the given Berksfile. If a
21
17
  # Lockfile exists, it is automatically loaded. Otherwise, an empty instance is
22
18
  # created and ready for use.
@@ -34,21 +30,13 @@ module Berkshelf
34
30
  # Load the lockfile from file system.
35
31
  def load!
36
32
  contents = File.read(filepath).strip
37
-
38
33
  hash = parse(contents)
39
- @sha = hash[:sha]
40
34
 
41
35
  hash[:sources].each do |name, options|
42
36
  add(CookbookSource.new(berksfile, name.to_s, options))
43
37
  end
44
38
  end
45
39
 
46
- # Set the sha value to nil to mark that the lockfile is not out of
47
- # sync with the Berksfile.
48
- def reset_sha!
49
- @sha = nil
50
- end
51
-
52
40
  # The list of sources constrained in this lockfile.
53
41
  #
54
42
  # @return [Array<Berkshelf::CookbookSource>]
@@ -86,10 +74,8 @@ module Berkshelf
86
74
  # the list of sources to update
87
75
  # @option options [String] :sha
88
76
  # the sha of the Berksfile updating the sources
89
- def update(sources, options = {})
77
+ def update(sources)
90
78
  reset_sources!
91
- @sha = options[:sha]
92
-
93
79
  sources.each { |source| append(source) }
94
80
  save
95
81
  end
@@ -137,11 +123,9 @@ module Berkshelf
137
123
  #
138
124
  # @return [Hash]
139
125
  # the hash representation of this lockfile
140
- # * :sha [String] the last-known sha for the berksfile
141
126
  # * :sources [Array<Berkshelf::CookbookSource>] the list of sources
142
127
  def to_hash
143
128
  {
144
- sha: sha,
145
129
  sources: @sources
146
130
  }
147
131
  end
@@ -225,8 +209,7 @@ module Berkshelf
225
209
  end
226
210
 
227
211
  {
228
- sha: nil,
229
- sources: sources
212
+ sources: sources,
230
213
  }
231
214
  end
232
215
  end
@@ -1,3 +1,3 @@
1
1
  module Berkshelf
2
- VERSION = "2.0.5"
2
+ VERSION = "2.0.6"
3
3
  end
@@ -1,5 +1,4 @@
1
1
  {
2
- "sha": null,
3
2
  "sources": {
4
3
  }
5
4
  }
@@ -279,10 +279,7 @@ describe Berkshelf::Berksfile do
279
279
  Berkshelf::Resolver.stub(:new).and_return(resolver)
280
280
  Berkshelf::Lockfile.stub(:new).and_return(lockfile)
281
281
 
282
- subject.stub(:sha).and_return('abc123')
283
-
284
282
  lockfile.stub(:sources).and_return([])
285
- lockfile.stub(:sha).and_return('xyz456')
286
283
 
287
284
  resolver.stub(:sources).and_return([])
288
285
  lockfile.stub(:update)
@@ -308,7 +305,7 @@ describe Berkshelf::Berksfile do
308
305
 
309
306
  it 'writes a lockfile with the resolvers sources' do
310
307
  resolver.should_receive(:resolve)
311
- lockfile.should_receive(:update).with([], sha: 'abc123')
308
+ lockfile.should_receive(:update).with([])
312
309
 
313
310
  subject.install
314
311
  end
@@ -15,10 +15,6 @@ describe Berkshelf::Lockfile do
15
15
  }.to_not raise_error
16
16
  end
17
17
 
18
- it 'has the correct sha' do
19
- expect(subject.sha).to eq('6b76225554cc1f7c0aea0f8b3f10c6743aeba67e')
20
- end
21
-
22
18
  it 'has the correct sources' do
23
19
  expect(subject).to have_source 'build-essential'
24
20
  expect(subject).to have_source 'chef-client'
@@ -29,12 +25,6 @@ describe Berkshelf::Lockfile do
29
25
 
30
26
  subject { Berkshelf::Lockfile.new(berksfile) }
31
27
 
32
- describe '#reset_sha!' do
33
- it 'sets the sha to nil' do
34
- expect { subject.reset_sha! }.to change { subject.sha }.to nil
35
- end
36
- end
37
-
38
28
  describe '#sources' do
39
29
  it 'returns an array' do
40
30
  expect(subject.sources).to be_a(Array)
@@ -67,12 +57,6 @@ describe Berkshelf::Lockfile do
67
57
  subject.update([])
68
58
  end
69
59
 
70
- it 'updates the sha' do
71
- expect {
72
- subject.update([])
73
- }.to change { subject.sha }
74
- end
75
-
76
60
  it 'appends each of the sources' do
77
61
  source = double('source')
78
62
  subject.should_receive(:append).with(source).once
@@ -133,10 +117,6 @@ describe Berkshelf::Lockfile do
133
117
  describe '#to_hash' do
134
118
  let(:hash) { subject.to_hash }
135
119
 
136
- it 'has the `:sha` key' do
137
- expect(hash).to have_key(:sha)
138
- end
139
-
140
120
  it 'has the `:sources` key' do
141
121
  expect(hash).to have_key(:sources)
142
122
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: berkshelf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.5
4
+ version: 2.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,14 +13,14 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2013-06-21 00:00:00.000000000 Z
16
+ date: 2013-07-03 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: activesupport
20
20
  requirement: !ruby/object:Gem::Requirement
21
21
  none: false
22
22
  requirements:
23
- - - ! '>='
23
+ - - ~>
24
24
  - !ruby/object:Gem::Version
25
25
  version: 3.2.0
26
26
  type: :runtime
@@ -28,7 +28,7 @@ dependencies:
28
28
  version_requirements: !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
- - - ! '>='
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: 3.2.0
34
34
  - !ruby/object:Gem::Dependency