rubygems-update 0.8.6 → 0.8.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubygems-update might be problematic. Click here for more details.

Files changed (42) hide show
  1. data/ChangeLog +134 -0
  2. data/Rakefile +41 -17
  3. data/bin/gemwhich +61 -0
  4. data/examples/application/an-app.gemspec +1 -0
  5. data/lib/gemconfigure.rb +18 -0
  6. data/lib/rubygems.rb +65 -47
  7. data/lib/rubygems/cmd_manager.rb +3 -1
  8. data/lib/rubygems/command.rb +4 -0
  9. data/lib/rubygems/config_file.rb +2 -6
  10. data/lib/rubygems/custom_require.rb +2 -2
  11. data/lib/rubygems/dependency_list.rb +131 -0
  12. data/lib/rubygems/deployment.rb +265 -0
  13. data/lib/rubygems/doc_manager.rb +1 -0
  14. data/lib/rubygems/gem_commands.rb +216 -15
  15. data/lib/rubygems/installer.rb +111 -286
  16. data/lib/rubygems/remote_installer.rb +16 -6
  17. data/lib/rubygems/rubygems_version.rb +1 -1
  18. data/lib/rubygems/source_index.rb +11 -5
  19. data/lib/rubygems/specification.rb +5 -0
  20. data/lib/rubygems/version.rb +146 -129
  21. data/test/test_configfile.rb +1 -1
  22. data/test/test_dependency_list.rb +163 -0
  23. data/test/test_deployment.rb +93 -0
  24. data/test/test_remote_fetcher.rb +38 -36
  25. metadata +23 -47
  26. data/test/data/a-0.0.1.gem +0 -0
  27. data/test/data/a-0.0.2.gem +0 -0
  28. data/test/data/b-0.0.2.gem +0 -0
  29. data/test/data/c-1.2.gem +0 -0
  30. data/test/data/gemhome/cache/a-0.0.1.gem +0 -0
  31. data/test/data/gemhome/cache/a-0.0.2.gem +0 -0
  32. data/test/data/gemhome/cache/b-0.0.2.gem +0 -0
  33. data/test/data/gemhome/cache/c-1.2.gem +0 -0
  34. data/test/data/gemhome/gems/a-0.0.1/lib/code.rb +0 -1
  35. data/test/data/gemhome/gems/a-0.0.2/lib/code.rb +0 -1
  36. data/test/data/gemhome/gems/b-0.0.2/lib/code.rb +0 -1
  37. data/test/data/gemhome/gems/c-1.2/lib/code.rb +0 -1
  38. data/test/data/gemhome/specifications/a-0.0.1.gemspec +0 -8
  39. data/test/data/gemhome/specifications/a-0.0.2.gemspec +0 -8
  40. data/test/data/gemhome/specifications/b-0.0.2.gemspec +0 -8
  41. data/test/data/gemhome/specifications/c-1.2.gemspec +0 -8
  42. data/test/data/one/one-0.0.1.gem +0 -0
@@ -16,7 +16,7 @@ module Gem
16
16
  # Initialize a remote fetcher using the source URI (and possible
17
17
  # proxy information).
18
18
  def initialize(source_uri, proxy)
19
- @uri = source_uri
19
+ @uri = normalize_uri(source_uri)
20
20
  @http_proxy = proxy
21
21
  if @http_proxy == true
22
22
  @http_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
@@ -61,6 +61,11 @@ module Gem
61
61
 
62
62
  private
63
63
 
64
+ # Normalize the URI by adding "http://" if it is missing.
65
+ def normalize_uri(uri)
66
+ (uri =~ /^(https?|ftp):/) ? uri : "http://#{uri}"
67
+ end
68
+
64
69
  # Connect to the source host/port, using a proxy if needed.
65
70
  def connect_to(host, port)
66
71
  if @http_proxy
@@ -169,7 +174,7 @@ module Gem
169
174
  # Write data to the proper cache.
170
175
  def write_cache
171
176
  data = cache_data
172
- open(writable_file, "w") do |f|
177
+ open(writable_file, "wb") do |f|
173
178
  f.puts Marshal.dump(data)
174
179
  end
175
180
  end
@@ -207,7 +212,7 @@ module Gem
207
212
  def read_cache
208
213
  @cache_file = select_cache_file
209
214
  begin
210
- open(@cache_file) { |f| load_local_cache(f) } || {}
215
+ open(@cache_file, "rb") { |f| load_local_cache(f) } || {}
211
216
  rescue StandardError => ex
212
217
  {}
213
218
  end
@@ -457,7 +462,10 @@ module Gem
457
462
  to_install = []
458
463
  dependencies.each do |dependency|
459
464
  begin
460
- require_gem(dependency.name, *dependency.requirement_list)
465
+ require_gem_with_options(
466
+ dependency.name,
467
+ dependency.requirement_list,
468
+ :auto_require=>false)
461
469
  rescue LoadError => e
462
470
  to_install.push dependency
463
471
  end
@@ -472,9 +480,11 @@ module Gem
472
480
  # way to do things (e.g. if a package fails to download, we
473
481
  # shouldn't install anything).
474
482
  def install_dependencies(dependencies, force, install_dir)
483
+ return if @options[:ignore_dependencies]
475
484
  installed_gems = []
476
485
  dependencies.each do |dependency|
477
- if ask_yes_no("Install required dependency #{dependency.name}?", true)
486
+ if @options[:include_dependencies] ||
487
+ ask_yes_no("Install required dependency #{dependency.name}?", true)
478
488
  remote_installer = RemoteInstaller.new(@options)
479
489
  installed_gems << remote_installer.install(
480
490
  dependency.name,
@@ -503,7 +513,7 @@ module Gem
503
513
  end
504
514
 
505
515
  def new_installer(gem)
506
- return Installer.new(gem)
516
+ return Installer.new(gem, @options)
507
517
  end
508
518
  end
509
519
 
@@ -2,5 +2,5 @@
2
2
  # This file is auto-generated by build scripts.
3
3
  # See: rake update_version
4
4
  module Gem
5
- RubyGemsVersion = '0.8.6'
5
+ RubyGemsVersion = '0.8.8'
6
6
  end
@@ -89,10 +89,16 @@ module Gem
89
89
 
90
90
  def_delegators :@gems, :size, :length
91
91
 
92
- # Search for a gem by name and optional version
92
+ # Find a gem by an exact match on the short name.
93
+ def find_name(gem_name, version_requirement=Version::Requirement.new(">= 0"))
94
+ search(/^#{gem_name}$/, version_requirement)
95
+ end
96
+
97
+ # Search for a gem by short name pattern and optional version
93
98
  #
94
99
  # gem_name::
95
- # [String] the (short) name of the gem
100
+ # [String] a partial for the (short) name of the gem, or
101
+ # [Regex] a pattern to match against the short name
96
102
  # version_requirement::
97
103
  # [String | default=Version::Requirement.new(">= 0")] version to
98
104
  # find
@@ -100,13 +106,13 @@ module Gem
100
106
  # [Array] list of Gem::Specification objects in sorted (version)
101
107
  # order. Empty if not found.
102
108
  #
103
- def search(gem_name, version_requirement=Version::Requirement.new(">= 0"))
109
+ def search(gem_pattern, version_requirement=Version::Requirement.new(">= 0"))
104
110
  #FIXME - remove duplication between this and RemoteInstaller.search
105
- gem_name = /#{ gem_name }/i if String === gem_name
111
+ gem_pattern = /#{ gem_pattern }/i if String === gem_pattern
106
112
  version_requirement = Gem::Version::Requirement.create(version_requirement)
107
113
  result = []
108
114
  @gems.each do |full_spec_name, spec|
109
- next unless spec.name =~ gem_name
115
+ next unless spec.name =~ gem_pattern
110
116
  result << spec if version_requirement.satisfied_by?(spec.version)
111
117
  end
112
118
  result = result.sort
@@ -559,6 +559,11 @@ module Gem
559
559
  # ------------------------- Dependency methods.
560
560
 
561
561
  ##
562
+ # Return a list of all gems that have a dependency on this
563
+ # gemspec. The list is structured with entries that conform to:
564
+ #
565
+ # [depending_gem, dependency, [list_of_gems_that_satisfy_dependency]]
566
+ #
562
567
  # return:: [Array] [[dependent_gem, dependency, [list_of_satisfiers]]]
563
568
  #
564
569
  def dependent_gems
@@ -1,6 +1,6 @@
1
1
  module Gem
2
2
 
3
- ##
3
+ ####################################################################
4
4
  # The Dependency class holds a Gem name and Version::Requirement
5
5
  #
6
6
  class Dependency
@@ -50,16 +50,22 @@ module Gem
50
50
  end
51
51
  end
52
52
 
53
- ##
53
+ ####################################################################
54
54
  # The Version class processes string versions into comparable values
55
55
  #
56
56
  class Version
57
57
  include Comparable
58
58
 
59
+ # The originating definition of Requirement is left nested in
60
+ # Version for compatibility. The full definition is given in
61
+ # Gem::Requirement.
62
+ class Requirement
63
+ end
64
+
59
65
  attr_accessor :version
60
-
66
+
61
67
  NUM_RE = /\s*(\d+(\.\d+)*)*\s*/
62
-
68
+
63
69
  ##
64
70
  # Checks if version string is valid format
65
71
  #
@@ -147,137 +153,148 @@ module Gem
147
153
  self.class.new(ints.join("."))
148
154
  end
149
155
 
156
+ end
157
+
158
+ # Class Requirement's original definition is nested in Version.
159
+ # Although an probably inappropriate place, current gems specs
160
+ # reference the nested class name explicitly. To remain compatible
161
+ # with old software loading gemspecs, we leave the original
162
+ # definition in Version, but define an alias Gem::Requirement for
163
+ # use everywhere else.
164
+ Requirement = ::Gem::Version::Requirement
165
+
166
+ ##################################################################
167
+ # Requirement version includes a prefaced comparator in addition
168
+ # to a version number.
169
+ #
170
+ # A Requirement object can actually contain multiple, er,
171
+ # requirements, as in (> 1.2, < 2.0).
172
+ #
173
+ class Requirement
174
+ include Comparable
175
+
176
+ OPS = {
177
+ "=" => lambda { |v, r| v == r },
178
+ "!=" => lambda { |v, r| v != r },
179
+ ">" => lambda { |v, r| v > r },
180
+ "<" => lambda { |v, r| v < r },
181
+ ">=" => lambda { |v, r| v >= r },
182
+ "<=" => lambda { |v, r| v <= r },
183
+ "~>" => lambda { |v, r| v >= r && v < r.bump }
184
+ }
185
+
186
+ OP_RE = Regexp.new(OPS.keys.collect{|k| Regexp.quote(k)}.join("|"))
187
+ REQ_RE = /\s*(#{OP_RE})\s*/
188
+
150
189
  ##
151
- # Requirement version includes a prefaced comparator in addition
152
- # to a version number.
190
+ # Factory method to create a Version::Requirement object. Input may be a
191
+ # Version, a String, or nil. Intended to simplify client code.
153
192
  #
154
- # A Requirement object can actually contain multiple, er, requirements, as
155
- # in (> 1.2, < 2.0).
193
+ # If the input is "weird", the default version requirement is returned.
156
194
  #
157
- class Requirement
158
- include Comparable
159
-
160
- OPS = {
161
- "=" => lambda { |v, r| v == r },
162
- "!=" => lambda { |v, r| v != r },
163
- ">" => lambda { |v, r| v > r },
164
- "<" => lambda { |v, r| v < r },
165
- ">=" => lambda { |v, r| v >= r },
166
- "<=" => lambda { |v, r| v <= r },
167
- "~>" => lambda { |v, r| v >= r && v < r.bump }
168
- }
169
-
170
- OP_RE = Regexp.new(OPS.keys.collect{|k| Regexp.quote(k)}.join("|"))
171
- REQ_RE = /\s*(#{OP_RE})\s*/
172
-
173
- ##
174
- # Factory method to create a Version::Requirement object. Input may be a
175
- # Version, a String, or nil. Intended to simplify client code.
176
- #
177
- # If the input is "weird", the default version requirement is returned.
178
- #
179
- def self.create(input)
180
- if input.kind_of?(Requirement)
181
- return input
182
- elsif input.kind_of?(Array)
183
- return self.new(input)
184
- elsif input.respond_to? :to_str
185
- return self.new([input.to_str])
186
- else
187
- return self.default
188
- end
189
- end
190
-
191
- ##
192
- # A default "version requirement" can surely _only_ be '> 0'.
193
- #
194
- def self.default
195
- self.new(['> 0.0.0'])
196
- end
197
-
198
- ##
199
- # Constructs a version requirement instance
200
- #
201
- # str:: [String Array] the version requirement string (e.g. ["> 1.23"])
202
- #
203
- def initialize(reqs)
204
- @requirements = reqs.collect do |rq|
205
- op, version_string = parse(rq)
206
- [op, Version.new(version_string)]
207
- end
208
- @version = nil # Avoid warnings.
209
- end
210
-
211
- ##
212
- # Overrides to check for comparator
213
- #
214
- # str:: [String] the version requirement string
215
- # return:: [Boolean] true if the string format is correct, otherwise false
216
- #
217
- def correct?(str)
218
- /^#{REQ_RE}#{NUM_RE}$/.match(str)
219
- end
220
-
221
- def to_s
222
- as_list.join(", ")
223
- end
224
-
225
- def as_list
226
- normalize
227
- @requirements.collect { |req|
228
- "#{req[0]} #{req[1]}"
229
- }
230
- end
231
-
232
- def normalize
233
- return if @version.nil?
234
- @requirements = [parse(@version)]
235
- @nums = nil
236
- @version = nil
237
- @op = nil
238
- end
239
-
240
- ##
241
- # Is the requirement satifised by +version+.
242
- #
243
- # version:: [Gem::Version] the version to compare against
244
- # return:: [Boolean] true if this requirement is satisfied by
245
- # the version, otherwise false
246
- #
247
- def satisfied_by?(version)
248
- normalize
249
- @requirements.all? { |op, rv| satisfy?(op, version, rv) }
250
- end
251
-
252
- private
253
-
254
- ##
255
- # Is "version op required_version" satisfied?
256
- #
257
- def satisfy?(op, version, required_version)
258
- OPS[op].call(version, required_version)
195
+ def self.create(input)
196
+ if input.kind_of?(Requirement)
197
+ return input
198
+ elsif input.kind_of?(Array)
199
+ return self.new(input)
200
+ elsif input.respond_to? :to_str
201
+ return self.new([input.to_str])
202
+ else
203
+ return self.default
259
204
  end
260
-
261
- ##
262
- # Parse the version requirement string. Return the operator and
263
- # version strings.
264
- #
265
- def parse(str)
266
- if md = /^\s*(#{OP_RE})\s*([0-9.]+)\s*$/.match(str)
267
- [md[1], md[2]]
268
- elsif md = /^\s*([0-9.]+)\s*$/.match(str)
269
- ["=", md[1]]
270
- elsif md = /^\s*(#{OP_RE})\s*$/.match(str)
271
- [md[1], "0"]
272
- else
273
- fail ArgumentError, "Illformed requirement [#{str}]"
274
- end
205
+ end
206
+
207
+ ##
208
+ # A default "version requirement" can surely _only_ be '> 0'.
209
+ #
210
+ def self.default
211
+ self.new(['> 0.0.0'])
212
+ end
213
+
214
+ ##
215
+ # Constructs a version requirement instance
216
+ #
217
+ # str:: [String Array] the version requirement string (e.g. ["> 1.23"])
218
+ #
219
+ def initialize(reqs)
220
+ @requirements = reqs.collect do |rq|
221
+ op, version_string = parse(rq)
222
+ [op, Version.new(version_string)]
275
223
  end
276
-
277
- def <=>(other)
278
- to_s <=> other.to_s
224
+ @version = nil # Avoid warnings.
225
+ end
226
+
227
+ ##
228
+ # Overrides to check for comparator
229
+ #
230
+ # str:: [String] the version requirement string
231
+ # return:: [Boolean] true if the string format is correct, otherwise false
232
+ #
233
+ # NOTE: Commented out because I don't think it is used.
234
+ # def correct?(str)
235
+ # /^#{REQ_RE}#{NUM_RE}$/.match(str)
236
+ # end
237
+
238
+ def to_s
239
+ as_list.join(", ")
240
+ end
241
+
242
+ def as_list
243
+ normalize
244
+ @requirements.collect { |req|
245
+ "#{req[0]} #{req[1]}"
246
+ }
247
+ end
248
+
249
+ def normalize
250
+ return if @version.nil?
251
+ @requirements = [parse(@version)]
252
+ @nums = nil
253
+ @version = nil
254
+ @op = nil
255
+ end
256
+
257
+ ##
258
+ # Is the requirement satifised by +version+.
259
+ #
260
+ # version:: [Gem::Version] the version to compare against
261
+ # return:: [Boolean] true if this requirement is satisfied by
262
+ # the version, otherwise false
263
+ #
264
+ def satisfied_by?(version)
265
+ normalize
266
+ @requirements.all? { |op, rv| satisfy?(op, version, rv) }
267
+ end
268
+
269
+ private
270
+
271
+ ##
272
+ # Is "version op required_version" satisfied?
273
+ #
274
+ def satisfy?(op, version, required_version)
275
+ OPS[op].call(version, required_version)
276
+ end
277
+
278
+ ##
279
+ # Parse the version requirement string. Return the operator and
280
+ # version strings.
281
+ #
282
+ def parse(str)
283
+ if md = /^\s*(#{OP_RE})\s*([0-9.]+)\s*$/.match(str)
284
+ [md[1], md[2]]
285
+ elsif md = /^\s*([0-9.]+)\s*$/.match(str)
286
+ ["=", md[1]]
287
+ elsif md = /^\s*(#{OP_RE})\s*$/.match(str)
288
+ [md[1], "0"]
289
+ else
290
+ fail ArgumentError, "Illformed requirement [#{str}]"
279
291
  end
280
-
281
292
  end
293
+
294
+ def <=>(other)
295
+ to_s <=> other.to_s
296
+ end
297
+
282
298
  end
299
+
283
300
  end
@@ -10,7 +10,7 @@ class TestArgPreprocessor < Test::Unit::TestCase
10
10
  def test_create
11
11
  @cfg = Gem::ConfigFile.new([])
12
12
  assert ! @cfg.backtrace
13
- assert_equal File.join(ENV['HOME'], '.gemrc'), @cfg.config_file_name
13
+ assert_equal File.join(Gem.user_home, '.gemrc'), @cfg.config_file_name
14
14
  end
15
15
 
16
16
  def test_backtrace
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'rubygems/dependency_list'
5
+ require 'rubygems/specification'
6
+
7
+ class TestDependencyList < Test::Unit::TestCase
8
+ def setup
9
+ @deplist = Gem::DependencyList.new
10
+ end
11
+
12
+ def test_create
13
+ assert @deplist.ok?, "all dependencies should be satisfied"
14
+ end
15
+
16
+ def test_one_unsatisfied_gem
17
+ @deplist.add(bspec)
18
+ assert ! @deplist.ok?
19
+ end
20
+
21
+ def test_one_satisfied_gem
22
+ @deplist.add(create_spec("a", "1.1"))
23
+ assert @deplist.ok?
24
+ end
25
+
26
+ def test_two_gems_with_dependency
27
+ @deplist.add(create_spec("a", "1.1"))
28
+ @deplist.add(bspec)
29
+ assert @deplist.ok?
30
+ end
31
+
32
+ def test_removing_required_gem
33
+ @deplist.add(create_spec("a", "1.1"))
34
+ @deplist.add(bspec)
35
+ a = @deplist.remove_by_name("a-1.1")
36
+ assert ! @deplist.ok?
37
+ end
38
+
39
+ def test_removing_redundent_gem
40
+ @deplist.add(create_spec("a", "1.1"))
41
+ @deplist.add(create_spec("a", "1.3"))
42
+ @deplist.add(bspec)
43
+ a = @deplist.remove_by_name("a-1.1")
44
+ assert @deplist.ok?
45
+ end
46
+
47
+ def test_finding_gems
48
+ @deplist.add(create_spec("a", "1.1"))
49
+ @deplist.add(bspec)
50
+ assert_equal "a-1.1", @deplist.find_name("a-1.1").full_name
51
+ assert_equal "b-1.2", @deplist.find_name("b-1.2").full_name
52
+ assert_nil @deplist.find_name("c-1.2")
53
+ end
54
+
55
+ def test_ok_to_remove
56
+ @deplist.add(create_spec("a", "1.1"))
57
+ assert @deplist.ok_to_remove?("a-1.1")
58
+ end
59
+
60
+ def test_not_ok_to_remove
61
+ @deplist.add(create_spec("a", "1.1"))
62
+ @deplist.add(bspec)
63
+ assert ! @deplist.ok_to_remove?("a-1.1")
64
+ end
65
+
66
+ def test_ok_to_remove_with_extras
67
+ @deplist.add(create_spec("a", "1.1"))
68
+ @deplist.add(create_spec("a", "1.2"))
69
+ @deplist.add(bspec)
70
+ assert @deplist.ok_to_remove?("a-1.1")
71
+ assert @deplist.ok_to_remove?("a-1.2")
72
+ assert @deplist.ok_to_remove?("b-1.2")
73
+ end
74
+
75
+ def test_not_ok_to_remove_after_sibling_removed
76
+ @deplist.add(create_spec("a", "1.1"))
77
+ @deplist.add(create_spec("a", "1.2"))
78
+ @deplist.add(bspec)
79
+ assert @deplist.ok_to_remove?("a-1.1")
80
+ assert @deplist.ok_to_remove?("a-1.2")
81
+ @deplist.remove_by_name("a-1.1")
82
+ assert ! @deplist.ok_to_remove?("a-1.2")
83
+ end
84
+
85
+ def test_sorting
86
+ @deplist.add(create_spec("a", "1.1"))
87
+ @deplist.add(bspec)
88
+ @deplist.add(create_spec("a", "1.3"))
89
+ order = @deplist.dependency_order
90
+ assert_equal "b-1.2", order.first.full_name
91
+ end
92
+
93
+ def test_sorting_four_with_out_ambiguities
94
+ @deplist.add(Gem::Specification.new do |s|
95
+ s.name = "a"
96
+ s.version = '1.1'
97
+ end)
98
+ @deplist.add(Gem::Specification.new do |s|
99
+ s.name = "b"
100
+ s.version = '1.1'
101
+ s.add_dependency("a", ">= 1.1")
102
+ end)
103
+ @deplist.add(Gem::Specification.new do |s|
104
+ s.name = "c"
105
+ s.version = '1.1'
106
+ s.add_dependency("b", ">= 1.1")
107
+ end)
108
+ @deplist.add(Gem::Specification.new do |s|
109
+ s.name = "d"
110
+ s.version = '1.1'
111
+ s.add_dependency("c", ">= 1.1")
112
+ end)
113
+ order = @deplist.dependency_order
114
+ assert_equal ['d', 'c', 'b', 'a'], order.collect { |s| s.name }
115
+ end
116
+
117
+ def test_sorting_with_circular_dependency
118
+ @deplist.add(Gem::Specification.new do |s|
119
+ s.name = "a"
120
+ s.version = '1.1'
121
+ s.add_dependency("c", ">= 1.1")
122
+ end)
123
+ @deplist.add(Gem::Specification.new do |s|
124
+ s.name = "b"
125
+ s.version = '1.1'
126
+ s.add_dependency("a", ">= 1.1")
127
+ end)
128
+ @deplist.add(Gem::Specification.new do |s|
129
+ s.name = "c"
130
+ s.version = '1.1'
131
+ s.add_dependency("b", ">= 1.1")
132
+ end)
133
+ order = @deplist.dependency_order
134
+ end
135
+
136
+ def test_from_source_index
137
+ hash = {
138
+ 'a-1.1' => create_spec("a", "1.1"),
139
+ 'b-1.2' => bspec,
140
+ }
141
+ si = Gem::SourceIndex.new(hash)
142
+ deps = Gem::DependencyList.from_source_index(si)
143
+ assert_equal ['b-1.2', 'a-1.1'],
144
+ deps.dependency_order.collect { |s| s.full_name }
145
+ end
146
+
147
+ # ------------------------------------------------------------------
148
+
149
+ def bspec
150
+ Gem::Specification.new do |s|
151
+ s.name = "b"
152
+ s.version = "1.2"
153
+ s.add_dependency("a", ">= 1.1")
154
+ end
155
+ end
156
+
157
+ def create_spec(name, version)
158
+ Gem::Specification.new do |s|
159
+ s.name = name
160
+ s.version = version
161
+ end
162
+ end
163
+ end