lib/berkshelf/installer.rb in berkshelf-3.0.0.beta4 vs lib/berkshelf/installer.rb in berkshelf-3.0.0.beta5

- old
+ new

@@ -1,5 +1,7 @@ +require 'berkshelf/api-client' + module Berkshelf class Installer extend Forwardable attr_reader :berksfile @@ -12,46 +14,55 @@ @berksfile = berksfile @downloader = Downloader.new(berksfile) end def build_universe - berksfile.sources.map(&:universe) + berksfile.sources.collect do |source| + Thread.new do + begin + source.build_universe + rescue Berkshelf::APIClientError => ex + Berkshelf.formatter.warn "Error retrieving universe from source: #{source}" + Berkshelf.formatter.warn " * [#{ex.class}] #{ex}" + end + end + end.map(&:join) end # @option options [Array<String>, String] cookbooks # # @return [Array<Berkshelf::CachedCookbook>] def run(options = {}) dependencies = lockfile_reduce(berksfile.dependencies(options.slice(:except, :only))) resolver = Resolver.new(berksfile, dependencies) + lock_deps = [] dependencies.each do |dependency| - next unless dependency.scm_location? - Berkshelf.formatter.fetch(dependency) - downloader.download(dependency) - end + if dependency.scm_location? + Berkshelf.formatter.fetch(dependency) + downloader.download(dependency) + end - dependencies.each do |dependency| - next unless dependency.cached_cookbook - resolver.add_explicit_dependencies(dependency) + next if (cookbook = dependency.cached_cookbook).nil? + + resolver.add_explicit_dependencies(cookbook) end Berkshelf.formatter.msg("building universe...") build_universe - lock_deps = [] - cached_cookbooks = resolver.resolve.collect do |name, version, dependency| lock_deps << dependency dependency.locked_version ||= Solve::Version.new(version) if dependency.downloaded? Berkshelf.formatter.use(dependency.name, dependency.cached_cookbook.version, dependency.location) dependency.cached_cookbook else source = berksfile.sources.find { |source| source.cookbook(name, version) } remote_cookbook = source.cookbook(name, version) - Berkshelf.formatter.install(name, version, api_source: source.to_s, location_path: remote_cookbook.location_path) + Berkshelf.formatter.install(name, version, api_source: source, location_type: remote_cookbook.location_type, + location_path: remote_cookbook.location_path) temp_filepath = downloader.download(name, version) CookbookStore.import(name, version, temp_filepath) end end @@ -90,10 +101,18 @@ end end private + # Returns an instance of `Berkshelf::Dependency` with an equality constraint matching + # the locked version of the dependency in the lockfile. + # + # If no matching dependency is found in the lockfile then nil is returned. + # + # @param [Berkshelf:Dependency] dependency + # + # @return [Berkshelf::Dependency, nil] def dependency_from_lockfile(dependency) locked = lockfile.find(dependency) return nil unless locked @@ -103,12 +122,11 @@ unless dependency.version_constraint.satisfies?(locked.locked_version) raise Berkshelf::OutdatedDependency.new(locked, dependency) end end - # Update to the constraint to be a hard one - locked.version_constraint = Solve::Constraint.new(locked.locked_version.to_s) + locked.version_constraint = Solve::Constraint.new("= #{locked.locked_version}") locked end # Merge the locked dependencies against the given dependencies. # @@ -123,16 +141,22 @@ # # @param [Array<Berkshelf::Dependency>] dependencies # # @return [Array<Berkshelf::Dependency>] def lockfile_reduce(dependencies = []) - dependencies.collect do |dependency| - if dependency.path_location? - dependency - else - dependency_from_lockfile(dependency) || dependency + {}.tap do |h| + (dependencies + lockfile.dependencies).each do |dependency| + next if h.has_key?(dependency.name) + + if dependency.path_location? + result = dependency + else + result = dependency_from_lockfile(dependency) || dependency + end + + h[result.name] = result end - end + end.values end # The list of dependencies "locked" by the lockfile. # # @return [Array<Berkshelf::Dependency>]