class Bundler::Installer
def self.install(root, definition, options)
def self.install(root, definition, options) new(root, definition).run(options) end
def actual_dependencies
def actual_dependencies @definition.actual_dependencies end
def ambiguous?(dep)
def ambiguous?(dep) dep.requirement.requirements.any? { |op,_| op != '=' } end
def cache_source
def cache_source Source::GemCache.new("path" => "#{root}/vendor/cache") end
def dependencies
def dependencies @definition.dependencies end
def index
def index @index ||= begin index = Index.new rg_sources = sources.select { |s| s.is_a?(Source::Rubygems) } other_sources = sources.select { |s| !s.is_a?(Source::Rubygems) } other_sources.each do |source| i = source.specs Bundler.ui.debug "Source: Processing index" index = i.merge(index) end index = Index.from_installed_gems.merge(index) index = Index.from_cached_specs("#{Bundler.bundle_path}/cache").merge(index) if File.directory?("#{root}/vendor/cache") index = cache_source.specs.merge(index) end rg_sources.each do |source| i = source.specs Bundler.ui.debug "Source: Processing index" index = i.merge(index) end index end end
def local_index
def local_index @local_index ||= begin index = Index.new sources.each do |source| next unless source.respond_to?(:local_specs) index = source.local_specs.merge(index) end index = Index.from_installed_gems.merge(index) if File.directory?("#{root}/vendor/cache") index = cache_source.specs.merge(index).freeze end Index.from_cached_specs("#{Bundler.bundle_path}/cache").merge(index) end end
def resolve_locally
def resolve_locally # Return unless all the dependencies have = version requirements return if actual_dependencies.any? { |d| ambiguous?(d) } source_requirements = {} actual_dependencies.each do |dep| next unless dep.source && dep.source.respond_to?(:local_specs) source_requirements[dep.name] = dep.source.local_specs end # Run a resolve against the locally available gems specs = Resolver.resolve(actual_dependencies, local_index, source_requirements) # Simple logic for now. Can improve later. specs.length == actual_dependencies.length && specs rescue GemNotFound, PathError => e nil end
def resolve_remotely
def resolve_remotely index # trigger building the index Bundler.ui.info "Resolving dependencies" source_requirements = {} actual_dependencies.each do |dep| next unless dep.source source_requirements[dep.name] = dep.source.specs end specs = Resolver.resolve(actual_dependencies, index, source_requirements) specs end
def run(options)
def run(options) if actual_dependencies.empty? Bundler.ui.warn "The Gemfile specifies no dependencies" return end # Ensure that BUNDLE_PATH exists FileUtils.mkdir_p(Bundler.bundle_path) # Must install gems in the order that the resolver provides # as dependencies might actually affect the installation of # the gem. specs.each do |spec| spec.source.fetch(spec) if spec.source.respond_to?(:fetch) if spec.groups & Bundler.settings.without == spec.groups Bundler.ui.debug " * Not in requested group; skipping." next end # unless spec.source.is_a?(Source::SystemGems) Bundler.ui.info "Installing #{spec.name} (#{spec.version}) from #{spec.source} " # end spec.source.install(spec) Bundler.ui.info "" end Bundler.ui.confirm "Your bundle is complete!" end
def sources
def sources @definition.sources end
def specs
def specs @specs ||= group_specs(resolve_locally || resolve_remotely) end