rubygems-update 2.1.0.rc.1 → 2.1.0.rc.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 (63) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/History.txt +11 -3
  5. data/Manifest.txt +1 -0
  6. data/Rakefile +22 -18
  7. data/lib/rubygems.rb +8 -10
  8. data/lib/rubygems/basic_specification.rb +112 -108
  9. data/lib/rubygems/commands/build_command.rb +19 -0
  10. data/lib/rubygems/commands/check_command.rb +7 -0
  11. data/lib/rubygems/commands/cleanup_command.rb +5 -5
  12. data/lib/rubygems/commands/contents_command.rb +8 -0
  13. data/lib/rubygems/commands/dependency_command.rb +11 -0
  14. data/lib/rubygems/commands/environment_command.rb +3 -0
  15. data/lib/rubygems/commands/fetch_command.rb +10 -0
  16. data/lib/rubygems/commands/list_command.rb +12 -1
  17. data/lib/rubygems/commands/mirror_command.rb +6 -0
  18. data/lib/rubygems/commands/outdated_command.rb +9 -0
  19. data/lib/rubygems/commands/owner_command.rb +9 -2
  20. data/lib/rubygems/commands/pristine_command.rb +12 -11
  21. data/lib/rubygems/commands/push_command.rb +8 -2
  22. data/lib/rubygems/commands/query_command.rb +9 -0
  23. data/lib/rubygems/commands/rdoc_command.rb +6 -2
  24. data/lib/rubygems/commands/search_command.rb +14 -1
  25. data/lib/rubygems/commands/sources_command.rb +47 -0
  26. data/lib/rubygems/commands/specification_command.rb +16 -0
  27. data/lib/rubygems/commands/stale_command.rb +10 -0
  28. data/lib/rubygems/commands/uninstall_command.rb +19 -6
  29. data/lib/rubygems/commands/unpack_command.rb +18 -0
  30. data/lib/rubygems/commands/update_command.rb +9 -0
  31. data/lib/rubygems/commands/which_command.rb +11 -0
  32. data/lib/rubygems/commands/yank_command.rb +16 -2
  33. data/lib/rubygems/core_ext/kernel_require.rb +4 -4
  34. data/lib/rubygems/defaults.rb +7 -0
  35. data/lib/rubygems/dependency_installer.rb +1 -4
  36. data/lib/rubygems/ext/builder.rb +118 -0
  37. data/lib/rubygems/installer.rb +7 -60
  38. data/lib/rubygems/package_task.rb +5 -2
  39. data/lib/rubygems/remote_fetcher.rb +1 -1
  40. data/lib/rubygems/security/policy.rb +5 -0
  41. data/lib/rubygems/security/signer.rb +19 -1
  42. data/lib/rubygems/source.rb +7 -3
  43. data/lib/rubygems/source/local.rb +5 -4
  44. data/lib/rubygems/source/specific_file.rb +28 -0
  45. data/lib/rubygems/specification.rb +55 -44
  46. data/lib/rubygems/stub_specification.rb +93 -92
  47. data/lib/rubygems/test_case.rb +10 -9
  48. data/test/rubygems/test_gem.rb +27 -0
  49. data/test/rubygems/test_gem_commands_install_command.rb +1 -0
  50. data/test/rubygems/test_gem_commands_uninstall_command.rb +17 -8
  51. data/test/rubygems/test_gem_ext_builder.rb +97 -2
  52. data/test/rubygems/test_gem_installer.rb +0 -89
  53. data/test/rubygems/test_gem_package.rb +6 -8
  54. data/test/rubygems/test_gem_package_task.rb +23 -2
  55. data/test/rubygems/test_gem_security_policy.rb +11 -0
  56. data/test/rubygems/test_gem_security_signer.rb +6 -0
  57. data/test/rubygems/test_gem_source.rb +23 -0
  58. data/test/rubygems/test_gem_source_installed.rb +28 -0
  59. data/test/rubygems/test_gem_source_local.rb +29 -6
  60. data/test/rubygems/test_gem_source_specific_file.rb +38 -0
  61. data/test/rubygems/test_gem_specification.rb +10 -2
  62. metadata +7 -5
  63. metadata.gz.sig +0 -0
@@ -52,6 +52,15 @@ class Gem::Commands::UpdateCommand < Gem::Command
52
52
  "--document --no-force --install-dir #{Gem.dir}"
53
53
  end
54
54
 
55
+ def description # :nodoc:
56
+ <<-EOF
57
+ The update command will update your gems to the latest version.
58
+
59
+ The update comamnd does not remove the previous version. Use the cleanup
60
+ command to remove old versions.
61
+ EOF
62
+ end
63
+
55
64
  def usage # :nodoc:
56
65
  "#{program_name} GEMNAME [GEMNAME ...]"
57
66
  end
@@ -23,6 +23,17 @@ class Gem::Commands::WhichCommand < Gem::Command
23
23
  "--no-gems-first --no-all"
24
24
  end
25
25
 
26
+ def description # :nodoc:
27
+ <<-EOF
28
+ The which command is like the shell which command and shows you where
29
+ the file you wish to require lives.
30
+
31
+ You can use the which command to help determine why you are requiring a
32
+ version you did not expect or to look at the content of a file you are
33
+ requiring to see why it does not behave as you expect.
34
+ EOF
35
+ end
36
+
26
37
  def execute
27
38
  found = false
28
39
 
@@ -9,7 +9,21 @@ class Gem::Commands::YankCommand < Gem::Command
9
9
  include Gem::GemcutterUtilities
10
10
 
11
11
  def description # :nodoc:
12
- 'Remove a specific gem version release from RubyGems.org'
12
+ <<-EOF
13
+ The yank command removes a gem you pushed to a server from the server's
14
+ index.
15
+
16
+ Note that if you push a gem to rubygems.org the yank command does not
17
+ prevent other people from downloading the gem via the download link.
18
+
19
+ Once you have pushed a gem several downloads will happen automatically
20
+ via the webhooks. If you accidentally pushed passwords or other sensitive
21
+ data you will need to change them immediately and yank your gem.
22
+
23
+ If you are yanking a gem due to intellectual property reasons contact
24
+ http://help.rubygems.org for permanant removal. Be sure to mention this
25
+ as the reason for the removal request.
26
+ EOF
13
27
  end
14
28
 
15
29
  def arguments # :nodoc:
@@ -21,7 +35,7 @@ class Gem::Commands::YankCommand < Gem::Command
21
35
  end
22
36
 
23
37
  def initialize
24
- super 'yank', description
38
+ super 'yank', 'Remove a pushed gem from the index'
25
39
 
26
40
  add_version_option("remove")
27
41
  add_platform_option("remove")
@@ -8,6 +8,8 @@ require 'monitor'
8
8
 
9
9
  module Kernel
10
10
 
11
+ RUBYGEMS_ACTIVATION_MONITOR = Monitor.new # :nodoc:
12
+
11
13
  if defined?(gem_original_require) then
12
14
  # Ruby ships with a custom_require, override its require
13
15
  remove_method :require
@@ -33,10 +35,8 @@ module Kernel
33
35
  # The normal <tt>require</tt> functionality of returning false if
34
36
  # that file has already been loaded is preserved.
35
37
 
36
- ACTIVATION_MONITOR = Monitor.new
37
-
38
38
  def require path
39
- ACTIVATION_MONITOR.enter
39
+ RUBYGEMS_ACTIVATION_MONITOR.enter
40
40
 
41
41
  spec = Gem.find_unresolved_default_spec(path)
42
42
  if spec
@@ -118,7 +118,7 @@ module Kernel
118
118
 
119
119
  raise load_error
120
120
  ensure
121
- ACTIVATION_MONITOR.exit
121
+ RUBYGEMS_ACTIVATION_MONITOR.exit
122
122
  end
123
123
 
124
124
  private :require
@@ -134,4 +134,11 @@ module Gem
134
134
  def self.default_cert_path
135
135
  File.join Gem.user_home, ".gem", "gem-public_cert.pem"
136
136
  end
137
+
138
+ ##
139
+ # Whether to expect full paths in default gems - true for non-MRI
140
+ # ruby implementations
141
+ def self.default_gems_use_full_paths?
142
+ ruby_engine != 'ruby'
143
+ end
137
144
  end
@@ -5,8 +5,7 @@ require 'rubygems/package'
5
5
  require 'rubygems/installer'
6
6
  require 'rubygems/spec_fetcher'
7
7
  require 'rubygems/user_interaction'
8
- require 'rubygems/source/local'
9
- require 'rubygems/source/specific_file'
8
+ require 'rubygems/source'
10
9
  require 'rubygems/available_set'
11
10
 
12
11
  ##
@@ -251,7 +250,6 @@ class Gem::DependencyInstaller
251
250
  def find_spec_by_name_and_version gem_name,
252
251
  version = Gem::Requirement.default,
253
252
  prerelease = false
254
-
255
253
  set = Gem::AvailableSet.new
256
254
 
257
255
  if consider_local?
@@ -269,7 +267,6 @@ class Gem::DependencyInstaller
269
267
 
270
268
  if set.empty?
271
269
  dep = Gem::Dependency.new gem_name, version
272
- # HACK Dependency objects should be immutable
273
270
  dep.prerelease = true if prerelease
274
271
 
275
272
  set = find_gems_with_sources(dep)
@@ -4,8 +4,23 @@
4
4
  # See LICENSE.txt for permissions.
5
5
  #++
6
6
 
7
+ require 'rubygems/user_interaction'
8
+ require 'thread'
9
+
7
10
  class Gem::Ext::Builder
8
11
 
12
+ include Gem::UserInteraction
13
+
14
+ ##
15
+ # The builder shells-out to run various commands after changing the
16
+ # directory. This means multiple installations cannot be allowed to build
17
+ # extensions in parallel as they may change each other's directories leading
18
+ # to broken extensions or failed installations.
19
+
20
+ CHDIR_MUTEX = Mutex.new # :nodoc:
21
+
22
+ attr_accessor :build_args # :nodoc:
23
+
9
24
  def self.class_name
10
25
  name =~ /Ext::(.*)Builder/
11
26
  $1.downcase
@@ -63,5 +78,108 @@ class Gem::Ext::Builder
63
78
  end
64
79
  end
65
80
 
81
+ ##
82
+ # Creates a new extension builder for +spec+ using the given +build_args+.
83
+ # The gem for +spec+ is unpacked in +gem_dir+.
84
+
85
+ def initialize spec, build_args
86
+ @spec = spec
87
+ @build_args = build_args
88
+ @gem_dir = spec.gem_dir
89
+
90
+ @ran_rake = nil
91
+ end
92
+
93
+ ##
94
+ # Chooses the extension builder class for +extension+
95
+
96
+ def builder_for extension # :nodoc:
97
+ case extension
98
+ when /extconf/ then
99
+ Gem::Ext::ExtConfBuilder
100
+ when /configure/ then
101
+ Gem::Ext::ConfigureBuilder
102
+ when /rakefile/i, /mkrf_conf/i then
103
+ @ran_rake = true
104
+ Gem::Ext::RakeBuilder
105
+ when /CMakeLists.txt/ then
106
+ Gem::Ext::CmakeBuilder
107
+ else
108
+ extension_dir = File.join @gem_dir, File.dirname(extension)
109
+
110
+ message = "No builder for extension '#{extension}'"
111
+ build_error extension_dir, message
112
+ end
113
+ end
114
+
115
+ ##
116
+ # Logs the build +output+ in +build_dir+, then raises ExtensionBuildError.
117
+
118
+ def build_error build_dir, output, backtrace = nil # :nodoc:
119
+ gem_make_out = File.join build_dir, 'gem_make.out'
120
+
121
+ open gem_make_out, 'wb' do |io| io.puts output end
122
+
123
+ message = <<-EOF
124
+ ERROR: Failed to build gem native extension.
125
+
126
+ #{output}
127
+
128
+ Gem files will remain installed in #{@gem_dir} for inspection.
129
+ Results logged to #{gem_make_out}
130
+ EOF
131
+
132
+ raise Gem::Installer::ExtensionBuildError, message, backtrace
133
+ end
134
+
135
+ def build_extension extension, dest_path # :nodoc:
136
+ results = []
137
+
138
+ extension ||= '' # I wish I knew why this line existed
139
+ extension_dir = File.join @gem_dir, File.dirname(extension)
140
+
141
+ builder = builder_for extension
142
+
143
+ begin
144
+ FileUtils.mkdir_p dest_path
145
+
146
+ CHDIR_MUTEX.synchronize do
147
+ Dir.chdir extension_dir do
148
+ results = builder.build(extension, @gem_dir, dest_path,
149
+ results, @build_args)
150
+
151
+ say results.join("\n") if Gem.configuration.really_verbose
152
+ end
153
+ end
154
+ rescue
155
+ build_error extension_dir, results.join("\n"), $@
156
+ end
157
+ end
158
+
159
+ ##
160
+ # Builds extensions. Valid types of extensions are extconf.rb files,
161
+ # configure scripts and rakefiles or mkrf_conf files.
162
+
163
+ def build_extensions
164
+ return if @spec.extensions.empty?
165
+
166
+ if @build_args.empty?
167
+ say "Building native extensions. This could take a while..."
168
+ else
169
+ say "Building native extensions with: '#{@build_args.join ' '}'"
170
+ say "This could take a while..."
171
+ end
172
+
173
+ dest_path = File.join @gem_dir, @spec.require_paths.first
174
+
175
+ @ran_rake = false # only run rake once
176
+
177
+ @spec.extensions.each do |extension|
178
+ break if @ran_rake
179
+
180
+ build_extension extension, dest_path
181
+ end
182
+ end
183
+
66
184
  end
67
185
 
@@ -661,73 +661,20 @@ TEXT
661
661
  # configure scripts and rakefiles or mkrf_conf files.
662
662
 
663
663
  def build_extensions
664
- return if spec.extensions.empty?
664
+ builder = Gem::Ext::Builder.new spec, @build_args
665
665
 
666
- if @build_args.empty?
667
- say "Building native extensions. This could take a while..."
668
- else
669
- say "Building native extensions with: '#{@build_args.join(' ')}'"
670
- say "This could take a while..."
671
- end
672
-
673
- dest_path = File.join gem_dir, spec.require_paths.first
674
- ran_rake = false # only run rake once
675
-
676
- spec.extensions.each do |extension|
677
- break if ran_rake
678
- results = []
679
-
680
- extension ||= ""
681
- extension_dir = File.join gem_dir, File.dirname(extension)
682
-
683
- builder = case extension
684
- when /extconf/ then
685
- Gem::Ext::ExtConfBuilder
686
- when /configure/ then
687
- Gem::Ext::ConfigureBuilder
688
- when /rakefile/i, /mkrf_conf/i then
689
- ran_rake = true
690
- Gem::Ext::RakeBuilder
691
- when /CMakeLists.txt/ then
692
- Gem::Ext::CmakeBuilder
693
- else
694
- message = "No builder for extension '#{extension}'"
695
- extension_build_error extension_dir, message
696
- end
697
-
698
- begin
699
- FileUtils.mkdir_p dest_path
700
-
701
- Dir.chdir extension_dir do
702
- results = builder.build(extension, gem_dir, dest_path,
703
- results, @build_args)
704
-
705
- say results.join("\n") if Gem.configuration.really_verbose
706
- end
707
- rescue
708
- extension_build_error(extension_dir, results.join("\n"), $@)
709
- end
710
- end
666
+ builder.build_extensions
711
667
  end
712
668
 
713
669
  ##
714
670
  # Logs the build +output+ in +build_dir+, then raises ExtensionBuildError.
671
+ #
672
+ # TODO: Delete this for RubyGems 3. It remains for API compatibility
715
673
 
716
- def extension_build_error(build_dir, output, backtrace = nil)
717
- gem_make_out = File.join build_dir, 'gem_make.out'
718
-
719
- open gem_make_out, 'wb' do |io| io.puts output end
720
-
721
- message = <<-EOF
722
- ERROR: Failed to build gem native extension.
723
-
724
- #{output}
725
-
726
- Gem files will remain installed in #{gem_dir} for inspection.
727
- Results logged to #{gem_make_out}
728
- EOF
674
+ def extension_build_error(build_dir, output, backtrace = nil) # :nodoc:
675
+ builder = Gem::Ext::Builder.new spec, @build_args
729
676
 
730
- raise ExtensionBuildError, message, backtrace
677
+ builder.build_error build_dir, output, backtrace
731
678
  end
732
679
 
733
680
  ##
@@ -96,12 +96,15 @@ class Gem::PackageTask < Rake::PackageTask
96
96
  def define
97
97
  super
98
98
 
99
- task :package => [:gem]
100
-
101
99
  gem_file = File.basename gem_spec.cache_file
102
100
  gem_path = File.join package_dir, gem_file
103
101
  gem_dir = File.join package_dir, gem_spec.full_name
104
102
 
103
+ task :package => [:gem]
104
+
105
+ directory package_dir
106
+ directory gem_dir
107
+
105
108
  desc "Build the gem file #{gem_file}"
106
109
  task :gem => [gem_path]
107
110
 
@@ -325,7 +325,7 @@ class Gem::RemoteFetcher
325
325
 
326
326
  def request(uri, request_class, last_modified = nil)
327
327
  request = Gem::Request.new uri, request_class, last_modified, @proxy
328
-
328
+
329
329
  request.fetch do |req|
330
330
  yield req if block_given?
331
331
  end
@@ -213,6 +213,9 @@ class Gem::Security::Policy
213
213
  if @only_signed then
214
214
  raise Gem::Security::Exception,
215
215
  "unsigned gems are not allowed by the #{name} policy"
216
+ elsif digests.empty? then
217
+ # lack of signatures is irrelevant if there is nothing to check
218
+ # against
216
219
  else
217
220
  alert_warning "#{full_name} is not signed"
218
221
  end
@@ -246,6 +249,8 @@ class Gem::Security::Policy
246
249
 
247
250
  if @only_trusted then
248
251
  check_trust chain, digester, trust_dir
252
+ elsif signatures.empty? and digests.empty? then
253
+ # trust is irrelevant if there's no signatures to verify
249
254
  else
250
255
  alert_warning "#{subject signer} is not trusted for #{full_name}"
251
256
  end
@@ -62,6 +62,22 @@ class Gem::Security::Signer
62
62
  end
63
63
  end
64
64
 
65
+ ##
66
+ # Extracts the full name of +cert+. If the certificate has a subjectAltName
67
+ # this value is preferred, otherwise the subject is used.
68
+
69
+ def extract_name cert # :nodoc:
70
+ subject_alt_name = cert.extensions.find { |e| 'subjectAltName' == e.oid }
71
+
72
+ if subject_alt_name then
73
+ /\Aemail:/ =~ subject_alt_name.value
74
+
75
+ $' || subject_alt_name.value
76
+ else
77
+ cert.subject
78
+ end
79
+ end
80
+
65
81
  ##
66
82
  # Loads any missing issuers in the cert chain from the trusted certificates.
67
83
  #
@@ -89,7 +105,9 @@ class Gem::Security::Signer
89
105
  re_sign_key
90
106
  end
91
107
 
92
- Gem::Security::SigningPolicy.verify @cert_chain, @key
108
+ full_name = extract_name @cert_chain.last
109
+
110
+ Gem::Security::SigningPolicy.verify @cert_chain, @key, {}, {}, full_name
93
111
 
94
112
  @key.sign @digest_algorithm.new, data
95
113
  end
@@ -26,15 +26,17 @@ class Gem::Source
26
26
 
27
27
  def <=>(other)
28
28
  case other
29
- when Gem::Source::Installed, Gem::Source::Local then
29
+ when Gem::Source::Installed,
30
+ Gem::Source::Local,
31
+ Gem::Source::SpecificFile then
30
32
  -1
31
33
  when Gem::Source then
32
34
  if !@uri
33
35
  return 0 unless other.uri
34
- return -1
36
+ return 1
35
37
  end
36
38
 
37
- return 1 if !other.uri
39
+ return -1 if !other.uri
38
40
 
39
41
  @uri.to_s <=> other.uri.to_s
40
42
  else
@@ -158,3 +160,5 @@ class Gem::Source
158
160
  end
159
161
 
160
162
  require 'rubygems/source/installed'
163
+ require 'rubygems/source/specific_file'
164
+ require 'rubygems/source/local'