berkshelf 6.3.4 → 7.0.0

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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +10 -0
  4. data/.travis.yml +6 -8
  5. data/CHANGELOG.md +7 -19
  6. data/Gemfile +10 -0
  7. data/Gemfile.lock +68 -103
  8. data/Thorfile +2 -2
  9. data/berkshelf.gemspec +6 -8
  10. data/features/commands/info.feature +50 -8
  11. data/features/commands/shelf/show.feature +10 -40
  12. data/features/commands/upload.feature +73 -0
  13. data/features/commands/vendor.feature +43 -0
  14. data/features/json_formatter.feature +1 -1
  15. data/features/step_definitions/chef_server_steps.rb +2 -2
  16. data/features/step_definitions/filesystem_steps.rb +16 -0
  17. data/features/support/env.rb +11 -10
  18. data/lib/berkshelf.rb +15 -20
  19. data/lib/berkshelf/berksfile.rb +57 -47
  20. data/lib/berkshelf/cached_cookbook.rb +120 -19
  21. data/lib/berkshelf/chef_config_compat.rb +50 -0
  22. data/lib/berkshelf/chef_repo_universe.rb +2 -2
  23. data/lib/berkshelf/cli.rb +3 -42
  24. data/lib/berkshelf/community_rest.rb +40 -61
  25. data/lib/berkshelf/config.rb +92 -118
  26. data/lib/berkshelf/cookbook_store.rb +3 -2
  27. data/lib/berkshelf/core_ext/file.rb +1 -1
  28. data/lib/berkshelf/dependency.rb +1 -10
  29. data/lib/berkshelf/downloader.rb +19 -7
  30. data/lib/berkshelf/errors.rb +3 -0
  31. data/lib/berkshelf/location.rb +1 -1
  32. data/lib/berkshelf/locations/base.rb +1 -1
  33. data/lib/berkshelf/lockfile.rb +17 -13
  34. data/lib/berkshelf/logger.rb +62 -1
  35. data/lib/berkshelf/packager.rb +1 -1
  36. data/lib/berkshelf/resolver.rb +1 -1
  37. data/lib/berkshelf/ridley_compat.rb +22 -3
  38. data/lib/berkshelf/uploader.rb +76 -48
  39. data/lib/berkshelf/version.rb +1 -1
  40. data/spec/fixtures/cookbook-path-uploader/apt-2.3.6/metadata.rb +2 -0
  41. data/spec/fixtures/cookbook-path-uploader/build-essential-1.4.2/metadata.rb +2 -0
  42. data/spec/fixtures/cookbook-path-uploader/jenkins-2.0.3/metadata.rb +5 -0
  43. data/spec/fixtures/cookbook-path-uploader/jenkins-config-0.1.0/metadata.rb +4 -0
  44. data/spec/fixtures/cookbook-path-uploader/runit-1.5.8/metadata.rb +5 -0
  45. data/spec/fixtures/cookbook-path-uploader/yum-3.0.6/metadata.rb +2 -0
  46. data/spec/fixtures/cookbook-path-uploader/yum-epel-0.2.0/metadata.rb +3 -0
  47. data/spec/spec_helper.rb +2 -2
  48. data/spec/support/chef_api.rb +4 -4
  49. data/spec/support/chef_server.rb +1 -1
  50. data/spec/support/matchers/file_system_matchers.rb +1 -3
  51. data/spec/support/path_helpers.rb +1 -1
  52. data/spec/unit/berkshelf/berksfile_spec.rb +3 -24
  53. data/spec/unit/berkshelf/cached_cookbook_spec.rb +13 -15
  54. data/spec/unit/berkshelf/community_rest_spec.rb +3 -12
  55. data/spec/unit/berkshelf/config_spec.rb +4 -4
  56. data/spec/unit/berkshelf/downloader_spec.rb +6 -11
  57. data/spec/unit/berkshelf/lockfile_spec.rb +10 -7
  58. data/spec/unit/berkshelf/source_spec.rb +1 -1
  59. data/spec/unit/berkshelf/ssl_policies_spec.rb +2 -5
  60. data/spec/unit/berkshelf/uploader_spec.rb +60 -10
  61. data/spec/unit/berkshelf/visualizer_spec.rb +2 -2
  62. metadata +49 -102
  63. data/features/commands/cookbook.feature +0 -35
  64. data/features/commands/init.feature +0 -27
  65. data/features/config.feature +0 -111
  66. data/lib/berkshelf/base_generator.rb +0 -42
  67. data/lib/berkshelf/cookbook_generator.rb +0 -133
  68. data/lib/berkshelf/init_generator.rb +0 -195
  69. data/lib/berkshelf/streaming_file_adapter.rb +0 -22
  70. data/spec/unit/berkshelf/cookbook_generator_spec.rb +0 -108
  71. data/spec/unit/berkshelf/init_generator_spec.rb +0 -265
@@ -22,7 +22,7 @@ module Berkshelf
22
22
  # @return [String]
23
23
  attr_reader :name
24
24
  # @return [Array<String,Symbol>]
25
- attr_reader :groups
25
+ attr_writer :groups
26
26
  # @return [Berkshelf::Location]
27
27
  attr_reader :location
28
28
  # @return [Semverse::Version]
@@ -151,15 +151,6 @@ module Berkshelf
151
151
  groups.include?(group.to_sym)
152
152
  end
153
153
 
154
- # The location for this dependency, such as a remote Chef Server, the
155
- # community API, :git, or a :path location. By default, this will be the
156
- # community API.
157
- #
158
- # @return [Berkshelf::Location]
159
- def location
160
- @location
161
- end
162
-
163
154
  # The list of groups this dependency belongs to.
164
155
  #
165
156
  # @return [Array<Symbol>]
@@ -33,11 +33,12 @@ module Berkshelf
33
33
  #
34
34
  # @return [String]
35
35
  def download(*args, &block)
36
- options = args.last.is_a?(Hash) ? args.pop : Hash.new
36
+ # options are ignored
37
+ #options = args.last.is_a?(Hash) ? args.pop : Hash.new
37
38
  dependency, version = args
38
39
 
39
40
  sources.each do |source|
40
- if result = try_download(source, dependency, version)
41
+ if ( result = try_download(source, dependency, version) )
41
42
  if block_given?
42
43
  value = yield result
43
44
  FileUtils.rm_rf(result)
@@ -57,7 +58,7 @@ module Berkshelf
57
58
  #
58
59
  # @return [String]
59
60
  def try_download(source, name, version)
60
- unless remote_cookbook = source.cookbook(name, version)
61
+ unless ( remote_cookbook = source.cookbook(name, version) )
61
62
  return nil
62
63
  end
63
64
 
@@ -69,6 +70,8 @@ module Berkshelf
69
70
  end
70
71
  CommunityREST.new(remote_cookbook.location_path, options).download(name, version)
71
72
  when :chef_server
73
+ tmp_dir = Dir.mktmpdir
74
+ unpack_dir = Pathname.new(tmp_dir) + "#{name}-#{version}"
72
75
  # @todo Dynamically get credentials for remote_cookbook.location_path
73
76
  credentials = {
74
77
  server_url: remote_cookbook.location_path,
@@ -76,10 +79,19 @@ module Berkshelf
76
79
  client_key: source.options[:client_key] || Berkshelf::Config.instance.chef.client_key,
77
80
  ssl: source.options[:ssl],
78
81
  }
79
- # @todo Something scary going on here - getting an instance of Kitchen::Logger from test-kitchen
80
- # https://github.com/opscode/test-kitchen/blob/master/lib/kitchen.rb#L99
81
- Celluloid.logger = nil unless ENV["DEBUG_CELLULOID"]
82
- Ridley.open(credentials) { |r| r.cookbook.download(name, version) }
82
+ RidleyCompat.new_client(credentials) do |conn|
83
+ cookbook = Chef::CookbookVersion.load(name, version)
84
+ manifest = cookbook.cookbook_manifest
85
+ manifest.by_parent_directory.each do |segment, files|
86
+ files.each do |segment_file|
87
+ dest = File.join(unpack_dir, segment_file["path"].gsub("/", File::SEPARATOR))
88
+ FileUtils.mkdir_p(File.dirname(dest))
89
+ tempfile = conn.streaming_request(segment_file["url"])
90
+ FileUtils.mv(tempfile.path, dest)
91
+ end
92
+ end
93
+ end
94
+ unpack_dir
83
95
  when :github
84
96
  require "octokit"
85
97
 
@@ -527,6 +527,9 @@ module Berkshelf
527
527
  alias_method :message, :to_s
528
528
  end
529
529
 
530
+ class CookbookSyntaxError < BerkshelfError; end
531
+ class RedirectLimitReached < BerkshelfError; end
532
+
530
533
  class MissingLockfileCookbookVersion < CookbookNotFound
531
534
  set_status_code(149)
532
535
 
@@ -19,7 +19,7 @@ module Berkshelf
19
19
  #
20
20
  # @return [~BaseLocation, nil]
21
21
  def init(dependency, options = {})
22
- if klass = klass_from_options(options)
22
+ if ( klass = klass_from_options(options) )
23
23
  klass.new(dependency, options)
24
24
  else
25
25
  nil
@@ -61,7 +61,7 @@ module Berkshelf
61
61
 
62
62
  begin
63
63
  cookbook = CachedCookbook.from_path(path)
64
- rescue Ridley::Errors::RidleyError => e
64
+ rescue => e
65
65
  raise InternalError, "The following error occurred while reading the " \
66
66
  "cookbook `#{dependency.name}':\n#{e.class}: #{e.message}"
67
67
  end
@@ -1,4 +1,5 @@
1
1
  require_relative "dependency"
2
+ require "chef/environment"
2
3
 
3
4
  module Berkshelf
4
5
  class Lockfile
@@ -57,7 +58,7 @@ module Berkshelf
57
58
  @dependencies = {}
58
59
  @graph = Graph.new(self)
59
60
 
60
- parse if File.exists?(@filepath)
61
+ parse if File.exist?(@filepath)
61
62
  end
62
63
 
63
64
  # Parse the lockfile.
@@ -75,7 +76,7 @@ module Berkshelf
75
76
  # @return [Boolean]
76
77
  # true if this lockfile exists on the disk, false otherwise
77
78
  def present?
78
- File.exists?(filepath) && !File.read(filepath).strip.empty?
79
+ File.exist?(filepath) && !File.read(filepath).strip.empty?
79
80
  end
80
81
 
81
82
  # Determine if we can "trust" this lockfile. A lockfile is trustworthy if:
@@ -113,7 +114,7 @@ module Berkshelf
113
114
  return false
114
115
  end
115
116
 
116
- if cookbook = locked.cached_cookbook
117
+ if ( cookbook = locked.cached_cookbook )
117
118
  Berkshelf.log.debug " Detected there is a cached cookbook"
118
119
 
119
120
  unless (cookbook.dependencies.keys - graphed.dependencies.keys).empty?
@@ -203,8 +204,8 @@ module Berkshelf
203
204
  # if you are locking cookbooks with an invalid or not-specified client
204
205
  # configuration
205
206
  def apply(name, options = {})
206
- locks = graph.locks.inject({}) do |hash, (name, dependency)|
207
- hash[name] = "= #{dependency.locked_version}"
207
+ locks = graph.locks.inject({}) do |hash, (dep_name, dependency)|
208
+ hash[dep_name] = "= #{dependency.locked_version}"
208
209
  hash
209
210
  end
210
211
 
@@ -212,11 +213,14 @@ module Berkshelf
212
213
  update_environment_file(options[:envfile], locks) if options[:envfile]
213
214
  else
214
215
  Berkshelf.ridley_connection(options) do |connection|
215
- environment = connection.environment.find(name)
216
-
217
- raise EnvironmentNotFound.new(name) if environment.nil?
216
+ environment =
217
+ begin
218
+ Chef::Environment.from_hash(connection.get("environments/#{name}"))
219
+ rescue Berkshelf::APIClient::ServiceNotFound
220
+ raise EnvironmentNotFound.new(name)
221
+ end
218
222
 
219
- environment.cookbook_versions = locks
223
+ environment.cookbook_versions locks
220
224
  environment.save unless options[:envfile]
221
225
  end
222
226
  end
@@ -314,7 +318,7 @@ module Berkshelf
314
318
  # @raise [EnvironmentFileNotFound]
315
319
  # If environment file doesn't exist
316
320
  def update_environment_file(environment_file, locks)
317
- unless File.exists?(environment_file)
321
+ unless File.exist?(environment_file)
318
322
  raise EnvironmentFileNotFound.new(environment_file)
319
323
  end
320
324
 
@@ -431,7 +435,7 @@ module Berkshelf
431
435
  # constraints are satisfied by it.
432
436
  dependency.locked_version = graphed.version
433
437
 
434
- if cookbook = dependency.cached_cookbook
438
+ if ( cookbook = dependency.cached_cookbook )
435
439
  Berkshelf.log.debug " Cached cookbook exists"
436
440
  Berkshelf.log.debug " Updating cookbook dependencies if required"
437
441
  graphed.set_dependencies(cookbook.dependencies)
@@ -799,8 +803,8 @@ module Berkshelf
799
803
  out << " #{name} (#{item.version})\n"
800
804
 
801
805
  unless item.dependencies.empty?
802
- item.dependencies.sort.each do |name, constraint|
803
- out << " #{name} (#{constraint})\n"
806
+ item.dependencies.sort.each do |dep_name, constraint|
807
+ out << " #{dep_name} (#{constraint})\n"
804
808
  end
805
809
  end
806
810
  end
@@ -1,5 +1,66 @@
1
1
  module Berkshelf
2
- class Logger < Ridley::Logging::Logger
2
+ class Logger < Logger
3
+ def initialize(device = STDOUT)
4
+ super
5
+ self.level = Logger::WARN
6
+ @filter_params = Array.new
7
+ end
8
+
9
+ # Reimplements Logger#add adding message filtering. The info,
10
+ # warn, debug, error, and fatal methods all call add.
11
+ #
12
+ # @param [Fixnum] severity
13
+ # an integer measuing the severity - Logger::INFO, etc.
14
+ # @param [String] message = nil
15
+ # the message to log
16
+ # @param [String] progname = nil
17
+ # the program name performing the logging
18
+ # @param &block
19
+ # a block that will be evaluated (for complicated logging)
20
+ #
21
+ # @example
22
+ # log.filter_param("hello")
23
+ # log.info("hello world!") => "FILTERED world!"
24
+ #
25
+ # @return [Boolean]
26
+ def add(severity, message = nil, progname = nil, &block)
27
+ severity ||= Logger::UNKNOWN
28
+ if @logdev.nil? || severity < (@level)
29
+ return true
30
+ end
31
+ progname ||= @progname
32
+ if message.nil?
33
+ if block_given?
34
+ message = yield
35
+ else
36
+ message = progname
37
+ progname = @progname
38
+ end
39
+ end
40
+ @logdev.write(
41
+ format_message(format_severity(severity), Time.now, progname, filter(message)))
42
+ true
43
+ end
44
+
45
+ def filter_params
46
+ @filter_params.dup
47
+ end
48
+
49
+ def filter_param(param)
50
+ @filter_params << param unless filter_params.include?(param)
51
+ end
52
+
53
+ def clear_filter_params
54
+ @filter_params.clear
55
+ end
56
+
57
+ def filter(message)
58
+ filter_params.each do |param|
59
+ message.gsub!(param.to_s, "FILTERED")
60
+ end
61
+ message
62
+ end
63
+
3
64
  alias_method :fatal, :error
4
65
 
5
66
  def deprecate(message)
@@ -15,7 +15,7 @@ module Berkshelf
15
15
  class Packager
16
16
  class << self
17
17
  def validate_destination(path)
18
- path = path.to_s
18
+ path.to_s
19
19
  end
20
20
  end
21
21
 
@@ -93,7 +93,7 @@ module Berkshelf
93
93
  # @return [Dependency]
94
94
  def [](demand)
95
95
  name = demand.respond_to?(:name) ? demand.name : demand.to_s
96
- demands.find { |demand| demand.name == name }
96
+ demands.find { |d| d.name == name }
97
97
  end
98
98
  alias_method :get_demand, :[]
99
99
 
@@ -26,6 +26,11 @@ module Berkshelf
26
26
  super(opts[:server_url].to_s, **chef_opts)
27
27
  end
28
28
 
29
+ # for compat with Ridley::Connection
30
+ def server_url
31
+ url
32
+ end
33
+
29
34
  def get(url)
30
35
  super(url)
31
36
  rescue Net::HTTPExceptions => e
@@ -42,10 +47,24 @@ module Berkshelf
42
47
  rescue Errno::EHOSTUNREACH, Errno::ECONNREFUSED => e
43
48
  raise Berkshelf::APIClient::ServiceUnavailable, e
44
49
  end
50
+
51
+ module ClassMethods
52
+ def new_client(**opts, &block)
53
+ client = new(**opts)
54
+ yield client
55
+ # ensure
56
+ # FIXME: does Chef::HTTP support close anywhere? this will just leak open fds
57
+ end
58
+ end
59
+
60
+ def self.included(klass)
61
+ klass.extend ClassMethods
62
+ end
63
+
45
64
  end
46
65
 
47
66
  # This is for simple HTTP
48
- class RidleyCompatSimple < Chef::ServerAPI
67
+ class RidleyCompatSimple < ::Chef::ServerAPI
49
68
  use Chef::HTTP::Decompressor
50
69
  use Chef::HTTP::CookieManager
51
70
  use Chef::HTTP::ValidateContentLength
@@ -54,7 +73,7 @@ module Berkshelf
54
73
  end
55
74
 
56
75
  # This is for JSON-REST
57
- class RidleyCompatJSON < Chef::HTTP::SimpleJSON
76
+ class RidleyCompatJSON < ::Chef::HTTP::SimpleJSON
58
77
  use Chef::HTTP::JSONInput
59
78
  use Chef::HTTP::JSONOutput
60
79
  use Chef::HTTP::CookieManager
@@ -67,7 +86,7 @@ module Berkshelf
67
86
 
68
87
  # RidleyCompat is the ServerAPI, but we inherit from Chef::HTTP::Simple and then include all our middlewares
69
88
  # and then need to include our own CompatAPI. The end result is a ridley-esque way of talking to a chef server.
70
- class RidleyCompat < Chef::HTTP::Simple
89
+ class RidleyCompat < ::Chef::HTTP::Simple
71
90
  use Chef::HTTP::JSONInput
72
91
  use Chef::HTTP::JSONOutput
73
92
  use Chef::HTTP::CookieManager
@@ -1,3 +1,8 @@
1
+ require "chef/cookbook/chefignore"
2
+ require "chef/cookbook/cookbook_version_loader"
3
+ require "chef/cookbook_uploader"
4
+ require "chef/exceptions"
5
+
1
6
  module Berkshelf
2
7
  class Uploader
3
8
  attr_reader :berksfile
@@ -8,7 +13,7 @@ module Berkshelf
8
13
  def initialize(berksfile, *args)
9
14
  @berksfile = berksfile
10
15
  @lockfile = berksfile.lockfile
11
- opts = args.last.respond_to?(:to_hash) ? args.pop.to_hash.symbolize_keys : {}
16
+ opts = args.last.respond_to?(:to_hash) ? args.pop.to_hash.each_with_object({}) { |(k, v), m| m[k.to_sym] = v } : {}
12
17
 
13
18
  @options = {
14
19
  force: false,
@@ -48,69 +53,92 @@ module Berkshelf
48
53
  Berkshelf.log.info "Starting upload"
49
54
 
50
55
  Berkshelf.ridley_connection(options) do |connection|
51
- cookbooks.each do |cookbook|
52
- Berkshelf.log.debug " Uploading #{cookbook}"
56
+ # this is a hack to work around a bug in chef 13.0-13.2 protocol negotiation on POST requests, its only
57
+ # use is to force protocol negotiation via a GET request -- it doesn't matter if it 404s. once we do not
58
+ # support those early 13.x versions this line can be safely deleted.
59
+ connection.get("users/#{Berkshelf.config.chef.node_name}") rescue nil
53
60
 
61
+ cookbooks.map do |cookbook|
54
62
  begin
55
- connection.cookbook.upload(cookbook.path,
56
- name: cookbook.cookbook_name,
57
- force: options[:force],
58
- freeze: options[:freeze],
59
- validate: options[:validate]
60
- )
61
-
62
- Berkshelf.formatter.uploaded(cookbook, connection)
63
- rescue Ridley::Errors::FrozenCookbook
64
- if options[:halt_on_frozen]
65
- raise FrozenCookbook.new(cookbook)
63
+ compiled_metadata = cookbook.compile_metadata
64
+ cookbook.reload if compiled_metadata
65
+ cookbook_version = cookbook.cookbook_version
66
+ Berkshelf.log.debug " Uploading #{cookbook}"
67
+ cookbook_version.freeze_version if options[:freeze]
68
+
69
+ # another two lines that are necessary for chef < 13.2 support (affects 11.x/12.x as well)
70
+ cookbook_version.metadata.maintainer "" if cookbook_version.metadata.maintainer.nil?
71
+ cookbook_version.metadata.maintainer_email "" if cookbook_version.metadata.maintainer_email.nil?
72
+
73
+ begin
74
+ Chef::CookbookUploader.new(
75
+ [ cookbook_version ],
76
+ force: options[:force],
77
+ concurrency: 1, # sadly
78
+ rest: connection
79
+ ).upload_cookbooks
80
+ Berkshelf.formatter.uploaded(cookbook, connection)
81
+ rescue Chef::Exceptions::CookbookFrozen
82
+ if options[:halt_on_frozen]
83
+ raise FrozenCookbook.new(cookbook)
84
+ end
85
+ Berkshelf.formatter.skipping(cookbook, connection)
86
+ end
87
+ ensure
88
+ if compiled_metadata
89
+ # this is necessary on windows to clean up the ruby object that was pointing at the file
90
+ # so that we can reliably delete it. windows is terrible.
91
+ GC.start
92
+ File.unlink(compiled_metadata)
66
93
  end
67
-
68
- Berkshelf.formatter.skipping(cookbook, connection)
69
94
  end
70
95
  end
71
96
  end
72
97
  end
73
98
 
74
- # Filter cookbooks based off the list of dependencies in the Berksfile.
75
- #
76
- # This method is secretly recursive. It iterates over each dependency in
77
- # the Berksfile (using {Berksfile#dependencies} to account for filters)
78
- # and retrieves that cookbook, it's dependencies, and the recusive
79
- # dependencies, but iteratively.
80
- #
81
- # @return [Array<CachedCookbook>]
82
- #
99
+ # Lookup dependencies in a cookbook and iterate to return dependencies of dependencies.
100
+ #
101
+ # This method is recursive. It iterates over a cookbook's dependencies
102
+ # and their dependencies in order to return an array of cookbooks, starting
103
+ # with the cookbook passed and followed by it's dependencies.
104
+ #
105
+ # @return [Array<CachedCookbook>]
106
+ #
107
+ def lookup_dependencies(cookbook, dependencies = [], checked = {})
108
+ Berkshelf.log.debug " Looking up dependencies for #{cookbook}"
109
+ lockfile.graph.find(cookbook).dependencies.each do |name, _|
110
+ next if checked[name]
111
+
112
+ dependencies << name
113
+
114
+ checked[name] = true
115
+
116
+ lookup_dependencies(name, dependencies, checked) unless lockfile.graph.find(name).dependencies.empty?
117
+ end
118
+
119
+ dependencies
120
+ end
121
+
122
+ # Filter cookbooks based off the list of dependencies in the Berksfile.
123
+ #
124
+ # This method is secretly recursive. It iterates over each dependency in
125
+ # the Berksfile (using {Berksfile#dependencies} to account for filters)
126
+ # and retrieves that cookbook, it's dependencies, and the recusive
127
+ # dependencies, but iteratively.
128
+ #
129
+ # @return [Array<CachedCookbook>]
130
+ #
83
131
  def filtered_cookbooks
84
132
  # Create a copy of the dependencies. We need to make a copy, or else
85
133
  # we would be adding dependencies directly to the Berksfile object, and
86
134
  # that would be a bad idea...
87
135
  dependencies = berksfile.dependencies.map(&:name)
88
136
 
89
- checked = {}
90
- cookbooks = {}
91
-
92
- dependencies.each do |dependency|
93
- next if checked[dependency]
94
-
95
- lockfile.graph.find(dependency).dependencies.each do |name, _|
96
- cookbooks[name] ||= lockfile.retrieve(name)
97
- dependencies << name
98
- end
99
-
100
- checked[dependency] = true
101
- cookbooks[dependency] ||= lockfile.retrieve(dependency)
137
+ cookbook_order = dependencies.each do |dependency|
138
+ lookup_dependencies(dependency, dependencies)
102
139
  end
103
140
 
104
- # This is a temporary change and will be removed in a future release. We should
105
- # add the ability to define a custom uploader which would allow the authors of Chef-Guard
106
- # to define their upload strategy instead of using Ridley.
107
- #
108
- # See https://github.com/berkshelf/berkshelf/pull/1316 for details.
109
- if Berkshelf.chef_config.knife[:chef_guard] == true
110
- cookbooks.values
111
- else
112
- cookbooks.values.sort
113
- end
141
+ cookbook_order.reverse.map { |dependency| lockfile.retrieve(dependency) }.uniq
114
142
  end
115
143
  end
116
144
  end