Class: Bundler::Definition

### Home Classes Methods

### In Files

- lib/bundler/definition.rb

### Parent

Object

### Methods

- ::build
- ::new
- #current_dependencies
- #ensure_equivalent_gemfile_and_lockfile
- #fixup_dependency_types!
- #groups
- #has_local_dependencies?
- #has_rubygems_remotes?
- #index
- #lock
- #lock_version
- #missing_specs
- #new_platform?
- #new_specs
- #removed_specs
- #requested_specs
- #resolve
- #resolve_remotely!
- #resolve_with_cache!
- #rubygems_index
- #spec_git_paths
- #specs
- #specs_for
- #to_lock
- #validate_ruby!

### Included Modules

- Bundler::GemHelpers

### Files

- bundle
- bundle-config
- bundle-config.txt
- bundle-exec
- bundle-exec.txt
- bundle-install
- bundle-install.txt
- bundle-package
- bundle-package.txt
- bundle-platform
- bundle-platform.txt
- bundle-update
- bundle-update.txt
- bundle.txt
- gemfile.5.txt
- Executable
- Gemfile

### Class/Module Index

Quicksearch

- Bundler
- Bundler::BundlerError
- Bundler::CLI
- Bundler::CLI::Binstubs
- Bundler::CLI::Cache
- Bundler::CLI::Check
- Bundler::CLI::Clean
- Bundler::CLI::Common
- Bundler::CLI::Config
- Bundler::CLI::Console
- Bundler::CLI::Exec
- Bundler::CLI::Gem
- Bundler::CLI::Init
- Bundler::CLI::Inject
- Bundler::CLI::Install
- Bundler::CLI::Lock
- Bundler::CLI::Open
- Bundler::CLI::Outdated
- Bundler::CLI::Package
- Bundler::CLI::Platform
- Bundler::CLI::Show
- Bundler::CLI::Update
- Bundler::CLI::Viz
- Bundler::CurrentRuby
- Bundler::CyclicDependencyError
- Bundler::Definition
- Bundler::DepProxy
- Bundler::Dependency
- Bundler::Deployment
- Bundler::Deprecate
- Bundler::DeprecatedError
- Bundler::Dsl
- Bundler::Dsl::DSLError
- Bundler::EndpointSpecification
- Bundler::Env
- Bundler::Environment
- Bundler::Fetcher
- Bundler::Fetcher::AuthenticationRequiredError
- Bundler::Fetcher::BadAuthenticationError
- Bundler::Fetcher::Base
- Bundler::Fetcher::CertificateFailureError
- Bundler::Fetcher::Dependency
- Bundler::Fetcher::Downloader
- Bundler::Fetcher::FallbackError
- Bundler::Fetcher::Index
- Bundler::Fetcher::NetworkDownError
- Bundler::Fetcher::SSLError
- Bundler::GemHelper
- Bundler::GemHelpers
- Bundler::GemInstaller
- Bundler::GemNotFound
- Bundler::GemfileError
- Bundler::GemfileLockNotFound
- Bundler::GemfileNotFound
- Bundler::GemspecError
- Bundler::GitError
- Bundler::Graph
- Bundler::Graph::GraphVizClient
- Bundler::HTTPError
- Bundler::Index
- Bundler::Injector
- Bundler::InstallError
- Bundler::InstallHookError
- Bundler::Installer
- Bundler::InvalidOption
- Bundler::LazySpecification
- Bundler::LockfileError
- Bundler::LockfileParser
- Bundler::MarshalError
- Bundler::MatchPlatform
- Bundler::Molinillo
- Bundler::Molinillo::CircularDependencyError
- Bundler::Molinillo::DependencyGraph
- Bundler::Molinillo::DependencyGraph::Vertex
- Bundler::Molinillo::DependencyState
- Bundler::Molinillo::NoSuchDependencyError
- Bundler::Molinillo::PossibilityState
- Bundler::Molinillo::Resolver
- Bundler::Molinillo::Resolver::Resolution
- Bundler::Molinillo::ResolverError
- Bundler::Molinillo::SpecificationProvider
- Bundler::Molinillo::UI
- Bundler::Molinillo::VersionConflict
- Bundler::PathError
- Bundler::ProductionError
- Bundler::RemoteSpecification
- Bundler::Resolver
- Bundler::Resolver::Molinillo
- Bundler::Resolver::Molinillo::VersionConflict
- Bundler::Resolver::SpecGroup
- Bundler::Retry
- Bundler::RubyDsl
- Bundler::RubyVersion
- Bundler::RubyVersionMismatch
- Bundler::RubygemsIntegration
- Bundler::RubygemsIntegration::AlmostModern
- Bundler::RubygemsIntegration::Ancient
- Bundler::RubygemsIntegration::Future
- Bundler::RubygemsIntegration::Gem
- Bundler::RubygemsIntegration::Legacy
- Bundler::RubygemsIntegration::Legacy::Gem::SourceIndex
- Bundler::RubygemsIntegration::Modern
- Bundler::RubygemsIntegration::MoreFuture
- Bundler::RubygemsIntegration::MoreModern
- Bundler::RubygemsIntegration::Transitional
- Bundler::Runtime
- Bundler::SecurityError
- Bundler::Settings
- Bundler::SharedHelpers
- Bundler::SimilarityDetector
- Bundler::Source
- Bundler::Source::Git
- Bundler::Source::Git::GitCommandError
- Bundler::Source::Git::GitNotAllowedError
- Bundler::Source::Git::GitNotInstalledError
- Bundler::Source::Git::GitProxy
- Bundler::Source::Path
- Bundler::Source::Path::Installer
- Bundler::Source::Rubygems
- Bundler::Source::Rubygems::Remote
- Bundler::SourceList
- Bundler::SpecSet
- Bundler::StubSpecification
- Bundler::SystemRubyVersion
- Bundler::Thor
- Bundler::Thor::Actions
- Bundler::Thor::Actions::ClassMethods
- Bundler::Thor::AmbiguousCommandError
- Bundler::Thor::Base
- Bundler::Thor::Base::ClassMethods
- Bundler::Thor::Command
- Bundler::Thor::DynamicCommand
- Bundler::Thor::Error
- Bundler::Thor::Group
- Bundler::Thor::HiddenCommand
- Bundler::Thor::Invocation
- Bundler::Thor::Invocation::ClassMethods
- Bundler::Thor::InvocationError
- Bundler::Thor::LineEditor
- Bundler::Thor::LineEditor::Basic
- Bundler::Thor::LineEditor::Readline
- Bundler::Thor::LineEditor::Readline::PathCompletion
- Bundler::Thor::MalformattedArgumentError
- Bundler::Thor::RakeCompat
- Bundler::Thor::RequiredArgumentMissingError
- Bundler::Thor::Shell
- Bundler::Thor::Shell::Basic
- Bundler::Thor::Shell::Color
- Bundler::Thor::Shell::HTML
- Bundler::Thor::UndefinedCommandError
- Bundler::Thor::UnknownArgumentError
- Bundler::Thor::Util
- Bundler::UI
- Bundler::UI::RGProxy
- Bundler::UI::Shell
- Bundler::UI::Silent
- Bundler::VersionConflict
- Bundler::Worker
- Bundler::Worker::WrappedException
- Gem
- Gem::Dependency
- Gem::Platform
- Gem::Requirement
- Gem::Specification
- Net
- Net::HTTP
- Net::HTTP::Persistent
- Net::HTTP::Persistent::Error
- Net::HTTP::Persistent::SSLReuse
- ParallelInstaller
- ParallelInstaller::SpecInstallation
- Object

No matching classes.

# Bundler::Definition

### Attributes

dependencies[R]
locked_deps[R]
platforms[R]
ruby_version[R]

### Public Class Methods

build(gemfile, lockfile, unlock) click to toggle source

Given a gemfile and lockfile creates a Bundler definition

@param gemfile [Pathname] Path to Gemfile @param lockfile [Pathname,nil] Path to Gemfile.lock @param unlock [Hash, Boolean, nil] Gems that have been requested

    to be updated or true if all gems should be updated

@return [Bundler::Definition]

    # File lib/bundler/definition.rb, line 18
    def self.build(gemfile, lockfile, unlock)
      unlock ||= {}
      gemfile = Pathname.new(gemfile).expand_path

      unless gemfile.file?
        raise GemfileNotFound, "#{gemfile} not found"
      end

      Dsl.evaluate(gemfile, lockfile, unlock)
    end

new(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = []) click to toggle source

How does the new system work?

- Load information from Gemfile and Lockfile

- Invalidate stale locked specs

- All specs from stale source are stale

- All specs that are reachable only through a stale dependency are stale.

- If all fresh dependencies are satisfied by the locked

    specs, then we can try to resolve locally.

@param lockfile [Pathname] Path to Gemfile.lock @param dependencies [Array(Bundler::Dependency)] array of dependencies from Gemfile @param sources [Bundler::SourceList] @param unlock [Hash, Boolean, nil] Gems that have been requested

    to be updated or true if all gems should be updated

@param ruby_version [Bundler::RubyVersion, nil] Requested Ruby Version @param optional_groups [Array(String)] A list of optional groups

    # File lib/bundler/definition.rb, line 48
    def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, optional_groups = [])
      @unlocking = unlock == true || !unlock.empty?

      @dependencies    = dependencies
      @sources         = sources
      @unlock          = unlock
      @optional_groups = optional_groups
      @remote          = false
      @specs           = nil
      @ruby_version    = ruby_version

      @lockfile_contents      = ""
      @locked_bundler_version = nil

      if lockfile && File.exist?(lockfile)
        @lockfile_contents = Bundler.read_file(lockfile)
        locked = LockfileParser.new(@lockfile_contents)
        @platforms      = locked.platforms
        @locked_bundler_version = locked.bundler_version

        if unlock != true
          @locked_deps    = locked.dependencies
          @locked_specs   = SpecSet.new(locked.specs)
          @locked_sources = locked.sources
        else
          @unlock         = {}
          @locked_deps    = []
          @locked_specs   = SpecSet.new([])
          @locked_sources = []
        end
      else
        @unlock         = {}
        @platforms      = []
        @locked_deps    = []
        @locked_specs   = SpecSet.new([])
        @locked_sources = []
      end

      @unlock[:gems] ||= []
      @unlock[:sources] ||= []

      current_platform = Bundler.rubygems.platforms.map { |p| generic(p) }.compact.last
      @new_platform = !@platforms.include?(current_platform)
      @platforms |= [current_platform]

      @path_changes = converge_paths
      eager_unlock = expand_dependencies(@unlock[:gems])
      @unlock[:gems] = @locked_specs.for(eager_unlock).map { |s| s.name }

      @source_changes = converge_sources
      @dependency_changes = converge_dependencies
      @local_changes = converge_locals

      fixup_dependency_types!
    end

### Public Instance Methods

current_dependencies() click to toggle source

    # File lib/bundler/definition.rb, line 178
    def current_dependencies
      dependencies.reject { |d| !d.should_include? }
    end

ensure_equivalent_gemfile_and_lockfile(explicit_flag = false) click to toggle source

    # File lib/bundler/definition.rb, line 332
    def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false)
      msg = "You are trying to install in deployment mode after changing\n"              "your Gemfile. Run `bundle install` elsewhere and add the\n"              "updated Gemfile.lock to version control."

      unless explicit_flag
        msg += "\n\nIf this is a development machine, remove the Gemfile "                 "freeze \nby running `bundle install --no-deployment`."
      end

      added =   []
      deleted = []
      changed = []

      gemfile_sources = sources.lock_sources
      if @locked_sources != gemfile_sources
        new_sources = gemfile_sources - @locked_sources
        deleted_sources = @locked_sources - gemfile_sources

        if new_sources.any?
          added.concat new_sources.map { |source| "* source: #{source}" }
        end

        if deleted_sources.any?
          deleted.concat deleted_sources.map { |source| "* source: #{source}" }
        end
      end

      new_deps = @dependencies - @locked_deps
      deleted_deps = @locked_deps - @dependencies

      if new_deps.any?
        added.concat new_deps.map { |d| "* #{pretty_dep(d)}" }
      end

      if deleted_deps.any?
        deleted.concat deleted_deps.map { |d| "* #{pretty_dep(d)}" }
      end

      both_sources = Hash.new { |h,k| h[k] = [] }
      @dependencies.each { |d| both_sources[d.name][0] = d }
      @locked_deps.each  { |d| both_sources[d.name][1] = d.source }

      both_sources.each do |name, (dep, lock_source)|
        if (dep.nil? && !lock_source.nil?) || (!dep.nil? && !lock_source.nil? && !lock_source.can_lock?(dep))
          gemfile_source_name = (dep && dep.source) || 'no specified source'
          lockfile_source_name = lock_source || 'no specified source'
          changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`"
        end
      end

      msg << "\n\nYou have added to the Gemfile:\n"     << added.join("\n") if added.any?
      msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any?
      msg << "\n\nYou have changed in the Gemfile:\n"   << changed.join("\n") if changed.any?
      msg << "\n"

      raise ProductionError, msg if added.any? || deleted.any? || changed.any?
    end

fixup_dependency_types!() click to toggle source

    # File lib/bundler/definition.rb, line 104
    def fixup_dependency_types!
      # XXX This is a temporary workaround for a bug when using rubygems 1.8.15
      # where Gem::Dependency#== matches Gem::Dependency#type. As the lockfile
      # doesn't carry a notion of the dependency type, if you use
      # add_development_dependency in a gemspec that's loaded with the gemspec
      # directive, the lockfile dependencies and resolved dependencies end up
      # with a mismatch on #type.
      # Test coverage to catch a regression on this is in gemspec_spec.rb
      @dependencies.each do |d|
        if ld = @locked_deps.find { |l| l.name == d.name }
          ld.instance_variable_set(:@type, d.type)
        end
      end
    end

groups() click to toggle source

    # File lib/bundler/definition.rb, line 240
    def groups
      dependencies.map { |d| d.groups }.flatten.uniq
    end

has_local_dependencies?() click to toggle source

    # File lib/bundler/definition.rb, line 232
    def has_local_dependencies?
      !sources.path_sources.empty? || !sources.git_sources.empty?
    end

has_rubygems_remotes?() click to toggle source

    # File lib/bundler/definition.rb, line 228
    def has_rubygems_remotes?
      sources.rubygems_sources.any? {|s| s.remotes.any? }
    end

index() click to toggle source

    # File lib/bundler/definition.rb, line 205
    def index
      @index ||= Index.build do |idx|
        dependency_names = @dependencies.map { |d| d.name }

        sources.all_sources.each do |source|
          source.dependency_names = dependency_names.dup
          idx.add_source source.specs
          dependency_names -= pinned_spec_names(source.specs)
          dependency_names.push(*source.unmet_deps).uniq!
        end
      end
    end

lock(file, preserve_bundled_with = false) click to toggle source

    # File lib/bundler/definition.rb, line 244
    def lock(file, preserve_bundled_with = false)
      contents = to_lock

      # Convert to \r\n if the existing lock has them
      # i.e., Windows with `git config core.autocrlf=true`
      contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match("\r\n")

      if @locked_bundler_version
        locked_major = @locked_bundler_version.segments.first
        current_major = Gem::Version.create(Bundler::VERSION).segments.first

        if updating_major = locked_major < current_major
          Bundler.ui.warn "Warning: the lockfile is being updated to Bundler #{current_major}, "                            "after which you will be unable to return to Bundler #{@locked_bundler_version.segments.first}."
        end
      end

      preserve_bundled_with ||= !updating_major && (Bundler.settings[:frozen] || !@unlocking)
      return if lockfiles_equal?(@lockfile_contents, contents, preserve_bundled_with)

      if Bundler.settings[:frozen]
        Bundler.ui.error "Cannot write a changed lockfile while frozen."
        return
      end

      File.open(file, 'wb'){|f| f.puts(contents) }
    rescue Errno::EACCES
      raise Bundler::InstallError,
        "There was an error while trying to write to Gemfile.lock. It is likely that \n"          "you need to allow write permissions for the file at path: \n"          "#{File.expand_path(file)}"
    end

lock_version() click to toggle source

Returns the version of Bundler that is creating or has created Gemfile.lock. Used in to_lock.

    # File lib/bundler/definition.rb, line 279
    def lock_version
      if @locked_bundler_version && @locked_bundler_version < Gem::Version.new(Bundler::VERSION)
        new_version = Bundler::VERSION
      end

      new_version || @locked_bundler_version || Bundler::VERSION
    end

missing_specs() click to toggle source

    # File lib/bundler/definition.rb, line 164
    def missing_specs
      missing = []
      resolve.materialize(requested_dependencies, missing)
      missing
    end

new_platform?() click to toggle source

    # File lib/bundler/definition.rb, line 160
    def new_platform?
      @new_platform
    end

new_specs() click to toggle source

    # File lib/bundler/definition.rb, line 152
    def new_specs
      specs - @locked_specs
    end

removed_specs() click to toggle source

    # File lib/bundler/definition.rb, line 156
    def removed_specs
      @locked_specs - specs
    end

requested_specs() click to toggle source

    # File lib/bundler/definition.rb, line 170
    def requested_specs
      @requested_specs ||= begin
        groups = requested_groups
        groups.map! { |g| g.to_sym }
        specs_for(groups)
      end
    end

resolve() click to toggle source

Resolve all the dependencies specified in Gemfile. It ensures that dependencies that have been already resolved via locked file and are fresh are reused when resolving dependencies

@return [SpecSet] resolved dependencies

    # File lib/bundler/definition.rb, line 193
    def resolve
      @resolve ||= begin
        last_resolve = converge_locked_specs
        if Bundler.settings[:frozen] || (!@unlocking && nothing_changed?)
          last_resolve
        else
          # Run a resolve against the locally available gems
          last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve)
        end
      end
    end

resolve_remotely!() click to toggle source

    # File lib/bundler/definition.rb, line 125
    def resolve_remotely!
      raise "Specs already loaded" if @specs
      @remote = true
      sources.remote!
      specs
    end

resolve_with_cache!() click to toggle source

    # File lib/bundler/definition.rb, line 119
    def resolve_with_cache!
      raise "Specs already loaded" if @specs
      sources.cached!
      specs
    end

rubygems_index() click to toggle source

used when frozen is enabled so we can find the bundler spec, even if (say) a git gem is not checked out.

    # File lib/bundler/definition.rb, line 220
    def rubygems_index
      @rubygems_index ||= Index.build do |idx|
        sources.rubygems_sources.each do |rubygems|
          idx.add_source rubygems.specs
        end
      end
    end

spec_git_paths() click to toggle source

    # File lib/bundler/definition.rb, line 236
    def spec_git_paths
      sources.git_sources.map {|s| s.path.to_s }
    end

specs() click to toggle source

For given dependency list returns a SpecSet with Gemspec of all the required dependencies.

    1. The method first resolves the dependencies specified in Gemfile
    2. After that it tries and fetches gemspec of resolved dependencies

@return [Bundler::SpecSet]

    # File lib/bundler/definition.rb, line 138
    def specs
      @specs ||= begin
        specs = resolve.materialize(Bundler.settings[:cache_all_platforms] ? dependencies : requested_dependencies)

        unless specs["bundler"].any?
          local = Bundler.settings[:frozen] ? rubygems_index : index
          bundler = local.search(Gem::Dependency.new('bundler', VERSION)).last
          specs["bundler"] = bundler if bundler
        end

        specs
      end
    end

specs_for(groups) click to toggle source

    # File lib/bundler/definition.rb, line 182
    def specs_for(groups)
      deps = dependencies.select { |d| (d.groups & groups).any? }
      deps.delete_if { |d| !d.should_include? }
      specs.for(expand_dependencies(deps))
    end

to_lock() click to toggle source

    # File lib/bundler/definition.rb, line 287
    def to_lock
      out = ""

      sources.lock_sources.each do |source|
        # Add the source header
        out << source.to_lock
        # Find all specs for this source
        resolve.
          select { |s| source.can_lock?(s) }.
          # This needs to be sorted by full name so that
          # gems with the same name, but different platform
          # are ordered consistently
          sort_by { |s| s.full_name }.
          each do |spec|
            next if spec.name == 'bundler'
            out << spec.to_lock
          end
        out << "\n"
      end

      out << "PLATFORMS\n"

      platforms.map { |p| p.to_s }.sort.each do |p|
        out << "  #{p}\n"
      end

      out << "\n"
      out << "DEPENDENCIES\n"

      handled = []
      dependencies.
        sort_by { |d| d.to_s }.
        each do |dep|
          next if handled.include?(dep.name)
          out << dep.to_lock
          handled << dep.name
      end

      # Record the version of Bundler that was used to create the lockfile
      out << "\nBUNDLED WITH\n"
      out << "   #{lock_version}\n"

      out
    end

validate_ruby!() click to toggle source

    # File lib/bundler/definition.rb, line 391
    def validate_ruby!
      return unless ruby_version

      if diff = ruby_version.diff(Bundler.ruby_version)
        problem, expected, actual = diff

        msg = case problem
        when :engine
          "Your Ruby engine is #{actual}, but your Gemfile specified #{expected}"
        when :version
          "Your Ruby version is #{actual}, but your Gemfile specified #{expected}"
        when :engine_version
          "Your #{Bundler.ruby_version.engine} version is #{actual}, but your Gemfile specified #{ruby_version.engine} #{expected}"
        when :patchlevel
          if !expected.is_a?(String)
            "The Ruby patchlevel in your Gemfile must be a string"
          else
            "Your Ruby patchlevel is #{actual}, but your Gemfile specified #{expected}"
          end
        end

        raise RubyVersionMismatch, msg
      end
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.