Exception: Bundler::Molinillo::VersionConflict

Inherits:
ResolverError
  • Object
show all
Includes:
Delegates::SpecificationProvider
Defined in:
lib/bundler/vendor/molinillo/lib/molinillo/errors.rb

Overview

An error caused by conflicts in version

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Delegates::SpecificationProvider

#allow_missing?, #dependencies_for, #name_for, #name_for_explicit_dependency_source, #name_for_locking_dependency_source, #requirement_satisfied_by?, #search_for, #sort_dependencies

Constructor Details

#initialize(conflicts, specification_provider) ⇒ VersionConflict

Initializes a new error with the given version conflicts.

Parameters:



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/bundler/vendor/molinillo/lib/molinillo/errors.rb', line 66

def initialize(conflicts, specification_provider)
  pairs = []
  conflicts.values.flat_map(&: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

Instance Attribute Details

#conflicts{String => Resolution::Conflict} (readonly)

Returns the conflicts that caused resolution to fail.

Returns:

  • ({String => Resolution::Conflict})

    the conflicts that caused resolution to fail



57
58
59
# File 'lib/bundler/vendor/molinillo/lib/molinillo/errors.rb', line 57

def conflicts
  @conflicts
end

#specification_providerSpecificationProvider (readonly)

Returns the specification provider used during resolution.

Returns:



61
62
63
# File 'lib/bundler/vendor/molinillo/lib/molinillo/errors.rb', line 61

def specification_provider
  @specification_provider
end

Instance Method Details

#message_with_trees(opts = {}) ⇒ String

Returns An error message that includes requirement trees, which is much more detailed & customizable than the default message.

Parameters:

  • opts (Hash) (defaults to: {})

    the options to create a message with.

Options Hash (opts):

  • :solver_name (String)

    The user-facing name of the solver

  • :possibility_type (String)

    The generic name of a possibility

  • :reduce_trees (Proc)

    A proc that reduced the list of requirement trees

  • :printable_requirement (Proc)

    A proc that pretty-prints requirements

  • :additional_message_for_conflict (Proc)

    A proc that appends additional messages for each conflict

  • :version_for_spec (Proc)

    A proc that returns the version number for a possibility

Returns:

  • (String)

    An error message that includes requirement trees, which is much more detailed & customizable than the default message



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# 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