class Bundler::Molinillo::VersionConflict

An error caused by conflicts in version

Attributes

conflicts[R]

@return [{String => Resolution::Conflict}] the conflicts that caused

resolution to fail
specification_provider[R]

@return [SpecificationProvider] the specification provider used during

resolution

Public Class Methods

new(conflicts, specification_provider) click to toggle source

Initializes a new error with the given version conflicts. @param [{String => Resolution::Conflict}] conflicts see {#conflicts} @param [SpecificationProvider] #specification_provider see {#specification_provider}

Calls superclass method Exception.new
# File lib/bundler/vendor/molinillo/lib/molinillo/errors.rb, line 66
def initialize(conflicts, specification_provider)
  pairs = []
  Compatibility.flat_map(conflicts.values.flatten, &:requirements).each do |conflicting|
    conflicting.each do |source, conflict_requirements|
      conflict_requirements.each do |c|
        pairs << [c, source]
      end
    end
  end

  super "Unable to satisfy the following requirements:\n\n" \
    "#{pairs.map { |r, d| "- `#{r}` required by `#{d}`" }.join("\n")}"

  @conflicts = conflicts
  @specification_provider = specification_provider
end

Public Instance Methods

message_with_trees(opts = {}) click to toggle source

@return [String] An error message that includes requirement trees,

which is much more detailed & customizable than the default message

@param [Hash] opts the options to create a message with. @option opts [String] :solver_name The user-facing name of the solver @option opts [String] :possibility_type The generic name of a possibility @option opts [Proc] :reduce_trees A proc that reduced the list of requirement trees @option opts [Proc] :printable_requirement A proc that pretty-prints requirements @option opts [Proc] :additional_message_for_conflict A proc that appends additional

messages for each conflict

@option opts [Proc] :version_for_spec A proc that returns the version number for a

possibility
# File lib/bundler/vendor/molinillo/lib/molinillo/errors.rb, line 97
def message_with_trees(opts = {})
  solver_name = opts.delete(:solver_name) { self.class.name.split('::').first }
  possibility_type = opts.delete(:possibility_type) { 'possibility named' }
  reduce_trees = opts.delete(:reduce_trees) { proc { |trees| trees.uniq.sort_by(&:to_s) } }
  printable_requirement = opts.delete(:printable_requirement) { proc { |req| req.to_s } }
  additional_message_for_conflict = opts.delete(:additional_message_for_conflict) { proc {} }
  version_for_spec = opts.delete(:version_for_spec) { proc(&:to_s) }
  incompatible_version_message_for_conflict = opts.delete(:incompatible_version_message_for_conflict) do
    proc do |name, _conflict|
      %(#{solver_name} could not find compatible versions for #{possibility_type} "#{name}":)
    end
  end

  conflicts.sort.reduce(''.dup) do |o, (name, conflict)|
    o << "\n" << incompatible_version_message_for_conflict.call(name, conflict) << "\n"
    if conflict.locked_requirement
      o << %(  In snapshot (#{name_for_locking_dependency_source}):\n)
      o << %(    #{printable_requirement.call(conflict.locked_requirement)}\n)
      o << %(\n)
    end
    o << %(  In #{name_for_explicit_dependency_source}:\n)
    trees = reduce_trees.call(conflict.requirement_trees)

    o << trees.map do |tree|
      t = ''.dup
      depth = 2
      tree.each do |req|
        t << '  ' * depth << req.to_s
        unless tree.last == req
          if spec = conflict.activated_by_name[name_for(req)]
            t << %( was resolved to #{version_for_spec.call(spec)}, which)
          end
          t << %( depends on)
        end
        t << %(\n)
        depth += 1
      end
      t
    end.join("\n")

    additional_message_for_conflict.call(o, name, conflict)

    o
  end.strip
end