rubygems-update 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -1
  4. data/.autotest +1 -0
  5. data/History.txt +32 -0
  6. data/Manifest.txt +2 -0
  7. data/lib/rubygems.rb +14 -5
  8. data/lib/rubygems/available_set.rb +70 -72
  9. data/lib/rubygems/commands/cert_command.rb +1 -0
  10. data/lib/rubygems/commands/query_command.rb +7 -7
  11. data/lib/rubygems/commands/setup_command.rb +21 -4
  12. data/lib/rubygems/commands/sources_command.rb +13 -0
  13. data/lib/rubygems/config_file.rb +29 -16
  14. data/lib/rubygems/defaults.rb +1 -1
  15. data/lib/rubygems/dependency_installer.rb +18 -10
  16. data/lib/rubygems/dependency_list.rb +1 -1
  17. data/lib/rubygems/dependency_resolver.rb +17 -4
  18. data/lib/rubygems/ext/builder.rb +0 -7
  19. data/lib/rubygems/ext/ext_conf_builder.rb +43 -8
  20. data/lib/rubygems/installer.rb +4 -4
  21. data/lib/rubygems/package.rb +2 -1
  22. data/lib/rubygems/rdoc.rb +10 -1
  23. data/lib/rubygems/remote_fetcher.rb +8 -3
  24. data/lib/rubygems/security.rb +21 -1
  25. data/lib/rubygems/security/policy.rb +2 -0
  26. data/lib/rubygems/source.rb +10 -0
  27. data/lib/rubygems/spec_fetcher.rb +38 -0
  28. data/lib/rubygems/specification.rb +1 -1
  29. data/lib/rubygems/ssl_certs/GeoTrust_Global_CA.pem +20 -0
  30. data/lib/rubygems/test_utilities.rb +6 -3
  31. data/test/rubygems/test_gem.rb +13 -1
  32. data/test/rubygems/test_gem_commands_fetch_command.rb +4 -0
  33. data/test/rubygems/test_gem_commands_query_command.rb +16 -0
  34. data/test/rubygems/test_gem_commands_setup_command.rb +18 -1
  35. data/test/rubygems/test_gem_commands_sources_command.rb +39 -0
  36. data/test/rubygems/test_gem_config_file.rb +15 -0
  37. data/test/rubygems/test_gem_dependency_installer.rb +55 -0
  38. data/test/rubygems/test_gem_dependency_resolver_api_set.rb +80 -0
  39. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +1 -7
  40. data/test/rubygems/test_gem_installer.rb +92 -1
  41. data/test/rubygems/test_gem_remote_fetcher.rb +3 -0
  42. data/test/rubygems/test_gem_source.rb +11 -0
  43. data/test/rubygems/test_gem_source_list.rb +1 -1
  44. data/test/rubygems/test_gem_spec_fetcher.rb +80 -8
  45. data/test/rubygems/test_require.rb +19 -8
  46. metadata +14 -11
  47. metadata.gz.sig +0 -0
@@ -11,7 +11,7 @@ module Gem
11
11
  # An Array of the default sources that come with RubyGems
12
12
 
13
13
  def self.default_sources
14
- %w[http://rubygems.org/]
14
+ %w[https://rubygems.org/]
15
15
  end
16
16
 
17
17
  ##
@@ -88,6 +88,7 @@ class Gem::DependencyInstaller
88
88
  # we absolutely must.
89
89
  @minimal_deps = options[:minimal_deps]
90
90
 
91
+ @available = nil
91
92
  @installed_gems = []
92
93
  @toplevel_specs = nil
93
94
 
@@ -100,6 +101,22 @@ class Gem::DependencyInstaller
100
101
 
101
102
  attr_reader :errors
102
103
 
104
+ ##
105
+ # Creates an AvailableSet to install from based on +dep_or_name+ and
106
+ # +version+
107
+
108
+ def available_set_for dep_or_name, version # :nodoc:
109
+ if String === dep_or_name then
110
+ find_spec_by_name_and_version dep_or_name, version, @prerelease
111
+ else
112
+ dep = dep_or_name.dup
113
+ dep.prerelease = @prerelease
114
+ @available = find_gems_with_sources dep
115
+ end
116
+
117
+ @available.pick_best!
118
+ end
119
+
103
120
  ##
104
121
  # Indicated, based on the requested domain, if local
105
122
  # gems should be considered.
@@ -302,13 +319,7 @@ class Gem::DependencyInstaller
302
319
  # separately.
303
320
 
304
321
  def install dep_or_name, version = Gem::Requirement.default
305
- if String === dep_or_name then
306
- find_spec_by_name_and_version dep_or_name, version, @prerelease
307
- else
308
- dep = dep_or_name.dup
309
- dep.prerelease = @prerelease
310
- @available = find_gems_with_sources(dep).pick_best!
311
- end
322
+ available_set_for dep_or_name, version
312
323
 
313
324
  @installed_gems = []
314
325
 
@@ -367,12 +378,9 @@ class Gem::DependencyInstaller
367
378
  # it's documentation. Ideally the hook adder could decide whether to be in
368
379
  # the background or not, and what to call it.
369
380
  in_background "Installing documentation" do
370
- start = Time.now
371
381
  Gem.done_installing_hooks.each do |hook|
372
382
  hook.call self, @installed_gems
373
383
  end
374
- finish = Time.now
375
- say "Done installing documentation for #{@installed_gems.map(&:name).join(', ')} (#{(finish-start).to_i} sec)."
376
384
  end unless Gem.done_installing_hooks.empty?
377
385
 
378
386
  @installed_gems
@@ -49,7 +49,7 @@ class Gem::DependencyList
49
49
  # Adds +gemspecs+ to the dependency list.
50
50
 
51
51
  def add(*gemspecs)
52
- @specs.push(*gemspecs)
52
+ @specs.concat gemspecs
53
53
  end
54
54
 
55
55
  def clear
@@ -69,6 +69,8 @@ module Gem
69
69
  # and dependencies.
70
70
  #
71
71
  class APISpecification
72
+ attr_reader :set # :nodoc:
73
+
72
74
  def initialize(set, api_data)
73
75
  @set = set
74
76
  @name = api_data[:name]
@@ -80,6 +82,14 @@ module Gem
80
82
 
81
83
  attr_reader :name, :version, :dependencies
82
84
 
85
+ def == other # :nodoc:
86
+ self.class === other and
87
+ @set == other.set and
88
+ @name == other.name and
89
+ @version == other.version and
90
+ @dependencies == other.dependencies
91
+ end
92
+
83
93
  def full_name
84
94
  "#{@name}-#{@version}"
85
95
  end
@@ -91,6 +101,7 @@ module Gem
91
101
  class APISet
92
102
  def initialize
93
103
  @data = Hash.new { |h,k| h[k] = [] }
104
+ @dep_uri = URI 'https://rubygems.org/api/v1/dependencies'
94
105
  end
95
106
 
96
107
  # Return data for all versions of the gem +name+.
@@ -100,8 +111,8 @@ module Gem
100
111
  return @data[name]
101
112
  end
102
113
 
103
- u = URI.parse "http://rubygems.org/api/v1/dependencies?gems=#{name}"
104
- str = Net::HTTP.get(u)
114
+ uri = @dep_uri + "?gems=#{name}"
115
+ str = Gem::RemoteFetcher.fetcher.fetch_path uri
105
116
 
106
117
  Marshal.load(str).each do |ver|
107
118
  @data[ver[:name]] << ver
@@ -134,8 +145,8 @@ module Gem
134
145
 
135
146
  return if needed.empty?
136
147
 
137
- u = URI.parse "http://rubygems.org/api/v1/dependencies?gems=#{needed.join ','}"
138
- str = Net::HTTP.get(u)
148
+ uri = @dep_uri + "?gems=#{needed.sort.join ','}"
149
+ str = Gem::RemoteFetcher.fetcher.fetch_path uri
139
150
 
140
151
  Marshal.load(str).each do |ver|
141
152
  @data[ver[:name]] << ver
@@ -395,6 +406,8 @@ module Gem
395
406
  source = Gem.sources.first
396
407
  end
397
408
 
409
+ Gem.ensure_gem_subdirectories path
410
+
398
411
  source.download full_spec, path
399
412
  end
400
413
 
@@ -16,13 +16,6 @@ class Gem::Ext::Builder
16
16
  raise Gem::InstallError, "Makefile not found:\n\n#{results.join "\n"}"
17
17
  end
18
18
 
19
- mf = Gem.read_binary 'Makefile'
20
- mf = mf.gsub(/^RUBYARCHDIR\s*=\s*\$[^$]*/, "RUBYARCHDIR = #{dest_path}")
21
- mf = mf.gsub(/^RUBYLIBDIR\s*=\s*\$[^$]*/, "RUBYLIBDIR = #{dest_path}")
22
- mf = mf.gsub(/\s*\S+\.time$/, "")
23
-
24
- File.open('Makefile', 'wb') {|f| f.print mf}
25
-
26
19
  # try to find make program from Ruby configure arguments first
27
20
  RbConfig::CONFIG['configure_args'] =~ /with-make-prog\=(\w+)/
28
21
  make_program = $1 || ENV['MAKE'] || ENV['make']
@@ -6,18 +6,53 @@
6
6
 
7
7
  require 'rubygems/ext/builder'
8
8
  require 'rubygems/command'
9
+ require 'fileutils'
10
+ require 'tempfile'
9
11
 
10
12
  class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
13
+ FileEntry = FileUtils::Entry_ # :nodoc:
11
14
 
12
15
  def self.build(extension, directory, dest_path, results, args=[])
13
- cmd = "#{Gem.ruby} #{File.basename extension}"
14
- cmd << " #{args.join ' '}" unless args.empty?
15
-
16
- run cmd, results
17
-
18
- make dest_path, results
19
-
20
- results
16
+ tmp_dest = Dir.mktmpdir(".gem.", ".") if File.identical?(dest_path, ".")
17
+
18
+ Tempfile.open %w"siteconf .rb", "." do |siteconf|
19
+ siteconf.puts "require 'rbconfig'"
20
+ siteconf.puts "dest_path = #{(tmp_dest || dest_path).dump}"
21
+ %w[sitearchdir sitelibdir].each do |dir|
22
+ siteconf.puts "RbConfig::MAKEFILE_CONFIG['#{dir}'] = dest_path"
23
+ siteconf.puts "RbConfig::CONFIG['#{dir}'] = dest_path"
24
+ end
25
+
26
+ siteconf.flush
27
+
28
+ rubyopt = ENV["RUBYOPT"]
29
+ destdir = ENV["DESTDIR"]
30
+
31
+ begin
32
+ ENV["RUBYOPT"] = ["-r#{siteconf.path}", rubyopt].compact.join(' ')
33
+ cmd = [Gem.ruby, File.basename(extension), *args].join ' '
34
+
35
+ run cmd, results
36
+
37
+ ENV["DESTDIR"] = nil
38
+
39
+ make dest_path, results
40
+
41
+ if tmp_dest
42
+ FileEntry.new(tmp_dest).traverse do |ent|
43
+ destent = ent.class.new(dest_path, ent.rel)
44
+ destent.exist? or File.rename(ent.path, destent.path)
45
+ end
46
+ end
47
+
48
+ results
49
+ ensure
50
+ ENV["RUBYOPT"] = rubyopt
51
+ ENV["DESTDIR"] = destdir
52
+ end
53
+ end
54
+ ensure
55
+ FileUtils.rm_rf tmp_dest if tmp_dest
21
56
  end
22
57
 
23
58
  end
@@ -132,7 +132,7 @@ class Gem::Installer
132
132
  def check_executable_overwrite filename # :nodoc:
133
133
  return if @force
134
134
 
135
- generated_bin = File.join @bin_dir, filename
135
+ generated_bin = File.join @bin_dir, formatted_program_filename(filename)
136
136
 
137
137
  return unless File.exist? generated_bin
138
138
 
@@ -681,7 +681,7 @@ TEXT
681
681
  say results.join("\n") if Gem.configuration.really_verbose
682
682
  end
683
683
  rescue
684
- extension_build_error(extension_dir, results.join("\n"))
684
+ extension_build_error(extension_dir, results.join("\n"), $@)
685
685
  end
686
686
  end
687
687
  end
@@ -689,7 +689,7 @@ TEXT
689
689
  ##
690
690
  # Logs the build +output+ in +build_dir+, then raises ExtensionBuildError.
691
691
 
692
- def extension_build_error(build_dir, output)
692
+ def extension_build_error(build_dir, output, backtrace = nil)
693
693
  gem_make_out = File.join build_dir, 'gem_make.out'
694
694
 
695
695
  open gem_make_out, 'wb' do |io| io.puts output end
@@ -703,7 +703,7 @@ Gem files will remain installed in #{gem_dir} for inspection.
703
703
  Results logged to #{gem_make_out}
704
704
  EOF
705
705
 
706
- raise ExtensionBuildError, message
706
+ raise ExtensionBuildError, message, backtrace
707
707
  end
708
708
 
709
709
  ##
@@ -388,7 +388,8 @@ EOM
388
388
  when 'metadata.gz' then
389
389
  args = [entry]
390
390
  args << { :external_encoding => Encoding::UTF_8 } if
391
- Object.const_defined? :Encoding
391
+ Object.const_defined?(:Encoding) &&
392
+ Zlib::GzipReader.method(:wrap).arity != 1
392
393
 
393
394
  Zlib::GzipReader.wrap(*args) do |gzio|
394
395
  @spec = Gem::Specification.from_yaml gzio.read
data/lib/rubygems/rdoc.rb CHANGED
@@ -37,6 +37,7 @@ end
37
37
  class Gem::RDoc # :nodoc: all
38
38
 
39
39
  include Gem::UserInteraction
40
+ extend Gem::UserInteraction
40
41
 
41
42
  @rdoc_version = nil
42
43
  @specs = []
@@ -70,7 +71,8 @@ class Gem::RDoc # :nodoc: all
70
71
  # +specs+
71
72
 
72
73
  def self.generation_hook installer, specs
73
- types = installer.document
74
+ start = Time.now
75
+ types = installer.document
74
76
 
75
77
  generate_rdoc = types.include? 'rdoc'
76
78
  generate_ri = types.include? 'ri'
@@ -78,6 +80,13 @@ class Gem::RDoc # :nodoc: all
78
80
  specs.each do |spec|
79
81
  new(spec, generate_rdoc, generate_ri).generate
80
82
  end
83
+
84
+ return unless generate_rdoc or generate_ri
85
+
86
+ duration = (Time.now - start).to_i
87
+ names = specs.map(&:name).join ', '
88
+
89
+ say "Done installing documentation for #{names} after #{duration} seconds"
81
90
  end
82
91
 
83
92
  ##
@@ -127,8 +127,6 @@ class Gem::RemoteFetcher
127
127
  # always replaced.
128
128
 
129
129
  def download(spec, source_uri, install_dir = Gem.dir)
130
- Gem.ensure_gem_subdirectories(install_dir) rescue nil
131
-
132
130
  cache_dir =
133
131
  if Dir.pwd == install_dir then # see fetch_command
134
132
  install_dir
@@ -403,7 +401,8 @@ class Gem::RemoteFetcher
403
401
  connection.start unless connection.started?
404
402
 
405
403
  connection
406
- rescue OpenSSL::SSL::SSLError, Errno::EHOSTDOWN => e
404
+ rescue defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : Errno::EHOSTDOWN,
405
+ Errno::EHOSTDOWN => e
407
406
  raise FetchError.new(e.message, uri)
408
407
  end
409
408
 
@@ -424,6 +423,12 @@ class Gem::RemoteFetcher
424
423
  add_rubygems_trusted_certs(store)
425
424
  end
426
425
  connection.cert_store = store
426
+ rescue LoadError => e
427
+ raise unless (e.respond_to?(:path) && e.path == 'openssl') ||
428
+ e.message =~ / -- openssl$/
429
+
430
+ raise Gem::Exception.new(
431
+ 'Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non-HTTPS sources')
427
432
  end
428
433
 
429
434
  def add_rubygems_trusted_certs(store)
@@ -5,9 +5,29 @@
5
5
  #++
6
6
 
7
7
  require 'rubygems/exceptions'
8
- require 'openssl'
9
8
  require 'fileutils'
10
9
 
10
+ begin
11
+ require 'openssl'
12
+ rescue LoadError => e
13
+ raise unless (e.respond_to?(:path) && e.path == 'openssl') ||
14
+ e.message =~ / -- openssl$/
15
+
16
+ module OpenSSL # :nodoc:
17
+ class Digest # :nodoc:
18
+ class SHA1 # :nodoc:
19
+ def name
20
+ 'SHA1'
21
+ end
22
+ end
23
+ end
24
+ module PKey # :nodoc:
25
+ class RSA # :nodoc:
26
+ end
27
+ end
28
+ end
29
+ end
30
+
11
31
  ##
12
32
  # = Signing gems
13
33
  #
@@ -20,6 +20,8 @@ class Gem::Security::Policy
20
20
  # options.
21
21
 
22
22
  def initialize name, policy = {}, opt = {}
23
+ require 'openssl'
24
+
23
25
  @name = name
24
26
 
25
27
  @opt = opt
@@ -141,4 +141,14 @@ class Gem::Source
141
141
  fetcher = Gem::RemoteFetcher.fetcher
142
142
  fetcher.download spec, @uri.to_s, dir
143
143
  end
144
+
145
+ ##
146
+ # Replaces the URI for this source with +uri+. Used for upgrading this
147
+ # source to HTTPS
148
+
149
+ def uri= uri # :nodoc:
150
+ @api_uri = nil
151
+ @uri = uri
152
+ end
153
+
144
154
  end
@@ -188,6 +188,8 @@ class Gem::SpecFetcher
188
188
  list = {}
189
189
 
190
190
  Gem.sources.each_source do |source|
191
+ source = upgrade_http_source source
192
+
191
193
  begin
192
194
  names = case type
193
195
  when :latest
@@ -225,5 +227,41 @@ class Gem::SpecFetcher
225
227
  cache[source.uri] ||= source.load_specs(type)
226
228
  end
227
229
  end
230
+
231
+ ##
232
+ # Attempts to upgrade +source+ to HTTPS if it is for http://rubygems.org
233
+
234
+ def upgrade_http_source source
235
+ uri = source.uri
236
+
237
+ return source unless uri.scheme.downcase == 'http' &&
238
+ uri.host.downcase == 'rubygems.org'
239
+
240
+ https_uri = uri.dup
241
+ https_uri.scheme = 'https'
242
+ https_uri += '/'
243
+
244
+ https_uri = URI https_uri.to_s # cast to URI::HTTPS
245
+
246
+ begin
247
+ Gem::RemoteFetcher.fetcher.fetch_path https_uri, nil, true
248
+ rescue Gem::RemoteFetcher::FetchError => e
249
+ raise unless e.message =~ / Not Allowed 405 /
250
+ end
251
+
252
+ say "Upgraded #{uri} to HTTPS"
253
+
254
+ https_uri += uri.request_uri
255
+
256
+ source.uri = URI https_uri.to_s # cast to URI::HTTPS
257
+
258
+ source
259
+ rescue Gem::RemoteFetcher::FetchError
260
+ say "Upgrading #{uri} to HTTPS failed, continuing" if
261
+ Gem.configuration.really_verbose
262
+
263
+ source
264
+ end
265
+
228
266
  end
229
267
 
@@ -17,7 +17,7 @@
17
17
  # s.authors = ["Ruby Coder"]
18
18
  # s.email = 'rubycoder@example.com'
19
19
  # s.files = ["lib/example.rb"]
20
- # s.homepage = 'http://rubygems.org/gems/example'
20
+ # s.homepage = 'https://rubygems.org/gems/example'
21
21
  # end
22
22
  #
23
23
  # Starting in RubyGems 1.9.0, a Specification can hold arbitrary