rubygems-update 2.0.0 → 2.0.2

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 (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