berkshelf 2.0.18 → 3.0.0.beta1

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.
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)