Class: PubGrub::Incompatibility

Inherits:
Object
  • Object
show all
Defined in:
lib/pub_grub/incompatibility.rb

Defined Under Namespace

Classes: ConflictCause, InvalidDependency, NoVersions

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(terms, cause:) ⇒ Incompatibility

Returns a new instance of Incompatibility.



16
17
18
19
20
21
22
23
# File 'lib/pub_grub/incompatibility.rb', line 16

def initialize(terms, cause:)
  @cause = cause
  @terms = cleanup_terms(terms)

  if cause == :dependency && @terms.length != 2
    raise ArgumentError, "a dependency Incompatibility must have exactly two terms. Got #{terms.inspect}"
  end
end

Instance Attribute Details

#causeObject (readonly)

Returns the value of attribute cause.



14
15
16
# File 'lib/pub_grub/incompatibility.rb', line 14

def cause
  @cause
end

#termsObject (readonly)

Returns the value of attribute terms.



14
15
16
# File 'lib/pub_grub/incompatibility.rb', line 14

def terms
  @terms
end

Instance Method Details

#conflict?Boolean

Returns:

  • (Boolean)


29
30
31
# File 'lib/pub_grub/incompatibility.rb', line 29

def conflict?
  ConflictCause === cause
end

#external_incompatibilitiesObject

Returns all external incompatibilities in this incompatibility’s derivation graph



35
36
37
38
39
40
41
42
43
44
# File 'lib/pub_grub/incompatibility.rb', line 35

def external_incompatibilities
  if conflict?
    [
      cause.conflict,
      cause.other
    ].flat_map(&:external_incompatibilities)
  else
    [this]
  end
end

#failure?Boolean

Returns:

  • (Boolean)


25
26
27
# File 'lib/pub_grub/incompatibility.rb', line 25

def failure?
  terms.empty? || (terms.length == 1 && terms[0].package == Package.root && terms[0].positive?)
end

#inspectObject



95
96
97
# File 'lib/pub_grub/incompatibility.rb', line 95

def inspect
  "#<#{self.class} #{to_s}>"
end

#pretty_print(q) ⇒ Object



99
100
101
102
103
104
105
106
107
108
# File 'lib/pub_grub/incompatibility.rb', line 99

def pretty_print(q)
  q.group 2, "#<#{self.class}", ">" do
    q.breakable
    q.text to_s

    q.breakable
    q.text " caused by "
    q.pp @cause
  end
end

#to_sObject



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/pub_grub/incompatibility.rb', line 46

def to_s
  case cause
  when :root
    "(root dependency)"
  when :dependency
    "#{terms[0].to_s(allow_every: true)} depends on #{terms[1].invert}"
  when PubGrub::Incompatibility::InvalidDependency
    "#{terms[0].to_s(allow_every: true)} depends on unknown package #{cause.package}"
  when PubGrub::Incompatibility::NoVersions
    "no versions satisfy #{cause.constraint}"
  when PubGrub::Incompatibility::ConflictCause
    if failure?
      "version solving has failed"
    elsif terms.length == 1
      term = terms[0]
      if term.positive?
        "#{terms[0].to_s(allow_every: true)} is forbidden"
      else
        "#{terms[0].invert} is required"
      end
    else
      if terms.all?(&:positive?)
        if terms.length == 2
          "#{terms[0].to_s(allow_every: true)} is incompatible with #{terms[1]}"
        else
          "one of #{terms.map(&:to_s).join(" or ")} must be false"
        end
      elsif terms.all?(&:negative?)
        if terms.length == 2
          "either #{terms[0].invert} or #{terms[1].invert}"
        else
          "one of #{terms.map(&:invert).join(" or ")} must be true";
        end
      else
        positive = terms.select(&:positive?)
        negative = terms.select(&:negative?).map(&:invert)

        if positive.length == 1
          "#{positive[0].to_s(allow_every: true)} requires #{negative.join(" or ")}"
        else
          "if #{positive.join(" and ")} then #{negative.join(" or ")}"
        end
      end
    end
  else
    raise "unhandled cause: #{cause.inspect}"
  end
end