Class: Gem::Dependency

Inherits:
Object
  • Object
show all
Defined in:
lib/rubygems/dependency.rb

Overview

The Dependency class holds a Gem name and a Gem::Requirement.

Constant Summary collapse

TYPES =

Valid dependency types. -- When this list is updated, be sure to change Gem::Specification::CURRENT_SPECIFICATION_VERSION as well.

[
 :development,
 :runtime,
]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, *requirements) ⇒ Dependency

Constructs a dependency with name and requirements. The last argument can optionally be the dependency type, which defaults to :runtime.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rubygems/dependency.rb', line 34

def initialize name, *requirements
  if Regexp === name then
    msg = ["NOTE: Dependency.new w/ a regexp is deprecated.",
           "Dependency.new called from #{Gem.location_of_caller.join(":")}"]
    warn msg.join("\n") unless Gem::Deprecate.skip
  end

  type         = Symbol === requirements.last ? requirements.pop : :runtime
  requirements = requirements.first if 1 == requirements.length # unpack

  unless TYPES.include? type
    raise ArgumentError, "Valid types are #{TYPES.inspect}, "
      + "not #{type.inspect}"
  end

  @name        = name
  @requirement = Gem::Requirement.create requirements
  @type        = type
  @prerelease  = false

  # This is for Marshal backwards compatibility. See the comments in
  # +requirement+ for the dirty details.

  @version_requirements = @requirement
end

Instance Attribute Details

#nameObject

Dependency name or regular expression.



22
23
24
# File 'lib/rubygems/dependency.rb', line 22

def name
  @name
end

#prerelease=(value) ⇒ Object (writeonly)

Allows you to force this dependency to be a prerelease.



27
28
29
# File 'lib/rubygems/dependency.rb', line 27

def prerelease=(value)
  @prerelease = value
end

Instance Method Details

#<=>(other) ⇒ Object

Dependencies are ordered by name.



154
155
156
# File 'lib/rubygems/dependency.rb', line 154

def <=> other
  self.name <=> other.name
end

#==(other) ⇒ Object

:nodoc:



144
145
146
147
148
149
# File 'lib/rubygems/dependency.rb', line 144

def == other # :nodoc:
  Gem::Dependency === other &&
    self.name        == other.name &&
    self.type        == other.type &&
    self.requirement == other.requirement
end

#=~(other) ⇒ Object

Uses this dependency as a pattern to compare to other. This dependency will match if the name matches the other's name, and other has only an equal version requirement that satisfies this dependency.



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/rubygems/dependency.rb', line 164

def =~ other
  unless Gem::Dependency === other
    return unless other.respond_to?(:name) && other.respond_to?(:version)
    other = Gem::Dependency.new other.name, other.version
  end

  return false unless name === other.name

  reqs = other.requirement.requirements

  return false unless reqs.length == 1
  return false unless reqs.first.first == '='

  version = reqs.first.last

  requirement.satisfied_by? version
end

#hashObject

A dependency's hash is the XOR of the hashes of name, type, and requirement.



64
65
66
# File 'lib/rubygems/dependency.rb', line 64

def hash # :nodoc:
  name.hash ^ type.hash ^ requirement.hash
end

#inspectObject

:nodoc:



68
69
70
71
# File 'lib/rubygems/dependency.rb', line 68

def inspect # :nodoc:
  "<%s type=%p name=%p requirements=%p>" %
    [self.class, self.type, self.name, requirement.to_s]
end

#match?(name, version) ⇒ Boolean

Returns:

  • (Boolean)


182
183
184
185
186
187
# File 'lib/rubygems/dependency.rb', line 182

def match? name, version
  return false unless self.name === name
  return true if requirement.none?

  requirement.satisfied_by? Gem::Version.new(version)
end

#matches_spec?(spec) ⇒ Boolean

Returns:

  • (Boolean)


189
190
191
192
193
194
# File 'lib/rubygems/dependency.rb', line 189

def matches_spec? spec
  return false unless name === spec.name
  return true  if requirement.none?

  requirement.satisfied_by?(spec.version)
end

#matching_specs(platform_only = false) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/rubygems/dependency.rb', line 215

def matching_specs platform_only = false
  matches = Gem::Specification.find_all { |spec|
    self.name === spec.name and # TODO: == instead of ===
      requirement.satisfied_by? spec.version
  }

  if platform_only
    matches.reject! { |spec|
      not Gem::Platform.match spec.platform
    }
  end

  matches = matches.sort_by { |s| s.sort_obj } # HACK: shouldn't be needed
end

#merge(other) ⇒ Object

Merges the requirements of other into this dependency



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/rubygems/dependency.rb', line 199

def merge other
  unless name == other.name then
    raise ArgumentError,
          "#{self} and #{other} have different names"
  end

  default = Gem::Requirement.default
  self_req  = self.requirement
  other_req = other.requirement

  return self.class.new name, self_req  if other_req == default
  return self.class.new name, other_req if self_req  == default

  self.class.new name, self_req.as_list.concat(other_req.as_list)
end

#prerelease?Boolean

Does this dependency require a prerelease?

Returns:

  • (Boolean)


76
77
78
# File 'lib/rubygems/dependency.rb', line 76

def prerelease?
  @prerelease || requirement.prerelease?
end

#pretty_print(q) ⇒ Object

:nodoc:



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rubygems/dependency.rb', line 80

def pretty_print q # :nodoc:
  q.group 1, 'Gem::Dependency.new(', ')' do
    q.pp name
    q.text ','
    q.breakable

    q.pp requirement

    q.text ','
    q.breakable

    q.pp type
  end
end

#requirementObject

What does this dependency require?



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
# File 'lib/rubygems/dependency.rb', line 98

def requirement
  return @requirement if defined?(@requirement) and @requirement

  # @version_requirements and @version_requirement are legacy ivar
  # names, and supported here because older gems need to keep
  # working and Dependency doesn't implement marshal_dump and
  # marshal_load. In a happier world, this would be an
  # attr_accessor. The horrifying instance_variable_get you see
  # below is also the legacy of some old restructurings.
  #
  # Note also that because of backwards compatibility (loading new
  # gems in an old RubyGems installation), we can't add explicit
  # marshaling to this class until we want to make a big
  # break. Maybe 2.0.
  #
  # Children, define explicit marshal and unmarshal behavior for
  # public classes. Marshal formats are part of your public API.

  if defined?(@version_requirement) && @version_requirement
    version = @version_requirement.instance_variable_get :@version
    @version_requirement  = nil
    @version_requirements = Gem::Requirement.new version
  end

  @requirement = @version_requirements if defined?(@version_requirements)
end

#requirements_listObject



125
126
127
# File 'lib/rubygems/dependency.rb', line 125

def requirements_list
  requirement.as_list
end

#specific?Boolean

True if the dependency will not always match the latest version.

Returns:

  • (Boolean)


233
234
235
# File 'lib/rubygems/dependency.rb', line 233

def specific?
  @requirement.specific?
end

#to_sObject

:nodoc:



129
130
131
132
133
134
135
# File 'lib/rubygems/dependency.rb', line 129

def to_s # :nodoc:
  if type != :runtime then
    "#{name} (#{requirement}, #{type})"
  else
    "#{name} (#{requirement})"
  end
end

#to_specObject



255
256
257
258
259
# File 'lib/rubygems/dependency.rb', line 255

def to_spec
  matches = self.to_specs

  matches.find { |spec| spec.activated? } or matches.last
end

#to_specsObject



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/rubygems/dependency.rb', line 237

def to_specs
  matches = matching_specs true

  # TODO: check Gem.activated_spec[self.name] in case matches falls outside

  if matches.empty? then
    specs = Gem::Specification.all_names.join ", "
    error = Gem::LoadError.new "Could not find #{name} (#{requirement}) amongst [#{specs}]"
    error.name        = self.name
    error.requirement = self.requirement
    raise error
  end

  # TODO: any other resolver validations should go here

  matches
end

#typeObject

Dependency type.



140
141
142
# File 'lib/rubygems/dependency.rb', line 140

def type
  @type ||= :runtime
end