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,129 +1,72 @@
1
1
  module Berkshelf
2
2
  class Downloader
3
- require_relative 'cookbook_source'
4
- require_relative 'location'
5
-
6
3
  extend Forwardable
7
4
 
8
- DEFAULT_LOCATIONS = [
9
- {
10
- type: :site,
11
- value: Location::OPSCODE_COMMUNITY_API,
12
- options: Hash.new
13
- }
14
- ]
15
-
16
- # @return [String]
17
- # a filepath to download cookbook sources to
18
- attr_reader :cookbook_store
19
-
20
- def_delegators :@cookbook_store, :storage_path
5
+ attr_reader :berksfile
21
6
 
22
- # @option options [Array<Hash>] locations
23
- def initialize(cookbook_store, options = {})
24
- @cookbook_store = cookbook_store
25
- @locations = options.fetch(:locations, Array.new)
26
- end
7
+ def_delegators :berksfile, :sources
27
8
 
28
- # @return [Array<Hash>]
29
- # an Array of Hashes representing each default location that can be used to attempt
30
- # to download cookbook sources which do not have an explicit location. An array of default locations will
31
- # be used if no locations are explicitly added by the {#add_location} function.
32
- def locations
33
- @locations.any? ? @locations : DEFAULT_LOCATIONS
9
+ # @param [Berkshelf::Berksfile] berksfile
10
+ def initialize(berksfile)
11
+ @berksfile = berksfile
34
12
  end
35
13
 
36
- # Create a location hash and add it to the end of the array of locations.
37
- #
38
- # subject.add_location(:chef_api, "http://chef:8080", node_name: "reset", client_key: "/Users/reset/.chef/reset.pem") =>
39
- # [ { type: :chef_api, value: "http://chef:8080/", node_name: "reset", client_key: "/Users/reset/.chef/reset.pem" } ]
14
+ # Download the given Berkshelf::Dependency.
40
15
  #
41
- # @param [Symbol] type
42
- # @param [String, Symbol] value
43
- # @param [Hash] options
16
+ # @param [String] name
17
+ # @param [String] version
44
18
  #
45
- # @return [Hash]
46
- def add_location(type, value, options = {})
47
- if has_location?(type, value)
48
- raise DuplicateLocationDefined,
49
- "A default '#{type}' location with the value '#{value}' is already defined"
50
- end
51
-
52
- @locations.push(type: type, value: value, options: options)
53
- end
54
-
55
- # Checks the list of default locations if a location of the given type and value has already
56
- # been added and returns true or false.
19
+ # @option options [String] :path
57
20
  #
58
- # @return [Boolean]
59
- def has_location?(type, value)
60
- @locations.select { |loc| loc[:type] == type && loc[:value] == value }.any?
61
- end
62
-
63
- # Download the given CookbookSource.
21
+ # @raise [CookbookNotFound]
64
22
  #
65
- # @param [CookbookSource] source
66
- # the source to download
67
- #
68
- # @return [Array]
69
- # an array containing the downloaded CachedCookbook and the Location used
70
- # to download the cookbook
71
- def download(source)
72
- if source.location
73
- begin
74
- location = source.location
75
- cached = download_location(source, location, true)
76
- source.cached_cookbook = cached
23
+ # @return [String]
24
+ def download(*args)
25
+ options = args.last.is_a?(Hash) ? args.pop : Hash.new
26
+ dependency, version = args
77
27
 
78
- return [cached, location]
79
- rescue => e
80
- raise if e.kind_of?(GitNotFound)
81
- raise if e.kind_of?(CookbookValidationFailure)
82
- Berkshelf.formatter.error "Failed to download '#{source.name}' from #{source.location}"
83
- end
28
+ if dependency.is_a?(Berkshelf::Dependency)
29
+ dependency.download
84
30
  else
85
- locations.each do |loc|
86
- options = loc[:options].merge(loc[:type] => loc[:value])
87
- location = Location.init(source.name, source.version_constraint, options)
88
-
89
- cached = download_location(source, location)
90
- if cached
91
- source.cached_cookbook = cached
92
- return [cached, location]
31
+ sources.each do |source|
32
+ if result = try_download(source, dependency, version)
33
+ return result
93
34
  end
94
35
  end
95
- end
96
36
 
97
- raise CookbookNotFound, "Cookbook '#{source.name}' not found in any of the default locations"
37
+ raise CookbookNotFound, "#{dependency} (#{version}) not found in any sources"
38
+ end
98
39
  end
99
40
 
100
- private
41
+ # @param [Berkshelf::Source] source
42
+ # @param [String] name
43
+ # @param [String] version
44
+ #
45
+ # @return [String]
46
+ def try_download(source, name, version)
47
+ unless remote_cookbook = source.cookbook(name, version)
48
+ return nil
49
+ end
101
50
 
102
- # Attempt to download the the given source from the given location, #
103
- # raising an error if `raise_if_not_found` is specified.
104
- #
105
- # @raise [Bershelf::CookbookNotFound]
106
- # if `raise_if_not_found` is true and the source could not be
107
- # downloaded
108
- #
109
- # @param [Berkshelf::CookbookSource] source
110
- # the source to download
111
- # @param [~Berkshelf::Location] location
112
- # the location to download from
113
- # @param [Boolean] raise_if_not_found
114
- # raise a {Berkshelf::CookbookNotFound} error if true, otherwise,
115
- # return nil
116
- #
117
- # @return [Berkshelf::CachedCookbook, nil]
118
- # the downloaded cached cookbook, or nil if one was not found
119
- def download_location(source, location, raise_if_not_found = false)
120
- location.download(storage_path)
121
- rescue Berkshelf::GitNotFound
122
- raise
123
- nil
124
- rescue Berkshelf::CookbookNotFound
125
- raise if raise_if_not_found
126
- nil
51
+ case remote_cookbook.location_type
52
+ when :opscode
53
+ CommunityREST.new(remote_cookbook.location_path).download(name, version)
54
+ when :chef_server
55
+ # @todo Dynamically get credentials for remote_cookbook.location_path
56
+ credentials = {
57
+ server_url: remote_cookbook.location_path,
58
+ client_name: Berkshelf::Config.instance.chef.node_name,
59
+ client_key: Berkshelf::Config.instance.chef.client_key,
60
+ ssl: {
61
+ verify: Berkshelf::Config.instance.ssl.verify
62
+ }
63
+ }
64
+ Ridley.open(credentials) { |r| r.cookbook.download(name, version) }
65
+ else
66
+ raise RuntimeError, "unknown location type #{remote_cookbook.location_type}"
127
67
  end
68
+ rescue CookbookNotFound
69
+ nil
70
+ end
128
71
  end
129
72
  end
@@ -11,6 +11,7 @@ module Berkshelf
11
11
  alias_method :message, :to_s
12
12
  end
13
13
 
14
+ class DeprecatedError < BerkshelfError; status_code(10); end
14
15
  class InternalError < BerkshelfError; status_code(99); end
15
16
  class ArgumentError < InternalError; end
16
17
  class AbstractFunction < InternalError
@@ -19,20 +20,7 @@ module Berkshelf
19
20
  end
20
21
  end
21
22
 
22
- class BerksfileNotFound < BerkshelfError
23
- status_code(100)
24
-
25
- # @param [#to_s] filepath
26
- # the path where a Berksfile was not found
27
- def initialize(filepath)
28
- @filepath = File.dirname(File.expand_path(filepath)) rescue filepath
29
- end
30
-
31
- def to_s
32
- "No Berksfile or Berksfile.lock found at '#{@filepath}'!"
33
- end
34
- end
35
-
23
+ class BerksfileNotFound < BerkshelfError; status_code(100); end
36
24
  class NoVersionForConstraints < BerkshelfError; status_code(101); end
37
25
  class DuplicateLocationDefined < BerkshelfError; status_code(102); end
38
26
  class CookbookNotFound < BerkshelfError; status_code(103); end
@@ -93,8 +81,23 @@ module Berkshelf
93
81
  end
94
82
  end
95
83
 
96
- class DuplicateSourceDefined < BerkshelfError; status_code(105); end
97
- class NoSolution < BerkshelfError; status_code(106); end
84
+ class DuplicateDependencyDefined < BerkshelfError; status_code(105); end
85
+
86
+ class NoSolutionError < BerkshelfError
87
+ status_code(106)
88
+
89
+ attr_reader :demands
90
+
91
+ # @param [Array<Berkshelf::Dependency>] demands
92
+ def initialize(demands)
93
+ @demands = demands
94
+ end
95
+
96
+ def to_s
97
+ "Unable to find a solution for demands: #{demands.join(', ')}"
98
+ end
99
+ end
100
+
98
101
  class CookbookSyntaxError < BerkshelfError; status_code(107); end
99
102
 
100
103
  class InvalidGitURI < BerkshelfError
@@ -132,8 +135,9 @@ module Berkshelf
132
135
  end
133
136
 
134
137
  class ConstraintNotSatisfied < BerkshelfError; status_code(111); end
135
- class InvalidChefAPILocation < BerkshelfError; status_code(112); end
136
138
  class BerksfileReadError < BerkshelfError
139
+ status_code(113)
140
+
137
141
  # @param [#status_code] original_error
138
142
  def initialize(original_error)
139
143
  @original_error = original_error
@@ -141,7 +145,6 @@ module Berkshelf
141
145
  @error_backtrace = original_error.backtrace
142
146
  end
143
147
 
144
- status_code(113)
145
148
 
146
149
  def status_code
147
150
  @original_error.respond_to?(:status_code) ? @original_error.status_code : 113
@@ -164,12 +167,12 @@ module Berkshelf
164
167
  class MismatchedCookbookName < BerkshelfError
165
168
  status_code(114)
166
169
 
167
- # @param [Berkshelf::Location] location
168
- # the location that is mismatched
170
+ # @param [Berkshelf::Dependency] dependency
171
+ # the dependency with the expected name
169
172
  # @param [Berkshelf::CachedCookbook] cached_cookbook
170
- # the cached_cookbook that is mismatched
171
- def initialize(location, cached_cookbook)
172
- @location = location
173
+ # the cached_cookbook with the mismatched name
174
+ def initialize(dependency, cached_cookbook)
175
+ @dependency = dependency
173
176
  @cached_cookbook = cached_cookbook
174
177
  end
175
178
 
@@ -177,7 +180,7 @@ module Berkshelf
177
180
  [
178
181
  "In your Berksfile, you have:",
179
182
  "",
180
- " cookbook '#{@location.name}'",
183
+ " cookbook '#{@dependency.name}'",
181
184
  "",
182
185
  "But that cookbook is actually named '#{@cached_cookbook.cookbook_name}'",
183
186
  "",
@@ -206,7 +209,7 @@ module Berkshelf
206
209
  class ConfigExists < BerkshelfError; status_code(116); end
207
210
  class ConfigurationError < BerkshelfError; status_code(117); end
208
211
  class InsufficientPrivledges < BerkshelfError; status_code(119); end
209
- class ExplicitCookbookNotFound < BerkshelfError; status_code(120); end
212
+ class DependencyNotFound < BerkshelfError; status_code(120); end
210
213
  class ValidationFailed < BerkshelfError; status_code(121); end
211
214
  class InvalidVersionConstraint < BerkshelfError; status_code(122); end
212
215
  class CommunitySiteError < BerkshelfError; status_code(123); end
@@ -218,21 +221,13 @@ module Berkshelf
218
221
  # the location (or any subclass) raising this validation error
219
222
  # @param [Berkshelf::CachedCookbook] cached_cookbook
220
223
  # the cached_cookbook that does not satisfy the constraint
221
- def initialize(location, cached_cookbook)
222
- @location = location
224
+ def initialize(dependency, cached_cookbook)
225
+ @dependency = dependency
223
226
  @cached_cookbook = cached_cookbook
224
227
  end
225
228
 
226
229
  def to_s
227
- [
228
- "The cookbook downloaded from #{@location.to_s}:",
229
- " #{@cached_cookbook.cookbook_name} (#{@cached_cookbook.version})",
230
- "",
231
- "does not satisfy the version constraint:",
232
- " #{@cached_cookbook.cookbook_name} (#{@location.version_constraint})",
233
- "",
234
- "This occurs when the Chef Server has a cookbook with a missing/mis-matched version number in its `metadata.rb`",
235
- ].join("\n")
230
+ "The cookbook downloaded for #{@dependency} did not satisfy the constraint."
236
231
  end
237
232
  end
238
233
 
@@ -240,45 +235,27 @@ module Berkshelf
240
235
 
241
236
  class UploadFailure < BerkshelfError; end
242
237
  class FrozenCookbook < UploadFailure; status_code(126); end
243
- class InvalidSiteShortnameError < BerkshelfError
244
- status_code(127)
245
238
 
246
- # @param [String,Symbol] shortname
247
- # the shortname for the site (see SiteLocation::SHORTNAMES)
248
- def initialize(shortname)
249
- @shortname = shortname
250
- end
251
-
252
- def to_s
253
- [
254
- "Unknown site shortname '#{@shortname}' - supported shortnames are:",
255
- "",
256
- " * " + SiteLocation::SHORTNAMES.keys.join("\n * "),
257
- ].join("\n")
258
- end
259
- end
260
-
261
- class OutdatedCookbookSource < BerkshelfError
239
+ class OutdatedDependency < BerkshelfError
262
240
  status_code(128)
263
241
 
264
- # @param [Berkshelf::CookbookSource] source
265
- # the cookbook source that is outdated
266
- def initialize(locked_source, source)
267
- @locked_source = locked_source
268
- @source = source
242
+ # @param [Berkshelf::Dependency] locked_dependency
243
+ # the locked dependency
244
+ # @param [Berkshelf::Dependency] dependency
245
+ # the dependency that is outdated
246
+ def initialize(locked_dependency, dependency)
247
+ @locked_dependency = locked_dependency
248
+ @dependency = dependency
269
249
  end
270
250
 
271
251
  def to_s
272
- [
273
- "Berkshelf could not find compatible versions for cookbook '#{@source.name}':",
274
- " In Berksfile:",
275
- " #{@source.name} (#{@source.version_constraint})",
276
- "",
277
- " In Berksfile.lock:",
278
- " #{@locked_source.name} (#{@locked_source.locked_version})",
279
- "",
280
- "Try running `berks update #{@source.name}, which will try to find '#{@source.name}' matching '#{@source.version_constraint}'.",
281
- ].join("\n")
252
+ "Berkshelf could not find compatible versions for cookbook '#{@dependency.name}':\n" +
253
+ " In Berksfile:\n" +
254
+ " #{@dependency.name} (#{@dependency.version_constraint})\n\n" +
255
+ " In Berksfile.lock:\n" +
256
+ " #{@locked_dependency.name} (#{@locked_dependency.locked_version})\n\n" +
257
+ "Try running `berks update #{@dependency.name}, which will try to find '#{@dependency.name}' matching " +
258
+ "'#{@dependency.version_constraint}'."
282
259
  end
283
260
  end
284
261
 
@@ -294,8 +271,6 @@ module Berkshelf
294
271
  end
295
272
  end
296
273
 
297
- class EnvironmentFileNotFound < BerkshelfError; status_code(137); end
298
-
299
274
  class ChefConnectionError < BerkshelfError
300
275
  status_code(130)
301
276
 
@@ -411,4 +386,22 @@ module Berkshelf
411
386
  "Error reading the Berkshelf lockfile `#{@lockfile}` (#{@original.class})"
412
387
  end
413
388
  end
389
+
390
+ class InvalidSourceURI < BerkshelfError
391
+ status_code(137)
392
+
393
+ attr_reader :reason
394
+
395
+ def initialize(url, reason = nil)
396
+ @url = url
397
+ @reason = reason
398
+ end
399
+
400
+ def to_s
401
+ msg = "'#{@url}' is not a valid Berkshelf source URI."
402
+ msg + " #{reason}." unless reason.nil?
403
+ end
404
+ end
405
+
406
+ class DuplicateDemand < BerkshelfError; status_code(138); end
414
407
  end
@@ -50,8 +50,6 @@ module Berkshelf
50
50
  #
51
51
  # Implement {#cleanup_hook} to run any steps required to run after the task is finished
52
52
  module AbstractFormatter
53
- extend ActiveSupport::Concern
54
-
55
53
  module ClassMethods
56
54
  # @param [Symbol] id
57
55
  #
@@ -66,18 +64,22 @@ module Berkshelf
66
64
  end
67
65
 
68
66
  class << self
67
+ def included(base)
68
+ base.send(:extend, ClassMethods)
69
+ end
70
+
69
71
  private
70
72
 
71
- def formatter_methods(*args)
72
- args.each do |meth|
73
- define_method(meth.to_sym) do |*args|
74
- raise AbstractFunction, "##{meth} must be implemented on #{self.class}"
75
- end unless respond_to?(meth.to_sym)
73
+ def formatter_methods(*args)
74
+ args.each do |meth|
75
+ define_method(meth.to_sym) do |*args|
76
+ raise AbstractFunction, "##{meth} must be implemented on #{self.class}"
77
+ end unless respond_to?(meth.to_sym)
78
+ end
76
79
  end
77
- end
78
80
  end
79
81
 
80
- formatter_methods :install, :use, :upload, :msg, :error, :package, :show
82
+ formatter_methods :fetch, :install, :use, :upload, :msg, :error, :package, :show
81
83
 
82
84
  def cleanup_hook
83
85
  # run after the task is finished
@@ -5,13 +5,18 @@ module Berkshelf
5
5
 
6
6
  register_formatter :human
7
7
 
8
+ # @param [Berkshelf::Dependency] dependency
9
+ def fetch(dependency)
10
+ Berkshelf.ui.info "Fetching '#{dependency.name}' from #{dependency.location}"
11
+ end
12
+
8
13
  # Output a Cookbook installation message using {Berkshelf.ui}
9
14
  #
10
15
  # @param [String] cookbook
11
16
  # @param [String] version
12
- # @param [~Location] location
13
- def install(cookbook, version, location)
14
- Berkshelf.ui.info "Installing #{cookbook} (#{version}) from #{location}"
17
+ # @param [Berkshelf::Dependency] dependency
18
+ def install(cookbook, version, dependency)
19
+ Berkshelf.ui.info "Installing #{cookbook} (#{version})"
15
20
  end
16
21
 
17
22
  # Output a Cookbook use message using {Berkshelf.ui}
@@ -21,12 +26,7 @@ module Berkshelf
21
26
  # @param [~Location] location
22
27
  def use(cookbook, version, location = nil)
23
28
  message = "Using #{cookbook} (#{version})"
24
-
25
- if location.is_a?(PathLocation)
26
- message << ' from metadata' if location.metadata?
27
- message << " at '#{location.relative_path}'" unless location.relative_path == '.'
28
- end
29
-
29
+ message += " #{location}" if location
30
30
  Berkshelf.ui.info message
31
31
  end
32
32