berkshelf 1.0.4 → 1.1.0.rc1
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.
- data/.rbenv-version +1 -1
- data/.rvmrc +1 -0
- data/features/{install.feature → install_command.feature} +46 -34
- data/features/list_command.feature +24 -0
- data/features/outdated_command.feature +56 -0
- data/features/show_command.feature +26 -0
- data/features/step_definitions/chef_server_steps.rb +6 -0
- data/features/step_definitions/cli_steps.rb +0 -4
- data/features/support/env.rb +4 -4
- data/features/update_command.feature +55 -0
- data/features/upload_command.feature +197 -0
- data/lib/berkshelf/berksfile.rb +99 -3
- data/lib/berkshelf/cached_cookbook.rb +4 -0
- data/lib/berkshelf/cli.rb +89 -14
- data/lib/berkshelf/errors.rb +31 -0
- data/lib/berkshelf/locations/github_location.rb +1 -1
- data/lib/berkshelf/lockfile.rb +29 -17
- data/lib/berkshelf/vagrant/action/clean.rb +2 -0
- data/lib/berkshelf/vagrant/action/install.rb +2 -0
- data/lib/berkshelf/vagrant/action/upload.rb +2 -0
- data/lib/berkshelf/version.rb +1 -1
- data/spec/support/chef_api.rb +4 -1
- data/spec/unit/berkshelf/errors_spec.rb +14 -0
- data/spec/unit/berkshelf/init_generator_spec.rb +3 -1
- metadata +18 -12
- data/features/update.feature +0 -19
@@ -69,3 +69,200 @@ Feature: upload command
|
|
69
69
|
And the Chef server should have the cookbooks:
|
70
70
|
| artifact | 0.9.8 |
|
71
71
|
And the exit status should be 0
|
72
|
+
|
73
|
+
@chef_server @slow_process
|
74
|
+
Scenario: Running the upload command for a single cookbook
|
75
|
+
Given I write to "Berksfile" with:
|
76
|
+
"""
|
77
|
+
cookbook "build-essential", "1.2.0"
|
78
|
+
cookbook "mysql", "1.2.4"
|
79
|
+
"""
|
80
|
+
And I successfully run `berks install`
|
81
|
+
And the Chef server does not have the cookbooks:
|
82
|
+
| mysql | 1.2.4 |
|
83
|
+
| openssl | 1.0.0 |
|
84
|
+
| build-essential | 1.2.0 |
|
85
|
+
When I run `berks upload mysql`
|
86
|
+
Then the output should contain "Uploading mysql (1.2.4)"
|
87
|
+
And the output should contain "Uploading openssl (1.0.0)"
|
88
|
+
And the output should not contain "Uploading build-essential (1.2.0)"
|
89
|
+
And the Chef server should have the cookbooks:
|
90
|
+
| mysql | 1.2.4 |
|
91
|
+
| openssl | 1.0.0 |
|
92
|
+
And the Chef server should not have the cookbooks:
|
93
|
+
| build-essential | 1.2.0 |
|
94
|
+
And the exit status should be 0
|
95
|
+
|
96
|
+
@chef_server @slow_process
|
97
|
+
Scenario: Running the upload command with multiple cookbooks
|
98
|
+
Given I write to "Berksfile" with:
|
99
|
+
"""
|
100
|
+
cookbook "build-essential"
|
101
|
+
cookbook "chef-client"
|
102
|
+
cookbook "database"
|
103
|
+
cookbook "editor"
|
104
|
+
cookbook "git"
|
105
|
+
cookbook "known_host"
|
106
|
+
cookbook "networking_basic"
|
107
|
+
cookbook "vim"
|
108
|
+
"""
|
109
|
+
And I successfully run `berks install`
|
110
|
+
And the Chef server does not have the cookbooks:
|
111
|
+
| build-essential |
|
112
|
+
| chef-client |
|
113
|
+
| database |
|
114
|
+
| editor |
|
115
|
+
| git |
|
116
|
+
| known_host |
|
117
|
+
| networking_basic |
|
118
|
+
| vim |
|
119
|
+
When I run `berks upload build-essential chef-client database`
|
120
|
+
Then the output should contain "Uploading build-essential"
|
121
|
+
And the output should contain "Uploading chef-client"
|
122
|
+
And the output should contain "Uploading database"
|
123
|
+
And the output should not contain "Uploading editor"
|
124
|
+
And the output should not contain "Uploading git"
|
125
|
+
And the output should not contain "Uploading known_host"
|
126
|
+
And the output should not contain "Uploading networking_basic"
|
127
|
+
And the output should not contain "Uploading vim"
|
128
|
+
And the Chef server should have the cookbooks:
|
129
|
+
| build_essential |
|
130
|
+
| chef-client |
|
131
|
+
| database |
|
132
|
+
And the Chef server should not have the cookbooks:
|
133
|
+
| editor |
|
134
|
+
| git |
|
135
|
+
| known_host |
|
136
|
+
| networking_basic |
|
137
|
+
| vim |
|
138
|
+
And the exit status should be 0
|
139
|
+
|
140
|
+
@chef_server @slow_process
|
141
|
+
Scenario: Running the upload command with the :only option
|
142
|
+
Given I write to "Berksfile" with:
|
143
|
+
"""
|
144
|
+
group :core do
|
145
|
+
cookbook "build-essential"
|
146
|
+
cookbook "chef-client"
|
147
|
+
end
|
148
|
+
|
149
|
+
group :system do
|
150
|
+
cookbook "database"
|
151
|
+
cookbook "editor"
|
152
|
+
end
|
153
|
+
"""
|
154
|
+
And I successfully run `berks install`
|
155
|
+
And the Chef server does not have the cookbooks:
|
156
|
+
| build-essential |
|
157
|
+
| chef-client |
|
158
|
+
| database |
|
159
|
+
| editor |
|
160
|
+
When I run `berks upload --only core`
|
161
|
+
Then the output should contain "Uploading build-essential"
|
162
|
+
And the output should contain "Uploading chef-client"
|
163
|
+
And the output should not contain "Uploading database"
|
164
|
+
And the output should not contain "Uploading editor"
|
165
|
+
And the Chef server should have the cookbooks:
|
166
|
+
| build_essential |
|
167
|
+
| chef-client |
|
168
|
+
And the Chef server should not have the cookbooks:
|
169
|
+
| database |
|
170
|
+
| editor |
|
171
|
+
And the exit status should be 0
|
172
|
+
|
173
|
+
@chef_server @slow_process
|
174
|
+
Scenario: Running the upload command with the :only option multiple
|
175
|
+
Given I write to "Berksfile" with:
|
176
|
+
"""
|
177
|
+
group :core do
|
178
|
+
cookbook "build-essential"
|
179
|
+
cookbook "chef-client"
|
180
|
+
end
|
181
|
+
|
182
|
+
group :system do
|
183
|
+
cookbook "database"
|
184
|
+
cookbook "editor"
|
185
|
+
end
|
186
|
+
"""
|
187
|
+
And I successfully run `berks install`
|
188
|
+
And the Chef server does not have the cookbooks:
|
189
|
+
| build-essential |
|
190
|
+
| chef-client |
|
191
|
+
| database |
|
192
|
+
| editor |
|
193
|
+
When I run `berks upload --only core system`
|
194
|
+
Then the output should contain "Uploading build-essential"
|
195
|
+
And the output should contain "Uploading chef-client"
|
196
|
+
And the output should contain "Uploading database"
|
197
|
+
And the output should contain "Uploading editor"
|
198
|
+
And the Chef server should have the cookbooks:
|
199
|
+
| build_essential |
|
200
|
+
| chef-client |
|
201
|
+
| database |
|
202
|
+
| editor |
|
203
|
+
And the exit status should be 0
|
204
|
+
|
205
|
+
@chef_server @slow_process
|
206
|
+
Scenario: Running the upload command with the :except option
|
207
|
+
Given I write to "Berksfile" with:
|
208
|
+
"""
|
209
|
+
group :core do
|
210
|
+
cookbook "build-essential"
|
211
|
+
cookbook "chef-client"
|
212
|
+
end
|
213
|
+
|
214
|
+
group :system do
|
215
|
+
cookbook "database"
|
216
|
+
cookbook "editor"
|
217
|
+
end
|
218
|
+
"""
|
219
|
+
And I successfully run `berks install`
|
220
|
+
And the Chef server does not have the cookbooks:
|
221
|
+
| build-essential |
|
222
|
+
| chef-client |
|
223
|
+
| database |
|
224
|
+
| editor |
|
225
|
+
When I run `berks upload --except core`
|
226
|
+
Then the output should not contain "Uploading build-essential"
|
227
|
+
And the output should not contain "Uploading chef-client"
|
228
|
+
And the output should contain "Uploading database"
|
229
|
+
And the output should contain "Uploading editor"
|
230
|
+
And the Chef server should not have the cookbooks:
|
231
|
+
| build_essential |
|
232
|
+
| chef-client |
|
233
|
+
And the Chef server should have the cookbooks:
|
234
|
+
| database |
|
235
|
+
| editor |
|
236
|
+
And the exit status should be 0
|
237
|
+
|
238
|
+
@chef_server @slow_process
|
239
|
+
Scenario: Running the upload command with the :except option multiple
|
240
|
+
Given I write to "Berksfile" with:
|
241
|
+
"""
|
242
|
+
group :core do
|
243
|
+
cookbook "build-essential"
|
244
|
+
cookbook "chef-client"
|
245
|
+
end
|
246
|
+
|
247
|
+
group :system do
|
248
|
+
cookbook "database"
|
249
|
+
cookbook "editor"
|
250
|
+
end
|
251
|
+
"""
|
252
|
+
And I successfully run `berks install`
|
253
|
+
And the Chef server does not have the cookbooks:
|
254
|
+
| build-essential |
|
255
|
+
| chef-client |
|
256
|
+
| database |
|
257
|
+
| editor |
|
258
|
+
When I run `berks upload --except core system`
|
259
|
+
Then the output should not contain "Uploading build-essential"
|
260
|
+
And the output should not contain "Uploading chef-client"
|
261
|
+
And the output should not contain "Uploading database"
|
262
|
+
And the output should not contain "Uploading editor"
|
263
|
+
And the Chef server should not have the cookbooks:
|
264
|
+
| build_essential |
|
265
|
+
| chef-client |
|
266
|
+
| database |
|
267
|
+
| editor |
|
268
|
+
And the exit status should be 0
|
data/lib/berkshelf/berksfile.rb
CHANGED
@@ -239,7 +239,11 @@ module Berkshelf
|
|
239
239
|
# @return [Array<Berkshelf::CookbookSource]
|
240
240
|
def add_source(name, constraint = nil, options = {})
|
241
241
|
if has_source?(name)
|
242
|
-
|
242
|
+
# Only raise an exception if the source is a true duplicate
|
243
|
+
groups = (options[:group].nil? || options[:group].empty?) ? [:default] : options[:group]
|
244
|
+
if !(@sources[name].groups & groups).empty?
|
245
|
+
raise DuplicateSourceDefined, "Berksfile contains multiple sources named '#{name}'. Use only one, or put them in different groups."
|
246
|
+
end
|
243
247
|
end
|
244
248
|
|
245
249
|
options[:constraint] = constraint
|
@@ -269,6 +273,8 @@ module Berkshelf
|
|
269
273
|
# @option options [Symbol, Array] :only
|
270
274
|
# Group(s) to include which will cause any sources marked as a member of the
|
271
275
|
# group to be installed and all others to be ignored
|
276
|
+
# @option cookbooks [String, Array] :cookbooks
|
277
|
+
# Names of the cookbooks to retrieve sources for
|
272
278
|
#
|
273
279
|
# @raise [Berkshelf::ArgumentError] if a value for both :except and :only is provided
|
274
280
|
#
|
@@ -276,12 +282,18 @@ module Berkshelf
|
|
276
282
|
def sources(options = {})
|
277
283
|
l_sources = @sources.collect { |name, source| source }.flatten
|
278
284
|
|
279
|
-
|
280
|
-
|
285
|
+
cookbooks = Array(options.fetch(:cookbooks, nil))
|
286
|
+
except = Array(options.fetch(:except, nil)).collect(&:to_sym)
|
287
|
+
only = Array(options.fetch(:only, nil)).collect(&:to_sym)
|
281
288
|
|
282
289
|
case
|
283
290
|
when !except.empty? && !only.empty?
|
284
291
|
raise Berkshelf::ArgumentError, "Cannot specify both :except and :only"
|
292
|
+
when !cookbooks.empty?
|
293
|
+
if !except.empty? && !only.empty?
|
294
|
+
Berkshelf.ui.warn "Cookbooks were specified, ignoring :except and :only"
|
295
|
+
end
|
296
|
+
l_sources.select { |source| options[:cookbooks].include?(source.name) }
|
285
297
|
when !except.empty?
|
286
298
|
l_sources.select { |source| (except & source.groups).empty? }
|
287
299
|
when !only.empty?
|
@@ -352,6 +364,75 @@ module Berkshelf
|
|
352
364
|
self.cached_cookbooks
|
353
365
|
end
|
354
366
|
|
367
|
+
# @option options [Symbol, Array] :except
|
368
|
+
# Group(s) to exclude which will cause any sources marked as a member of the
|
369
|
+
# group to not be installed
|
370
|
+
# @option options [Symbol, Array] :only
|
371
|
+
# Group(s) to include which will cause any sources marked as a member of the
|
372
|
+
# group to be installed and all others to be ignored
|
373
|
+
# @option cookbooks [String, Array] :cookbooks
|
374
|
+
# Names of the cookbooks to retrieve sources for
|
375
|
+
def update(options = {})
|
376
|
+
resolver = Resolver.new(
|
377
|
+
self.downloader,
|
378
|
+
sources: sources(options)
|
379
|
+
)
|
380
|
+
|
381
|
+
cookbooks = resolver.resolve
|
382
|
+
sources = resolver.sources
|
383
|
+
missing_cookbooks = (options[:cookbooks] - cookbooks.map(&:cookbook_name))
|
384
|
+
|
385
|
+
unless missing_cookbooks.empty?
|
386
|
+
raise Berkshelf::CookbookNotFound, "Could not find cookbooks #{missing_cookbooks.collect{|cookbook| "'#{cookbook}'"}.join(', ')} in any of the sources. #{missing_cookbooks.size == 1 ? 'Is it' : 'Are they' } in your Berksfile?"
|
387
|
+
end
|
388
|
+
|
389
|
+
update_lockfile(sources)
|
390
|
+
|
391
|
+
if options[:path]
|
392
|
+
self.class.vendor(cookbooks, options[:path])
|
393
|
+
end
|
394
|
+
|
395
|
+
cookbooks
|
396
|
+
end
|
397
|
+
|
398
|
+
# Get a list of all the cookbooks which have newer versions found on the community
|
399
|
+
# site versus what your current constraints allow
|
400
|
+
#
|
401
|
+
# @option options [Symbol, Array] :except
|
402
|
+
# Group(s) to exclude which will cause any sources marked as a member of the
|
403
|
+
# group to not be installed
|
404
|
+
# @option options [Symbol, Array] :only
|
405
|
+
# Group(s) to include which will cause any sources marked as a member of the
|
406
|
+
# group to be installed and all others to be ignored
|
407
|
+
# @option cookbooks [String, Array] :cookbooks
|
408
|
+
# Names of the cookbooks to retrieve sources for
|
409
|
+
#
|
410
|
+
# @return [Hash]
|
411
|
+
# a hash of cached cookbooks and their latest version. An empty hash is returned
|
412
|
+
# if there are no newer cookbooks for any of your sources
|
413
|
+
#
|
414
|
+
# @example
|
415
|
+
# berksfile.outdated => {
|
416
|
+
# <#CachedCookbook name="artifact"> => "0.11.2"
|
417
|
+
# }
|
418
|
+
def outdated(options = {})
|
419
|
+
outdated = Hash.new
|
420
|
+
|
421
|
+
sources(options).each do |cookbook|
|
422
|
+
location = cookbook.location || Location.init(cookbook.name, cookbook.version_constraint)
|
423
|
+
|
424
|
+
if location.is_a?(SiteLocation)
|
425
|
+
latest_version = SiteLocation.new(cookbook.name, cookbook.version_constraint).latest_version[0]
|
426
|
+
|
427
|
+
unless cookbook.version_constraint.satisfies?(latest_version)
|
428
|
+
outdated[cookbook] = latest_version
|
429
|
+
end
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
outdated
|
434
|
+
end
|
435
|
+
|
355
436
|
# @option options [String] :server_url
|
356
437
|
# URL to the Chef API
|
357
438
|
# @option options [String] :client_name
|
@@ -372,6 +453,8 @@ module Berkshelf
|
|
372
453
|
# @option options [Symbol, Array] :only
|
373
454
|
# Group(s) to include which will cause any sources marked as a member of the
|
374
455
|
# group to be installed and all others to be ignored
|
456
|
+
# @option cookbooks [String, Array] :cookbooks
|
457
|
+
# Names of the cookbooks to retrieve sources for
|
375
458
|
# @option options [Integer] :thread_count
|
376
459
|
# @option options [Hash] :params
|
377
460
|
# URI query unencoded key/value pairs
|
@@ -383,6 +466,8 @@ module Berkshelf
|
|
383
466
|
# SSL options
|
384
467
|
# @option options [URI, String, Hash] :proxy
|
385
468
|
# URI, String, or Hash of HTTP proxy options
|
469
|
+
#
|
470
|
+
# @raise [UploadFailure] if you are uploading cookbooks with an invalid or not-specified client key
|
386
471
|
def upload(options = {})
|
387
472
|
uploader = Uploader.new(options)
|
388
473
|
solution = resolve(options)
|
@@ -391,6 +476,11 @@ module Berkshelf
|
|
391
476
|
Berkshelf.formatter.upload cb.cookbook_name, cb.version, options[:server_url]
|
392
477
|
uploader.upload(cb, options)
|
393
478
|
end
|
479
|
+
|
480
|
+
rescue Ridley::Errors::ClientKeyFileNotFound => e
|
481
|
+
msg = "Could not upload cookbooks: Missing Chef client key: '#{Berkshelf::Config.instance.chef.client_key}'."
|
482
|
+
msg << " Generate or update your Berkshelf configuration that contains a valid path to a Chef client key."
|
483
|
+
raise UploadFailure, msg
|
394
484
|
end
|
395
485
|
|
396
486
|
# Finds a solution for the Berksfile and returns an array of CachedCookbooks.
|
@@ -401,6 +491,8 @@ module Berkshelf
|
|
401
491
|
# @option options [Symbol, Array] :only
|
402
492
|
# Group(s) to include which will cause any sources marked as a member of the
|
403
493
|
# group to be installed and all others to be ignored
|
494
|
+
# @option cookbooks [String, Array] :cookbooks
|
495
|
+
# Names of the cookbooks to retrieve sources for
|
404
496
|
#
|
405
497
|
# @return [Array<Berkshelf::CachedCookbooks]
|
406
498
|
def resolve(options = {})
|
@@ -441,5 +533,9 @@ module Berkshelf
|
|
441
533
|
def write_lockfile(sources)
|
442
534
|
Berkshelf::Lockfile.new(sources).write
|
443
535
|
end
|
536
|
+
|
537
|
+
def update_lockfile(sources)
|
538
|
+
Berkshelf::Lockfile.update!(sources)
|
539
|
+
end
|
444
540
|
end
|
445
541
|
end
|
@@ -213,6 +213,10 @@ module Berkshelf
|
|
213
213
|
"#{cookbook_name} (#{version}) '#{path}'"
|
214
214
|
end
|
215
215
|
|
216
|
+
def <=>(other_cookbook)
|
217
|
+
[self.cookbook_name, self.version] <=> [other_cookbook.cookbook_name, other_cookbook.version]
|
218
|
+
end
|
219
|
+
|
216
220
|
private
|
217
221
|
|
218
222
|
attr_reader :files
|
data/lib/berkshelf/cli.rb
CHANGED
@@ -31,6 +31,7 @@ module Berkshelf
|
|
31
31
|
map 'in' => :install
|
32
32
|
map 'up' => :upload
|
33
33
|
map 'ud' => :update
|
34
|
+
map 'ls' => :list
|
34
35
|
map 'ver' => :version
|
35
36
|
map 'book' => :cookbook
|
36
37
|
|
@@ -130,10 +131,15 @@ module Berkshelf
|
|
130
131
|
type: :array,
|
131
132
|
desc: "Only cookbooks that are in these groups.",
|
132
133
|
aliases: "-o"
|
133
|
-
desc "update", "Update all Cookbooks and their dependencies specified by a Berksfile to their latest versions"
|
134
|
-
def update
|
135
|
-
|
136
|
-
|
134
|
+
desc "update [COOKBOOKS]", "Update all Cookbooks and their dependencies specified by a Berksfile to their latest versions"
|
135
|
+
def update(*cookbook_names)
|
136
|
+
berksfile = Berksfile.from_file(options[:berksfile])
|
137
|
+
|
138
|
+
update_options = {
|
139
|
+
cookbooks: cookbook_names
|
140
|
+
}.merge(options).symbolize_keys
|
141
|
+
|
142
|
+
berksfile.update(update_options)
|
137
143
|
end
|
138
144
|
|
139
145
|
method_option :berksfile,
|
@@ -157,13 +163,13 @@ module Berkshelf
|
|
157
163
|
option :force,
|
158
164
|
type: :boolean,
|
159
165
|
default: false,
|
160
|
-
desc: "Upload
|
166
|
+
desc: "Upload cookbook(s) even if a frozen one exists on the target Chef Server"
|
161
167
|
option :ssl_verify,
|
162
168
|
type: :boolean,
|
163
169
|
default: nil,
|
164
170
|
desc: "Disable/Enable SSL verification when uploading cookbooks"
|
165
|
-
desc "upload", "Upload
|
166
|
-
def upload
|
171
|
+
desc "upload [COOKBOOKS]", "Upload cookbook(s) specified by a Berksfile to the configured Chef Server."
|
172
|
+
def upload(*cookbook_names)
|
167
173
|
berksfile = ::Berkshelf::Berksfile.from_file(options[:berksfile])
|
168
174
|
|
169
175
|
unless Berkshelf::Config.instance.chef.chef_server_url.present?
|
@@ -178,18 +184,54 @@ module Berkshelf
|
|
178
184
|
raise UploadFailure, msg
|
179
185
|
end
|
180
186
|
|
181
|
-
|
187
|
+
upload_options = {
|
182
188
|
server_url: Berkshelf::Config.instance.chef.chef_server_url,
|
183
189
|
client_name: Berkshelf::Config.instance.chef.node_name,
|
184
190
|
client_key: Berkshelf::Config.instance.chef.client_key,
|
185
191
|
ssl: {
|
186
192
|
verify: (options[:ssl_verify].nil? ? Berkshelf::Config.instance.ssl.verify : options[:ssl_verify])
|
187
|
-
}
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
+
},
|
194
|
+
cookbooks: cookbook_names
|
195
|
+
}.merge(options).symbolize_keys
|
196
|
+
|
197
|
+
berksfile.upload(upload_options)
|
198
|
+
end
|
199
|
+
|
200
|
+
method_option :berksfile,
|
201
|
+
type: :string,
|
202
|
+
default: File.join(Dir.pwd, Berkshelf::DEFAULT_FILENAME),
|
203
|
+
desc: "Path to a Berksfile to operate off of.",
|
204
|
+
aliases: "-b",
|
205
|
+
banner: "PATH"
|
206
|
+
method_option :except,
|
207
|
+
type: :array,
|
208
|
+
desc: "Exclude cookbooks that are in these groups.",
|
209
|
+
aliases: "-e"
|
210
|
+
method_option :only,
|
211
|
+
type: :array,
|
212
|
+
desc: "Only cookbooks that are in these groups.",
|
213
|
+
aliases: "-o"
|
214
|
+
desc "outdated [COOKBOOKS]", "Show all outdated cookbooks (exclusively from the community site)"
|
215
|
+
def outdated(*cookbook_names)
|
216
|
+
berksfile = ::Berkshelf::Berksfile.from_file(options[:berksfile])
|
217
|
+
Berkshelf.formatter.msg "Listing outdated cookbooks with newer versions available..."
|
218
|
+
Berkshelf.formatter.msg "BETA: this feature will only pull differences from the community site and will"
|
219
|
+
Berkshelf.formatter.msg "BETA: ignore all other sources you may have defined"
|
220
|
+
Berkshelf.formatter.msg ""
|
221
|
+
|
222
|
+
outdated_options = {
|
223
|
+
cookbooks: cookbook_names
|
224
|
+
}.merge(options).symbolize_keys
|
225
|
+
|
226
|
+
outdated = berksfile.outdated(outdated_options)
|
227
|
+
|
228
|
+
if outdated.empty?
|
229
|
+
Berkshelf.formatter.msg "All cookbooks up to date"
|
230
|
+
else
|
231
|
+
outdated.each do |cookbook, latest_version|
|
232
|
+
Berkshelf.formatter.msg "Cookbook '#{cookbook.name} (#{cookbook.version_constraint})' is outdated (#{latest_version})"
|
233
|
+
end
|
234
|
+
end
|
193
235
|
end
|
194
236
|
|
195
237
|
method_option :foodcritic,
|
@@ -228,6 +270,39 @@ module Berkshelf
|
|
228
270
|
::Berkshelf.formatter.msg "Successfully initialized"
|
229
271
|
end
|
230
272
|
|
273
|
+
method_option :berksfile,
|
274
|
+
type: :string,
|
275
|
+
default: File.join(Dir.pwd, Berkshelf::DEFAULT_FILENAME),
|
276
|
+
desc: "Path to a Berksfile to operate off of.",
|
277
|
+
aliases: "-b",
|
278
|
+
banner: "PATH"
|
279
|
+
desc "list", "Show all of the cookbooks in the current Berkshelf"
|
280
|
+
def list
|
281
|
+
berksfile = ::Berkshelf::Berksfile.from_file(options[:berksfile])
|
282
|
+
|
283
|
+
Berkshelf.ui.say "Cookbooks installed by your Berksfile:"
|
284
|
+
Berkshelf.ui.mute { berksfile.resolve }.sort.each do |cookbook|
|
285
|
+
Berkshelf.ui.say " * #{cookbook.cookbook_name} (#{cookbook.version})"
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
method_option :berksfile,
|
290
|
+
type: :string,
|
291
|
+
default: File.join(Dir.pwd, Berkshelf::DEFAULT_FILENAME),
|
292
|
+
desc: "Path to a Berksfile to operate off of.",
|
293
|
+
aliases: "-b",
|
294
|
+
banner: "PATH"
|
295
|
+
desc "show [COOKBOOK]", "Display the source path on the local file system for the given cookbook"
|
296
|
+
def show(name = nil)
|
297
|
+
return list if name.nil?
|
298
|
+
|
299
|
+
berksfile = ::Berkshelf::Berksfile.from_file(options[:berksfile])
|
300
|
+
cookbook = Berkshelf.ui.mute { berksfile.resolve }.find{ |cookbook| cookbook.cookbook_name == name }
|
301
|
+
|
302
|
+
raise CookbookNotFound, "Cookbook '#{name}' was not installed by your Berksfile" unless cookbook
|
303
|
+
Berkshelf.ui.say(cookbook.path)
|
304
|
+
end
|
305
|
+
|
231
306
|
desc "version", "Display version and copyright information"
|
232
307
|
def version
|
233
308
|
Berkshelf.formatter.msg version_header
|