Class: DepSelector::Package

Inherits:
Object
  • Object
show all
Defined in:
lib/dep_selector/package.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dependency_graph, name) ⇒ Package

Returns a new instance of Package.



27
28
29
30
31
# File 'lib/dep_selector/package.rb', line 27

def initialize(dependency_graph, name)
  @dependency_graph = dependency_graph
  @name = name
  @versions = []
end

Instance Attribute Details

#dependency_graphObject (readonly)

Returns the value of attribute dependency_graph.



25
26
27
# File 'lib/dep_selector/package.rb', line 25

def dependency_graph
  @dependency_graph
end

#nameObject (readonly)

Returns the value of attribute name.



25
26
27
# File 'lib/dep_selector/package.rb', line 25

def name
  @name
end

#versionsObject (readonly)

Returns the value of attribute versions.



25
26
27
# File 'lib/dep_selector/package.rb', line 25

def versions
  @versions
end

Instance Method Details

#[](version_or_constraint) ⇒ Object

Given a version, this method returns the corresonding PackageVersion. Given a version constraint, this method returns an array of matching PackageVersions. – TODO [cw,2011/2/4]: rationalize this with DenselyPackedSet#[]



55
56
57
58
59
60
61
62
63
64
# File 'lib/dep_selector/package.rb', line 55

def [](version_or_constraint)
  # version constraints must abide the include? contract
  if version_or_constraint.respond_to?(:include?)
    versions.select do |ver|
      version_or_constraint.include?(ver.version)
    end
  else
    versions.find{|pkg_version| pkg_version.version == version_or_constraint}
  end
end

#add_version(version) ⇒ Object



33
34
35
36
# File 'lib/dep_selector/package.rb', line 33

def add_version(version)
  versions << (pv = PackageVersion.new(self, version))
  pv
end

#densely_packed_versionsObject

Note: only invoke this method after all PackageVersions have been added



39
40
41
42
43
44
45
46
47
48
# File 'lib/dep_selector/package.rb', line 39

def densely_packed_versions
  if @densely_packed_versions.nil?
    @densely_packed_versions = DenselyPackedSet.new(versions.map{|pkg_version| pkg_version.version})
    Debug.log.debug { "Package Versions for '#{@name}' :" }
    versions.each do |v|
      Debug.log.debug { "    #{v.to_s(true)}" }
    end
  end
  @densely_packed_versions
end

#eql?(o) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)


119
120
121
122
123
# File 'lib/dep_selector/package.rb', line 119

def eql?(o)
  # TODO [cw,2011/2/7]: this is really shallow. should implement
  # == for DependencyGraph
  self.class == o.class && name == o.name
end

#gecode_package_idObject

Note: only invoke this method after all PackageVersions have been added



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/dep_selector/package.rb', line 82

def gecode_package_id
  # Note: gecode does naive bounds propagation at every post,
  # which means that any package with exactly one version is
  # considered bound and its dependencies propagated even though
  # there might not be a solution constraint that requires that
  # package to be bound, which means that otherwise-irrelevant
  # constraints (e.g. A1->B1 when the solution constraint is B=2
  # and there is nothing to induce a dependency on A) can cause
  # unsatisfiability. Therefore, we want every package to have at
  # least two versions, one of which is neither the target of
  # other packages' dependencies nor induces other
  # dependencies. Package version id -1 serves this purpose.
  #
  # TODO [cw, 2011/2/22]: Do we likewise want to leave packages
  # with no versions (the target of an invalid dependency) with
  # two versions in order to allow the solver to explore the
  # invalid portion of the state space instead of naively limiting
  # it for the purposes of having failure count heuristics?
  max = densely_packed_versions.range.max || -1
  if @gecode_package_id.nil?
     @gecode_package_id = dependency_graph.gecode_wrapper.add_package(-1, max, 0)
     Debug.log.debug { "Adding Package '#{@name}' PackageId: #{@gecode_package_id}" }
  end
  @gecode_package_id
end

#generate_gecode_wrapper_constraintsObject



108
109
110
111
112
113
114
115
116
117
# File 'lib/dep_selector/package.rb', line 108

def generate_gecode_wrapper_constraints
  # if this is a valid package (has versions), we don't need to
  # explicitly call gecode_package_id, because they will do it for
  # us; however, if this package isn't valid (it only exists as an
  # invalid dependency and thus has no versions), the solver gets
  # confused, because we won't have generated its package id by
  # the time it starts solving.
  gecode_package_id
  versions.each{|version| version.generate_gecode_wrapper_constraints }
end

#to_s(incl_densely_packed_versions = false) ⇒ Object



71
72
73
74
75
76
77
78
79
# File 'lib/dep_selector/package.rb', line 71

def to_s(incl_densely_packed_versions = false)
  components = []
  components << "Package #{name}"
  if incl_densely_packed_versions
    components << " (#{densely_packed_versions.range})"
  end
  versions.each{|version| components << "\n  #{version.to_s(incl_densely_packed_versions)}"}
  components.flatten.join
end

#valid?Boolean

A Package is considered valid if it has at least one version

Returns:

  • (Boolean)


67
68
69
# File 'lib/dep_selector/package.rb', line 67

def valid?
  versions.any?
end