rubygems-update 2.0.17 → 2.1.0.rc.1

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 (154) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -0
  4. data/.autotest +1 -1
  5. data/History.txt +82 -153
  6. data/Manifest.txt +35 -9
  7. data/Rakefile +35 -36
  8. data/lib/rubygems.rb +106 -18
  9. data/lib/rubygems/available_set.rb +68 -0
  10. data/lib/rubygems/basic_specification.rb +139 -0
  11. data/lib/rubygems/command_manager.rb +37 -40
  12. data/lib/rubygems/commands/cert_command.rb +78 -29
  13. data/lib/rubygems/commands/cleanup_command.rb +2 -2
  14. data/lib/rubygems/commands/contents_command.rb +101 -58
  15. data/lib/rubygems/commands/dependency_command.rb +94 -53
  16. data/lib/rubygems/commands/environment_command.rb +70 -53
  17. data/lib/rubygems/commands/fetch_command.rb +1 -2
  18. data/lib/rubygems/commands/help_command.rb +85 -55
  19. data/lib/rubygems/commands/install_command.rb +84 -42
  20. data/lib/rubygems/commands/outdated_command.rb +2 -12
  21. data/lib/rubygems/commands/owner_command.rb +6 -0
  22. data/lib/rubygems/commands/pristine_command.rb +26 -16
  23. data/lib/rubygems/commands/sources_command.rb +85 -70
  24. data/lib/rubygems/commands/uninstall_command.rb +32 -2
  25. data/lib/rubygems/commands/update_command.rb +111 -75
  26. data/lib/rubygems/config_file.rb +15 -3
  27. data/lib/rubygems/core_ext/kernel_require.rb +9 -31
  28. data/lib/rubygems/defaults.rb +8 -0
  29. data/lib/rubygems/dependency.rb +4 -2
  30. data/lib/rubygems/dependency_installer.rb +180 -170
  31. data/lib/rubygems/dependency_resolver.rb +191 -526
  32. data/lib/rubygems/dependency_resolver/activation_request.rb +109 -0
  33. data/lib/rubygems/dependency_resolver/api_set.rb +65 -0
  34. data/lib/rubygems/dependency_resolver/api_specification.rb +36 -0
  35. data/lib/rubygems/dependency_resolver/composed_set.rb +18 -0
  36. data/lib/rubygems/dependency_resolver/current_set.rb +16 -0
  37. data/lib/rubygems/dependency_resolver/dependency_conflict.rb +85 -0
  38. data/lib/rubygems/dependency_resolver/dependency_request.rb +51 -0
  39. data/lib/rubygems/dependency_resolver/index_set.rb +59 -0
  40. data/lib/rubygems/dependency_resolver/index_specification.rb +53 -0
  41. data/lib/rubygems/dependency_resolver/installed_specification.rb +38 -0
  42. data/lib/rubygems/dependency_resolver/installer_set.rb +130 -0
  43. data/lib/rubygems/exceptions.rb +88 -1
  44. data/lib/rubygems/ext/builder.rb +1 -1
  45. data/lib/rubygems/gem_runner.rb +17 -9
  46. data/lib/rubygems/gemcutter_utilities.rb +72 -42
  47. data/lib/rubygems/install_default_message.rb +12 -0
  48. data/lib/rubygems/install_update_options.rb +3 -0
  49. data/lib/rubygems/installer.rb +55 -30
  50. data/lib/rubygems/name_tuple.rb +18 -7
  51. data/lib/rubygems/package.rb +50 -25
  52. data/lib/rubygems/package/tar_test_case.rb +9 -9
  53. data/lib/rubygems/package/tar_writer.rb +35 -12
  54. data/lib/rubygems/package_task.rb +2 -5
  55. data/lib/rubygems/path_support.rb +10 -0
  56. data/lib/rubygems/platform.rb +9 -3
  57. data/lib/rubygems/psych_additions.rb +1 -1
  58. data/lib/rubygems/remote_fetcher.rb +9 -276
  59. data/lib/rubygems/request.rb +267 -0
  60. data/lib/rubygems/request_set.rb +123 -125
  61. data/lib/rubygems/request_set/gem_dependency_api.rb +39 -0
  62. data/lib/rubygems/security.rb +32 -23
  63. data/lib/rubygems/security/policy.rb +35 -9
  64. data/lib/rubygems/security/signer.rb +2 -2
  65. data/lib/rubygems/server.rb +8 -16
  66. data/lib/rubygems/source.rb +25 -14
  67. data/lib/rubygems/source/installed.rb +28 -0
  68. data/lib/rubygems/source/local.rb +122 -0
  69. data/lib/rubygems/source/specific_file.rb +28 -0
  70. data/lib/rubygems/source_local.rb +2 -89
  71. data/lib/rubygems/source_specific_file.rb +2 -26
  72. data/lib/rubygems/spec_fetcher.rb +11 -11
  73. data/lib/rubygems/specification.rb +186 -198
  74. data/lib/rubygems/ssl_certs/AddTrustExternalCARoot.pem +88 -30
  75. data/lib/rubygems/ssl_certs/Entrust_net-Secure-Server-Certification-Authority.pem +90 -0
  76. data/lib/rubygems/ssl_certs/{GeoTrustGlobalCA.pem → GeoTrust_Global_CA.pem} +20 -20
  77. data/lib/rubygems/ssl_certs/VerisignClass3PublicPrimaryCertificationAuthority-G2.pem +57 -0
  78. data/lib/rubygems/stub_specification.rb +119 -0
  79. data/lib/rubygems/test_case.rb +117 -49
  80. data/lib/rubygems/uninstaller.rb +14 -9
  81. data/lib/rubygems/uri_formatter.rb +39 -0
  82. data/lib/rubygems/util/list.rb +44 -0
  83. data/lib/rubygems/version.rb +15 -5
  84. data/lib/rubygems/version_option.rb +8 -2
  85. data/test/rubygems/ca_cert.pem +23 -0
  86. data/test/rubygems/client.pem +49 -0
  87. data/test/rubygems/encrypted_private_key.pem +30 -0
  88. data/test/rubygems/invalid_client.pem +49 -0
  89. data/test/rubygems/specifications/bar-0.0.2.gemspec +9 -0
  90. data/test/rubygems/specifications/foo-0.0.1.gemspec +0 -0
  91. data/test/rubygems/test_gem.rb +76 -454
  92. data/test/rubygems/test_gem_command_manager.rb +23 -21
  93. data/test/rubygems/test_gem_commands_cert_command.rb +154 -14
  94. data/test/rubygems/test_gem_commands_cleanup_command.rb +15 -0
  95. data/test/rubygems/test_gem_commands_contents_command.rb +32 -4
  96. data/test/rubygems/test_gem_commands_environment_command.rb +9 -1
  97. data/test/rubygems/test_gem_commands_fetch_command.rb +2 -28
  98. data/test/rubygems/test_gem_commands_help_command.rb +6 -3
  99. data/test/rubygems/test_gem_commands_install_command.rb +2 -65
  100. data/test/rubygems/test_gem_commands_owner_command.rb +49 -0
  101. data/test/rubygems/test_gem_commands_pristine_command.rb +30 -0
  102. data/test/rubygems/test_gem_commands_sources_command.rb +1 -1
  103. data/test/rubygems/test_gem_commands_uninstall_command.rb +33 -0
  104. data/test/rubygems/test_gem_commands_update_command.rb +2 -1
  105. data/test/rubygems/test_gem_config_file.rb +12 -0
  106. data/test/rubygems/test_gem_dependency_installer.rb +58 -65
  107. data/test/rubygems/test_gem_dependency_resolver.rb +6 -3
  108. data/test/rubygems/test_gem_dependency_resolver_dependency_conflict.rb +36 -0
  109. data/test/rubygems/test_gem_ext_builder.rb +2 -4
  110. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +7 -2
  111. data/test/rubygems/test_gem_gem_runner.rb +17 -13
  112. data/test/rubygems/test_gem_gemcutter_utilities.rb +6 -19
  113. data/test/rubygems/test_gem_impossible_dependencies_error.rb +41 -0
  114. data/test/rubygems/test_gem_install_update_options.rb +4 -1
  115. data/test/rubygems/test_gem_installer.rb +31 -2
  116. data/test/rubygems/test_gem_name_tuple.rb +22 -0
  117. data/test/rubygems/test_gem_package.rb +122 -11
  118. data/test/rubygems/test_gem_package_old.rb +8 -0
  119. data/test/rubygems/test_gem_package_tar_reader.rb +9 -8
  120. data/test/rubygems/test_gem_package_tar_reader_entry.rb +1 -1
  121. data/test/rubygems/test_gem_package_tar_writer.rb +78 -56
  122. data/test/rubygems/test_gem_package_task.rb +2 -23
  123. data/test/rubygems/test_gem_path_support.rb +17 -0
  124. data/test/rubygems/test_gem_platform.rb +18 -0
  125. data/test/rubygems/test_gem_remote_fetcher.rb +106 -385
  126. data/test/rubygems/test_gem_request.rb +239 -0
  127. data/test/rubygems/test_gem_requirement.rb +9 -11
  128. data/test/rubygems/test_gem_security.rb +58 -2
  129. data/test/rubygems/test_gem_security_policy.rb +42 -1
  130. data/test/rubygems/test_gem_security_signer.rb +13 -1
  131. data/test/rubygems/test_gem_security_trust_dir.rb +5 -1
  132. data/test/rubygems/test_gem_server.rb +1 -105
  133. data/test/rubygems/test_gem_source.rb +4 -14
  134. data/test/rubygems/test_gem_source_local.rb +4 -4
  135. data/test/rubygems/test_gem_source_specific_file.rb +1 -1
  136. data/test/rubygems/test_gem_spec_fetcher.rb +0 -12
  137. data/test/rubygems/test_gem_specification.rb +452 -28
  138. data/test/rubygems/test_gem_stub_specification.rb +30 -0
  139. data/test/rubygems/test_gem_uninstaller.rb +14 -0
  140. data/test/rubygems/test_gem_uri_formatter.rb +20 -0
  141. data/test/rubygems/test_gem_version.rb +23 -13
  142. data/test/rubygems/test_gem_version_option.rb +63 -1
  143. data/test/rubygems/test_require.rb +0 -12
  144. data/util/create_encrypted_key.rb +16 -0
  145. metadata +161 -23
  146. metadata.gz.sig +0 -0
  147. data/CVE-2013-4287.txt +0 -36
  148. data/CVE-2013-4363.txt +0 -45
  149. data/lib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem +0 -25
  150. data/lib/rubygems/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
  151. data/lib/rubygems/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +0 -23
  152. data/lib/rubygems/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
  153. data/test/rubygems/test_bundled_ca.rb +0 -59
  154. data/util/update_bundled_ca_certificates.rb +0 -103
@@ -38,13 +38,7 @@ class Gem::SpecFetcher
38
38
  end
39
39
 
40
40
  def initialize
41
- @dir = File.join Gem.user_home, '.gem', 'specs'
42
- @update_cache =
43
- begin
44
- File.stat(Gem.user_home).uid == Process.uid
45
- rescue Errno::EACCES, Errno::ENOENT
46
- false
47
- end
41
+ @update_cache = File.stat(Gem.user_home).uid == Process.uid
48
42
 
49
43
  @specs = {}
50
44
  @latest_specs = {}
@@ -80,6 +74,12 @@ class Gem::SpecFetcher
80
74
 
81
75
  list, errors = available_specs(type)
82
76
  list.each do |source, specs|
77
+ if dependency.name.is_a?(String) && specs.respond_to?(:bsearch)
78
+ start_index = (0 ... specs.length).bsearch{ |i| specs[i].name >= dependency.name }
79
+ end_index = (0 ... specs.length).bsearch{ |i| specs[i].name > dependency.name }
80
+ specs = specs[start_index ... end_index] if start_index && end_index
81
+ end
82
+
83
83
  found[source] = specs.select do |tup|
84
84
  if dependency.match?(tup)
85
85
  if matching_platform and !Gem::Platform.match(tup.platform)
@@ -220,15 +220,15 @@ class Gem::SpecFetcher
220
220
  def tuples_for(source, type, gracefully_ignore=false)
221
221
  cache = @caches[type]
222
222
 
223
- if gracefully_ignore
223
+ tuples =
224
224
  begin
225
225
  cache[source.uri] ||= source.load_specs(type)
226
226
  rescue Gem::RemoteFetcher::FetchError
227
+ raise unless gracefully_ignore
227
228
  []
228
229
  end
229
- else
230
- cache[source.uri] ||= source.load_specs(type)
231
- end
230
+
231
+ tuples.sort_by { |tup| tup.name }
232
232
  end
233
233
 
234
234
  end
@@ -5,10 +5,13 @@
5
5
  # See LICENSE.txt for permissions.
6
6
  #++
7
7
 
8
+
8
9
  require 'rubygems/version'
9
10
  require 'rubygems/requirement'
10
11
  require 'rubygems/platform'
11
12
  require 'rubygems/deprecate'
13
+ require 'rubygems/basic_specification'
14
+ require 'rubygems/stub_specification'
12
15
 
13
16
  # :stopdoc:
14
17
  # date.rb can't be loaded for `make install` due to miniruby
@@ -45,7 +48,7 @@ class Date; end
45
48
  #
46
49
  # s.metadata = { "bugtracker" => "http://somewhere.com/blah" }
47
50
 
48
- class Gem::Specification
51
+ class Gem::Specification < Gem::BasicSpecification
49
52
 
50
53
  # REFACTOR: Consider breaking out this version stuff into a separate
51
54
  # module. There's enough special stuff around it that it may justify
@@ -107,6 +110,10 @@ class Gem::Specification
107
110
  today = Time.now.utc
108
111
  TODAY = Time.utc(today.year, today.month, today.day)
109
112
 
113
+ LOAD_CACHE = {}
114
+
115
+ private_constant :LOAD_CACHE if defined? private_constant
116
+
110
117
  # :startdoc:
111
118
 
112
119
  ##
@@ -156,6 +163,17 @@ class Gem::Specification
156
163
  :version => nil,
157
164
  }
158
165
 
166
+ Dupable = { }
167
+
168
+ @@default_value.each do |k,v|
169
+ case v
170
+ when Time, Numeric, Symbol, true, false, nil
171
+ Dupable[k] = false
172
+ else
173
+ Dupable[k] = true
174
+ end
175
+ end
176
+
159
177
  @@attributes = @@default_value.keys.sort_by { |s| s.to_s }
160
178
  @@array_attributes = @@default_value.reject { |k,v| v != [] }.keys
161
179
  @@nil_attributes, @@non_nil_attributes = @@default_value.keys.partition { |k|
@@ -188,19 +206,15 @@ class Gem::Specification
188
206
  attr_reader :version
189
207
 
190
208
  ##
191
- # Paths in the gem to add to <code>$LOAD_PATH</code> when this gem is
192
- # activated.
193
- #
194
- # If you have an extension you do not need to add <code>"ext"</code> to the
195
- # require path, the extension build process will copy the extension files
196
- # into "lib" for you.
197
- #
198
- # The default value is <code>"lib"</code>
209
+ # Paths in the gem to add to <tt>$LOAD_PATH</tt> when this gem is activated.
199
210
  #
200
211
  # Usage:
201
212
  #
202
213
  # # If all library files are in the root directory...
203
214
  # spec.require_path = '.'
215
+ #
216
+ # # If you have 'lib' and 'ext' directories...
217
+ # spec.require_paths << 'ext'
204
218
 
205
219
  attr_accessor :require_paths
206
220
 
@@ -214,7 +228,7 @@ class Gem::Specification
214
228
  ##
215
229
  # A short summary of this gem's description. Displayed in `gem list -d`.
216
230
  #
217
- # The #description should be more detailed than the summary.
231
+ # The description should be more detailed than the summary.
218
232
  #
219
233
  # Usage:
220
234
  #
@@ -227,23 +241,21 @@ class Gem::Specification
227
241
  #
228
242
  # This is usually Gem::Platform::RUBY or Gem::Platform::CURRENT.
229
243
  #
230
- # Most gems contain pure Ruby code; they should simply leave the default
231
- # value in place. Some gems contain C (or other) code to be compiled into a
232
- # Ruby "extension". The should leave the default value in place unless
233
- # their code will only compile on a certain type of system. Some gems
234
- # consist of pre-compiled code ("binary gems"). It's especially important
235
- # that they set the platform attribute appropriately. A shortcut is to set
236
- # the platform to Gem::Platform::CURRENT, which will cause the gem builder
237
- # to set the platform to the appropriate value for the system on which the
238
- # build is being performed.
244
+ # Most gems contain pure Ruby code; they should simply leave the default value
245
+ # in place. Some gems contain C (or other) code to be compiled into a Ruby
246
+ # “extension”. The should leave the default value in place unless their code
247
+ # will only compile on a certain type of system. Some gems consist of
248
+ # pre-compiled code (binary gems). Its especially important that they set
249
+ # the platform attribute appropriately. A shortcut is to set the platform to
250
+ # Gem::Platform::CURRENT, which will cause the gem builder to set the platform
251
+ # to the appropriate value for the system on which the build is being performed.
239
252
  #
240
- # If this attribute is set to a non-default value, it will be included in
241
- # the filename of the gem when it is built such as:
242
- # nokogiri-1.6.0-x86-mingw32.gem
253
+ # If this attribute is set to a non-default value, it will be included in the
254
+ # filename of the gem when it is built, e.g. fxruby-1.2.0-win32.gem.
243
255
  #
244
256
  # Usage:
245
257
  #
246
- # spec.platform = Gem::Platform.local
258
+ # spec.platform = Gem::Platform::Win32
247
259
 
248
260
  def platform= platform
249
261
  if @original_platform.nil? or
@@ -345,7 +357,7 @@ class Gem::Specification
345
357
  attr_reader :description
346
358
 
347
359
  ##
348
- # A contact email address (or addresses) for this gem
360
+ # A contact email for this gem
349
361
  #
350
362
  # Usage:
351
363
  #
@@ -440,7 +452,7 @@ class Gem::Specification
440
452
  #
441
453
  # For example, the rake gem has rake as an executable. You don’t specify the
442
454
  # full path (as in bin/rake); all application-style files are expected to be
443
- # found in bindir. These files must be executable ruby files. Files that
455
+ # found in bindir. These files must be executable Ruby files. Files that
444
456
  # use bash or other interpreters will not work.
445
457
  #
446
458
  # Usage:
@@ -461,8 +473,6 @@ class Gem::Specification
461
473
  # Usage:
462
474
  #
463
475
  # spec.extensions << 'ext/rmagic/extconf.rb'
464
- #
465
- # See Gem::Ext::Builder for information about writing extensions for gems.
466
476
 
467
477
  def extensions
468
478
  @extensions ||= []
@@ -492,8 +502,6 @@ class Gem::Specification
492
502
  # This should just be the name of your license. The full
493
503
  # text of the license should be inside of the gem when you build it.
494
504
  #
495
- # You can set multiple licenses with #licenses=
496
- #
497
505
  # Usage:
498
506
  # spec.license = 'MIT'
499
507
 
@@ -530,20 +538,15 @@ class Gem::Specification
530
538
  end
531
539
 
532
540
  ##
533
- # The version of Ruby required by this gem. The ruby version can be
534
- # specified to the patch-level:
535
- #
536
- # $ ruby -v -e 'p Gem.ruby_version'
537
- # ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]
538
- # #<Gem::Version "2.0.0.247">
541
+ # The version of Ruby required by this gem
539
542
  #
540
543
  # Usage:
541
544
  #
542
- # # This gem will work with 1.8.6 or greater...
545
+ # # If it will work with 1.8.6 or greater...
543
546
  # spec.required_ruby_version = '>= 1.8.6'
544
547
  #
545
- # # Only with ruby 2.0.x
546
- # spec.required_ruby_version = '~> 2.0'
548
+ # # Hopefully by now:
549
+ # spec.required_ruby_version = '>= 1.9.2'
547
550
 
548
551
  def required_ruby_version= req
549
552
  @required_ruby_version = Gem::Requirement.create req
@@ -551,7 +554,7 @@ class Gem::Specification
551
554
 
552
555
  ##
553
556
  # Lists the external (to RubyGems) requirements that must be met for this gem
554
- # to work. It's simply information for the user.
557
+ # to work. Its simply information for the user.
555
558
  #
556
559
  # Usage:
557
560
  #
@@ -563,7 +566,7 @@ class Gem::Specification
563
566
  end
564
567
 
565
568
  ##
566
- # A collection of unit test files. They will be loaded as unit tests when
569
+ # A collection of unit test files. They will be loaded as unit tests when
567
570
  # the user requests a gem to be unit tested.
568
571
  #
569
572
  # Usage:
@@ -589,7 +592,7 @@ class Gem::Specification
589
592
  #
590
593
  # Deprecated: It is neither supported nor functional.
591
594
 
592
- attr_accessor :autorequire # :nodoc:
595
+ attr_accessor :autorequire
593
596
 
594
597
  ##
595
598
  # Sets the default executable for this gem.
@@ -598,18 +601,13 @@ class Gem::Specification
598
601
 
599
602
  attr_writer :default_executable
600
603
 
601
- ##
602
- # Path this gemspec was loaded from. This attribute is not persisted.
603
-
604
- attr_reader :loaded_from
605
-
606
604
  ##
607
605
  # Allows deinstallation of gems with legacy platforms.
608
606
 
609
607
  attr_writer :original_platform # :nodoc:
610
608
 
611
609
  ##
612
- # The version of ruby required by this gem
610
+ # The version of Ruby required by this gem
613
611
 
614
612
  attr_reader :required_ruby_version
615
613
 
@@ -617,12 +615,9 @@ class Gem::Specification
617
615
  # The RubyGems version required by this gem
618
616
 
619
617
  attr_reader :required_rubygems_version
620
-
621
618
  ##
622
619
  # The rubyforge project this gem lives under. i.e. RubyGems'
623
620
  # rubyforge_project is "rubygems".
624
- #
625
- # This option is deprecated.
626
621
 
627
622
  attr_accessor :rubyforge_project
628
623
 
@@ -633,58 +628,68 @@ class Gem::Specification
633
628
 
634
629
  attr_accessor :specification_version
635
630
 
636
- class << self
637
- def default_specifications_dir
638
- File.join(Gem.default_dir, "specifications", "default")
631
+ def self._all # :nodoc:
632
+ unless defined?(@@all) && @@all then
633
+ @@all = stubs.map(&:to_spec)
634
+
635
+ # After a reset, make sure already loaded specs
636
+ # are still marked as activated.
637
+ specs = {}
638
+ Gem.loaded_specs.each_value{|s| specs[s] = true}
639
+ @@all.each{|s| s.activated = true if specs[s]}
640
+
641
+ _resort!(@@all)
639
642
  end
643
+ @@all
644
+ end
640
645
 
641
- def each_spec(search_dirs) # :nodoc:
642
- search_dirs.each { |dir|
643
- Dir[File.join(dir, "*.gemspec")].each { |path|
644
- spec = Gem::Specification.load path.untaint
645
- # #load returns nil if the spec is bad, so we just ignore
646
- # it at this stage
647
- yield(spec) if spec
648
- }
649
- }
646
+ def self._clear_load_cache # :nodoc:
647
+ LOAD_CACHE.clear
648
+ end
649
+
650
+ # :nodoc:
651
+ def self.each_gemspec(dirs)
652
+ dirs.each do |dir|
653
+ Dir[File.join(dir, "*.gemspec")].each do |path|
654
+ yield path.untaint
655
+ end
650
656
  end
657
+ end
651
658
 
652
- def each_default(&block) # :nodoc:
653
- each_spec([default_specifications_dir],
654
- &block)
659
+ # :nodoc:
660
+ def self.each_stub(dirs)
661
+ each_gemspec(dirs) do |path|
662
+ stub = Gem::StubSpecification.new(path)
663
+ yield stub if stub.valid?
655
664
  end
665
+ end
656
666
 
657
- def each_normal(&block) # :nodoc:
658
- each_spec(dirs, &block)
667
+ # :nodoc:
668
+ def self.each_spec(dirs)
669
+ each_gemspec(dirs) do |path|
670
+ spec = self.load path
671
+ yield spec if spec
659
672
  end
660
673
  end
661
674
 
662
- def self._all # :nodoc:
663
- unless defined?(@@all) && @@all then
675
+ ##
676
+ # Returns a Gem::StubSpecification for every installed gem
664
677
 
665
- specs = {}
666
- each_default do |spec|
667
- specs[spec.full_name] ||= spec
668
- end
669
- each_normal do |spec|
670
- specs[spec.full_name] ||= spec
678
+ def self.stubs
679
+ @@stubs ||= begin
680
+ stubs = {}
681
+ each_stub([default_specifications_dir] + dirs) do |stub|
682
+ stubs[stub.full_name] ||= stub
671
683
  end
672
684
 
673
- @@all = specs.values
674
-
675
- # After a reset, make sure already loaded specs
676
- # are still marked as activated.
677
- specs = {}
678
- Gem.loaded_specs.each_value{|s| specs[s] = true}
679
- @@all.each{|s| s.activated = true if specs[s]}
680
-
681
- _resort!
685
+ stubs = stubs.values
686
+ _resort!(stubs)
687
+ stubs
682
688
  end
683
- @@all
684
689
  end
685
690
 
686
- def self._resort! # :nodoc:
687
- @@all.sort! { |a, b|
691
+ def self._resort!(specs) # :nodoc:
692
+ specs.sort! { |a, b|
688
693
  names = a.name <=> b.name
689
694
  next names if names.nonzero?
690
695
  b.version <=> a.version
@@ -695,7 +700,9 @@ class Gem::Specification
695
700
  # Loads the default specifications. It should be called only once.
696
701
 
697
702
  def self.load_defaults
698
- each_default do |spec|
703
+ each_spec([default_specifications_dir]) do |spec|
704
+ # #load returns nil if the spec is bad, so we just ignore
705
+ # it at this stage
699
706
  Gem.register_default_spec(spec)
700
707
  end
701
708
  end
@@ -718,7 +725,9 @@ class Gem::Specification
718
725
  return if _all.include? spec
719
726
 
720
727
  _all << spec
721
- _resort!
728
+ stubs << spec
729
+ _resort!(_all)
730
+ _resort!(stubs)
722
731
  end
723
732
 
724
733
  ##
@@ -861,9 +870,10 @@ class Gem::Specification
861
870
  # amongst the specs that are not activated.
862
871
 
863
872
  def self.find_inactive_by_path path
864
- self.find { |spec|
865
- spec.contains_requirable_file? path unless spec.activated?
873
+ stub = stubs.find { |s|
874
+ s.contains_requirable_file? path unless s.activated?
866
875
  }
876
+ stub && stub.to_spec
867
877
  end
868
878
 
869
879
  ##
@@ -944,7 +954,7 @@ class Gem::Specification
944
954
  result.map(&:last).map(&:values).flatten.reject { |spec|
945
955
  minimum = native[spec.name]
946
956
  minimum && spec.version < minimum
947
- }
957
+ }.sort_by{ |tup| tup.name }
948
958
  end
949
959
 
950
960
  ##
@@ -955,6 +965,9 @@ class Gem::Specification
955
965
  file = file.dup.untaint
956
966
  return unless File.file?(file)
957
967
 
968
+ spec = LOAD_CACHE[file]
969
+ return spec if spec
970
+
958
971
  code = if defined? Encoding
959
972
  File.read file, :mode => 'r:UTF-8:-'
960
973
  else
@@ -968,6 +981,7 @@ class Gem::Specification
968
981
 
969
982
  if Gem::Specification === spec
970
983
  spec.loaded_from = file.to_s
984
+ LOAD_CACHE[file] = spec
971
985
  return spec
972
986
  end
973
987
 
@@ -1002,32 +1016,54 @@ class Gem::Specification
1002
1016
  end
1003
1017
 
1004
1018
  ##
1005
- # Return a list of all outdated specifications. This method is HEAVY
1019
+ # Return a list of all outdated local gem names. This method is HEAVY
1006
1020
  # as it must go fetch specifications from the server.
1021
+ #
1022
+ # Use outdated_and_latest_version if you wish to retrieve the latest remote
1023
+ # version as well.
1007
1024
 
1008
1025
  def self.outdated
1009
- outdateds = []
1026
+ outdated_and_latest_version.map { |local, _| local.name }
1027
+ end
1028
+
1029
+ ##
1030
+ # Enumerates the outdated local gems yielding the local specification and
1031
+ # the latest remote version.
1032
+ #
1033
+ # This method may take some time to return as it must check each local gem
1034
+ # against the server's index.
1035
+
1036
+ def self.outdated_and_latest_version
1037
+ return enum_for __method__ unless block_given?
1010
1038
 
1011
1039
  # TODO: maybe we should switch to rubygems' version service?
1012
1040
  fetcher = Gem::SpecFetcher.fetcher
1013
1041
 
1014
- latest_specs(true).each do |local|
1015
- dependency = Gem::Dependency.new local.name, ">= #{local.version}"
1016
- remotes, _ = fetcher.search_for_dependency dependency
1017
- remotes = remotes.map { |n, _| n.version }
1018
- latest = remotes.sort.last
1042
+ latest_specs(true).each do |local_spec|
1043
+ dependency =
1044
+ Gem::Dependency.new local_spec.name, ">= #{local_spec.version}"
1045
+
1046
+ remotes, = fetcher.search_for_dependency dependency
1047
+ remotes = remotes.map { |n, _| n.version }
1048
+
1049
+ latest_remote = remotes.sort.last
1019
1050
 
1020
- outdateds << local.name if latest and local.version < latest
1051
+ yield [local_spec, latest_remote] if
1052
+ latest_remote and local_spec.version < latest_remote
1021
1053
  end
1022
1054
 
1023
- outdateds
1055
+ nil
1024
1056
  end
1025
1057
 
1026
1058
  ##
1027
1059
  # Removes +spec+ from the known specs.
1028
1060
 
1029
1061
  def self.remove_spec spec
1062
+ # TODO: beat on the tests
1063
+ raise "wtf: #{spec.full_name} not in #{all_names.inspect}" unless
1064
+ _all.include? spec
1030
1065
  _all.delete spec
1066
+ stubs.delete_if { |s| s.full_name == spec.full_name }
1031
1067
  end
1032
1068
 
1033
1069
  ##
@@ -1052,6 +1088,8 @@ class Gem::Specification
1052
1088
  @@dirs = nil
1053
1089
  Gem.pre_reset_hooks.each { |hook| hook.call }
1054
1090
  @@all = nil
1091
+ @@stubs = nil
1092
+ _clear_load_cache
1055
1093
  unresolved = unresolved_deps
1056
1094
  unless unresolved.empty? then
1057
1095
  w = "W" + "ARN"
@@ -1282,7 +1320,7 @@ class Gem::Specification
1282
1320
  end
1283
1321
 
1284
1322
  ##
1285
- # Singular reader for #authors. Returns the first author in the list
1323
+ # Singular reader for #authors
1286
1324
 
1287
1325
  def author
1288
1326
  val = authors and val.first
@@ -1290,27 +1328,11 @@ class Gem::Specification
1290
1328
 
1291
1329
  ##
1292
1330
  # The list of author names who wrote this gem.
1293
- #
1294
- # spec.authors = ['Chad Fowler', 'Jim Weirich', 'Rich Kilmer']
1295
1331
 
1296
1332
  def authors
1297
1333
  @authors ||= []
1298
1334
  end
1299
1335
 
1300
- ##
1301
- # Returns the full path to the base gem directory.
1302
- #
1303
- # eg: /usr/local/lib/ruby/gems/1.8
1304
-
1305
- def base_dir
1306
- return Gem.dir unless loaded_from
1307
- @base_dir ||= if default_gem? then
1308
- File.dirname File.dirname File.dirname loaded_from
1309
- else
1310
- File.dirname File.dirname loaded_from
1311
- end
1312
- end
1313
-
1314
1336
  ##
1315
1337
  # Returns the full path to installed gem's bin directory.
1316
1338
  #
@@ -1385,22 +1407,7 @@ class Gem::Specification
1385
1407
  end
1386
1408
 
1387
1409
  ##
1388
- # Return true if this spec can require +file+.
1389
-
1390
- def contains_requirable_file? file
1391
- root = full_gem_path
1392
- suffixes = Gem.suffixes
1393
-
1394
- require_paths.any? do |lib|
1395
- base = "#{root}/#{lib}/#{file}"
1396
- suffixes.any? { |suf| File.file? "#{base}#{suf}" }
1397
- end
1398
- end
1399
-
1400
- ##
1401
- # The date this gem was created. Lazily defaults to the current UTC date.
1402
- #
1403
- # There is no need to set this in your gem specification.
1410
+ # The date this gem was created. Lazily defaults to TODAY.
1404
1411
 
1405
1412
  def date
1406
1413
  @date ||= TODAY
@@ -1447,7 +1454,7 @@ class Gem::Specification
1447
1454
  # Deprecated: The name of the gem is assumed to be the name of the
1448
1455
  # executable now. See Gem.bin_path.
1449
1456
 
1450
- def default_executable # :nodoc:
1457
+ def default_executable
1451
1458
  if defined?(@default_executable) and @default_executable
1452
1459
  result = @default_executable
1453
1460
  elsif @executables and @executables.size == 1
@@ -1506,7 +1513,7 @@ class Gem::Specification
1506
1513
  end
1507
1514
 
1508
1515
  ##
1509
- # A detailed description of this gem. See also #summary
1516
+ # A long description of this gem
1510
1517
 
1511
1518
  def description= str
1512
1519
  @description = str.to_s
@@ -1642,35 +1649,14 @@ class Gem::Specification
1642
1649
  spec
1643
1650
  end
1644
1651
 
1645
- ##
1646
- # The full path to the gem (install path + full name).
1647
-
1648
- def full_gem_path
1649
- # TODO: This is a heavily used method by gems, so we'll need
1650
- # to aleast just alias it to #gem_dir rather than remove it.
1651
-
1652
- # TODO: also, shouldn't it default to full_name if it hasn't been written?
1653
- return @full_gem_path if defined?(@full_gem_path) && @full_gem_path
1654
-
1655
- @full_gem_path = File.expand_path File.join(gems_dir, full_name)
1656
- @full_gem_path.untaint
1657
-
1658
- return @full_gem_path if File.directory? @full_gem_path
1659
-
1660
- @full_gem_path = File.expand_path File.join(gems_dir, original_name)
1652
+ # :nodoc:
1653
+ def find_full_gem_path
1654
+ super || File.expand_path(File.join(gems_dir, original_name))
1661
1655
  end
1662
-
1663
- ##
1664
- # Returns the full name (name-version) of this Gem. Platform information
1665
- # is included (name-version-platform) if it is specified and not the
1666
- # default Ruby platform.
1656
+ private :find_full_gem_path
1667
1657
 
1668
1658
  def full_name
1669
- @full_name ||= if platform == Gem::Platform::RUBY or platform.nil? then
1670
- "#{@name}-#{@version}".untaint
1671
- else
1672
- "#{@name}-#{@version}-#{platform}".untaint
1673
- end
1659
+ @full_name ||= super
1674
1660
  end
1675
1661
 
1676
1662
  ##
@@ -1681,21 +1667,12 @@ class Gem::Specification
1681
1667
  @gem_dir ||= File.expand_path File.join(gems_dir, full_name)
1682
1668
  end
1683
1669
 
1684
- ##
1685
- # Returns the full path to the gems directory containing this spec's
1686
- # gem directory. eg: /usr/local/lib/ruby/1.8/gems
1687
-
1688
- def gems_dir
1689
- # TODO: this logic seems terribly broken, but tests fail if just base_dir
1690
- @gems_dir ||= File.join(loaded_from && base_dir || Gem.dir, "gems")
1691
- end
1692
-
1693
1670
  ##
1694
1671
  # Deprecated and ignored, defaults to true.
1695
1672
  #
1696
1673
  # Formerly used to indicate this gem was RDoc-capable.
1697
1674
 
1698
- def has_rdoc # :nodoc:
1675
+ def has_rdoc
1699
1676
  true
1700
1677
  end
1701
1678
 
@@ -1704,11 +1681,11 @@ class Gem::Specification
1704
1681
  #
1705
1682
  # Formerly used to indicate this gem was RDoc-capable.
1706
1683
 
1707
- def has_rdoc= ignored # :nodoc:
1684
+ def has_rdoc= ignored
1708
1685
  @has_rdoc = true
1709
1686
  end
1710
1687
 
1711
- alias :has_rdoc? :has_rdoc # :nodoc:
1688
+ alias :has_rdoc? :has_rdoc
1712
1689
 
1713
1690
  ##
1714
1691
  # True if this gem has files in test_files
@@ -1722,9 +1699,7 @@ class Gem::Specification
1722
1699
  # :startdoc:
1723
1700
 
1724
1701
  def hash # :nodoc:
1725
- @@attributes.inject(0) { |hash_code, (name, _)|
1726
- hash_code ^ self.send(name).hash
1727
- }
1702
+ name.hash ^ version.hash
1728
1703
  end
1729
1704
 
1730
1705
  def init_with coder # :nodoc:
@@ -1739,7 +1714,7 @@ class Gem::Specification
1739
1714
  def initialize name = nil, version = nil
1740
1715
  @loaded = false
1741
1716
  @activated = false
1742
- @loaded_from = nil
1717
+ self.loaded_from = nil
1743
1718
  @original_platform = nil
1744
1719
 
1745
1720
  @@nil_attributes.each do |key|
@@ -1748,11 +1723,7 @@ class Gem::Specification
1748
1723
 
1749
1724
  @@non_nil_attributes.each do |key|
1750
1725
  default = default_value(key)
1751
- value = case default
1752
- when Time, Numeric, Symbol, true, false, nil then default
1753
- else default.dup
1754
- end
1755
-
1726
+ value = Dupable[key] ? default.dup : default
1756
1727
  instance_variable_set "@#{key}", value
1757
1728
  end
1758
1729
 
@@ -1847,27 +1818,30 @@ class Gem::Specification
1847
1818
  @licenses ||= []
1848
1819
  end
1849
1820
 
1850
- ##
1851
- # Set the location a Specification was loaded from. +obj+ is converted
1852
- # to a String.
1853
-
1854
- def loaded_from= path
1855
- @loaded_from = path.to_s
1821
+ def filename= path
1822
+ super
1856
1823
 
1857
- # reset everything @loaded_from depends upon
1858
- @base_dir = nil
1859
1824
  @bin_dir = nil
1860
1825
  @cache_dir = nil
1861
1826
  @cache_file = nil
1862
1827
  @doc_dir = nil
1863
- @full_gem_path = nil
1864
1828
  @gem_dir = nil
1865
- @gems_dir = nil
1866
1829
  @ri_dir = nil
1867
1830
  @spec_dir = nil
1868
1831
  @spec_file = nil
1869
1832
  end
1870
1833
 
1834
+ ##
1835
+ # Path this gemspec was loaded from. This attribute is not persisted.
1836
+
1837
+ alias loaded_from filename
1838
+
1839
+ ##
1840
+ # Set the location a Specification was loaded from. +obj+ is converted
1841
+ # to a String.
1842
+
1843
+ alias loaded_from= filename=
1844
+
1871
1845
  ##
1872
1846
  # Sets the rubygems_version to the current RubyGems version.
1873
1847
 
@@ -2047,6 +2021,10 @@ class Gem::Specification
2047
2021
  @requirements = Array req
2048
2022
  end
2049
2023
 
2024
+ def respond_to_missing? m, include_private = false # :nodoc:
2025
+ false
2026
+ end
2027
+
2050
2028
  ##
2051
2029
  # Returns the full path to this spec's ri directory.
2052
2030
 
@@ -2112,6 +2090,13 @@ class Gem::Specification
2112
2090
  [@name, @version, @new_platform == Gem::Platform::RUBY ? -1 : 1]
2113
2091
  end
2114
2092
 
2093
+ ##
2094
+ # Used by Gem::DependencyResolver to order Gem::Specification objects
2095
+
2096
+ def source # :nodoc:
2097
+ self
2098
+ end
2099
+
2115
2100
  ##
2116
2101
  # Returns the full path to the directory containing this spec's
2117
2102
  # gemspec file. eg: /usr/local/lib/ruby/gems/1.8/specifications
@@ -2191,6 +2176,7 @@ class Gem::Specification
2191
2176
  mark_version
2192
2177
  result = []
2193
2178
  result << "# -*- encoding: utf-8 -*-"
2179
+ result << "#{Gem::StubSpecification::PREFIX}#{name} #{version} #{platform} #{require_paths.join("\0")}"
2194
2180
  result << nil
2195
2181
  result << "Gem::Specification.new do |s|"
2196
2182
 
@@ -2278,6 +2264,13 @@ class Gem::Specification
2278
2264
  "#<Gem::Specification name=#{@name} version=#{@version}>"
2279
2265
  end
2280
2266
 
2267
+ ##
2268
+ # Returns self
2269
+
2270
+ def to_spec
2271
+ self
2272
+ end
2273
+
2281
2274
  def to_yaml(opts = {}) # :nodoc:
2282
2275
  if YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck? then
2283
2276
  # Because the user can switch the YAML engine behind our
@@ -2578,11 +2571,6 @@ class Gem::Specification
2578
2571
  end
2579
2572
  end
2580
2573
 
2581
- def default_gem?
2582
- loaded_from &&
2583
- File.dirname(loaded_from) == self.class.default_specifications_dir
2584
- end
2585
-
2586
2574
  extend Gem::Deprecate
2587
2575
 
2588
2576
  # TODO: