module Solve module Errors class SolveError < StandardError alias_method :mesage, :to_s end class NoSolutionError < SolveError # Artifacts that don't exist at any version but are required for a valid # solution # @return [Array] Missing artifact names attr_reader :missing_artifacts # Constraints that eliminate all versions of an artifact, e.g. you ask # for mysql >= 2.0.0 but only 1.0.0 exists. # @return [Array] Invalid constraints as strings attr_reader :constraints_excluding_all_artifacts # A demand that has conflicting dependencies # @return [String] the unsatisfiable demand attr_reader :unsatisfiable_demand # The artifact for which there are conflicting dependencies # @return [Array] The "most constrained" artifacts attr_reader :artifacts_with_no_satisfactory_version # @param [#to_s] message # @option causes [Array] :missing_artifacts ([]) # @option causes [Array] :constraints_excluding_all_artifacts ([]) # @option causes [#to_s] :unsatisfiable_demand (nil) # @option causes [Array] :artifacts_with_no_satisfactory_version ([]) def initialize(message = nil, causes = {}) super(message) @message = message @missing_artifacts = causes[:missing_artifacts] || [] @constraints_excluding_all_artifacts = causes[:constraints_excluding_all_artifacts] || [] @unsatisfiable_demand = causes[:unsatisfiable_demand] || nil @artifacts_with_no_satisfactory_version = causes[:artifacts_with_no_satisfactory_version] || [] end def to_s s = "" s << "#{@message}\n" s << "Missing artifacts: #{missing_artifacts.join(',')}\n" unless missing_artifacts.empty? unless constraints_excluding_all_artifacts.empty? pretty = constraints_excluding_all_artifacts.map { |constraint| "(#{constraint[0]} #{constraint[1]})" }.join(',') s << "Constraints that match no available version: #{pretty}\n" end s << "Demand that cannot be met: #{unsatisfiable_demand}\n" if unsatisfiable_demand unless artifacts_with_no_satisfactory_version.empty? s << "Artifacts for which there are conflicting dependencies: #{artifacts_with_no_satisfactory_version.join(',')}" end s end end # Indicates that the solver could not find the conflicting constraints when # solving the given demands and graph. class NoSolutionCauseUnknown < NoSolutionError; end class UnsortableSolutionError < SolveError attr_reader :internal_exception attr_reader :unsorted_solution def initialize(internal_exception, unsorted_solution) @internal_exception = internal_exception @unsorted_solution = unsorted_solution end def to_s "The solution contains a cycle and cannot be topologically sorted. See #unsorted_solution on this exception for the unsorted solution" end end end end