berkshelf 2.0.4 → 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +6 -0
- data/features/lockfile.feature +34 -11
- data/features/update_command.feature +10 -20
- data/lib/berkshelf/cookbook_source.rb +0 -4
- data/lib/berkshelf/downloader.rb +1 -22
- data/lib/berkshelf/errors.rb +17 -0
- data/lib/berkshelf/lockfile.rb +21 -12
- data/lib/berkshelf/resolver.rb +11 -2
- data/lib/berkshelf/version.rb +1 -1
- data/spec/unit/berkshelf/cookbook_source_spec.rb +1 -7
- data/spec/unit/berkshelf/resolver_spec.rb +2 -0
- metadata +2 -2
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
# 2.0.5
|
2
|
+
|
3
|
+
* Improve speed of resolution when a lockfile is present
|
4
|
+
* Gracefully fail when a lockfile is present but empty
|
5
|
+
* Fix issue where locked version was not honored if the cookbook store was empty
|
6
|
+
|
1
7
|
# 2.0.4
|
2
8
|
|
3
9
|
* Fix bug where community cookbooks compressed with bzip2 would not download and install
|
data/features/lockfile.feature
CHANGED
@@ -17,7 +17,6 @@ Feature: Creating and reading the Berkshelf lockfile
|
|
17
17
|
"sha":"80396ed07db133e0192593adebb360c27eed88c2",
|
18
18
|
"sources":{
|
19
19
|
"fake":{
|
20
|
-
"constraint":"= 1.0.0",
|
21
20
|
"locked_version":"1.0.0"
|
22
21
|
}
|
23
22
|
}
|
@@ -44,7 +43,6 @@ Feature: Creating and reading the Berkshelf lockfile
|
|
44
43
|
"sha": "374a3d22920abae4a6d620a14a32b90d8babda8f",
|
45
44
|
"sources": {
|
46
45
|
"fake": {
|
47
|
-
"constraint": "= 1.0.0",
|
48
46
|
"locked_version": "1.0.0"
|
49
47
|
}
|
50
48
|
}
|
@@ -69,7 +67,6 @@ Feature: Creating and reading the Berkshelf lockfile
|
|
69
67
|
"sha":"ebf27d476739b5aba7e7e8a61de23b3330e20a7d",
|
70
68
|
"sources":{
|
71
69
|
"fake":{
|
72
|
-
"constraint":"= 0.0.0",
|
73
70
|
"path":"./fake"
|
74
71
|
}
|
75
72
|
}
|
@@ -92,11 +89,9 @@ Feature: Creating and reading the Berkshelf lockfile
|
|
92
89
|
"sha":"80396ed07db133e0192593adebb360c27eed88c2",
|
93
90
|
"sources":{
|
94
91
|
"fake":{
|
95
|
-
"constraint":"= 1.0.0",
|
96
92
|
"locked_version":"1.0.0"
|
97
93
|
},
|
98
94
|
"dep":{
|
99
|
-
"constraint":"~> 1.0.0",
|
100
95
|
"locked_version":"1.0.0"
|
101
96
|
}
|
102
97
|
}
|
@@ -117,7 +112,6 @@ Feature: Creating and reading the Berkshelf lockfile
|
|
117
112
|
"sha":"e42f8e41a5e646bd86591c5b7ec25442736b87fd",
|
118
113
|
"sources":{
|
119
114
|
"berkshelf-cookbook-fixture":{
|
120
|
-
"constraint":"~> 1.0.0",
|
121
115
|
"locked_version":"1.0.0"
|
122
116
|
}
|
123
117
|
}
|
@@ -130,7 +124,6 @@ Feature: Creating and reading the Berkshelf lockfile
|
|
130
124
|
"sha":"e42f8e41a5e646bd86591c5b7ec25442736b87fd",
|
131
125
|
"sources":{
|
132
126
|
"berkshelf-cookbook-fixture":{
|
133
|
-
"constraint":"~> 1.0.0",
|
134
127
|
"locked_version":"1.0.0"
|
135
128
|
}
|
136
129
|
}
|
@@ -152,7 +145,6 @@ Feature: Creating and reading the Berkshelf lockfile
|
|
152
145
|
"sha":"3dced4fcd9c3f72b68e746190aaa1140bdc6cc3d",
|
153
146
|
"sources":{
|
154
147
|
"berkshelf-cookbook-fixture":{
|
155
|
-
"constraint":"~> 0.1",
|
156
148
|
"locked_version":"0.1.0"
|
157
149
|
}
|
158
150
|
}
|
@@ -165,7 +157,6 @@ Feature: Creating and reading the Berkshelf lockfile
|
|
165
157
|
"sha":"b2714a4f9bdf500cb20267067160a0b3c1d8404c",
|
166
158
|
"sources":{
|
167
159
|
"berkshelf-cookbook-fixture":{
|
168
|
-
"constraint":"~> 0.1",
|
169
160
|
"locked_version":"0.2.0"
|
170
161
|
}
|
171
162
|
}
|
@@ -186,7 +177,6 @@ Feature: Creating and reading the Berkshelf lockfile
|
|
186
177
|
"sha":"c6438d7590f4d695d8abae83ff22586ba6d3a52e",
|
187
178
|
"sources":{
|
188
179
|
"berkshelf-cookbook-fixture":{
|
189
|
-
"constraint":"= 1.0.0",
|
190
180
|
"locked_version":"1.0.0"
|
191
181
|
}
|
192
182
|
}
|
@@ -199,7 +189,6 @@ Feature: Creating and reading the Berkshelf lockfile
|
|
199
189
|
"sha":"c6438d7590f4d695d8abae83ff22586ba6d3a52e",
|
200
190
|
"sources":{
|
201
191
|
"berkshelf-cookbook-fixture":{
|
202
|
-
"constraint":"= 1.0.0",
|
203
192
|
"locked_version":"1.0.0"
|
204
193
|
}
|
205
194
|
}
|
@@ -441,3 +430,37 @@ Feature: Creating and reading the Berkshelf lockfile
|
|
441
430
|
Try running `berks update berkshelf-cookbook-fixture, which will try to find 'berkshelf-cookbook-fixture' matching '~> 1.3.0'
|
442
431
|
"""
|
443
432
|
And the CLI should exit with the status code for error "OutdatedCookbookSource"
|
433
|
+
|
434
|
+
Scenario: Installing when the Lockfile is empty
|
435
|
+
Given the cookbook store has the cookbooks:
|
436
|
+
| fake | 1.0.0 |
|
437
|
+
And I write to "Berksfile" with:
|
438
|
+
"""
|
439
|
+
site :opscode
|
440
|
+
cookbook 'fake', '1.0.0'
|
441
|
+
"""
|
442
|
+
And an empty file named "Berksfile.lock"
|
443
|
+
When I successfully run `berks install`
|
444
|
+
Then the output should contain:
|
445
|
+
"""
|
446
|
+
Using fake (1.0.0)
|
447
|
+
"""
|
448
|
+
And the exit status should be 0
|
449
|
+
|
450
|
+
Scenario: Installing when the Lockfile is in a bad state
|
451
|
+
Given I write to "Berksfile" with:
|
452
|
+
"""
|
453
|
+
site :opscode
|
454
|
+
cookbook 'fake', '1.0.0'
|
455
|
+
"""
|
456
|
+
Given I write to "Berksfile.lock" with:
|
457
|
+
"""
|
458
|
+
this is totally not valid
|
459
|
+
"""
|
460
|
+
When I run `berks install`
|
461
|
+
Then the output should contain:
|
462
|
+
"""
|
463
|
+
Error reading the Berkshelf lockfile `Berksfile.lock` (JSON::ParserError)
|
464
|
+
"""
|
465
|
+
And the CLI should exit with the status code for error "LockfileParserError"
|
466
|
+
|
@@ -23,8 +23,7 @@ Feature: Updating a cookbook defined by a Berksfile
|
|
23
23
|
"sha":"b2714a4f9bdf500cb20267067160a0b3c1d8404c",
|
24
24
|
"sources":{
|
25
25
|
"berkshelf-cookbook-fixture":{
|
26
|
-
"locked_version":"0.1.0"
|
27
|
-
"constraint":"~> 0.1"
|
26
|
+
"locked_version":"0.1.0"
|
28
27
|
}
|
29
28
|
}
|
30
29
|
}
|
@@ -47,12 +46,10 @@ Feature: Updating a cookbook defined by a Berksfile
|
|
47
46
|
"sha":"69b2e00e970d2bb6a9b1d09aeb3e6a17ef3df955",
|
48
47
|
"sources":{
|
49
48
|
"berkshelf-cookbook-fixture":{
|
50
|
-
"locked_version":"0.1.0"
|
51
|
-
"constraint":"~> 0.1"
|
49
|
+
"locked_version":"0.1.0"
|
52
50
|
},
|
53
51
|
"hostsfile":{
|
54
|
-
"locked_version":"1.0.1"
|
55
|
-
"constraint":"= 1.0.1"
|
52
|
+
"locked_version":"1.0.1"
|
56
53
|
}
|
57
54
|
}
|
58
55
|
}
|
@@ -64,12 +61,10 @@ Feature: Updating a cookbook defined by a Berksfile
|
|
64
61
|
"sha":"69b2e00e970d2bb6a9b1d09aeb3e6a17ef3df955",
|
65
62
|
"sources":{
|
66
63
|
"berkshelf-cookbook-fixture":{
|
67
|
-
"locked_version":"0.2.0"
|
68
|
-
"constraint":"~> 0.1"
|
64
|
+
"locked_version":"0.2.0"
|
69
65
|
},
|
70
66
|
"hostsfile":{
|
71
|
-
"locked_version":"1.0.1"
|
72
|
-
"constraint":"~> 1.0.0"
|
67
|
+
"locked_version":"1.0.1"
|
73
68
|
}
|
74
69
|
}
|
75
70
|
}
|
@@ -92,12 +87,10 @@ Feature: Updating a cookbook defined by a Berksfile
|
|
92
87
|
"sha":"69b2e00e970d2bb6a9b1d09aeb3e6a17ef3df955",
|
93
88
|
"sources":{
|
94
89
|
"berkshelf-cookbook-fixture":{
|
95
|
-
"locked_version":"0.1.0"
|
96
|
-
"constraint":"~> 0.1"
|
90
|
+
"locked_version":"0.1.0"
|
97
91
|
},
|
98
92
|
"hostsfile":{
|
99
|
-
"locked_version":"1.0.0"
|
100
|
-
"constraint":"~> 1.0.0"
|
93
|
+
"locked_version":"1.0.0"
|
101
94
|
}
|
102
95
|
}
|
103
96
|
}
|
@@ -109,12 +102,10 @@ Feature: Updating a cookbook defined by a Berksfile
|
|
109
102
|
"sha":"69b2e00e970d2bb6a9b1d09aeb3e6a17ef3df955",
|
110
103
|
"sources":{
|
111
104
|
"berkshelf-cookbook-fixture":{
|
112
|
-
"locked_version":"0.2.0"
|
113
|
-
"constraint":"~> 0.1"
|
105
|
+
"locked_version":"0.2.0"
|
114
106
|
},
|
115
107
|
"hostsfile":{
|
116
|
-
"locked_version":"1.0.0"
|
117
|
-
"constraint":"~> 1.0.0"
|
108
|
+
"locked_version":"1.0.0"
|
118
109
|
}
|
119
110
|
}
|
120
111
|
}
|
@@ -134,8 +125,7 @@ Feature: Updating a cookbook defined by a Berksfile
|
|
134
125
|
"sha":"23150cfe61b7b86882013c8664883058560b899d",
|
135
126
|
"sources":{
|
136
127
|
"berkshelf-cookbook-fixture":{
|
137
|
-
"locked_version":"0.1.0"
|
138
|
-
"constraint":"~> 0.1"
|
128
|
+
"locked_version":"0.1.0"
|
139
129
|
}
|
140
130
|
}
|
141
131
|
}
|
@@ -198,10 +198,6 @@ module Berkshelf
|
|
198
198
|
h[:locked_version] = locked_version.to_s
|
199
199
|
end
|
200
200
|
|
201
|
-
unless version_constraint.to_s == DEFAULT_CONSTRAINT
|
202
|
-
h[:constraint] = version_constraint.to_s
|
203
|
-
end
|
204
|
-
|
205
201
|
if location.kind_of?(SiteLocation)
|
206
202
|
h[:site] = location.api_uri if location.api_uri != CommunityREST::V1_API
|
207
203
|
end
|
data/lib/berkshelf/downloader.rb
CHANGED
@@ -116,31 +116,10 @@ module Berkshelf
|
|
116
116
|
# @return [Berkshelf::CachedCookbook, nil]
|
117
117
|
# the downloaded cached cookbook, or nil if one was not found
|
118
118
|
def download_location(source, location, raise_if_not_found = false)
|
119
|
-
|
119
|
+
location.download(storage_path)
|
120
120
|
rescue Berkshelf::CookbookNotFound
|
121
121
|
raise if raise_if_not_found
|
122
122
|
nil
|
123
123
|
end
|
124
|
-
|
125
|
-
# Load the cached cookbook from the cookbook store.
|
126
|
-
#
|
127
|
-
# @param [Berkshelf::CookbookSource] source
|
128
|
-
# the source to find in the cache
|
129
|
-
#
|
130
|
-
# @return [Berkshelf::CachedCookbook, nil]
|
131
|
-
def from_cache(source)
|
132
|
-
# Can't safely read a git location from cache
|
133
|
-
return nil if source.location.kind_of?(Berkshelf::GitLocation)
|
134
|
-
|
135
|
-
if source.locked_version
|
136
|
-
cookbook = cookbook_store.cookbook_path(source.name, source.locked_version)
|
137
|
-
path = File.expand_path(File.join(storage_path, cookbook))
|
138
|
-
|
139
|
-
return nil unless File.exists?(path)
|
140
|
-
return Berkshelf::CachedCookbook.from_path(path, name: source.name)
|
141
|
-
end
|
142
|
-
|
143
|
-
cookbook_store.satisfy(source.name, source.version_constraint)
|
144
|
-
end
|
145
124
|
end
|
146
125
|
end
|
data/lib/berkshelf/errors.rb
CHANGED
@@ -379,4 +379,21 @@ module Berkshelf
|
|
379
379
|
"No #{@type.capitalize} config file found at: '#{@path}'!"
|
380
380
|
end
|
381
381
|
end
|
382
|
+
|
383
|
+
class LockfileParserError < BerkshelfError
|
384
|
+
status_code(136)
|
385
|
+
|
386
|
+
# @param [String] lockfile
|
387
|
+
# the path to the Lockfile
|
388
|
+
# @param [~Exception] original
|
389
|
+
# the original exception class
|
390
|
+
def initialize(lockfile, original)
|
391
|
+
@lockfile = Pathname.new(lockfile.to_s).basename.to_s
|
392
|
+
@original = original
|
393
|
+
end
|
394
|
+
|
395
|
+
def to_s
|
396
|
+
"Error reading the Berkshelf lockfile `#{@lockfile}` (#{@original.class})"
|
397
|
+
end
|
398
|
+
end
|
382
399
|
end
|
data/lib/berkshelf/lockfile.rb
CHANGED
@@ -33,19 +33,9 @@ module Berkshelf
|
|
33
33
|
|
34
34
|
# Load the lockfile from file system.
|
35
35
|
def load!
|
36
|
-
contents = File.read(filepath)
|
37
|
-
|
38
|
-
begin
|
39
|
-
hash = JSON.parse(contents, symbolize_names: true)
|
40
|
-
rescue JSON::ParserError
|
41
|
-
if contents =~ /^cookbook ["'](.+)["']/
|
42
|
-
Berkshelf.ui.warn 'You are using the old lockfile format. Attempting to convert...'
|
43
|
-
hash = LockfileLegacy.parse(berksfile, contents)
|
44
|
-
else
|
45
|
-
raise
|
46
|
-
end
|
47
|
-
end
|
36
|
+
contents = File.read(filepath).strip
|
48
37
|
|
38
|
+
hash = parse(contents)
|
49
39
|
@sha = hash[:sha]
|
50
40
|
|
51
41
|
hash[:sources].each do |name, options|
|
@@ -168,6 +158,25 @@ module Berkshelf
|
|
168
158
|
|
169
159
|
private
|
170
160
|
|
161
|
+
# Parse the given string as JSON.
|
162
|
+
#
|
163
|
+
# @param [String] contents
|
164
|
+
#
|
165
|
+
# @return [Hash]
|
166
|
+
def parse(contents)
|
167
|
+
# Ruby's JSON.parse cannot handle an empty string/file
|
168
|
+
return { sha: nil, sources: [] } if contents.strip.empty?
|
169
|
+
|
170
|
+
JSON.parse(contents, symbolize_names: true)
|
171
|
+
rescue Exception => e
|
172
|
+
if e.class == JSON::ParserError && contents =~ /^cookbook ["'](.+)["']/
|
173
|
+
Berkshelf.ui.warn 'You are using the old lockfile format. Attempting to convert...'
|
174
|
+
return LockfileLegacy.parse(berksfile, contents)
|
175
|
+
else
|
176
|
+
raise Berkshelf::LockfileParserError.new(filepath, e)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
171
180
|
# Save the contents of the lockfile to disk.
|
172
181
|
def save
|
173
182
|
File.open(filepath, 'w') do |file|
|
data/lib/berkshelf/resolver.rb
CHANGED
@@ -154,9 +154,13 @@ module Berkshelf
|
|
154
154
|
# @return [Boolean]
|
155
155
|
def use_source(source)
|
156
156
|
name = source.name
|
157
|
-
|
157
|
+
locked = source.locked_version
|
158
158
|
location = source.location
|
159
159
|
|
160
|
+
# Lock the version constraint if a locked version was supplied
|
161
|
+
source.version_constraint = Solve::Constraint.new(locked.to_s) if locked
|
162
|
+
constraint = source.version_constraint
|
163
|
+
|
160
164
|
if source.downloaded?
|
161
165
|
cached = source.cached_cookbook
|
162
166
|
location.validate_cached(cached)
|
@@ -165,7 +169,12 @@ module Berkshelf
|
|
165
169
|
elsif location.is_a?(GitLocation)
|
166
170
|
false
|
167
171
|
else
|
168
|
-
|
172
|
+
# If a locked version if specified, it must exist
|
173
|
+
if locked
|
174
|
+
cached = downloader.cookbook_store.cookbook(name, locked)
|
175
|
+
else
|
176
|
+
cached = downloader.cookbook_store.satisfy(name, constraint)
|
177
|
+
end
|
169
178
|
|
170
179
|
if cached
|
171
180
|
get_source(source).cached_cookbook = cached
|
data/lib/berkshelf/version.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
describe Berkshelf::CookbookSource do
|
@@ -260,13 +261,6 @@ describe Berkshelf::CookbookSource do
|
|
260
261
|
end
|
261
262
|
end
|
262
263
|
|
263
|
-
it 'includes the constraint' do
|
264
|
-
subject.version_constraint = '~> 1.0.0'
|
265
|
-
|
266
|
-
expect(hash).to have_key(:constraint)
|
267
|
-
expect(hash[:constraint]).to eq('~> 1.0.0')
|
268
|
-
end
|
269
|
-
|
270
264
|
it 'includes the locked version' do
|
271
265
|
subject.cached_cookbook = double('cached', version: '1.2.3')
|
272
266
|
|
@@ -7,6 +7,8 @@ describe Berkshelf::Resolver, :chef_server, vcr: { record: :new_episodes, serial
|
|
7
7
|
double('source',
|
8
8
|
name: 'mysql',
|
9
9
|
version_constraint: Solve::Constraint.new('= 1.2.4'),
|
10
|
+
:version_constraint= => nil,
|
11
|
+
locked_version: '1.2.4',
|
10
12
|
downloaded?: true,
|
11
13
|
cached_cookbook: double('mysql-cookbook',
|
12
14
|
name: 'mysql-1.2.4',
|
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.
|
4
|
+
version: 2.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2013-06-
|
16
|
+
date: 2013-06-21 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: activesupport
|