berkshelf 3.0.0.beta6 → 3.0.0.beta7
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.
- checksums.yaml +4 -4
 - data/features/berksfile.feature +2 -0
 - data/features/commands/apply.feature +1 -1
 - data/features/commands/contingent.feature +5 -3
 - data/features/commands/install.feature +40 -40
 - data/features/commands/list.feature +42 -20
 - data/features/commands/outdated.feature +60 -16
 - data/features/commands/show.feature +51 -8
 - data/features/commands/update.feature +43 -15
 - data/features/commands/upload.feature +4 -1
 - data/features/commands/vendor.feature +27 -0
 - data/features/json_formatter.feature +20 -8
 - data/features/lockfile.feature +192 -71
 - data/generator_files/CHANGELOG.md.erb +5 -0
 - data/lib/berkshelf/berksfile.rb +166 -139
 - data/lib/berkshelf/cli.rb +33 -30
 - data/lib/berkshelf/cookbook_generator.rb +1 -0
 - data/lib/berkshelf/dependency.rb +64 -14
 - data/lib/berkshelf/downloader.rb +7 -10
 - data/lib/berkshelf/errors.rb +59 -11
 - data/lib/berkshelf/formatters/human_readable.rb +23 -36
 - data/lib/berkshelf/formatters/json.rb +25 -29
 - data/lib/berkshelf/installer.rb +111 -122
 - data/lib/berkshelf/locations/git_location.rb +22 -9
 - data/lib/berkshelf/locations/mercurial_location.rb +20 -5
 - data/lib/berkshelf/locations/path_location.rb +22 -7
 - data/lib/berkshelf/lockfile.rb +435 -203
 - data/lib/berkshelf/resolver.rb +4 -2
 - data/lib/berkshelf/source.rb +10 -1
 - data/lib/berkshelf/version.rb +1 -1
 - data/spec/fixtures/cookbooks/example_cookbook/Berksfile.lock +3 -4
 - data/spec/fixtures/lockfiles/2.0.lock +17 -0
 - data/spec/fixtures/lockfiles/blank.lock +0 -0
 - data/spec/fixtures/lockfiles/default.lock +18 -10
 - data/spec/fixtures/lockfiles/empty.lock +3 -0
 - data/spec/unit/berkshelf/berksfile_spec.rb +31 -74
 - data/spec/unit/berkshelf/cookbook_generator_spec.rb +4 -0
 - data/spec/unit/berkshelf/installer_spec.rb +4 -7
 - data/spec/unit/berkshelf/lockfile_parser_spec.rb +124 -0
 - data/spec/unit/berkshelf/lockfile_spec.rb +140 -163
 - metadata +11 -6
 - data/features/licenses.feature +0 -79
 - data/features/step_definitions/lockfile_steps.rb +0 -57
 
    
        data/lib/berkshelf/berksfile.rb
    CHANGED
    
    | 
         @@ -3,22 +3,23 @@ require_relative "packager" 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Berkshelf
         
     | 
| 
       4 
4 
     | 
    
         
             
              class Berksfile
         
     | 
| 
       5 
5 
     | 
    
         
             
                class << self
         
     | 
| 
       6 
     | 
    
         
            -
                  #  
     | 
| 
      
 6 
     | 
    
         
            +
                  # Instantiate a Berksfile from the given options. This method is used
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # heavily by the CLI to reduce duplication.
         
     | 
| 
       7 
8 
     | 
    
         
             
                  #
         
     | 
| 
       8 
     | 
    
         
            -
                  # @ 
     | 
| 
       9 
     | 
    
         
            -
                  def  
     | 
| 
       10 
     | 
    
         
            -
                     
     | 
| 
      
 9 
     | 
    
         
            +
                  # @param (see Berksfile#initialize)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  def from_options(options = {})
         
     | 
| 
      
 11 
     | 
    
         
            +
                    from_file(options[:berksfile], options.slice(:except, :only))
         
     | 
| 
       11 
12 
     | 
    
         
             
                  end
         
     | 
| 
       12 
13 
     | 
    
         | 
| 
       13 
14 
     | 
    
         
             
                  # @param [#to_s] file
         
     | 
| 
       14 
15 
     | 
    
         
             
                  #   a path on disk to a Berksfile to instantiate from
         
     | 
| 
       15 
16 
     | 
    
         
             
                  #
         
     | 
| 
       16 
17 
     | 
    
         
             
                  # @return [Berksfile]
         
     | 
| 
       17 
     | 
    
         
            -
                  def from_file(file)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def from_file(file, options = {})
         
     | 
| 
       18 
19 
     | 
    
         
             
                    raise BerksfileNotFound.new(file) unless File.exist?(file)
         
     | 
| 
       19 
20 
     | 
    
         | 
| 
       20 
21 
     | 
    
         
             
                    begin
         
     | 
| 
       21 
     | 
    
         
            -
                      new(file).dsl_eval_file(file)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      new(file, options).dsl_eval_file(file)
         
     | 
| 
       22 
23 
     | 
    
         
             
                    rescue => ex
         
     | 
| 
       23 
24 
     | 
    
         
             
                      raise BerksfileReadError.new(ex)
         
     | 
| 
       24 
25 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -38,18 +39,37 @@ module Berkshelf 
     | 
|
| 
       38 
39 
     | 
    
         
             
                expose_method :cookbook
         
     | 
| 
       39 
40 
     | 
    
         
             
                expose_method :group
         
     | 
| 
       40 
41 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                @@active_group = nil
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
42 
     | 
    
         
             
                # @return [String]
         
     | 
| 
       44 
43 
     | 
    
         
             
                #   The path on disk to the file representing this instance of Berksfile
         
     | 
| 
       45 
44 
     | 
    
         
             
                attr_reader :filepath
         
     | 
| 
       46 
45 
     | 
    
         | 
| 
      
 46 
     | 
    
         
            +
                # Create a new Berksfile object.
         
     | 
| 
      
 47 
     | 
    
         
            +
                #
         
     | 
| 
       47 
48 
     | 
    
         
             
                # @param [String] path
         
     | 
| 
       48 
49 
     | 
    
         
             
                #   path on disk to the file containing the contents of this Berksfile
         
     | 
| 
       49 
     | 
    
         
            -
                 
     | 
| 
      
 50 
     | 
    
         
            +
                #
         
     | 
| 
      
 51 
     | 
    
         
            +
                # @option options [Symbol, Array<String>] :except
         
     | 
| 
      
 52 
     | 
    
         
            +
                #   Group(s) to exclude which will cause any dependencies marked as a member of the
         
     | 
| 
      
 53 
     | 
    
         
            +
                #   group to not be installed
         
     | 
| 
      
 54 
     | 
    
         
            +
                # @option options [Symbol, Array<String>] :only
         
     | 
| 
      
 55 
     | 
    
         
            +
                #   Group(s) to include which will cause any dependencies marked as a member of the
         
     | 
| 
      
 56 
     | 
    
         
            +
                #   group to be installed and all others to be ignored
         
     | 
| 
      
 57 
     | 
    
         
            +
                def initialize(path, options = {})
         
     | 
| 
       50 
58 
     | 
    
         
             
                  @filepath         = path
         
     | 
| 
       51 
59 
     | 
    
         
             
                  @dependencies     = Hash.new
         
     | 
| 
       52 
     | 
    
         
            -
                  @sources          =  
     | 
| 
      
 60 
     | 
    
         
            +
                  @sources          = Hash.new
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  if options[:except] && options[:only]
         
     | 
| 
      
 63 
     | 
    
         
            +
                    raise Berkshelf::ArgumentError, 'Cannot specify both :except and :only!'
         
     | 
| 
      
 64 
     | 
    
         
            +
                  elsif options[:except]
         
     | 
| 
      
 65 
     | 
    
         
            +
                    except = Array(options[:except]).collect(&:to_sym)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    @filter = ->(dependency) { (except & dependency.groups).empty? }
         
     | 
| 
      
 67 
     | 
    
         
            +
                  elsif options[:only]
         
     | 
| 
      
 68 
     | 
    
         
            +
                    only = Array(options[:only]).collect(&:to_sym)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    @filter = ->(dependency) { !(only & dependency.groups).empty? }
         
     | 
| 
      
 70 
     | 
    
         
            +
                  else
         
     | 
| 
      
 71 
     | 
    
         
            +
                    @filter = ->(dependency) { true }
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
       53 
73 
     | 
    
         
             
                end
         
     | 
| 
       54 
74 
     | 
    
         | 
| 
       55 
75 
     | 
    
         
             
                # Add a cookbook dependency to the Berksfile to be retrieved and have its dependencies recursively retrieved
         
     | 
| 
         @@ -96,17 +116,17 @@ module Berkshelf 
     | 
|
| 
       96 
116 
     | 
    
         
             
                  options[:path] &&= File.expand_path(options[:path], File.dirname(filepath))
         
     | 
| 
       97 
117 
     | 
    
         
             
                  options[:group] = Array(options[:group])
         
     | 
| 
       98 
118 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
                  if  
     | 
| 
       100 
     | 
    
         
            -
                    options[:group] +=  
     | 
| 
      
 119 
     | 
    
         
            +
                  if @active_group
         
     | 
| 
      
 120 
     | 
    
         
            +
                    options[:group] += @active_group
         
     | 
| 
       101 
121 
     | 
    
         
             
                  end
         
     | 
| 
       102 
122 
     | 
    
         | 
| 
       103 
123 
     | 
    
         
             
                  add_dependency(name, constraint, options)
         
     | 
| 
       104 
124 
     | 
    
         
             
                end
         
     | 
| 
       105 
125 
     | 
    
         | 
| 
       106 
126 
     | 
    
         
             
                def group(*args)
         
     | 
| 
       107 
     | 
    
         
            -
                   
     | 
| 
      
 127 
     | 
    
         
            +
                  @active_group = args
         
     | 
| 
       108 
128 
     | 
    
         
             
                  yield
         
     | 
| 
       109 
     | 
    
         
            -
                   
     | 
| 
      
 129 
     | 
    
         
            +
                  @active_group = nil
         
     | 
| 
       110 
130 
     | 
    
         
             
                end
         
     | 
| 
       111 
131 
     | 
    
         | 
| 
       112 
132 
     | 
    
         
             
                # Use a Cookbook metadata file to determine additional cookbook dependencies to retrieve. All
         
     | 
| 
         @@ -143,13 +163,22 @@ module Berkshelf 
     | 
|
| 
       143 
163 
     | 
    
         
             
                #
         
     | 
| 
       144 
164 
     | 
    
         
             
                # @return [Array<Berkshelf::Source>]
         
     | 
| 
       145 
165 
     | 
    
         
             
                def source(api_url)
         
     | 
| 
       146 
     | 
    
         
            -
                   
     | 
| 
       147 
     | 
    
         
            -
                  @sources.push(new_source) unless @sources.include?(new_source)
         
     | 
| 
      
 166 
     | 
    
         
            +
                  @sources[api_url] = Source.new(api_url)
         
     | 
| 
       148 
167 
     | 
    
         
             
                end
         
     | 
| 
       149 
168 
     | 
    
         | 
| 
       150 
169 
     | 
    
         
             
                # @return [Array<Berkshelf::Source>]
         
     | 
| 
       151 
170 
     | 
    
         
             
                def sources
         
     | 
| 
       152 
     | 
    
         
            -
                  @sources.empty? 
     | 
| 
      
 171 
     | 
    
         
            +
                  if @sources.empty?
         
     | 
| 
      
 172 
     | 
    
         
            +
                    raise NoAPISourcesDefined
         
     | 
| 
      
 173 
     | 
    
         
            +
                  else
         
     | 
| 
      
 174 
     | 
    
         
            +
                    @sources.values
         
     | 
| 
      
 175 
     | 
    
         
            +
                  end
         
     | 
| 
      
 176 
     | 
    
         
            +
                end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
                # @param [Dependency] dependency
         
     | 
| 
      
 179 
     | 
    
         
            +
                #   the dependency to find the source for
         
     | 
| 
      
 180 
     | 
    
         
            +
                def source_for(name, version)
         
     | 
| 
      
 181 
     | 
    
         
            +
                  sources.find { |source| source.cookbook(name, version) }
         
     | 
| 
       153 
182 
     | 
    
         
             
                end
         
     | 
| 
       154 
183 
     | 
    
         | 
| 
       155 
184 
     | 
    
         
             
                # @todo remove in Berkshelf 4.0
         
     | 
| 
         @@ -232,36 +261,27 @@ module Berkshelf 
     | 
|
| 
       232 
261 
     | 
    
         
             
                  @dependencies.has_key?(dependency.to_s)
         
     | 
| 
       233 
262 
     | 
    
         
             
                end
         
     | 
| 
       234 
263 
     | 
    
         | 
| 
       235 
     | 
    
         
            -
             
     | 
| 
       236 
     | 
    
         
            -
                #   Group(s) to exclude which will cause any dependencies marked as a member of the
         
     | 
| 
       237 
     | 
    
         
            -
                #   group to not be installed
         
     | 
| 
       238 
     | 
    
         
            -
                # @option options [Symbol, Array] :only
         
     | 
| 
       239 
     | 
    
         
            -
                #   Group(s) to include which will cause any dependencies marked as a member of the
         
     | 
| 
       240 
     | 
    
         
            -
                #   group to be installed and all others to be ignored
         
     | 
| 
       241 
     | 
    
         
            -
                # @option cookbooks [String, Array] :cookbooks
         
     | 
| 
       242 
     | 
    
         
            -
                #   Names of the cookbooks to retrieve dependencies for
         
     | 
| 
       243 
     | 
    
         
            -
                #
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
       244 
265 
     | 
    
         
             
                # @return [Array<Berkshelf::Dependency>]
         
     | 
| 
       245 
     | 
    
         
            -
                def dependencies 
     | 
| 
       246 
     | 
    
         
            -
                   
     | 
| 
       247 
     | 
    
         
            -
             
     | 
| 
       248 
     | 
    
         
            -
             
     | 
| 
       249 
     | 
    
         
            -
             
     | 
| 
       250 
     | 
    
         
            -
             
     | 
| 
       251 
     | 
    
         
            -
             
     | 
| 
       252 
     | 
    
         
            -
             
     | 
| 
       253 
     | 
    
         
            -
             
     | 
| 
       254 
     | 
    
         
            -
             
     | 
| 
       255 
     | 
    
         
            -
             
     | 
| 
       256 
     | 
    
         
            -
             
     | 
| 
       257 
     | 
    
         
            -
             
     | 
| 
       258 
     | 
    
         
            -
             
     | 
| 
       259 
     | 
    
         
            -
             
     | 
| 
       260 
     | 
    
         
            -
             
     | 
| 
       261 
     | 
    
         
            -
             
     | 
| 
       262 
     | 
    
         
            -
             
     | 
| 
       263 
     | 
    
         
            -
             
     | 
| 
       264 
     | 
    
         
            -
                  end
         
     | 
| 
      
 266 
     | 
    
         
            +
                def dependencies
         
     | 
| 
      
 267 
     | 
    
         
            +
                  @dependencies.values.sort.select(&@filter)
         
     | 
| 
      
 268 
     | 
    
         
            +
                end
         
     | 
| 
      
 269 
     | 
    
         
            +
             
     | 
| 
      
 270 
     | 
    
         
            +
                #
         
     | 
| 
      
 271 
     | 
    
         
            +
                # Behaves the same as {Berksfile#dependencies}, but this method returns an
         
     | 
| 
      
 272 
     | 
    
         
            +
                # array of CachedCookbook objects instead of dependency objects. This method
         
     | 
| 
      
 273 
     | 
    
         
            +
                # relies on the {Berksfile#retrieve_locked} method to load the proper
         
     | 
| 
      
 274 
     | 
    
         
            +
                # cached cookbook from the Berksfile + lockfile combination.
         
     | 
| 
      
 275 
     | 
    
         
            +
                #
         
     | 
| 
      
 276 
     | 
    
         
            +
                # @see [Berksfile#dependencies]
         
     | 
| 
      
 277 
     | 
    
         
            +
                #   for a description of the +options+ hash
         
     | 
| 
      
 278 
     | 
    
         
            +
                # @see [Berksfile#retrieve_locked]
         
     | 
| 
      
 279 
     | 
    
         
            +
                #   for a list of possible exceptions that might be raised and why
         
     | 
| 
      
 280 
     | 
    
         
            +
                #
         
     | 
| 
      
 281 
     | 
    
         
            +
                # @return [Array<CachedCookbook>]
         
     | 
| 
      
 282 
     | 
    
         
            +
                #
         
     | 
| 
      
 283 
     | 
    
         
            +
                def cookbooks
         
     | 
| 
      
 284 
     | 
    
         
            +
                  dependencies.map { |dependency| retrieve_locked(dependency) }
         
     | 
| 
       265 
285 
     | 
    
         
             
                end
         
     | 
| 
       266 
286 
     | 
    
         | 
| 
       267 
287 
     | 
    
         
             
                # Find a dependency defined in this berksfile by name.
         
     | 
| 
         @@ -336,36 +356,30 @@ module Berkshelf 
     | 
|
| 
       336 
356 
     | 
    
         
             
                #
         
     | 
| 
       337 
357 
     | 
    
         
             
                # 3. Write out a new lockfile.
         
     | 
| 
       338 
358 
     | 
    
         
             
                #
         
     | 
| 
       339 
     | 
    
         
            -
                # @option options [Symbol, Array] :except
         
     | 
| 
       340 
     | 
    
         
            -
                #   Group(s) to exclude which will cause any dependencies marked as a member of the
         
     | 
| 
       341 
     | 
    
         
            -
                #   group to not be installed
         
     | 
| 
       342 
     | 
    
         
            -
                # @option options [Symbol, Array] :only
         
     | 
| 
       343 
     | 
    
         
            -
                #   Group(s) to include which will cause any dependencies marked as a member of the
         
     | 
| 
       344 
     | 
    
         
            -
                #   group to be installed and all others to be ignored
         
     | 
| 
       345 
     | 
    
         
            -
                # @option cookbooks [String, Array] :cookbooks
         
     | 
| 
       346 
     | 
    
         
            -
                #   Names of the cookbooks to retrieve dependencies for
         
     | 
| 
       347 
     | 
    
         
            -
                #
         
     | 
| 
       348 
359 
     | 
    
         
             
                # @raise [Berkshelf::OutdatedDependency]
         
     | 
| 
       349 
360 
     | 
    
         
             
                #   if the lockfile constraints do not satisfy the Berksfile constraints
         
     | 
| 
       350 
361 
     | 
    
         
             
                #
         
     | 
| 
       351 
362 
     | 
    
         
             
                # @return [Array<Berkshelf::CachedCookbook>]
         
     | 
| 
       352 
     | 
    
         
            -
                def install 
     | 
| 
       353 
     | 
    
         
            -
                  Installer.new(self).run 
     | 
| 
      
 363 
     | 
    
         
            +
                def install
         
     | 
| 
      
 364 
     | 
    
         
            +
                  Installer.new(self).run
         
     | 
| 
       354 
365 
     | 
    
         
             
                end
         
     | 
| 
       355 
366 
     | 
    
         | 
| 
       356 
     | 
    
         
            -
                #  
     | 
| 
       357 
     | 
    
         
            -
                # 
     | 
| 
       358 
     | 
    
         
            -
                # 
     | 
| 
       359 
     | 
    
         
            -
                # @option options [Symbol, Array] :only
         
     | 
| 
       360 
     | 
    
         
            -
                #   Group(s) to include which will cause any dependencies marked as a member of the
         
     | 
| 
       361 
     | 
    
         
            -
                #   group to be installed and all others to be ignored
         
     | 
| 
       362 
     | 
    
         
            -
                # @option cookbooks [String, Array] :cookbooks
         
     | 
| 
      
 367 
     | 
    
         
            +
                # Update the given set of dependencies (or all if no names are given).
         
     | 
| 
      
 368 
     | 
    
         
            +
                #
         
     | 
| 
      
 369 
     | 
    
         
            +
                # @option options [String, Array<String>] :cookbooks
         
     | 
| 
       363 
370 
     | 
    
         
             
                #   Names of the cookbooks to retrieve dependencies for
         
     | 
| 
       364 
     | 
    
         
            -
                def update( 
     | 
| 
       365 
     | 
    
         
            -
                  validate_cookbook_names!( 
     | 
| 
      
 371 
     | 
    
         
            +
                def update(*names)
         
     | 
| 
      
 372 
     | 
    
         
            +
                  validate_cookbook_names!(names)
         
     | 
| 
      
 373 
     | 
    
         
            +
             
     | 
| 
      
 374 
     | 
    
         
            +
                  # Calculate the list of cookbooks to unlock
         
     | 
| 
      
 375 
     | 
    
         
            +
                  if names.empty?
         
     | 
| 
      
 376 
     | 
    
         
            +
                    list = dependencies
         
     | 
| 
      
 377 
     | 
    
         
            +
                  else
         
     | 
| 
      
 378 
     | 
    
         
            +
                    list = dependencies.select { |dependency| names.include?(dependency.name) }
         
     | 
| 
      
 379 
     | 
    
         
            +
                  end
         
     | 
| 
       366 
380 
     | 
    
         | 
| 
       367 
381 
     | 
    
         
             
                  # Unlock any/all specified cookbooks
         
     | 
| 
       368 
     | 
    
         
            -
                   
     | 
| 
      
 382 
     | 
    
         
            +
                  list.each { |dependency| lockfile.unlock(dependency) }
         
     | 
| 
       369 
383 
     | 
    
         | 
| 
       370 
384 
     | 
    
         
             
                  # NOTE: We intentionally do NOT pass options to the installer
         
     | 
| 
       371 
385 
     | 
    
         
             
                  self.install
         
     | 
| 
         @@ -386,22 +400,7 @@ module Berkshelf 
     | 
|
| 
       386 
400 
     | 
    
         
             
                # @return [CachedCookbook]
         
     | 
| 
       387 
401 
     | 
    
         
             
                #   the CachedCookbook that corresponds to the given name parameter
         
     | 
| 
       388 
402 
     | 
    
         
             
                def retrieve_locked(dependency)
         
     | 
| 
       389 
     | 
    
         
            -
                   
     | 
| 
       390 
     | 
    
         
            -
             
     | 
| 
       391 
     | 
    
         
            -
                  unless locked
         
     | 
| 
       392 
     | 
    
         
            -
                    raise CookbookNotFound, "Could not find cookbook '#{dependency.to_s}'."\
         
     | 
| 
       393 
     | 
    
         
            -
                      " Try running `berks install` to download and install the missing"\
         
     | 
| 
       394 
     | 
    
         
            -
                      " dependencies."
         
     | 
| 
       395 
     | 
    
         
            -
                  end
         
     | 
| 
       396 
     | 
    
         
            -
             
     | 
| 
       397 
     | 
    
         
            -
                  unless locked.downloaded?
         
     | 
| 
       398 
     | 
    
         
            -
                    raise CookbookNotFound, "Could not find cookbook '#{locked.to_s}'."\
         
     | 
| 
       399 
     | 
    
         
            -
                      " Try running `berks install` to download and install the missing"\
         
     | 
| 
       400 
     | 
    
         
            -
                      " dependencies."
         
     | 
| 
       401 
     | 
    
         
            -
                  end
         
     | 
| 
       402 
     | 
    
         
            -
             
     | 
| 
       403 
     | 
    
         
            -
                  @dependencies[dependency.name] = locked
         
     | 
| 
       404 
     | 
    
         
            -
                  locked.cached_cookbook
         
     | 
| 
      
 403 
     | 
    
         
            +
                  lockfile.retrieve(dependency)
         
     | 
| 
       405 
404 
     | 
    
         
             
                end
         
     | 
| 
       406 
405 
     | 
    
         | 
| 
       407 
406 
     | 
    
         
             
                # The cached cookbooks installed by this Berksfile.
         
     | 
| 
         @@ -414,52 +413,54 @@ module Berkshelf 
     | 
|
| 
       414 
413 
     | 
    
         
             
                # @return [Hash<Berkshelf::Dependency, Berkshelf::CachedCookbook>]
         
     | 
| 
       415 
414 
     | 
    
         
             
                #   the list of dependencies as keys and the cached cookbook as the value
         
     | 
| 
       416 
415 
     | 
    
         
             
                def list
         
     | 
| 
       417 
     | 
    
         
            -
                   
     | 
| 
      
 416 
     | 
    
         
            +
                  validate_lockfile_present!
         
     | 
| 
      
 417 
     | 
    
         
            +
                  validate_lockfile_trusted!
         
     | 
| 
      
 418 
     | 
    
         
            +
                  validate_dependencies_installed!
         
     | 
| 
      
 419 
     | 
    
         
            +
             
     | 
| 
      
 420 
     | 
    
         
            +
                  lockfile.graph.locks.values
         
     | 
| 
       418 
421 
     | 
    
         
             
                end
         
     | 
| 
       419 
422 
     | 
    
         | 
| 
       420 
     | 
    
         
            -
                # List of all the cookbooks which have a newer version found at a source 
     | 
| 
       421 
     | 
    
         
            -
                # the constraints of your dependencies
         
     | 
| 
       422 
     | 
    
         
            -
                #
         
     | 
| 
       423 
     | 
    
         
            -
                # @option options [Symbol, Array] :except
         
     | 
| 
       424 
     | 
    
         
            -
                #   Group(s) to exclude which will cause any dependencies marked as a member of the
         
     | 
| 
       425 
     | 
    
         
            -
                #   group to not be installed
         
     | 
| 
       426 
     | 
    
         
            -
                # @option options [Symbol, Array] :only
         
     | 
| 
       427 
     | 
    
         
            -
                #   Group(s) to include which will cause any dependencies marked as a member of the
         
     | 
| 
       428 
     | 
    
         
            -
                #   group to be installed and all others to be ignored
         
     | 
| 
       429 
     | 
    
         
            -
                # @option cookbooks [String, Array] :cookbooks
         
     | 
| 
       430 
     | 
    
         
            -
                #   Whitelist of cookbooks to to check for updated versions for
         
     | 
| 
      
 423 
     | 
    
         
            +
                # List of all the cookbooks which have a newer version found at a source
         
     | 
| 
      
 424 
     | 
    
         
            +
                # that satisfies the constraints of your dependencies.
         
     | 
| 
       431 
425 
     | 
    
         
             
                #
         
     | 
| 
       432 
426 
     | 
    
         
             
                # @return [Hash]
         
     | 
| 
       433 
     | 
    
         
            -
                #   a hash of cached cookbooks and their latest version. An empty hash is 
     | 
| 
       434 
     | 
    
         
            -
                #   if there are no newer cookbooks for any of your dependencies
         
     | 
| 
      
 427 
     | 
    
         
            +
                #   a hash of cached cookbooks and their latest version. An empty hash is
         
     | 
| 
      
 428 
     | 
    
         
            +
                #   returned if there are no newer cookbooks for any of your dependencies
         
     | 
| 
       435 
429 
     | 
    
         
             
                #
         
     | 
| 
       436 
430 
     | 
    
         
             
                # @example
         
     | 
| 
       437 
431 
     | 
    
         
             
                #   berksfile.outdated #=> {
         
     | 
| 
       438 
432 
     | 
    
         
             
                #     #<CachedCookbook name="artifact"> => "0.11.2"
         
     | 
| 
       439 
433 
     | 
    
         
             
                #   }
         
     | 
| 
       440 
     | 
    
         
            -
                def outdated( 
     | 
| 
       441 
     | 
    
         
            -
                   
     | 
| 
       442 
     | 
    
         
            -
             
     | 
| 
       443 
     | 
    
         
            -
                   
     | 
| 
       444 
     | 
    
         
            -
                   
     | 
| 
       445 
     | 
    
         
            -
             
     | 
| 
       446 
     | 
    
         
            -
             
     | 
| 
      
 434 
     | 
    
         
            +
                def outdated(*names)
         
     | 
| 
      
 435 
     | 
    
         
            +
                  validate_lockfile_present!
         
     | 
| 
      
 436 
     | 
    
         
            +
                  validate_lockfile_trusted!
         
     | 
| 
      
 437 
     | 
    
         
            +
                  validate_dependencies_installed!
         
     | 
| 
      
 438 
     | 
    
         
            +
                  validate_cookbook_names!(names)
         
     | 
| 
      
 439 
     | 
    
         
            +
             
     | 
| 
      
 440 
     | 
    
         
            +
                  # Calculate the list of cookbooks to unlock
         
     | 
| 
      
 441 
     | 
    
         
            +
                  if names.empty?
         
     | 
| 
      
 442 
     | 
    
         
            +
                    list = dependencies
         
     | 
| 
      
 443 
     | 
    
         
            +
                  else
         
     | 
| 
      
 444 
     | 
    
         
            +
                    list = dependencies.select { |dependency| names.include?(dependency.name) }
         
     | 
| 
      
 445 
     | 
    
         
            +
                  end
         
     | 
| 
       447 
446 
     | 
    
         | 
| 
      
 447 
     | 
    
         
            +
                  lockfile.graph.locks.inject({}) do |hash, (name, dependency)|
         
     | 
| 
       448 
448 
     | 
    
         
             
                    sources.each do |source|
         
     | 
| 
       449 
     | 
    
         
            -
                      cookbooks = source.versions( 
     | 
| 
      
 449 
     | 
    
         
            +
                      cookbooks = source.versions(name)
         
     | 
| 
       450 
450 
     | 
    
         | 
| 
       451 
451 
     | 
    
         
             
                      latest = cookbooks.select do |cookbook|
         
     | 
| 
       452 
452 
     | 
    
         
             
                        dependency.version_constraint.satisfies?(cookbook.version) &&
         
     | 
| 
       453 
     | 
    
         
            -
                        cookbook.version !=  
     | 
| 
      
 453 
     | 
    
         
            +
                        cookbook.version.to_s != dependency.locked_version.to_s
         
     | 
| 
       454 
454 
     | 
    
         
             
                      end.sort_by { |cookbook| cookbook.version }.last
         
     | 
| 
       455 
455 
     | 
    
         | 
| 
       456 
456 
     | 
    
         
             
                      unless latest.nil?
         
     | 
| 
       457 
     | 
    
         
            -
                         
     | 
| 
      
 457 
     | 
    
         
            +
                        hash[name] ||= {}
         
     | 
| 
      
 458 
     | 
    
         
            +
                        hash[name][source.uri.to_s] = latest
         
     | 
| 
       458 
459 
     | 
    
         
             
                      end
         
     | 
| 
       459 
460 
     | 
    
         
             
                    end
         
     | 
| 
       460 
     | 
    
         
            -
                  end
         
     | 
| 
       461 
461 
     | 
    
         | 
| 
       462 
     | 
    
         
            -
             
     | 
| 
      
 462 
     | 
    
         
            +
                    hash
         
     | 
| 
      
 463 
     | 
    
         
            +
                  end
         
     | 
| 
       463 
464 
     | 
    
         
             
                end
         
     | 
| 
       464 
465 
     | 
    
         | 
| 
       465 
466 
     | 
    
         
             
                # Upload the cookbooks installed by this Berksfile
         
     | 
| 
         @@ -469,12 +470,6 @@ module Berkshelf 
     | 
|
| 
       469 
470 
     | 
    
         
             
                #   target Chef Server
         
     | 
| 
       470 
471 
     | 
    
         
             
                # @option options [Boolean] :freeze (true)
         
     | 
| 
       471 
472 
     | 
    
         
             
                #   Freeze the uploaded Cookbook on the Chef Server so that it cannot be overwritten
         
     | 
| 
       472 
     | 
    
         
            -
                # @option options [Symbol, Array] :except
         
     | 
| 
       473 
     | 
    
         
            -
                #   Group(s) to exclude which will cause any dependencies marked as a member of the
         
     | 
| 
       474 
     | 
    
         
            -
                #   group to not be installed
         
     | 
| 
       475 
     | 
    
         
            -
                # @option options [Symbol, Array] :only
         
     | 
| 
       476 
     | 
    
         
            -
                #   Group(s) to include which will cause any dependencies marked as a member of the
         
     | 
| 
       477 
     | 
    
         
            -
                #   group to be installed and all others to be ignored
         
     | 
| 
       478 
473 
     | 
    
         
             
                # @option options [String, Array] :cookbooks
         
     | 
| 
       479 
474 
     | 
    
         
             
                #   Names of the cookbooks to retrieve dependencies for
         
     | 
| 
       480 
475 
     | 
    
         
             
                # @option options [Hash] :ssl_verify (true)
         
     | 
| 
         @@ -506,9 +501,9 @@ module Berkshelf 
     | 
|
| 
       506 
501 
     | 
    
         
             
                    validate: true
         
     | 
| 
       507 
502 
     | 
    
         
             
                  }.merge(options)
         
     | 
| 
       508 
503 
     | 
    
         | 
| 
       509 
     | 
    
         
            -
                  validate_cookbook_names!(options)
         
     | 
| 
      
 504 
     | 
    
         
            +
                  validate_cookbook_names!(options[:cookbooks])
         
     | 
| 
       510 
505 
     | 
    
         | 
| 
       511 
     | 
    
         
            -
                  cached_cookbooks = install 
     | 
| 
      
 506 
     | 
    
         
            +
                  cached_cookbooks = install
         
     | 
| 
       512 
507 
     | 
    
         
             
                  cached_cookbooks = filter_to_upload(cached_cookbooks, options[:cookbooks]) if options[:cookbooks]
         
     | 
| 
       513 
508 
     | 
    
         
             
                  do_upload(cached_cookbooks, options)
         
     | 
| 
       514 
509 
     | 
    
         
             
                end
         
     | 
| 
         @@ -520,24 +515,17 @@ module Berkshelf 
     | 
|
| 
       520 
515 
     | 
    
         
             
                # @param [String] path
         
     | 
| 
       521 
516 
     | 
    
         
             
                #   the path where the tarball will be created
         
     | 
| 
       522 
517 
     | 
    
         
             
                #
         
     | 
| 
       523 
     | 
    
         
            -
                # @option options [Symbol, Array] :except
         
     | 
| 
       524 
     | 
    
         
            -
                #   Group(s) to exclude which will cause any dependencies marked as a member of the
         
     | 
| 
       525 
     | 
    
         
            -
                #   group to not be installed
         
     | 
| 
       526 
     | 
    
         
            -
                # @option options [Symbol, Array] :only
         
     | 
| 
       527 
     | 
    
         
            -
                #   Group(s) to include which will cause any dependencies marked as a member of the
         
     | 
| 
       528 
     | 
    
         
            -
                #   group to be installed and all others to be ignored
         
     | 
| 
       529 
     | 
    
         
            -
                #
         
     | 
| 
       530 
518 
     | 
    
         
             
                # @raise [Berkshelf::PackageError]
         
     | 
| 
       531 
519 
     | 
    
         
             
                #
         
     | 
| 
       532 
520 
     | 
    
         
             
                # @return [String]
         
     | 
| 
       533 
521 
     | 
    
         
             
                #   the path to the package
         
     | 
| 
       534 
     | 
    
         
            -
                def package(path 
     | 
| 
      
 522 
     | 
    
         
            +
                def package(path)
         
     | 
| 
       535 
523 
     | 
    
         
             
                  packager = Packager.new(path)
         
     | 
| 
       536 
524 
     | 
    
         
             
                  packager.validate!
         
     | 
| 
       537 
525 
     | 
    
         | 
| 
       538 
526 
     | 
    
         
             
                  outdir = Dir.mktmpdir do |temp_dir|
         
     | 
| 
       539 
527 
     | 
    
         
             
                    source = Berkshelf.ui.mute do
         
     | 
| 
       540 
     | 
    
         
            -
                      vendor(File.join(temp_dir,  
     | 
| 
      
 528 
     | 
    
         
            +
                      vendor(File.join(temp_dir, 'cookbooks'))
         
     | 
| 
       541 
529 
     | 
    
         
             
                    end
         
     | 
| 
       542 
530 
     | 
    
         
             
                    packager.run(source)
         
     | 
| 
       543 
531 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -552,16 +540,9 @@ module Berkshelf 
     | 
|
| 
       552 
540 
     | 
    
         
             
                # @param [String] destination
         
     | 
| 
       553 
541 
     | 
    
         
             
                #   filepath to vendor cookbooks to
         
     | 
| 
       554 
542 
     | 
    
         
             
                #
         
     | 
| 
       555 
     | 
    
         
            -
                # @option options [Symbol, Array] :except
         
     | 
| 
       556 
     | 
    
         
            -
                #   Group(s) to exclude which will cause any dependencies marked as a member of the
         
     | 
| 
       557 
     | 
    
         
            -
                #   group to not be installed
         
     | 
| 
       558 
     | 
    
         
            -
                # @option options [Symbol, Array] :only
         
     | 
| 
       559 
     | 
    
         
            -
                #   Group(s) to include which will cause any dependencies marked as a member of the
         
     | 
| 
       560 
     | 
    
         
            -
                #   group to be installed and all others to be ignored
         
     | 
| 
       561 
     | 
    
         
            -
                #
         
     | 
| 
       562 
543 
     | 
    
         
             
                # @return [String, nil]
         
     | 
| 
       563 
544 
     | 
    
         
             
                #   the expanded path cookbooks were vendored to or nil if nothing was vendored
         
     | 
| 
       564 
     | 
    
         
            -
                def vendor(destination 
     | 
| 
      
 545 
     | 
    
         
            +
                def vendor(destination)
         
     | 
| 
       565 
546 
     | 
    
         
             
                  destination = File.expand_path(destination)
         
     | 
| 
       566 
547 
     | 
    
         | 
| 
       567 
548 
     | 
    
         
             
                  if Dir.exist?(destination)
         
     | 
| 
         @@ -569,9 +550,12 @@ module Berkshelf 
     | 
|
| 
       569 
550 
     | 
    
         
             
                      "different filepath."
         
     | 
| 
       570 
551 
     | 
    
         
             
                  end
         
     | 
| 
       571 
552 
     | 
    
         | 
| 
      
 553 
     | 
    
         
            +
                  # Ensure the parent directory exists, in case a nested path was given
         
     | 
| 
      
 554 
     | 
    
         
            +
                  FileUtils.mkdir_p(File.expand_path(File.join(destination, '..')))
         
     | 
| 
      
 555 
     | 
    
         
            +
             
     | 
| 
       572 
556 
     | 
    
         
             
                  scratch          = Berkshelf.mktmpdir
         
     | 
| 
       573 
557 
     | 
    
         
             
                  chefignore       = nil
         
     | 
| 
       574 
     | 
    
         
            -
                  cached_cookbooks = install 
     | 
| 
      
 558 
     | 
    
         
            +
                  cached_cookbooks = install
         
     | 
| 
       575 
559 
     | 
    
         | 
| 
       576 
560 
     | 
    
         
             
                  return nil if cached_cookbooks.empty?
         
     | 
| 
       577 
561 
     | 
    
         | 
| 
         @@ -686,15 +670,58 @@ module Berkshelf 
     | 
|
| 
       686 
670 
     | 
    
         
             
                    cookbooks
         
     | 
| 
       687 
671 
     | 
    
         
             
                  end
         
     | 
| 
       688 
672 
     | 
    
         | 
| 
      
 673 
     | 
    
         
            +
                  # Ensure the lockfile is present on disk.
         
     | 
| 
      
 674 
     | 
    
         
            +
                  #
         
     | 
| 
      
 675 
     | 
    
         
            +
                  # @raise [LockfileNotFound]
         
     | 
| 
      
 676 
     | 
    
         
            +
                  #   if the lockfile does not exist on disk
         
     | 
| 
      
 677 
     | 
    
         
            +
                  #
         
     | 
| 
      
 678 
     | 
    
         
            +
                  # @return [true]
         
     | 
| 
      
 679 
     | 
    
         
            +
                  def validate_lockfile_present!
         
     | 
| 
      
 680 
     | 
    
         
            +
                    raise LockfileNotFound unless lockfile.present?
         
     | 
| 
      
 681 
     | 
    
         
            +
                    true
         
     | 
| 
      
 682 
     | 
    
         
            +
                  end
         
     | 
| 
      
 683 
     | 
    
         
            +
             
     | 
| 
      
 684 
     | 
    
         
            +
                  # Ensure that all dependencies defined in the Berksfile exist in this
         
     | 
| 
      
 685 
     | 
    
         
            +
                  # lockfile.
         
     | 
| 
      
 686 
     | 
    
         
            +
                  #
         
     | 
| 
      
 687 
     | 
    
         
            +
                  # @raise [LockfileOutOfSync]
         
     | 
| 
      
 688 
     | 
    
         
            +
                  #   if there are dependencies specified in the Berksfile which do not
         
     | 
| 
      
 689 
     | 
    
         
            +
                  #   exist (or are not satisifed by) the lockfile
         
     | 
| 
      
 690 
     | 
    
         
            +
                  #
         
     | 
| 
      
 691 
     | 
    
         
            +
                  # @return [true]
         
     | 
| 
      
 692 
     | 
    
         
            +
                  def validate_lockfile_trusted!
         
     | 
| 
      
 693 
     | 
    
         
            +
                    raise LockfileOutOfSync unless lockfile.trusted?
         
     | 
| 
      
 694 
     | 
    
         
            +
                    true
         
     | 
| 
      
 695 
     | 
    
         
            +
                  end
         
     | 
| 
      
 696 
     | 
    
         
            +
             
     | 
| 
      
 697 
     | 
    
         
            +
                  # Ensure that all dependencies in the lockfile are installed on this
         
     | 
| 
      
 698 
     | 
    
         
            +
                  # system. You should validate that the lockfile can be trusted before
         
     | 
| 
      
 699 
     | 
    
         
            +
                  # using this method.
         
     | 
| 
      
 700 
     | 
    
         
            +
                  #
         
     | 
| 
      
 701 
     | 
    
         
            +
                  # @raise [DependencyNotInstalled]
         
     | 
| 
      
 702 
     | 
    
         
            +
                  #   if the dependency in the lockfile is not in the Berkshelf shelf on
         
     | 
| 
      
 703 
     | 
    
         
            +
                  #   this system
         
     | 
| 
      
 704 
     | 
    
         
            +
                  #
         
     | 
| 
      
 705 
     | 
    
         
            +
                  # @return [true]
         
     | 
| 
      
 706 
     | 
    
         
            +
                  def validate_dependencies_installed!
         
     | 
| 
      
 707 
     | 
    
         
            +
                    lockfile.graph.locks.each do |_, dependency|
         
     | 
| 
      
 708 
     | 
    
         
            +
                      unless dependency.downloaded?
         
     | 
| 
      
 709 
     | 
    
         
            +
                        raise DependencyNotInstalled.new(dependency)
         
     | 
| 
      
 710 
     | 
    
         
            +
                      end
         
     | 
| 
      
 711 
     | 
    
         
            +
                    end
         
     | 
| 
      
 712 
     | 
    
         
            +
             
     | 
| 
      
 713 
     | 
    
         
            +
                    true
         
     | 
| 
      
 714 
     | 
    
         
            +
                  end
         
     | 
| 
      
 715 
     | 
    
         
            +
             
     | 
| 
       689 
716 
     | 
    
         
             
                  # Determine if any cookbooks were specified that aren't in our shelf.
         
     | 
| 
       690 
717 
     | 
    
         
             
                  #
         
     | 
| 
       691 
     | 
    
         
            -
                  # @ 
     | 
| 
       692 
     | 
    
         
            -
                  #   a list of  
     | 
| 
      
 718 
     | 
    
         
            +
                  # @param [Array<String>] names
         
     | 
| 
      
 719 
     | 
    
         
            +
                  #   a list of cookbook names
         
     | 
| 
       693 
720 
     | 
    
         
             
                  #
         
     | 
| 
       694 
721 
     | 
    
         
             
                  # @raise [Berkshelf::DependencyNotFound]
         
     | 
| 
       695 
722 
     | 
    
         
             
                  #   if a cookbook name is given that does not exist
         
     | 
| 
       696 
     | 
    
         
            -
                  def validate_cookbook_names!( 
     | 
| 
       697 
     | 
    
         
            -
                    missing =  
     | 
| 
      
 723 
     | 
    
         
            +
                  def validate_cookbook_names!(names)
         
     | 
| 
      
 724 
     | 
    
         
            +
                    missing = names - dependencies.map(&:name)
         
     | 
| 
       698 
725 
     | 
    
         | 
| 
       699 
726 
     | 
    
         
             
                    unless missing.empty?
         
     | 
| 
       700 
727 
     | 
    
         
             
                      raise Berkshelf::DependencyNotFound.new(missing)
         
     |