rubygems-update 2.7.3 → 2.7.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -30
  3. data/History.txt +146 -0
  4. data/Manifest.txt +5 -4
  5. data/Rakefile +19 -2
  6. data/bundler/CHANGELOG.md +143 -0
  7. data/bundler/README.md +5 -1
  8. data/bundler/bundler.gemspec +4 -1
  9. data/bundler/lib/bundler.rb +12 -8
  10. data/bundler/lib/bundler/build_metadata.rb +19 -2
  11. data/bundler/lib/bundler/cli.rb +3 -1
  12. data/bundler/lib/bundler/cli/check.rb +1 -1
  13. data/bundler/lib/bundler/cli/exec.rb +4 -4
  14. data/bundler/lib/bundler/cli/gem.rb +6 -3
  15. data/bundler/lib/bundler/cli/init.rb +6 -5
  16. data/bundler/lib/bundler/cli/install.rb +2 -2
  17. data/bundler/lib/bundler/cli/outdated.rb +1 -1
  18. data/bundler/lib/bundler/cli/update.rb +6 -4
  19. data/bundler/lib/bundler/compact_index_client/updater.rb +10 -1
  20. data/bundler/lib/bundler/current_ruby.rb +8 -1
  21. data/bundler/lib/bundler/definition.rb +34 -24
  22. data/bundler/lib/bundler/dep_proxy.rb +2 -2
  23. data/bundler/lib/bundler/dependency.rb +1 -0
  24. data/bundler/lib/bundler/deprecate.rb +2 -1
  25. data/bundler/lib/bundler/endpoint_specification.rb +1 -1
  26. data/bundler/lib/bundler/env.rb +10 -8
  27. data/bundler/lib/bundler/fetcher.rb +3 -3
  28. data/bundler/lib/bundler/fetcher/downloader.rb +10 -5
  29. data/bundler/lib/bundler/fetcher/index.rb +2 -2
  30. data/bundler/lib/bundler/friendly_errors.rb +2 -0
  31. data/bundler/lib/bundler/gem_helper.rb +1 -1
  32. data/bundler/lib/bundler/gem_version_promoter.rb +12 -0
  33. data/bundler/lib/bundler/injector.rb +5 -5
  34. data/bundler/lib/bundler/installer.rb +12 -4
  35. data/bundler/lib/bundler/installer/gem_installer.rb +9 -2
  36. data/bundler/lib/bundler/installer/parallel_installer.rb +1 -1
  37. data/bundler/lib/bundler/lazy_specification.rb +1 -1
  38. data/bundler/lib/bundler/mirror.rb +2 -2
  39. data/bundler/lib/bundler/plugin.rb +2 -2
  40. data/bundler/lib/bundler/plugin/index.rb +7 -2
  41. data/bundler/lib/bundler/process_lock.rb +1 -1
  42. data/bundler/lib/bundler/resolver.rb +14 -10
  43. data/bundler/lib/bundler/resolver/spec_group.rb +0 -5
  44. data/bundler/lib/bundler/ruby_version.rb +1 -1
  45. data/bundler/lib/bundler/rubygems_integration.rb +9 -3
  46. data/bundler/lib/bundler/runtime.rb +2 -2
  47. data/bundler/lib/bundler/shared_helpers.rb +15 -3
  48. data/bundler/lib/bundler/source/git.rb +2 -1
  49. data/bundler/lib/bundler/source/git/git_proxy.rb +6 -1
  50. data/bundler/lib/bundler/source/metadata.rb +1 -1
  51. data/bundler/lib/bundler/source/rubygems.rb +13 -6
  52. data/bundler/lib/bundler/source/rubygems/remote.rb +4 -1
  53. data/bundler/lib/bundler/spec_set.rb +4 -1
  54. data/bundler/lib/bundler/templates/.document +1 -0
  55. data/bundler/lib/bundler/templates/Executable +11 -3
  56. data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +8 -2
  57. data/bundler/lib/bundler/templates/newgem/{.travis.yml.tt → travis.yml.tt} +2 -0
  58. data/bundler/lib/bundler/ui/shell.rb +3 -1
  59. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +11 -1
  60. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +7 -2
  61. data/bundler/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +1 -1
  62. data/bundler/lib/bundler/version.rb +1 -1
  63. data/bundler/man/bundle-binstubs.ronn +3 -3
  64. data/bundler/man/bundle-check.ronn +3 -3
  65. data/bundler/man/bundle-config.ronn +13 -9
  66. data/bundler/man/bundle-doctor.ronn +33 -0
  67. data/bundler/man/bundle-exec.ronn +3 -3
  68. data/bundler/man/bundle-gem.ronn +1 -1
  69. data/bundler/man/bundle-init.ronn +15 -4
  70. data/bundler/man/bundle-inject.ronn +3 -3
  71. data/bundler/man/bundle-install.ronn +12 -3
  72. data/bundler/man/bundle-lock.ronn +1 -1
  73. data/bundler/man/bundle-outdated.ronn +1 -1
  74. data/bundler/man/bundle-package.ronn +3 -3
  75. data/bundler/man/bundle-show.ronn +3 -2
  76. data/bundler/man/bundle-update.ronn +18 -14
  77. data/bundler/man/bundle-viz.ronn +1 -1
  78. data/bundler/man/bundle.ronn +27 -27
  79. data/bundler/man/gemfile.5.ronn +24 -9
  80. data/lib/rubygems.rb +30 -17
  81. data/lib/rubygems/bundler_version_finder.rb +9 -22
  82. data/lib/rubygems/command.rb +9 -1
  83. data/lib/rubygems/command_manager.rb +6 -4
  84. data/lib/rubygems/commands/generate_index_command.rb +1 -1
  85. data/lib/rubygems/commands/install_command.rb +7 -0
  86. data/lib/rubygems/commands/owner_command.rb +4 -1
  87. data/lib/rubygems/commands/push_command.rb +37 -4
  88. data/lib/rubygems/commands/setup_command.rb +22 -7
  89. data/lib/rubygems/commands/uninstall_command.rb +1 -1
  90. data/lib/rubygems/commands/unpack_command.rb +3 -3
  91. data/lib/rubygems/config_file.rb +1 -1
  92. data/lib/rubygems/core_ext/kernel_require.rb +2 -7
  93. data/lib/rubygems/dependency.rb +1 -0
  94. data/lib/rubygems/dependency_installer.rb +4 -2
  95. data/lib/rubygems/exceptions.rb +5 -1
  96. data/lib/rubygems/ext/builder.rb +1 -1
  97. data/lib/rubygems/gemcutter_utilities.rb +5 -2
  98. data/lib/rubygems/indexer.rb +6 -5
  99. data/lib/rubygems/install_update_options.rb +1 -1
  100. data/lib/rubygems/installer.rb +38 -10
  101. data/lib/rubygems/package.rb +54 -7
  102. data/lib/rubygems/package/file_source.rb +2 -2
  103. data/lib/rubygems/package/old.rb +1 -1
  104. data/lib/rubygems/package/tar_header.rb +17 -10
  105. data/lib/rubygems/package/tar_writer.rb +4 -3
  106. data/lib/rubygems/remote_fetcher.rb +1 -1
  107. data/lib/rubygems/request_set.rb +28 -17
  108. data/lib/rubygems/request_set/lockfile.rb +1 -1
  109. data/lib/rubygems/requirement.rb +14 -3
  110. data/lib/rubygems/resolver/api_specification.rb +5 -0
  111. data/lib/rubygems/security.rb +7 -2
  112. data/lib/rubygems/security/trust_dir.rb +1 -1
  113. data/lib/rubygems/server.rb +16 -4
  114. data/lib/rubygems/source.rb +2 -2
  115. data/lib/rubygems/specification.rb +22 -14
  116. data/lib/rubygems/ssl_certs/{index.rubygems.org → rubygems.org}/GlobalSignRootCA.pem +0 -0
  117. data/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA_R3.pem +21 -0
  118. data/lib/rubygems/stub_specification.rb +2 -0
  119. data/lib/rubygems/test_case.rb +36 -12
  120. data/lib/rubygems/test_utilities.rb +2 -2
  121. data/lib/rubygems/user_interaction.rb +9 -2
  122. data/lib/rubygems/util.rb +2 -1
  123. data/lib/rubygems/util/licenses.rb +35 -4
  124. data/lib/rubygems/validator.rb +3 -3
  125. data/lib/rubygems/version.rb +7 -1
  126. data/lib/ubygems.rb +3 -0
  127. data/test/rubygems/test_bundled_ca.rb +7 -4
  128. data/test/rubygems/test_gem.rb +62 -24
  129. data/test/rubygems/test_gem_bundler_version_finder.rb +8 -7
  130. data/test/rubygems/test_gem_command_manager.rb +2 -2
  131. data/test/rubygems/test_gem_commands_build_command.rb +2 -0
  132. data/test/rubygems/test_gem_commands_cleanup_command.rb +1 -1
  133. data/test/rubygems/test_gem_commands_install_command.rb +38 -0
  134. data/test/rubygems/test_gem_commands_owner_command.rb +25 -0
  135. data/test/rubygems/test_gem_commands_push_command.rb +25 -5
  136. data/test/rubygems/test_gem_commands_setup_command.rb +46 -21
  137. data/test/rubygems/test_gem_commands_signin_command.rb +1 -1
  138. data/test/rubygems/test_gem_commands_uninstall_command.rb +3 -3
  139. data/test/rubygems/test_gem_dependency.rb +1 -1
  140. data/test/rubygems/test_gem_dependency_installer.rb +1 -1
  141. data/test/rubygems/test_gem_doctor.rb +2 -2
  142. data/test/rubygems/test_gem_ext_builder.rb +6 -6
  143. data/test/rubygems/test_gem_ext_rake_builder.rb +0 -4
  144. data/test/rubygems/test_gem_gemcutter_utilities.rb +4 -4
  145. data/test/rubygems/test_gem_indexer.rb +1 -2
  146. data/test/rubygems/test_gem_install_update_options.rb +4 -0
  147. data/test/rubygems/test_gem_installer.rb +114 -4
  148. data/test/rubygems/test_gem_package.rb +178 -21
  149. data/test/rubygems/test_gem_package_old.rb +1 -1
  150. data/test/rubygems/test_gem_package_tar_header.rb +21 -0
  151. data/test/rubygems/test_gem_rdoc.rb +2 -0
  152. data/test/rubygems/test_gem_remote_fetcher.rb +7 -3
  153. data/test/rubygems/test_gem_request.rb +5 -2
  154. data/test/rubygems/test_gem_request_connection_pools.rb +6 -7
  155. data/test/rubygems/test_gem_request_set.rb +7 -7
  156. data/test/rubygems/test_gem_request_set_lockfile.rb +4 -4
  157. data/test/rubygems/test_gem_request_set_lockfile_parser.rb +1 -1
  158. data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +1 -1
  159. data/test/rubygems/test_gem_requirement.rb +6 -0
  160. data/test/rubygems/test_gem_resolver_api_specification.rb +24 -0
  161. data/test/rubygems/test_gem_resolver_git_specification.rb +1 -1
  162. data/test/rubygems/test_gem_resolver_installer_set.rb +1 -1
  163. data/test/rubygems/test_gem_security_policy.rb +3 -3
  164. data/test/rubygems/test_gem_server.rb +177 -12
  165. data/test/rubygems/test_gem_source.rb +3 -3
  166. data/test/rubygems/test_gem_source_git.rb +1 -1
  167. data/test/rubygems/test_gem_specification.rb +64 -31
  168. data/test/rubygems/test_gem_stream_ui.rb +2 -2
  169. data/test/rubygems/test_gem_stub_specification.rb +7 -7
  170. data/test/rubygems/test_gem_text.rb +5 -0
  171. data/test/rubygems/test_gem_util.rb +25 -0
  172. data/test/rubygems/test_gem_version.rb +40 -2
  173. data/test/rubygems/test_require.rb +15 -21
  174. data/util/ci +1 -0
  175. data/util/generate_spdx_license_list.rb +15 -6
  176. data/util/update_bundled_ca_certificates.rb +1 -3
  177. metadata +14 -13
  178. data/lib/rubygems/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +0 -23
  179. data/lib/rubygems/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +0 -25
@@ -23,11 +23,11 @@ class Gem::Package::FileSource < Gem::Package::Source # :nodoc: all
23
23
  end
24
24
 
25
25
  def with_write_io &block
26
- open path, 'wb', &block
26
+ File.open path, 'wb', &block
27
27
  end
28
28
 
29
29
  def with_read_io &block
30
- open path, 'rb', &block
30
+ File.open path, 'rb', &block
31
31
  end
32
32
 
33
33
  end
@@ -80,7 +80,7 @@ class Gem::Package::Old < Gem::Package
80
80
 
81
81
  FileUtils.mkdir_p File.dirname destination
82
82
 
83
- open destination, 'wb', entry['mode'] do |out|
83
+ File.open destination, 'wb', entry['mode'] do |out|
84
84
  out.write file_data
85
85
  end
86
86
 
@@ -94,35 +94,42 @@ class Gem::Package::TarHeader
94
94
 
95
95
  attr_reader(*FIELDS)
96
96
 
97
+ EMPTY_HEADER = ("\0" * 512).freeze # :nodoc:
98
+
97
99
  ##
98
100
  # Creates a tar header from IO +stream+
99
101
 
100
102
  def self.from(stream)
101
103
  header = stream.read 512
102
- empty = (header == "\0" * 512)
104
+ empty = (EMPTY_HEADER == header)
103
105
 
104
106
  fields = header.unpack UNPACK_FORMAT
105
107
 
106
108
  new :name => fields.shift,
107
- :mode => fields.shift.oct,
108
- :uid => fields.shift.oct,
109
- :gid => fields.shift.oct,
110
- :size => fields.shift.oct,
111
- :mtime => fields.shift.oct,
112
- :checksum => fields.shift.oct,
109
+ :mode => strict_oct(fields.shift),
110
+ :uid => strict_oct(fields.shift),
111
+ :gid => strict_oct(fields.shift),
112
+ :size => strict_oct(fields.shift),
113
+ :mtime => strict_oct(fields.shift),
114
+ :checksum => strict_oct(fields.shift),
113
115
  :typeflag => fields.shift,
114
116
  :linkname => fields.shift,
115
117
  :magic => fields.shift,
116
- :version => fields.shift.oct,
118
+ :version => strict_oct(fields.shift),
117
119
  :uname => fields.shift,
118
120
  :gname => fields.shift,
119
- :devmajor => fields.shift.oct,
120
- :devminor => fields.shift.oct,
121
+ :devmajor => strict_oct(fields.shift),
122
+ :devminor => strict_oct(fields.shift),
121
123
  :prefix => fields.shift,
122
124
 
123
125
  :empty => empty
124
126
  end
125
127
 
128
+ def self.strict_oct(str)
129
+ return str.oct if str =~ /\A[0-7]*\z/
130
+ raise ArgumentError, "#{str.inspect} is not an octal string"
131
+ end
132
+
126
133
  ##
127
134
  # Creates a new TarHeader using +vals+
128
135
 
@@ -111,7 +111,7 @@ class Gem::Package::TarWriter
111
111
  name, prefix = split_name name
112
112
 
113
113
  init_pos = @io.pos
114
- @io.write "\0" * 512 # placeholder for the header
114
+ @io.write Gem::Package::TarHeader::EMPTY_HEADER # placeholder for the header
115
115
 
116
116
  yield RestrictedStream.new(@io) if block_given?
117
117
 
@@ -189,13 +189,14 @@ class Gem::Package::TarWriter
189
189
  if digest.respond_to? :name then
190
190
  digest.name
191
191
  else
192
- /::([^:]+)$/ =~ digest.class.name
193
- $1
192
+ digest.class.name[/::([^:]+)\z/, 1]
194
193
  end
195
194
 
196
195
  digest_name == signer.digest_name
197
196
  end
198
197
 
198
+ raise "no #{signer.digest_name} in #{digests.values.compact}" unless signature_digest
199
+
199
200
  if signer.key then
200
201
  signature = signer.sign signature_digest.digest
201
202
 
@@ -293,7 +293,7 @@ class Gem::RemoteFetcher
293
293
 
294
294
  if data and !head and uri.to_s =~ /\.gz$/
295
295
  begin
296
- data = Gem.gunzip data
296
+ data = Gem::Util.gunzip data
297
297
  rescue Zlib::GzipFile::Error
298
298
  raise FetchError.new("server did not return a valid file", uri.to_s)
299
299
  end
@@ -171,7 +171,9 @@ class Gem::RequestSet
171
171
  rescue Gem::RuntimeRequirementNotMetError => e
172
172
  recent_match = req.spec.set.find_all(req.request).sort_by(&:version).reverse_each.find do |s|
173
173
  s = s.spec
174
- s.required_ruby_version.satisfied_by?(Gem.ruby_version) && s.required_rubygems_version.satisfied_by?(Gem.rubygems_version)
174
+ s.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
175
+ s.required_rubygems_version.satisfied_by?(Gem.rubygems_version) &&
176
+ Gem::Platform.installable?(s)
175
177
  end
176
178
  if recent_match
177
179
  suggestion = "The last version of #{req.request} to support your Ruby & RubyGems was #{recent_match.version}. Try installing it with `gem install #{recent_match.name} -v #{recent_match.version}`"
@@ -189,22 +191,7 @@ class Gem::RequestSet
189
191
 
190
192
  return requests if options[:gemdeps]
191
193
 
192
- specs = requests.map do |request|
193
- case request
194
- when Gem::Resolver::ActivationRequest then
195
- request.spec.spec
196
- else
197
- request
198
- end
199
- end
200
-
201
- require 'rubygems/dependency_installer'
202
- inst = Gem::DependencyInstaller.new options
203
- inst.installed_gems.replace specs
204
-
205
- Gem.done_installing_hooks.each do |hook|
206
- hook.call inst, specs
207
- end unless Gem.done_installing_hooks.empty?
194
+ install_hooks requests, options
208
195
 
209
196
  requests
210
197
  end
@@ -281,11 +268,35 @@ class Gem::RequestSet
281
268
  installed << request
282
269
  end
283
270
 
271
+ install_hooks installed, options
272
+
284
273
  installed
285
274
  ensure
286
275
  ENV['GEM_HOME'] = gem_home
287
276
  end
288
277
 
278
+ ##
279
+ # Call hooks on installed gems
280
+
281
+ def install_hooks requests, options
282
+ specs = requests.map do |request|
283
+ case request
284
+ when Gem::Resolver::ActivationRequest then
285
+ request.spec.spec
286
+ else
287
+ request
288
+ end
289
+ end
290
+
291
+ require "rubygems/dependency_installer"
292
+ inst = Gem::DependencyInstaller.new options
293
+ inst.installed_gems.replace specs
294
+
295
+ Gem.done_installing_hooks.each do |hook|
296
+ hook.call inst, specs
297
+ end unless Gem.done_installing_hooks.empty?
298
+ end
299
+
289
300
  ##
290
301
  # Load a dependency management file.
291
302
 
@@ -223,7 +223,7 @@ class Gem::RequestSet::Lockfile
223
223
  def write
224
224
  content = to_s
225
225
 
226
- open "#{@gem_deps_file}.lock", 'w' do |io|
226
+ File.open "#{@gem_deps_file}.lock", 'w' do |io|
227
227
  io.write content
228
228
  end
229
229
  end
@@ -133,6 +133,7 @@ class Gem::Requirement
133
133
  @requirements = [DefaultRequirement]
134
134
  else
135
135
  @requirements = requirements.map! { |r| self.class.parse r }
136
+ sort_requirements!
136
137
  end
137
138
  end
138
139
 
@@ -146,6 +147,7 @@ class Gem::Requirement
146
147
  new = new.map { |r| self.class.parse r }
147
148
 
148
149
  @requirements.concat new
150
+ sort_requirements!
149
151
  end
150
152
 
151
153
  ##
@@ -183,11 +185,11 @@ class Gem::Requirement
183
185
  end
184
186
 
185
187
  def as_list # :nodoc:
186
- requirements.map { |op, version| "#{op} #{version}" }.sort
188
+ requirements.map { |op, version| "#{op} #{version}" }
187
189
  end
188
190
 
189
191
  def hash # :nodoc:
190
- requirements.sort.hash
192
+ requirements.hash
191
193
  end
192
194
 
193
195
  def marshal_dump # :nodoc:
@@ -264,7 +266,8 @@ class Gem::Requirement
264
266
  end
265
267
 
266
268
  def == other # :nodoc:
267
- Gem::Requirement === other and to_s == other.to_s
269
+ return unless Gem::Requirement === other
270
+ requirements == other.requirements
268
271
  end
269
272
 
270
273
  private
@@ -279,6 +282,14 @@ class Gem::Requirement
279
282
  end
280
283
  end
281
284
  end
285
+
286
+ def sort_requirements! # :nodoc:
287
+ @requirements.sort! do |l, r|
288
+ comp = l.last <=> r.last # first, sort by the requirement's version
289
+ next comp unless comp == 0
290
+ l.first <=> r.first # then, sort by the operator (for stability)
291
+ end
292
+ end
282
293
  end
283
294
 
284
295
  class Gem::Version
@@ -21,6 +21,7 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
21
21
  @name = api_data[:name]
22
22
  @version = Gem::Version.new api_data[:number]
23
23
  @platform = Gem::Platform.new api_data[:platform]
24
+ @original_platform = api_data[:platform]
24
25
  @dependencies = api_data[:dependencies].map do |name, ver|
25
26
  Gem::Dependency.new name, ver.split(/\s*,\s*/)
26
27
  end
@@ -73,7 +74,11 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
73
74
  @spec ||=
74
75
  begin
75
76
  tuple = Gem::NameTuple.new @name, @version, @platform
77
+ source.fetch_spec tuple
78
+ rescue Gem::RemoteFetcher::FetchError
79
+ raise if @original_platform == @platform
76
80
 
81
+ tuple = Gem::NameTuple.new @name, @version, @original_platform
77
82
  source.fetch_spec tuple
78
83
  end
79
84
  end
@@ -344,14 +344,19 @@ module Gem::Security
344
344
  OpenSSL::Digest::SHA256
345
345
  elsif defined?(OpenSSL::Digest::SHA1) then
346
346
  OpenSSL::Digest::SHA1
347
+ else
348
+ require 'digest'
349
+ Digest::SHA512
347
350
  end
348
351
 
349
352
  ##
350
353
  # Used internally to select the signing digest from all computed digests
351
354
 
352
355
  DIGEST_NAME = # :nodoc:
353
- if DIGEST_ALGORITHM then
356
+ if DIGEST_ALGORITHM.method_defined? :name then
354
357
  DIGEST_ALGORITHM.new.name
358
+ else
359
+ DIGEST_ALGORITHM.name[/::([^:]+)\z/, 1]
355
360
  end
356
361
 
357
362
  ##
@@ -578,7 +583,7 @@ module Gem::Security
578
583
  def self.write pemmable, path, permissions = 0600, passphrase = nil, cipher = KEY_CIPHER
579
584
  path = File.expand_path path
580
585
 
581
- open path, 'wb', permissions do |io|
586
+ File.open path, 'wb', permissions do |io|
582
587
  if passphrase and cipher
583
588
  io.write pemmable.to_pem cipher, passphrase
584
589
  else
@@ -93,7 +93,7 @@ class Gem::Security::TrustDir
93
93
 
94
94
  destination = cert_path certificate
95
95
 
96
- open destination, 'wb', @permissions[:trusted_cert] do |io|
96
+ File.open destination, 'wb', @permissions[:trusted_cert] do |io|
97
97
  io.write certificate.to_pem
98
98
  end
99
99
  end
@@ -492,7 +492,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
492
492
  specs = Marshal.dump specs
493
493
 
494
494
  if req.path =~ /\.gz$/ then
495
- specs = Gem.gzip specs
495
+ specs = Gem::Util.gzip specs
496
496
  res['content-type'] = 'application/x-gzip'
497
497
  else
498
498
  res['content-type'] = 'application/octet-stream'
@@ -553,7 +553,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
553
553
  specs = Marshal.dump specs
554
554
 
555
555
  if req.path =~ /\.gz$/ then
556
- specs = Gem.gzip specs
556
+ specs = Gem::Util.gzip specs
557
557
  res['content-type'] = 'application/x-gzip'
558
558
  else
559
559
  res['content-type'] = 'application/octet-stream'
@@ -623,6 +623,18 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
623
623
  executables = nil if executables.empty?
624
624
  executables.last["is_last"] = true if executables
625
625
 
626
+ # Pre-process spec homepage for safety reasons
627
+ begin
628
+ homepage_uri = URI.parse(spec.homepage)
629
+ if [URI::HTTP, URI::HTTPS].member? homepage_uri.class
630
+ homepage_uri = spec.homepage
631
+ else
632
+ homepage_uri = "."
633
+ end
634
+ rescue URI::InvalidURIError
635
+ homepage_uri = "."
636
+ end
637
+
626
638
  specs << {
627
639
  "authors" => spec.authors.sort.join(", "),
628
640
  "date" => spec.date.to_s,
@@ -632,7 +644,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
632
644
  "only_one_executable" => (executables && executables.size == 1),
633
645
  "full_name" => spec.full_name,
634
646
  "has_deps" => !deps.empty?,
635
- "homepage" => spec.homepage,
647
+ "homepage" => homepage_uri,
636
648
  "name" => spec.name,
637
649
  "rdoc_installed" => Gem::RDoc.new(spec).rdoc_installed?,
638
650
  "ri_installed" => Gem::RDoc.new(spec).ri_installed?,
@@ -840,7 +852,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
840
852
  specs = Marshal.dump specs
841
853
 
842
854
  if req.path =~ /\.gz$/ then
843
- specs = Gem.gzip specs
855
+ specs = Gem::Util.gzip specs
844
856
  res['content-type'] = 'application/x-gzip'
845
857
  else
846
858
  res['content-type'] = 'application/octet-stream'
@@ -155,12 +155,12 @@ class Gem::Source
155
155
  uri.path << '.rz'
156
156
 
157
157
  spec = fetcher.fetch_path uri
158
- spec = Gem.inflate spec
158
+ spec = Gem::Util.inflate spec
159
159
 
160
160
  if update_cache? then
161
161
  FileUtils.mkdir_p cache_dir
162
162
 
163
- open local_spec, 'wb' do |io|
163
+ File.open local_spec, 'wb' do |io|
164
164
  io.write spec
165
165
  end
166
166
  end
@@ -15,6 +15,7 @@ require 'rubygems/basic_specification'
15
15
  require 'rubygems/stub_specification'
16
16
  require 'rubygems/util/list'
17
17
  require 'stringio'
18
+ require 'uri'
18
19
 
19
20
  ##
20
21
  # The Specification class contains the information for a Gem. Typically
@@ -39,6 +40,8 @@ require 'stringio'
39
40
 
40
41
  class Gem::Specification < Gem::BasicSpecification
41
42
 
43
+ extend Gem::Deprecate
44
+
42
45
  # REFACTOR: Consider breaking out this version stuff into a separate
43
46
  # module. There's enough special stuff around it that it may justify
44
47
  # a separate class.
@@ -714,6 +717,7 @@ class Gem::Specification < Gem::BasicSpecification
714
717
  # Deprecated: You must now specify the executable name to Gem.bin_path.
715
718
 
716
719
  attr_writer :default_executable
720
+ deprecate :default_executable=, :none, 2018, 12
717
721
 
718
722
  ##
719
723
  # Allows deinstallation of gems with legacy platforms.
@@ -738,6 +742,9 @@ class Gem::Specification < Gem::BasicSpecification
738
742
  def self._all # :nodoc:
739
743
  unless defined?(@@all) && @@all then
740
744
  @@all = stubs.map(&:to_spec)
745
+ if @@all.any?(&:nil?) # TODO: remove once we're happy
746
+ raise "pid: #{$$} nil spec! included in #{stubs.inspect}"
747
+ end
741
748
 
742
749
  # After a reset, make sure already loaded specs
743
750
  # are still marked as activated.
@@ -958,6 +965,7 @@ class Gem::Specification < Gem::BasicSpecification
958
965
  # -- wilsonb
959
966
 
960
967
  def self.all= specs
968
+ raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy
961
969
  @@stubs_by_name = specs.group_by(&:name)
962
970
  @@all = @@stubs = specs
963
971
  end
@@ -1805,6 +1813,7 @@ class Gem::Specification < Gem::BasicSpecification
1805
1813
  end
1806
1814
  result
1807
1815
  end
1816
+ deprecate :default_executable, :none, 2018, 12
1808
1817
 
1809
1818
  ##
1810
1819
  # The default value for specification attribute +name+
@@ -2013,6 +2022,7 @@ class Gem::Specification < Gem::BasicSpecification
2013
2022
  def has_rdoc # :nodoc:
2014
2023
  true
2015
2024
  end
2025
+ deprecate :has_rdoc, :none, 2018, 12
2016
2026
 
2017
2027
  ##
2018
2028
  # Deprecated and ignored.
@@ -2022,8 +2032,10 @@ class Gem::Specification < Gem::BasicSpecification
2022
2032
  def has_rdoc= ignored # :nodoc:
2023
2033
  @has_rdoc = true
2024
2034
  end
2035
+ deprecate :has_rdoc=, :none, 2018, 12
2025
2036
 
2026
2037
  alias :has_rdoc? :has_rdoc # :nodoc:
2038
+ deprecate :has_rdoc?, :none, 2018, 12
2027
2039
 
2028
2040
  ##
2029
2041
  # True if this gem has files in test_files
@@ -2818,10 +2830,16 @@ http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard li
2818
2830
  raise Gem::InvalidSpecificationException, "#{lazy} is not a summary"
2819
2831
  end
2820
2832
 
2821
- if homepage and not homepage.empty? and
2822
- homepage !~ /\A[a-z][a-z\d+.-]*:/i then
2823
- raise Gem::InvalidSpecificationException,
2824
- "\"#{homepage}\" is not a URI"
2833
+ # Make sure a homepage is valid HTTP/HTTPS URI
2834
+ if homepage and not homepage.empty?
2835
+ begin
2836
+ homepage_uri = URI.parse(homepage)
2837
+ unless [URI::HTTP, URI::HTTPS].member? homepage_uri.class
2838
+ raise Gem::InvalidSpecificationException, "\"#{homepage}\" is not a valid HTTP URI"
2839
+ end
2840
+ rescue URI::InvalidURIError
2841
+ raise Gem::InvalidSpecificationException, "\"#{homepage}\" is not a valid HTTP URI"
2842
+ end
2825
2843
  end
2826
2844
 
2827
2845
  # Warnings
@@ -3063,16 +3081,6 @@ open-ended dependency on #{dep} is not recommended
3063
3081
  @require_paths
3064
3082
  end
3065
3083
 
3066
- extend Gem::Deprecate
3067
-
3068
- # TODO:
3069
- # deprecate :has_rdoc, :none, 2011, 10
3070
- # deprecate :has_rdoc?, :none, 2011, 10
3071
- # deprecate :has_rdoc=, :none, 2011, 10
3072
- # deprecate :default_executable, :none, 2011, 10
3073
- # deprecate :default_executable=, :none, 2011, 10
3074
- # deprecate :file_name, :cache_file, 2011, 10
3075
- # deprecate :full_gem_path, :cache_file, 2011, 10
3076
3084
  end
3077
3085
 
3078
3086
  # DOC: What is this and why is it here, randomly, at the end of this file?