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
 
| 
         @@ -39,34 +39,30 @@ module Berkshelf 
     | 
|
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
                  # Add a Cookbook installation entry to delayed output
         
     | 
| 
       41 
41 
     | 
    
         
             
                  #
         
     | 
| 
       42 
     | 
    
         
            -
                  # @param [ 
     | 
| 
       43 
     | 
    
         
            -
                  #  
     | 
| 
       44 
     | 
    
         
            -
                  # @ 
     | 
| 
       45 
     | 
    
         
            -
                  #   the  
     | 
| 
       46 
     | 
    
         
            -
                   
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                     
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                      cookbooks[cookbook][:api_source] = options[:api_source] unless options[:api_source] == Berkshelf::Berksfile::DEFAULT_API_URL
         
     | 
| 
       54 
     | 
    
         
            -
                      cookbooks[cookbook][:location_path] = options[:location_path] unless options[:api_source] == Berkshelf::Berksfile::DEFAULT_API_URL
         
     | 
| 
      
 42 
     | 
    
         
            +
                  # @param [Source] source
         
     | 
| 
      
 43 
     | 
    
         
            +
                  #   the source the dependency is being downloaded from
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # @param [RemoteCookbook] cookbook
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #   the cookbook to be downloaded
         
     | 
| 
      
 46 
     | 
    
         
            +
                  def install(source, cookbook)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    cookbooks[cookbook.name] ||= {}
         
     | 
| 
      
 48 
     | 
    
         
            +
                    cookbooks[cookbook.name][:version] = cookbook.version
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    unless source.default?
         
     | 
| 
      
 51 
     | 
    
         
            +
                      cookbooks[cookbook.name][:api_source]    = source.uri
         
     | 
| 
      
 52 
     | 
    
         
            +
                      cookbooks[cookbook.name][:location_path] = cookbook.location_path
         
     | 
| 
       55 
53 
     | 
    
         
             
                    end
         
     | 
| 
       56 
54 
     | 
    
         
             
                  end
         
     | 
| 
       57 
55 
     | 
    
         | 
| 
       58 
56 
     | 
    
         
             
                  # Add a Cookbook use entry to delayed output
         
     | 
| 
       59 
57 
     | 
    
         
             
                  #
         
     | 
| 
       60 
     | 
    
         
            -
                  # @param [ 
     | 
| 
       61 
     | 
    
         
            -
                   
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
                     
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
                      cookbooks[cookbook][:metadata] = true if location.metadata?
         
     | 
| 
       69 
     | 
    
         
            -
                      cookbooks[cookbook][:location] = location.relative_path
         
     | 
| 
      
 58 
     | 
    
         
            +
                  # @param [Dependency] dependency
         
     | 
| 
      
 59 
     | 
    
         
            +
                  def use(dependency)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    cookbooks[dependency.name] ||= {}
         
     | 
| 
      
 61 
     | 
    
         
            +
                    cookbooks[dependency.name][:version] = dependency.cached_cookbook.version
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                    if dependency.location.is_a?(PathLocation)
         
     | 
| 
      
 64 
     | 
    
         
            +
                      cookbooks[dependency.name][:metadata] = true if dependency.location.metadata?
         
     | 
| 
      
 65 
     | 
    
         
            +
                      cookbooks[dependency.name][:location] = dependency.location.relative_path
         
     | 
| 
       70 
66 
     | 
    
         
             
                    end
         
     | 
| 
       71 
67 
     | 
    
         
             
                  end
         
     | 
| 
       72 
68 
     | 
    
         | 
| 
         @@ -111,13 +107,13 @@ module Berkshelf 
     | 
|
| 
       111 
107 
     | 
    
         | 
| 
       112 
108 
     | 
    
         
             
                  # Output a list of cookbooks to delayed output
         
     | 
| 
       113 
109 
     | 
    
         
             
                  #
         
     | 
| 
       114 
     | 
    
         
            -
                  # @param [ 
     | 
| 
       115 
     | 
    
         
            -
                  def list( 
     | 
| 
       116 
     | 
    
         
            -
                     
     | 
| 
       117 
     | 
    
         
            -
                      cookbooks[ 
     | 
| 
       118 
     | 
    
         
            -
                      cookbooks[ 
     | 
| 
      
 110 
     | 
    
         
            +
                  # @param [Array<Dependency>] dependencies
         
     | 
| 
      
 111 
     | 
    
         
            +
                  def list(dependencies)
         
     | 
| 
      
 112 
     | 
    
         
            +
                    dependencies.each do |dependency, cookbook|
         
     | 
| 
      
 113 
     | 
    
         
            +
                      cookbooks[dependency.name] ||= {}
         
     | 
| 
      
 114 
     | 
    
         
            +
                      cookbooks[dependency.name][:version] = dependency.locked_version.to_s
         
     | 
| 
       119 
115 
     | 
    
         
             
                      if dependency.location
         
     | 
| 
       120 
     | 
    
         
            -
                        cookbooks[ 
     | 
| 
      
 116 
     | 
    
         
            +
                        cookbooks[dependency.name][:location] = dependency.location
         
     | 
| 
       121 
117 
     | 
    
         
             
                      end
         
     | 
| 
       122 
118 
     | 
    
         
             
                    end
         
     | 
| 
       123 
119 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/berkshelf/installer.rb
    CHANGED
    
    | 
         @@ -2,16 +2,14 @@ require 'berkshelf/api-client' 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Berkshelf
         
     | 
| 
       4 
4 
     | 
    
         
             
              class Installer
         
     | 
| 
       5 
     | 
    
         
            -
                extend Forwardable
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
5 
     | 
    
         
             
                attr_reader :berksfile
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_reader :lockfile
         
     | 
| 
       8 
7 
     | 
    
         
             
                attr_reader :downloader
         
     | 
| 
       9 
8 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                def_delegator :berksfile, :lockfile
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
9 
     | 
    
         
             
                # @param [Berkshelf::Berksfile] berksfile
         
     | 
| 
       13 
10 
     | 
    
         
             
                def initialize(berksfile)
         
     | 
| 
       14 
11 
     | 
    
         
             
                  @berksfile  = berksfile
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @lockfile   = berksfile.lockfile
         
     | 
| 
       15 
13 
     | 
    
         
             
                  @downloader = Downloader.new(berksfile)
         
     | 
| 
       16 
14 
     | 
    
         
             
                end
         
     | 
| 
       17 
15 
     | 
    
         | 
| 
         @@ -19,6 +17,7 @@ module Berkshelf 
     | 
|
| 
       19 
17 
     | 
    
         
             
                  berksfile.sources.collect do |source|
         
     | 
| 
       20 
18 
     | 
    
         
             
                    Thread.new do
         
     | 
| 
       21 
19 
     | 
    
         
             
                      begin
         
     | 
| 
      
 20 
     | 
    
         
            +
                        Berkshelf.formatter.msg("Fetching cookbook index from #{source.uri}...")
         
     | 
| 
       22 
21 
     | 
    
         
             
                        source.build_universe
         
     | 
| 
       23 
22 
     | 
    
         
             
                      rescue Berkshelf::APIClientError => ex
         
     | 
| 
       24 
23 
     | 
    
         
             
                        Berkshelf.formatter.warn "Error retrieving universe from source: #{source}"
         
     | 
| 
         @@ -28,146 +27,136 @@ module Berkshelf 
     | 
|
| 
       28 
27 
     | 
    
         
             
                  end.map(&:join)
         
     | 
| 
       29 
28 
     | 
    
         
             
                end
         
     | 
| 
       30 
29 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
                # @option options [Array<String>, String] cookbooks
         
     | 
| 
       32 
     | 
    
         
            -
                #
         
     | 
| 
       33 
30 
     | 
    
         
             
                # @return [Array<Berkshelf::CachedCookbook>]
         
     | 
| 
       34 
     | 
    
         
            -
                def run 
     | 
| 
       35 
     | 
    
         
            -
                   
     | 
| 
       36 
     | 
    
         
            -
                  resolver     = Resolver.new(berksfile, dependencies)
         
     | 
| 
       37 
     | 
    
         
            -
                  lock_deps    = []
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                  dependencies.each do |dependency|
         
     | 
| 
       40 
     | 
    
         
            -
                    if dependency.scm_location?
         
     | 
| 
       41 
     | 
    
         
            -
                      Berkshelf.formatter.fetch(dependency)
         
     | 
| 
       42 
     | 
    
         
            -
                      downloader.download(dependency)
         
     | 
| 
       43 
     | 
    
         
            -
                    end
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                    next if (cookbook = dependency.cached_cookbook).nil?
         
     | 
| 
      
 31 
     | 
    
         
            +
                def run
         
     | 
| 
      
 32 
     | 
    
         
            +
                  reduce_lockfile!
         
     | 
| 
       46 
33 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
      
 34 
     | 
    
         
            +
                  cookbooks = if lockfile.trusted?
         
     | 
| 
      
 35 
     | 
    
         
            +
                    install_from_lockfile
         
     | 
| 
      
 36 
     | 
    
         
            +
                  else
         
     | 
| 
      
 37 
     | 
    
         
            +
                    install_from_universe
         
     | 
| 
       48 
38 
     | 
    
         
             
                  end
         
     | 
| 
       49 
39 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
                   
     | 
| 
       51 
     | 
    
         
            -
                   
     | 
| 
      
 40 
     | 
    
         
            +
                  lockfile.graph.update(cookbooks)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  lockfile.update(berksfile.dependencies)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  lockfile.save
         
     | 
| 
       52 
43 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
                   
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  cookbooks
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                # Install all the dependencies from the lockfile graph.
         
     | 
| 
      
 48 
     | 
    
         
            +
                #
         
     | 
| 
      
 49 
     | 
    
         
            +
                # @return [Array<CachedCookbook>]
         
     | 
| 
      
 50 
     | 
    
         
            +
                #   the list of installed cookbooks
         
     | 
| 
      
 51 
     | 
    
         
            +
                def install_from_lockfile
         
     | 
| 
      
 52 
     | 
    
         
            +
                  locks = lockfile.graph.locks
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  # Only construct the universe if we are going to download things
         
     | 
| 
      
 55 
     | 
    
         
            +
                  unless locks.all? { |_, dependency| dependency.downloaded? }
         
     | 
| 
      
 56 
     | 
    
         
            +
                    build_universe
         
     | 
| 
       67 
57 
     | 
    
         
             
                  end
         
     | 
| 
       68 
58 
     | 
    
         | 
| 
       69 
     | 
    
         
            -
                   
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
                   
     | 
| 
      
 59 
     | 
    
         
            +
                  locks.sort.collect do |name, dependency|
         
     | 
| 
      
 60 
     | 
    
         
            +
                    install(dependency)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
       72 
62 
     | 
    
         
             
                end
         
     | 
| 
       73 
63 
     | 
    
         | 
| 
       74 
     | 
    
         
            -
                #  
     | 
| 
       75 
     | 
    
         
            -
                #  
     | 
| 
       76 
     | 
    
         
            -
                #
         
     | 
| 
       77 
     | 
    
         
            -
                # @param [Array<Berkshelf::Dependencies>] dependencies
         
     | 
| 
      
 64 
     | 
    
         
            +
                # Resolve and install the dependencies from the "universe", updating the
         
     | 
| 
      
 65 
     | 
    
         
            +
                # lockfile appropiately.
         
     | 
| 
       78 
66 
     | 
    
         
             
                #
         
     | 
| 
       79 
     | 
    
         
            -
                # @ 
     | 
| 
       80 
     | 
    
         
            -
                #    
     | 
| 
       81 
     | 
    
         
            -
                def  
     | 
| 
       82 
     | 
    
         
            -
                   
     | 
| 
       83 
     | 
    
         
            -
                   
     | 
| 
      
 67 
     | 
    
         
            +
                # @return [Array<CachedCookbook>]
         
     | 
| 
      
 68 
     | 
    
         
            +
                #   the list of installed cookbooks
         
     | 
| 
      
 69 
     | 
    
         
            +
                def install_from_universe
         
     | 
| 
      
 70 
     | 
    
         
            +
                  dependencies = lockfile.graph.locks.values + berksfile.dependencies
         
     | 
| 
      
 71 
     | 
    
         
            +
                  dependencies = dependencies.inject({}) do |hash, dependency|
         
     | 
| 
      
 72 
     | 
    
         
            +
                    # Fancy way of ensuring no duplicate dependencies are used...
         
     | 
| 
      
 73 
     | 
    
         
            +
                    hash[dependency.name] ||= dependency
         
     | 
| 
      
 74 
     | 
    
         
            +
                    hash
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end.values
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  resolver = Resolver.new(berksfile, dependencies)
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  # Download all SCM locations first, since they might have additional
         
     | 
| 
      
 80 
     | 
    
         
            +
                  # constraints that we don't yet know about
         
     | 
| 
      
 81 
     | 
    
         
            +
                  dependencies.select(&:scm_location?).each do |dependency|
         
     | 
| 
      
 82 
     | 
    
         
            +
                    Berkshelf.formatter.fetch(dependency)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    dependency.download
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                  # Unlike when installing from the lockfile, we _always_ need to build
         
     | 
| 
      
 87 
     | 
    
         
            +
                  # the universe when installing from the universe... duh
         
     | 
| 
      
 88 
     | 
    
         
            +
                  build_universe
         
     | 
| 
       84 
89 
     | 
    
         | 
| 
      
 90 
     | 
    
         
            +
                  # Add any explicit dependencies for already-downloaded cookbooks (like
         
     | 
| 
      
 91 
     | 
    
         
            +
                  # path locations)
         
     | 
| 
       85 
92 
     | 
    
         
             
                  dependencies.each do |dependency|
         
     | 
| 
       86 
     | 
    
         
            -
                     
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
      
 93 
     | 
    
         
            +
                    if cookbook = dependency.cached_cookbook
         
     | 
| 
      
 94 
     | 
    
         
            +
                      resolver.add_explicit_dependencies(cookbook)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  end
         
     | 
| 
       88 
97 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
                    rescue Berkshelf::LicenseNotAllowed => e
         
     | 
| 
       94 
     | 
    
         
            -
                      if Berkshelf.config.raise_license_exception
         
     | 
| 
       95 
     | 
    
         
            -
                        FileUtils.rm_rf(cached.path)
         
     | 
| 
       96 
     | 
    
         
            -
                        raise
         
     | 
| 
       97 
     | 
    
         
            -
                      end
         
     | 
| 
      
 98 
     | 
    
         
            +
                  resolver.resolve.sort.collect do |dependency|
         
     | 
| 
      
 99 
     | 
    
         
            +
                    install(dependency)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  end
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
       98 
102 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
      
 103 
     | 
    
         
            +
                # Install a specific dependency.
         
     | 
| 
      
 104 
     | 
    
         
            +
                #
         
     | 
| 
      
 105 
     | 
    
         
            +
                # @param [Dependency]
         
     | 
| 
      
 106 
     | 
    
         
            +
                #   the dependency to install
         
     | 
| 
      
 107 
     | 
    
         
            +
                # @return [CachedCookbook]
         
     | 
| 
      
 108 
     | 
    
         
            +
                #   the installed cookbook
         
     | 
| 
      
 109 
     | 
    
         
            +
                def install(dependency)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  if dependency.downloaded?
         
     | 
| 
      
 111 
     | 
    
         
            +
                    Berkshelf.formatter.use(dependency)
         
     | 
| 
      
 112 
     | 
    
         
            +
                    dependency.cached_cookbook
         
     | 
| 
      
 113 
     | 
    
         
            +
                  else
         
     | 
| 
      
 114 
     | 
    
         
            +
                    name, version = dependency.name, dependency.locked_version.to_s
         
     | 
| 
      
 115 
     | 
    
         
            +
                    source   = berksfile.source_for(name, version)
         
     | 
| 
      
 116 
     | 
    
         
            +
                    cookbook = source.cookbook(name, version)
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                    Berkshelf.formatter.install(source, cookbook)
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                    stash = downloader.download(name, version)
         
     | 
| 
      
 121 
     | 
    
         
            +
                    CookbookStore.import(name, version, stash)
         
     | 
| 
       101 
122 
     | 
    
         
             
                  end
         
     | 
| 
       102 
123 
     | 
    
         
             
                end
         
     | 
| 
       103 
124 
     | 
    
         | 
| 
       104 
125 
     | 
    
         
             
                private
         
     | 
| 
       105 
126 
     | 
    
         | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
             
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
      
 127 
     | 
    
         
            +
                # Iterate over each top-level dependency defined in the lockfile and
         
     | 
| 
      
 128 
     | 
    
         
            +
                # check if that dependency is still defined in the Berksfile.
         
     | 
| 
      
 129 
     | 
    
         
            +
                #
         
     | 
| 
      
 130 
     | 
    
         
            +
                # If the dependency is no longer present in the Berksfile, it is "safely"
         
     | 
| 
      
 131 
     | 
    
         
            +
                # removed using {Lockfile#unlock} and {Lockfile#remove}. This prevents
         
     | 
| 
      
 132 
     | 
    
         
            +
                # the lockfile from "leaking" dependencies when they have been removed
         
     | 
| 
      
 133 
     | 
    
         
            +
                # from the Berksfile, but still remained locked in the lockfile.
         
     | 
| 
      
 134 
     | 
    
         
            +
                #
         
     | 
| 
      
 135 
     | 
    
         
            +
                # If the dependency exists, a constraint comparison is conducted to verify
         
     | 
| 
      
 136 
     | 
    
         
            +
                # that the locked dependency still satisifes the original constraint. This
         
     | 
| 
      
 137 
     | 
    
         
            +
                # handles the edge case where a user has updated or removed a constraint
         
     | 
| 
      
 138 
     | 
    
         
            +
                # on a dependency that already existed in the lockfile.
         
     | 
| 
      
 139 
     | 
    
         
            +
                #
         
     | 
| 
      
 140 
     | 
    
         
            +
                # @raise [OutdatedDependency]
         
     | 
| 
      
 141 
     | 
    
         
            +
                #   if the constraint exists, but is no longer satisifed by the existing
         
     | 
| 
      
 142 
     | 
    
         
            +
                #   locked version
         
     | 
| 
      
 143 
     | 
    
         
            +
                #
         
     | 
| 
      
 144 
     | 
    
         
            +
                # @return [Array<Dependency>]
         
     | 
| 
      
 145 
     | 
    
         
            +
                def reduce_lockfile!
         
     | 
| 
      
 146 
     | 
    
         
            +
                  lockfile.dependencies.each do |dependency|
         
     | 
| 
      
 147 
     | 
    
         
            +
                    if berksfile.dependencies.map(&:name).include?(dependency.name)
         
     | 
| 
      
 148 
     | 
    
         
            +
                      locked = lockfile.graph.find(dependency)
         
     | 
| 
      
 149 
     | 
    
         
            +
                      next if locked.nil?
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                      unless dependency.version_constraint.satisfies?(locked.version)
         
     | 
| 
      
 152 
     | 
    
         
            +
                        raise OutdatedDependency.new(locked, dependency)
         
     | 
| 
       124 
153 
     | 
    
         
             
                      end
         
     | 
| 
      
 154 
     | 
    
         
            +
                    else
         
     | 
| 
      
 155 
     | 
    
         
            +
                      lockfile.unlock(dependency)
         
     | 
| 
       125 
156 
     | 
    
         
             
                    end
         
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
                    locked.version_constraint = Solve::Constraint.new("= #{locked.locked_version}")
         
     | 
| 
       128 
     | 
    
         
            -
                    locked
         
     | 
| 
       129 
     | 
    
         
            -
                  end
         
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
                  # Merge the locked dependencies against the given dependencies.
         
     | 
| 
       132 
     | 
    
         
            -
                  #
         
     | 
| 
       133 
     | 
    
         
            -
                  # For each the given dependencies, check if there's a locked version that
         
     | 
| 
       134 
     | 
    
         
            -
                  # still satisfies the version constraint. If it does, "lock" that dependency
         
     | 
| 
       135 
     | 
    
         
            -
                  # because we should just use the locked version.
         
     | 
| 
       136 
     | 
    
         
            -
                  #
         
     | 
| 
       137 
     | 
    
         
            -
                  # If a locked dependency exists, but doesn't satisfy the constraint, raise a
         
     | 
| 
       138 
     | 
    
         
            -
                  # {Berkshelf::OutdatedDependency} and tell the user to run update.
         
     | 
| 
       139 
     | 
    
         
            -
                  #
         
     | 
| 
       140 
     | 
    
         
            -
                  # Never use the locked constraint for a dependency with a {PathLocation}
         
     | 
| 
       141 
     | 
    
         
            -
                  #
         
     | 
| 
       142 
     | 
    
         
            -
                  # @param [Array<Berkshelf::Dependency>] dependencies
         
     | 
| 
       143 
     | 
    
         
            -
                  #
         
     | 
| 
       144 
     | 
    
         
            -
                  # @return [Array<Berkshelf::Dependency>]
         
     | 
| 
       145 
     | 
    
         
            -
                  def lockfile_reduce(dependencies = [])
         
     | 
| 
       146 
     | 
    
         
            -
                    {}.tap do |h|
         
     | 
| 
       147 
     | 
    
         
            -
                      (dependencies + lockfile.dependencies).each do |dependency|
         
     | 
| 
       148 
     | 
    
         
            -
                        next if h.has_key?(dependency.name)
         
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
     | 
    
         
            -
                        if dependency.path_location?
         
     | 
| 
       151 
     | 
    
         
            -
                          result = dependency
         
     | 
| 
       152 
     | 
    
         
            -
                        else
         
     | 
| 
       153 
     | 
    
         
            -
                          result = dependency_from_lockfile(dependency) || dependency
         
     | 
| 
       154 
     | 
    
         
            -
                        end
         
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
                        h[result.name] = result
         
     | 
| 
       157 
     | 
    
         
            -
                      end
         
     | 
| 
       158 
     | 
    
         
            -
                    end.values
         
     | 
| 
       159 
157 
     | 
    
         
             
                  end
         
     | 
| 
       160 
158 
     | 
    
         | 
| 
       161 
     | 
    
         
            -
                   
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
                  # @return [Array<Berkshelf::Dependency>]
         
     | 
| 
       164 
     | 
    
         
            -
                  #   the list of dependencies in this lockfile
         
     | 
| 
       165 
     | 
    
         
            -
                  def locked_dependencies
         
     | 
| 
       166 
     | 
    
         
            -
                    lockfile.dependencies
         
     | 
| 
       167 
     | 
    
         
            -
                  end
         
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
                  def reduce_scm_locations(dependencies)
         
     | 
| 
       170 
     | 
    
         
            -
                    dependencies.select { |dependency| SCM_LOCATIONS.include?(dependency.class.location_key) }
         
     | 
| 
       171 
     | 
    
         
            -
                  end
         
     | 
| 
      
 159 
     | 
    
         
            +
                  lockfile.save
         
     | 
| 
      
 160 
     | 
    
         
            +
                end
         
     | 
| 
       172 
161 
     | 
    
         
             
              end
         
     | 
| 
       173 
162 
     | 
    
         
             
            end
         
     | 
| 
         @@ -68,7 +68,7 @@ module Berkshelf 
     | 
|
| 
       68 
68 
     | 
    
         | 
| 
       69 
69 
     | 
    
         
             
                  tmp_path = rel ? File.join(repo_path, rel) : repo_path
         
     | 
| 
       70 
70 
     | 
    
         
             
                  unless File.chef_cookbook?(tmp_path)
         
     | 
| 
       71 
     | 
    
         
            -
                    msg = "Cookbook '#{dependency.name}' not found at  
     | 
| 
      
 71 
     | 
    
         
            +
                    msg = "Cookbook '#{dependency.name}' not found at #{to_s}"
         
     | 
| 
       72 
72 
     | 
    
         
             
                    msg << " at path '#{rel}'" if rel
         
     | 
| 
       73 
73 
     | 
    
         
             
                    raise CookbookNotFound, msg
         
     | 
| 
       74 
74 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -90,18 +90,31 @@ module Berkshelf 
     | 
|
| 
       90 
90 
     | 
    
         
             
                  end
         
     | 
| 
       91 
91 
     | 
    
         
             
                end
         
     | 
| 
       92 
92 
     | 
    
         | 
| 
      
 93 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 94 
     | 
    
         
            +
                  other.is_a?(GitLocation) &&
         
     | 
| 
      
 95 
     | 
    
         
            +
                  other.uri == uri &&
         
     | 
| 
      
 96 
     | 
    
         
            +
                  other.branch == branch &&
         
     | 
| 
      
 97 
     | 
    
         
            +
                  other.ref == ref &&
         
     | 
| 
      
 98 
     | 
    
         
            +
                  other.rel == rel
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
       93 
101 
     | 
    
         
             
                def to_s
         
     | 
| 
       94 
     | 
    
         
            -
                   
     | 
| 
      
 102 
     | 
    
         
            +
                  if rel
         
     | 
| 
      
 103 
     | 
    
         
            +
                    "#{uri} (at #{branch || ref[0...7]}/#{rel})"
         
     | 
| 
      
 104 
     | 
    
         
            +
                  else
         
     | 
| 
      
 105 
     | 
    
         
            +
                    "#{uri} (at #{branch || ref[0...7]})"
         
     | 
| 
      
 106 
     | 
    
         
            +
                  end
         
     | 
| 
       95 
107 
     | 
    
         
             
                end
         
     | 
| 
       96 
108 
     | 
    
         | 
| 
       97 
     | 
    
         
            -
                 
     | 
| 
      
 109 
     | 
    
         
            +
                def to_lock
         
     | 
| 
      
 110 
     | 
    
         
            +
                  out =  "    git: #{uri}\n"
         
     | 
| 
      
 111 
     | 
    
         
            +
                  out << "    branch: #{branch}\n" if branch
         
     | 
| 
      
 112 
     | 
    
         
            +
                  out << "    ref: #{ref}\n"       if ref
         
     | 
| 
      
 113 
     | 
    
         
            +
                  out << "    rel: #{rel}\n"       if rel
         
     | 
| 
      
 114 
     | 
    
         
            +
                  out
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
       98 
116 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
                    info = checkout_info
         
     | 
| 
       101 
     | 
    
         
            -
                    s = "'#{uri}' with #{info[:kind]}: '#{info[:rev]}'"
         
     | 
| 
       102 
     | 
    
         
            -
                    s << " at ref: '#{ref}'" if ref && (info[:kind] != "ref" || ref != info[:rev])
         
     | 
| 
       103 
     | 
    
         
            -
                    s
         
     | 
| 
       104 
     | 
    
         
            -
                  end
         
     | 
| 
      
 117 
     | 
    
         
            +
                private
         
     | 
| 
       105 
118 
     | 
    
         | 
| 
       106 
119 
     | 
    
         
             
                  def cached?(destination)
         
     | 
| 
       107 
120 
     | 
    
         
             
                    revision_path(destination) && File.exists?(revision_path(destination))
         
     | 
| 
         @@ -49,8 +49,7 @@ module Berkshelf 
     | 
|
| 
       49 
49 
     | 
    
         | 
| 
       50 
50 
     | 
    
         
             
                  tmp_path = rel ? File.join(repo_path, rel) : repo_path
         
     | 
| 
       51 
51 
     | 
    
         
             
                  unless File.chef_cookbook?(tmp_path)
         
     | 
| 
       52 
     | 
    
         
            -
                    msg = "Cookbook '#{dependency.name}' not found at  
     | 
| 
       53 
     | 
    
         
            -
                    msg << " with rev '#{rev}'" if rev
         
     | 
| 
      
 52 
     | 
    
         
            +
                    msg = "Cookbook '#{dependency.name}' not found at #{to_s}"
         
     | 
| 
       54 
53 
     | 
    
         
             
                    msg << " at path '#{rel}'" if rel
         
     | 
| 
       55 
54 
     | 
    
         
             
                    raise CookbookNotFound, msg
         
     | 
| 
       56 
55 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -72,10 +71,26 @@ module Berkshelf 
     | 
|
| 
       72 
71 
     | 
    
         
             
                  end
         
     | 
| 
       73 
72 
     | 
    
         
             
                end
         
     | 
| 
       74 
73 
     | 
    
         | 
| 
      
 74 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  other.is_a?(MercurialLocation) &&
         
     | 
| 
      
 76 
     | 
    
         
            +
                  other.uri == uri &&
         
     | 
| 
      
 77 
     | 
    
         
            +
                  other.rev == rev &&
         
     | 
| 
      
 78 
     | 
    
         
            +
                  other.rel == rel
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
       75 
81 
     | 
    
         
             
                def to_s
         
     | 
| 
       76 
     | 
    
         
            -
                   
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
                   
     | 
| 
      
 82 
     | 
    
         
            +
                  if rel
         
     | 
| 
      
 83 
     | 
    
         
            +
                    "#{uri} (at #{rev}/#{rel})"
         
     | 
| 
      
 84 
     | 
    
         
            +
                  else
         
     | 
| 
      
 85 
     | 
    
         
            +
                    "#{uri} (at #{rev})"
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                def to_lock
         
     | 
| 
      
 90 
     | 
    
         
            +
                  out =  "    hg: #{uri}\n"
         
     | 
| 
      
 91 
     | 
    
         
            +
                  out << "    rev: #{rev}\n" if rev
         
     | 
| 
      
 92 
     | 
    
         
            +
                  out << "    rel: #{rel}\n" if rel
         
     | 
| 
      
 93 
     | 
    
         
            +
                  out
         
     | 
| 
       79 
94 
     | 
    
         
             
                end
         
     | 
| 
       80 
95 
     | 
    
         | 
| 
       81 
96 
     | 
    
         
             
                private
         
     | 
| 
         @@ -49,6 +49,15 @@ module Berkshelf 
     | 
|
| 
       49 
49 
     | 
    
         
             
                  "./#{new_path}"
         
     | 
| 
       50 
50 
     | 
    
         
             
                end
         
     | 
| 
       51 
51 
     | 
    
         | 
| 
      
 52 
     | 
    
         
            +
                #
         
     | 
| 
      
 53 
     | 
    
         
            +
                # The expanded path of this path on disk, relative to the berksfile.
         
     | 
| 
      
 54 
     | 
    
         
            +
                #
         
     | 
| 
      
 55 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 56 
     | 
    
         
            +
                #
         
     | 
| 
      
 57 
     | 
    
         
            +
                def expanded_path
         
     | 
| 
      
 58 
     | 
    
         
            +
                  relative_path(dependency.berksfile.filepath)
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
       52 
61 
     | 
    
         
             
                # Valid if the path exists and is readable
         
     | 
| 
       53 
62 
     | 
    
         
             
                #
         
     | 
| 
       54 
63 
     | 
    
         
             
                # @return [Boolean]
         
     | 
| 
         @@ -60,14 +69,20 @@ module Berkshelf 
     | 
|
| 
       60 
69 
     | 
    
         
             
                  super.merge(value: self.path)
         
     | 
| 
       61 
70 
     | 
    
         
             
                end
         
     | 
| 
       62 
71 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
                 
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                 
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
      
 72 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  other.is_a?(PathLocation) &&
         
     | 
| 
      
 74 
     | 
    
         
            +
                  other.metadata? == metadata? &&
         
     | 
| 
      
 75 
     | 
    
         
            +
                  other.expanded_path == expanded_path
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                def to_lock
         
     | 
| 
      
 79 
     | 
    
         
            +
                  out =  "    path: #{relative_path(dependency.berksfile.filepath)}\n"
         
     | 
| 
      
 80 
     | 
    
         
            +
                  out << "    metadata: true\n" if metadata?
         
     | 
| 
      
 81 
     | 
    
         
            +
                  out
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
       69 
84 
     | 
    
         
             
                def to_s
         
     | 
| 
       70 
     | 
    
         
            -
                  "#{ 
     | 
| 
      
 85 
     | 
    
         
            +
                  "source at #{relative_path(dependency.berksfile.filepath)}"
         
     | 
| 
       71 
86 
     | 
    
         
             
                end
         
     | 
| 
       72 
87 
     | 
    
         
             
              end
         
     | 
| 
       73 
88 
     | 
    
         
             
            end
         
     |