berkshelf 2.0.18 → 3.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/.ruby-version +1 -1
  2. data/.travis.yml +4 -1
  3. data/CHANGELOG.md +2 -26
  4. data/Gemfile +12 -2
  5. data/README.md +9 -1
  6. data/berkshelf.gemspec +9 -18
  7. data/bin/berks +3 -13
  8. data/features/apply_command.feature +11 -9
  9. data/features/berksfile.feature +8 -10
  10. data/features/config.feature +1 -2
  11. data/features/configure_command.feature +13 -14
  12. data/features/contingent_command.feature +13 -1
  13. data/features/cookbook_command.feature +2 -4
  14. data/features/groups_install.feature +10 -2
  15. data/features/help.feature +1 -1
  16. data/features/init_command.feature +5 -7
  17. data/features/install_command.feature +157 -228
  18. data/features/json_formatter.feature +27 -15
  19. data/features/licenses.feature +18 -12
  20. data/features/list_command.feature +6 -1
  21. data/features/lockfile.feature +116 -72
  22. data/features/outdated_command.feature +3 -47
  23. data/features/package_command.feature +10 -7
  24. data/features/shelf/show.feature +2 -2
  25. data/features/shelf/uninstall.feature +2 -2
  26. data/features/show_command.feature +10 -3
  27. data/features/step_definitions/chef/config_steps.rb +12 -0
  28. data/features/step_definitions/chef_server_steps.rb +16 -16
  29. data/features/step_definitions/cli_steps.rb +3 -79
  30. data/features/step_definitions/config_steps.rb +43 -0
  31. data/features/step_definitions/environment_steps.rb +7 -0
  32. data/features/step_definitions/filesystem_steps.rb +12 -57
  33. data/features/step_definitions/gem_steps.rb +1 -2
  34. data/features/step_definitions/json_steps.rb +3 -1
  35. data/features/step_definitions/lockfile_steps.rb +4 -0
  36. data/features/step_definitions/utility_steps.rb +0 -19
  37. data/features/support/aruba.rb +12 -0
  38. data/features/support/env.rb +52 -57
  39. data/features/update_command.feature +37 -23
  40. data/features/upload_command.feature +96 -160
  41. data/generator_files/Berksfile.erb +2 -1
  42. data/generator_files/Vagrantfile.erb +3 -0
  43. data/generator_files/default_test.rb.erb +1 -1
  44. data/generator_files/helpers.rb.erb +1 -1
  45. data/lib/berkshelf.rb +43 -24
  46. data/lib/berkshelf/api_client.rb +67 -0
  47. data/lib/berkshelf/api_client/remote_cookbook.rb +42 -0
  48. data/lib/berkshelf/berksfile.rb +232 -420
  49. data/lib/berkshelf/cached_cookbook.rb +22 -10
  50. data/lib/berkshelf/chef/config.rb +1 -0
  51. data/lib/berkshelf/cli.rb +66 -68
  52. data/lib/berkshelf/commands/shelf.rb +1 -1
  53. data/lib/berkshelf/community_rest.rb +10 -17
  54. data/lib/berkshelf/config.rb +23 -27
  55. data/lib/berkshelf/cookbook_generator.rb +3 -4
  56. data/lib/berkshelf/cookbook_store.rb +74 -17
  57. data/lib/berkshelf/core_ext/file.rb +2 -2
  58. data/lib/berkshelf/core_ext/pathname.rb +7 -5
  59. data/lib/berkshelf/{cookbook_source.rb → dependency.rb} +47 -67
  60. data/lib/berkshelf/downloader.rb +49 -106
  61. data/lib/berkshelf/errors.rb +64 -71
  62. data/lib/berkshelf/formatters.rb +11 -9
  63. data/lib/berkshelf/formatters/human_readable.rb +9 -9
  64. data/lib/berkshelf/formatters/json.rb +14 -4
  65. data/lib/berkshelf/init_generator.rb +3 -3
  66. data/lib/berkshelf/installer.rb +136 -0
  67. data/lib/berkshelf/location.rb +91 -131
  68. data/lib/berkshelf/locations/git_location.rb +9 -11
  69. data/lib/berkshelf/locations/github_location.rb +1 -1
  70. data/lib/berkshelf/locations/path_location.rb +10 -27
  71. data/lib/berkshelf/lockfile.rb +92 -70
  72. data/lib/berkshelf/logger.rb +4 -7
  73. data/lib/berkshelf/mixin/config.rb +21 -4
  74. data/lib/berkshelf/resolver.rb +60 -150
  75. data/lib/berkshelf/resolver/graph.rb +44 -0
  76. data/lib/berkshelf/source.rb +55 -0
  77. data/lib/berkshelf/source_uri.rb +38 -0
  78. data/lib/berkshelf/version.rb +1 -1
  79. data/spec/config/knife.rb +1 -1
  80. data/spec/fixtures/cassettes/Berkshelf_Resolver/_initialize/adds_the_dependencies_of_the_dependency_as_dependencies.yml +3694 -0
  81. data/spec/fixtures/cookbooks/example_cookbook/Berksfile.lock +1 -1
  82. data/spec/fixtures/lockfiles/default.lock +1 -1
  83. data/spec/spec_helper.rb +20 -121
  84. data/spec/support/chef_api.rb +3 -4
  85. data/spec/support/chef_server.rb +20 -11
  86. data/spec/support/git.rb +127 -0
  87. data/spec/support/kitchen.rb +12 -0
  88. data/spec/support/path_helpers.rb +69 -0
  89. data/spec/unit/berkshelf/api_client/remote_cookbook_spec.rb +23 -0
  90. data/spec/unit/berkshelf/api_client_spec.rb +57 -0
  91. data/spec/unit/berkshelf/berksfile_spec.rb +206 -324
  92. data/spec/unit/berkshelf/cached_cookbook_spec.rb +73 -38
  93. data/spec/unit/berkshelf/community_rest_spec.rb +30 -71
  94. data/spec/unit/berkshelf/config_spec.rb +3 -14
  95. data/spec/unit/berkshelf/cookbook_generator_spec.rb +1 -2
  96. data/spec/unit/berkshelf/cookbook_store_spec.rb +12 -7
  97. data/spec/unit/berkshelf/dependency_spec.rb +285 -0
  98. data/spec/unit/berkshelf/downloader_spec.rb +4 -183
  99. data/spec/unit/berkshelf/formatters/null_spec.rb +1 -1
  100. data/spec/unit/berkshelf/formatters_spec.rb +4 -2
  101. data/spec/unit/berkshelf/git_spec.rb +15 -15
  102. data/spec/unit/berkshelf/installer_spec.rb +39 -0
  103. data/spec/unit/berkshelf/location_spec.rb +87 -114
  104. data/spec/unit/berkshelf/locations/git_location_spec.rb +41 -53
  105. data/spec/unit/berkshelf/locations/path_location_spec.rb +13 -23
  106. data/spec/unit/berkshelf/lockfile_spec.rb +38 -40
  107. data/spec/unit/berkshelf/resolver/graph_spec.rb +44 -0
  108. data/spec/unit/berkshelf/resolver_spec.rb +34 -83
  109. data/spec/unit/berkshelf/source_spec.rb +23 -0
  110. data/spec/unit/berkshelf/source_uri_spec.rb +29 -0
  111. metadata +149 -188
  112. checksums.yaml +0 -7
  113. data/features/default_locations.feature +0 -127
  114. data/features/step_definitions/berksfile_steps.rb +0 -8
  115. data/features/step_definitions/configure_cli_steps.rb +0 -19
  116. data/features/vendor_install.feature +0 -19
  117. data/lib/berkshelf/core_ext/openuri.rb +0 -36
  118. data/lib/berkshelf/core_ext/rbzip2.rb +0 -8
  119. data/lib/berkshelf/locations/chef_api_location.rb +0 -228
  120. data/lib/berkshelf/locations/site_location.rb +0 -92
  121. data/lib/berkshelf/test.rb +0 -35
  122. data/spec/knife.rb.sample +0 -12
  123. data/spec/support/test_generators.rb +0 -27
  124. data/spec/unit/berkshelf/cli_spec.rb +0 -16
  125. data/spec/unit/berkshelf/cookbook_source_spec.rb +0 -358
  126. data/spec/unit/berkshelf/core_ext/pathname_spec.rb +0 -46
  127. data/spec/unit/berkshelf/locations/chef_api_location_spec.rb +0 -139
  128. data/spec/unit/berkshelf/locations/site_location_spec.rb +0 -19
@@ -1,7 +1,5 @@
1
1
  module Berkshelf
2
2
  class CachedCookbook < Ridley::Chef::Cookbook
3
- @loaded = Hash.new
4
-
5
3
  class << self
6
4
  # @param [#to_s] path
7
5
  # a path on disk to the location of a Cookbook downloaded by the Downloader
@@ -14,12 +12,20 @@ module Berkshelf
14
12
  cached_name = File.basename(path.to_s).slice(DIRNAME_REGEXP, 1)
15
13
  return nil if cached_name.nil?
16
14
 
17
- @loaded[path.to_s] ||= from_path(path, name: cached_name)
15
+ from_path(path, name: cached_name)
18
16
  end
19
17
  end
20
18
 
21
19
  DIRNAME_REGEXP = /^(.+)-(.+)$/
22
20
 
21
+ extend Forwardable
22
+
23
+ def_delegator :metadata, :description
24
+ def_delegator :metadata, :maintainer
25
+ def_delegator :metadata, :maintainer_email
26
+ def_delegator :metadata, :license
27
+ def_delegator :metadata, :platforms
28
+
23
29
  # @return [Hash]
24
30
  def dependencies
25
31
  metadata.recommendations.merge(metadata.dependencies)
@@ -38,19 +44,25 @@ module Berkshelf
38
44
  end.join("\n")
39
45
  end
40
46
 
47
+ # High-level information about this cached cookbook in JSON format
48
+ #
49
+ # @return [String]
41
50
  def pretty_json
42
- pretty_hash.to_json
51
+ JSON.pretty_generate(pretty_hash)
43
52
  end
44
53
 
54
+ # High-level information about this cached cookbook in Hash format
55
+ #
56
+ # @return [Hash]
45
57
  def pretty_hash
46
58
  {}.tap do |h|
47
- h[:name] = cookbook_name unless name.blank?
59
+ h[:name] = cookbook_name unless cookbook_name.blank?
48
60
  h[:version] = version unless version.blank?
49
- h[:description] = metadata.description unless metadata.description.blank?
50
- h[:author] = metadata.maintainer unless metadata.maintainer.blank?
51
- h[:email] = metadata.maintainer_email unless metadata.maintainer_email.blank?
52
- h[:license] = metadata.license unless metadata.license.blank?
53
- h[:platforms] = metadata.platforms.to_hash unless metadata.platforms.blank?
61
+ h[:description] = description unless description.blank?
62
+ h[:author] = maintainer unless maintainer.blank?
63
+ h[:email] = maintainer_email unless maintainer_email.blank?
64
+ h[:license] = license unless license.blank?
65
+ h[:platforms] = platforms.to_hash unless platforms.blank?
54
66
  h[:dependencies] = dependencies.to_hash unless dependencies.blank?
55
67
  end
56
68
  end
@@ -8,6 +8,7 @@ module Berkshelf
8
8
 
9
9
  class << self
10
10
  private
11
+
11
12
  # Return the most sensible path to the Chef configuration file. This can
12
13
  # be configured by setting a value for the 'BERKSHELF_CHEF_CONFIG' environment
13
14
  # variable.
@@ -7,6 +7,37 @@ require_relative 'commands/test_command'
7
7
 
8
8
  module Berkshelf
9
9
  class Cli < Thor
10
+ # This is the main entry point for the CLI. It exposes the method {#execute!} to
11
+ # start the CLI.
12
+ #
13
+ # @note the arity of {#initialize} and {#execute!} are extremely important for testing purposes. It
14
+ # is a requirement to perform in-process testing with Aruba. In process testing is much faster
15
+ # than spawning a new Ruby process for each test.
16
+ class Runner
17
+ def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = Kernel)
18
+ @argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
19
+ end
20
+
21
+ def execute!
22
+ begin
23
+ $stdin = @stdin
24
+ $stdout = @stdout
25
+ $stderr = @stderr
26
+
27
+ Berkshelf::Cli.start(@argv)
28
+ @kernel.exit(0)
29
+ rescue Berkshelf::BerkshelfError => e
30
+ Berkshelf.ui.error e
31
+ Berkshelf.ui.error "\t" + e.backtrace.join("\n\t") if ENV['BERKSHELF_DEBUG']
32
+ @kernel.exit(e.status_code)
33
+ rescue Ridley::Errors::RidleyError => e
34
+ Berkshelf.ui.error "#{e.class} #{e}"
35
+ Berkshelf.ui.error "\t" + e.backtrace.join("\n\t") if ENV['BERKSHELF_DEBUG']
36
+ @kernel.exit(47)
37
+ end
38
+ end
39
+ end
40
+
10
41
  class << self
11
42
  def dispatch(meth, given_args, given_opts, config)
12
43
  unless (given_args & ['-h', '--help']).empty?
@@ -31,7 +62,8 @@ module Berkshelf
31
62
  unless File.exist?(@options[:config])
32
63
  raise ConfigNotFound.new(:berkshelf, @options[:config])
33
64
  end
34
- Berkshelf::Config.set_path(@options[:config])
65
+
66
+ Berkshelf.config = Berkshelf::Config.from_file(@options[:config])
35
67
  end
36
68
 
37
69
  if @options[:debug]
@@ -85,7 +117,7 @@ module Berkshelf
85
117
  desc: 'create a new configuration file even if one already exists.'
86
118
  method_option :path,
87
119
  type: :string,
88
- default: Berkshelf::Config.path,
120
+ default: Berkshelf.config.path,
89
121
  desc: 'The path to save the configuration file'
90
122
  desc 'configure', 'Create a new Berkshelf configuration file'
91
123
  def configure
@@ -95,7 +127,7 @@ module Berkshelf
95
127
  raise Berkshelf::ConfigExists, 'A configuration file already exists. Re-run with the --force flag if you wish to overwrite it.'
96
128
  end
97
129
 
98
- @config = Berkshelf::Config.new(path)
130
+ config = Berkshelf::Config.new(path)
99
131
 
100
132
  [
101
133
  'chef.chef_server_url',
@@ -106,7 +138,7 @@ module Berkshelf
106
138
  'vagrant.vm.box',
107
139
  'vagrant.vm.box_url',
108
140
  ].each do |attribute|
109
- default = @config.get_attribute(attribute)
141
+ default = config.get_attribute(attribute)
110
142
 
111
143
  message = "Enter value for #{attribute}"
112
144
  message << " (default: '#{default}')" if default
@@ -115,15 +147,16 @@ module Berkshelf
115
147
  input = Berkshelf.ui.ask(message)
116
148
 
117
149
  if input.present?
118
- @config.set_attribute(attribute, input)
150
+ config.set_attribute(attribute, input)
119
151
  end
120
152
  end
121
153
 
122
- unless @config.valid?
123
- raise InvalidConfiguration.new(@config.errors)
154
+ unless config.valid?
155
+ raise InvalidConfiguration.new(config.errors)
124
156
  end
125
157
 
126
- @config.save
158
+ config.save
159
+ Berkshelf.config = config
127
160
 
128
161
  Berkshelf.formatter.msg "Config written to: '#{path}'"
129
162
  end
@@ -155,7 +188,7 @@ module Berkshelf
155
188
 
156
189
  method_option :berksfile,
157
190
  type: :string,
158
- default: File.join(Dir.pwd, Berkshelf::DEFAULT_FILENAME),
191
+ default: Berkshelf::DEFAULT_FILENAME,
159
192
  desc: 'Path to a Berksfile to operate off of.',
160
193
  aliases: '-b',
161
194
  banner: 'PATH'
@@ -180,7 +213,7 @@ module Berkshelf
180
213
 
181
214
  method_option :berksfile,
182
215
  type: :string,
183
- default: File.join(Dir.pwd, Berkshelf::DEFAULT_FILENAME),
216
+ default: Berkshelf::DEFAULT_FILENAME,
184
217
  desc: 'Path to a Berksfile to operate off of.',
185
218
  aliases: '-b',
186
219
  banner: 'PATH'
@@ -209,11 +242,6 @@ module Berkshelf
209
242
  default: false,
210
243
  desc: 'Skip Ruby syntax check when uploading cookbooks.',
211
244
  aliases: '-s'
212
- method_option :skip_dependencies,
213
- type: :boolean,
214
- desc: 'Skip uploading dependent cookbook(s).',
215
- default: false,
216
- aliases: '-D'
217
245
  method_option :halt_on_frozen,
218
246
  type: :boolean,
219
247
  default: false,
@@ -225,14 +253,13 @@ module Berkshelf
225
253
  upload_options = Hash[options.except(:no_freeze, :berksfile)].symbolize_keys
226
254
  upload_options[:cookbooks] = cookbook_names
227
255
  upload_options[:freeze] = false if options[:no_freeze]
228
- upload_options[:validate] = false if options[:skip_syntax_check]
229
256
 
230
257
  berksfile.upload(upload_options)
231
258
  end
232
259
 
233
260
  method_option :berksfile,
234
261
  type: :string,
235
- default: File.join(Dir.pwd, Berkshelf::DEFAULT_FILENAME),
262
+ default: Berkshelf::DEFAULT_FILENAME,
236
263
  desc: 'Path to a Berksfile to operate off of.',
237
264
  aliases: '-b',
238
265
  banner: 'PATH'
@@ -240,11 +267,6 @@ module Berkshelf
240
267
  type: :boolean,
241
268
  default: nil,
242
269
  desc: 'Disable/Enable SSL verification when locking cookbooks.'
243
- method_option :from_file,
244
- type: :string,
245
- desc: 'overwrite environment attributes when using apply using local environment file',
246
- aliases: '-f',
247
- banner: 'PATH'
248
270
  desc 'apply ENVIRONMENT', 'Apply the cookbook version locks from Berksfile.lock to a Chef environment'
249
271
  def apply(environment_name)
250
272
  berksfile = ::Berkshelf::Berksfile.from_file(options[:berksfile])
@@ -255,7 +277,7 @@ module Berkshelf
255
277
 
256
278
  method_option :berksfile,
257
279
  type: :string,
258
- default: File.join(Dir.pwd, Berkshelf::DEFAULT_FILENAME),
280
+ default: Berkshelf::DEFAULT_FILENAME,
259
281
  desc: 'Path to a Berksfile to operate off of.',
260
282
  aliases: '-b',
261
283
  banner: 'PATH'
@@ -267,36 +289,22 @@ module Berkshelf
267
289
  type: :array,
268
290
  desc: 'Only cookbooks that are in these groups.',
269
291
  aliases: '-o'
270
- desc 'outdated [COOKBOOKS]', 'Show outdated cookbooks (from the community site)'
292
+ desc 'outdated [COOKBOOKS]', 'List dependencies that have new versions available that satisfy their constraints'
271
293
  def outdated(*cookbook_names)
272
- berksfile = ::Berkshelf::Berksfile.from_file(options[:berksfile])
294
+ berksfile = Berkshelf::Berksfile.from_file(options[:berksfile])
273
295
  Berkshelf.formatter.msg 'Listing outdated cookbooks with newer versions available...'
274
- Berkshelf.formatter.msg 'BETA: this feature will only pull differences from the community site and will'
275
- Berkshelf.formatter.msg 'BETA: ignore all other sources you may have defined'
276
- Berkshelf.formatter.msg ''
277
-
278
- outdated_options = {
279
- cookbooks: cookbook_names
280
- }.merge(options).symbolize_keys
281
-
282
- outdated = berksfile.outdated(outdated_options)
283
296
 
284
- if outdated.empty?
285
- Berkshelf.formatter.msg 'All cookbooks up to date'
286
- else
287
- outdated.each do |cookbook, latest_version|
288
- Berkshelf.formatter.msg "Cookbook '#{cookbook.name} (#{cookbook.version_constraint})' is outdated (#{latest_version})"
289
- end
290
- end
297
+ outdated_options = { cookbooks: cookbook_names }.merge(options).symbolize_keys
298
+ berksfile.outdated(outdated_options)
291
299
  end
292
300
 
293
301
  desc 'init [PATH]', 'Initialize Berkshelf in the given directory'
294
- def init(path = Dir.pwd)
302
+ def init(path = '.')
295
303
  Berkshelf.formatter.deprecation '--git is now the default' if options[:git]
296
304
  Berkshelf.formatter.deprecation '--vagrant is now the default' if options[:vagrant]
297
305
 
298
306
  if File.chef_cookbook?(path)
299
- options[:chefignore] = true
307
+ options[:chefignore] = true
300
308
  options[:metadata_entry] = true
301
309
  end
302
310
 
@@ -311,16 +319,16 @@ module Berkshelf
311
319
  desc: 'Path to a Berksfile to operate off of.',
312
320
  aliases: '-b',
313
321
  banner: 'PATH'
314
- desc 'list', 'List all cookbooks (and dependencies) specified in the Berksfile'
322
+ desc 'list', 'List all cookbooks and their dependencies specified by your Berksfile'
315
323
  def list
316
- berksfile = Berksfile.from_file(options[:berksfile])
317
- sources = Berkshelf.ui.mute { berksfile.resolve(berksfile.sources)[:solution] }.sort
324
+ berksfile = Berksfile.from_file(options[:berksfile])
325
+ dependencies = Berkshelf.ui.mute { berksfile.install }.sort
318
326
 
319
- if sources.empty?
327
+ if dependencies.empty?
320
328
  Berkshelf.formatter.msg 'There are no cookbooks installed by your Berksfile'
321
329
  else
322
330
  Berkshelf.formatter.msg 'Cookbooks installed by your Berksfile:'
323
- print_list(sources)
331
+ print_list(dependencies)
324
332
  end
325
333
  end
326
334
 
@@ -333,12 +341,11 @@ module Berkshelf
333
341
  desc "show [COOKBOOK]", "Display name, author, copyright, and dependency information about a cookbook"
334
342
  def show(name)
335
343
  berksfile = Berksfile.from_file(options[:berksfile])
344
+ cookbook = Berkshelf.ui.mute { berksfile.install(cookbooks: name) }.first
336
345
 
337
- cookbook = Berkshelf.ui.mute {
338
- berksfile.resolve(berksfile.find(name))[:solution].first
339
- }
340
-
341
- raise CookbookNotFound, "Cookbook '#{name}' is not installed by your Berksfile" unless cookbook
346
+ unless cookbook
347
+ raise CookbookNotFound, "Cookbook '#{name}' is not installed by your Berksfile"
348
+ end
342
349
 
343
350
  Berkshelf.formatter.show(cookbook)
344
351
  end
@@ -351,10 +358,9 @@ module Berkshelf
351
358
  banner: 'PATH'
352
359
  desc 'contingent COOKBOOK', 'List all cookbooks that depend on the given cookbook'
353
360
  def contingent(name)
354
- berksfile = Berksfile.from_file(options[:berksfile])
355
-
356
- sources = Berkshelf.ui.mute { berksfile.resolve(berksfile.sources)[:solution] }.sort
357
- dependencies = sources.select { |cookbook| cookbook.dependencies.include?(name) }
361
+ berksfile = Berksfile.from_file(options[:berksfile])
362
+ dependencies = Berkshelf.ui.mute { berksfile.install }.sort
363
+ dependencies = dependencies.select { |cookbook| cookbook.dependencies.include?(name) }
358
364
 
359
365
  if dependencies.empty?
360
366
  Berkshelf.formatter.msg "There are no cookbooks contingent upon '#{name}' defined in this Berksfile"
@@ -366,25 +372,21 @@ module Berkshelf
366
372
 
367
373
  method_option :berksfile,
368
374
  type: :string,
369
- default: File.join(Dir.pwd, Berkshelf::DEFAULT_FILENAME),
375
+ default: Berkshelf::DEFAULT_FILENAME,
370
376
  desc: 'Path to a Berksfile to operate off of.',
371
377
  aliases: '-b',
372
378
  banner: 'PATH'
373
379
  method_option :output,
374
380
  type: :string,
375
- default: Dir.pwd,
381
+ default: '.',
376
382
  desc: 'Path to output the tarball',
377
383
  aliases: '-o',
378
384
  banner: 'PATH'
379
- method_option :skip_dependencies,
380
- type: :boolean,
381
- desc: 'Skip packaging dependent cookbook(s).',
382
- default: false
383
385
  method_option :ignore_chefignore,
384
386
  type: :boolean,
385
387
  desc: 'Do not apply the chefignore to the packaged contents',
386
388
  default: false
387
- desc 'package [COOKBOOK]', 'Package a cookbook (and dependencies) as a tarball'
389
+ desc "package [COOKBOOK]", "Package a cookbook and it's dependencies as a tarball"
388
390
  def package(name = nil)
389
391
  berksfile = Berkshelf::Berksfile.from_file(options[:berksfile])
390
392
  berksfile.package(name, options)
@@ -402,10 +404,6 @@ module Berkshelf
402
404
  Berkshelf.formatter.deprecation '--git is now the default' if options[:git]
403
405
  Berkshelf.formatter.deprecation '--vagrant is now the default' if options[:vagrant]
404
406
 
405
- unless Config.instance.valid?
406
- raise InvalidConfiguration.new(Config.instance.errors)
407
- end
408
-
409
407
  ::Berkshelf::CookbookGenerator.new([File.join(Dir.pwd, name), name], options).invoke_all
410
408
  end
411
409
  tasks['cookbook'].options = Berkshelf::CookbookGenerator.class_options
@@ -102,7 +102,7 @@ module Berkshelf
102
102
  contingent = contingent.map { |c| "#{c.cookbook_name} (#{c.version})" }.join(', ')
103
103
  confirm = Berkshelf.ui.ask("[#{contingent}] depend on #{cookbook.cookbook_name}.\n\nAre you sure you want to continue? (y/N)")
104
104
 
105
- exit unless confirm.upcase[0] == 'Y'
105
+ exit unless confirm.to_s.upcase[0] == 'Y'
106
106
  end
107
107
 
108
108
  FileUtils.rm_rf(cookbook.path)
@@ -2,8 +2,6 @@ require 'open-uri'
2
2
  require 'retryable'
3
3
  require 'addressable/uri'
4
4
 
5
- require_relative 'core_ext/openuri'
6
-
7
5
  module Berkshelf
8
6
  class CommunityREST < Faraday::Connection
9
7
  class << self
@@ -18,8 +16,6 @@ module Berkshelf
18
16
  Archive::Tar::Minitar.unpack(Zlib::GzipReader.new(File.open(target, 'rb')), destination)
19
17
  elsif is_tar_file(target)
20
18
  Archive::Tar::Minitar.unpack(target, destination)
21
- elsif is_bzip2_file(target)
22
- Archive::Tar::Minitar.unpack(RBzip2::Decompressor.new(File.open(target, 'rb')), destination)
23
19
  else
24
20
  raise Berkshelf::UnknownCompressionType.new(target)
25
21
  end
@@ -41,6 +37,7 @@ module Berkshelf
41
37
  end
42
38
 
43
39
  private
40
+
44
41
  def is_gzip_file(path)
45
42
  # You cannot write "\x1F\x8B" because the default encoding of
46
43
  # ruby >= 1.9.3 is UTF-8 and 8B is an invalid in UTF-8.
@@ -50,13 +47,9 @@ module Berkshelf
50
47
  def is_tar_file(path)
51
48
  IO.binread(path, 8, 257).to_s == "ustar\x0000"
52
49
  end
53
-
54
- def is_bzip2_file(path)
55
- IO.binread(path, 3) == 'BZh'
56
- end
57
50
  end
58
51
 
59
- V1_API = 'http://cookbooks.opscode.com/api/v1/cookbooks'.freeze
52
+ V1_API = 'http://cookbooks.opscode.com/api/v1'.freeze
60
53
 
61
54
  # @return [String]
62
55
  attr_reader :api_uri
@@ -82,8 +75,7 @@ module Berkshelf
82
75
 
83
76
  builder = Faraday::Builder.new do |b|
84
77
  b.response :parse_json
85
- b.response :follow_redirects
86
-
78
+ b.response :gzip
87
79
  b.request :retry,
88
80
  max: @retries,
89
81
  interval: @retry_interval,
@@ -100,20 +92,21 @@ module Berkshelf
100
92
  #
101
93
  # @return [String]
102
94
  def download(name, version)
103
- archive = stream(find(name, version)[:file])
104
- self.class.unpack(archive.path)
95
+ archive = stream(find(name, version)[:file])
96
+ extracted = self.class.unpack(archive.path)
97
+ Dir.glob(File.join(extracted, "*")).first
105
98
  ensure
106
99
  archive.unlink unless archive.nil?
107
100
  end
108
101
 
109
102
  def find(name, version)
110
- response = get("#{name}/versions/#{self.class.uri_escape_version(version)}")
103
+ response = get("cookbooks/#{name}/versions/#{self.class.uri_escape_version(version)}")
111
104
 
112
105
  case response.status
113
106
  when (200..299)
114
107
  response.body
115
108
  when 404
116
- raise CookbookNotFound, "Cookbook '#{name}' not found at site: '#{api_uri}'"
109
+ raise CookbookNotFound, "Cookbook '#{name}' (#{version}) not found at site: '#{api_uri}'"
117
110
  else
118
111
  raise CommunitySiteError, "Error finding cookbook '#{name}' (#{version}) at site: '#{api_uri}'"
119
112
  end
@@ -123,7 +116,7 @@ module Berkshelf
123
116
  #
124
117
  # @return [String]
125
118
  def latest_version(name)
126
- response = get(name)
119
+ response = get("cookbooks/#{name}")
127
120
 
128
121
  case response.status
129
122
  when (200..299)
@@ -139,7 +132,7 @@ module Berkshelf
139
132
  #
140
133
  # @return [Array]
141
134
  def versions(name)
142
- response = get(name)
135
+ response = get("cookbooks/#{name}")
143
136
 
144
137
  case response.status
145
138
  when (200..299)