rubygems-update 1.5.3 → 1.6.0

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 (79) hide show
  1. data.tar.gz.sig +2 -1
  2. data/History.txt +60 -9
  3. data/Manifest.txt +1 -1
  4. data/Rakefile +0 -2
  5. data/lib/rubygems.rb +142 -65
  6. data/lib/rubygems/commands/owner_command.rb +3 -2
  7. data/lib/rubygems/commands/pristine_command.rb +5 -3
  8. data/lib/rubygems/commands/push_command.rb +8 -4
  9. data/lib/rubygems/commands/setup_command.rb +1 -2
  10. data/lib/rubygems/commands/uninstall_command.rb +5 -0
  11. data/lib/rubygems/commands/unpack_command.rb +10 -16
  12. data/lib/rubygems/config_file.rb +12 -5
  13. data/lib/rubygems/custom_require.rb +27 -7
  14. data/lib/rubygems/dependency.rb +33 -8
  15. data/lib/rubygems/dependency_installer.rb +21 -6
  16. data/lib/rubygems/dependency_list.rb +35 -3
  17. data/lib/rubygems/doc_manager.rb +6 -4
  18. data/lib/rubygems/gem_path_searcher.rb +45 -1
  19. data/lib/rubygems/gemcutter_utilities.rb +33 -0
  20. data/lib/rubygems/indexer.rb +1 -0
  21. data/lib/rubygems/installer.rb +11 -7
  22. data/lib/rubygems/installer_test_case.rb +23 -15
  23. data/lib/rubygems/mock_gem_ui.rb +1 -1
  24. data/lib/rubygems/remote_fetcher.rb +29 -10
  25. data/lib/rubygems/requirement.rb +1 -1
  26. data/lib/rubygems/security.rb +1 -0
  27. data/lib/rubygems/source_index.rb +3 -2
  28. data/lib/rubygems/spec_fetcher.rb +3 -1
  29. data/lib/rubygems/specification.rb +54 -12
  30. data/lib/rubygems/test_case.rb +99 -28
  31. data/lib/rubygems/test_utilities.rb +11 -1
  32. data/lib/rubygems/uninstaller.rb +22 -11
  33. data/lib/rubygems/user_interaction.rb +50 -29
  34. data/lib/rubygems/validator.rb +1 -1
  35. data/test/rubygems/fix_openssl_warnings.rb +12 -0
  36. data/test/rubygems/plugin/load/rubygems_plugin.rb +3 -1
  37. data/test/rubygems/test_gem.rb +384 -38
  38. data/test/rubygems/test_gem_builder.rb +1 -1
  39. data/test/rubygems/test_gem_command_manager.rb +2 -2
  40. data/test/rubygems/test_gem_commands_build_command.rb +1 -1
  41. data/test/rubygems/test_gem_commands_cert_command.rb +2 -1
  42. data/test/rubygems/test_gem_commands_dependency_command.rb +6 -5
  43. data/test/rubygems/test_gem_commands_fetch_command.rb +4 -4
  44. data/test/rubygems/test_gem_commands_install_command.rb +21 -18
  45. data/test/rubygems/test_gem_commands_lock_command.rb +1 -1
  46. data/test/rubygems/test_gem_commands_outdated_command.rb +2 -5
  47. data/test/rubygems/test_gem_commands_owner_command.rb +42 -0
  48. data/test/rubygems/test_gem_commands_pristine_command.rb +28 -8
  49. data/test/rubygems/test_gem_commands_push_command.rb +31 -5
  50. data/test/rubygems/test_gem_commands_specification_command.rb +8 -8
  51. data/test/rubygems/test_gem_commands_stale_command.rb +4 -2
  52. data/test/rubygems/test_gem_commands_uninstall_command.rb +23 -4
  53. data/test/rubygems/test_gem_commands_unpack_command.rb +10 -8
  54. data/test/rubygems/test_gem_commands_update_command.rb +16 -13
  55. data/test/rubygems/test_gem_commands_which_command.rb +1 -1
  56. data/test/rubygems/test_gem_config_file.rb +14 -0
  57. data/test/rubygems/test_gem_dependency.rb +39 -0
  58. data/test/rubygems/test_gem_dependency_installer.rb +213 -92
  59. data/test/rubygems/test_gem_dependency_list.rb +37 -17
  60. data/test/rubygems/test_gem_doc_manager.rb +5 -4
  61. data/test/rubygems/test_gem_format.rb +2 -2
  62. data/test/rubygems/test_gem_gemcutter_utilities.rb +48 -0
  63. data/test/rubygems/test_gem_indexer.rb +11 -10
  64. data/test/rubygems/test_gem_install_update_options.rb +0 -2
  65. data/test/rubygems/test_gem_installer.rb +151 -78
  66. data/test/rubygems/test_gem_package_tar_output.rb +3 -0
  67. data/test/rubygems/test_gem_remote_fetcher.rb +23 -14
  68. data/test/rubygems/test_gem_requirement.rb +4 -0
  69. data/test/rubygems/test_gem_security.rb +1 -0
  70. data/test/rubygems/test_gem_source_index.rb +17 -16
  71. data/test/rubygems/test_gem_spec_fetcher.rb +6 -1
  72. data/test/rubygems/test_gem_specification.rb +81 -31
  73. data/test/rubygems/test_gem_stream_ui.rb +11 -1
  74. data/test/rubygems/test_gem_uninstaller.rb +70 -10
  75. data/test/rubygems/test_gem_validator.rb +1 -1
  76. data/test/rubygems/test_kernel.rb +1 -1
  77. metadata +7 -7
  78. metadata.gz.sig +0 -0
  79. data/ChangeLog +0 -5811
@@ -162,10 +162,10 @@ class Gem::DocManager
162
162
  def run_rdoc(*args)
163
163
  args << @spec.rdoc_options
164
164
  args << self.class.configured_args
165
- args << '--quiet'
166
165
  args << @spec.require_paths.clone
167
166
  args << @spec.extra_rdoc_files
168
167
  args << '--title' << "#{@spec.full_name} Documentation"
168
+ args << '--quiet'
169
169
  args = args.flatten.map do |arg| arg.to_s end
170
170
 
171
171
  if self.class.rdoc_version >= Gem::Version.new('2.4.0') then
@@ -176,6 +176,8 @@ class Gem::DocManager
176
176
  # HACK more
177
177
  end
178
178
 
179
+ debug_args = args.dup
180
+
179
181
  r = RDoc::RDoc.new
180
182
 
181
183
  old_pwd = Dir.pwd
@@ -193,10 +195,10 @@ class Gem::DocManager
193
195
  rescue Exception => ex
194
196
  alert_error "While generating documentation for #{@spec.full_name}"
195
197
  ui.errs.puts "... MESSAGE: #{ex}"
196
- ui.errs.puts "... RDOC args: #{args.join(' ')}"
198
+ ui.errs.puts "... RDOC args: #{debug_args.join(' ')}"
197
199
  ui.errs.puts "\t#{ex.backtrace.join "\n\t"}" if
198
- Gem.configuration.backtrace
199
- ui.errs.puts "(continuing with the rest of the installation)"
200
+ Gem.configuration.backtrace
201
+ terminate_interaction 1
200
202
  ensure
201
203
  Dir.chdir old_pwd
202
204
  end
@@ -10,6 +10,7 @@ class Gem::GemPathSearcher
10
10
  def initialize
11
11
  # We want a record of all the installed gemspecs, in the order we wish to
12
12
  # examine them.
13
+ # TODO: remove this stupid method
13
14
  @gemspecs = init_gemspecs
14
15
 
15
16
  # Map gem spec to glob of full require_path directories. Preparing this
@@ -42,7 +43,9 @@ class Gem::GemPathSearcher
42
43
  # only that there is a match.
43
44
 
44
45
  def find(glob)
46
+ # HACK violation of encapsulation
45
47
  @gemspecs.find do |spec|
48
+ # TODO: inverted responsibility
46
49
  matching_file? spec, glob
47
50
  end
48
51
  end
@@ -51,9 +54,39 @@ class Gem::GemPathSearcher
51
54
  # Works like #find, but finds all gemspecs matching +glob+.
52
55
 
53
56
  def find_all(glob)
57
+ # HACK violation of encapsulation
54
58
  @gemspecs.select do |spec|
59
+ # TODO: inverted responsibility
55
60
  matching_file? spec, glob
61
+ end || []
62
+ end
63
+
64
+ def find_in_unresolved(glob)
65
+ # HACK violation
66
+ specs = Gem.unresolved_deps.values.map { |dep|
67
+ Gem.source_index.search dep, true
68
+ }.flatten
69
+
70
+ specs.select do |spec|
71
+ # TODO: inverted responsibility
72
+ matching_file? spec, glob
73
+ end || []
74
+ end
75
+
76
+ def find_in_unresolved_tree glob
77
+ # HACK violation
78
+ # TODO: inverted responsibility
79
+ specs = Gem.unresolved_deps.values.map { |dep|
80
+ Gem.source_index.search dep, true
81
+ }.flatten
82
+
83
+ specs.reverse_each do |spec|
84
+ trails = matching_paths(spec, glob)
85
+ next if trails.empty?
86
+ return trails.map(&:reverse).sort.first.reverse
56
87
  end
88
+
89
+ []
57
90
  end
58
91
 
59
92
  ##
@@ -61,7 +94,18 @@ class Gem::GemPathSearcher
61
94
  # +spec+.
62
95
 
63
96
  def matching_file?(spec, path)
64
- !matching_files(spec, path).empty?
97
+ not matching_files(spec, path).empty?
98
+ end
99
+
100
+ def matching_paths(spec, path)
101
+ trails = []
102
+
103
+ spec.traverse do |from_spec, dep, to_spec, trail|
104
+ next unless to_spec.conflicts.empty?
105
+ trails << trail unless matching_files(to_spec, path).empty?
106
+ end
107
+
108
+ trails
65
109
  end
66
110
 
67
111
  ##
@@ -1,6 +1,28 @@
1
1
  require 'rubygems/remote_fetcher'
2
2
 
3
3
  module Gem::GemcutterUtilities
4
+ OptionParser.accept Symbol do |value|
5
+ value.to_sym
6
+ end
7
+
8
+ ##
9
+ # Add the --key option
10
+
11
+ def add_key_option
12
+ add_option('-k', '--key KEYNAME', Symbol,
13
+ 'Use the given API key',
14
+ 'from ~/.gem/credentials') do |value,options|
15
+ options[:key] = value
16
+ end
17
+ end
18
+
19
+ def api_key
20
+ if options[:key] then
21
+ verify_api_key options[:key]
22
+ else
23
+ Gem.configuration.rubygems_api_key
24
+ end
25
+ end
4
26
 
5
27
  def sign_in
6
28
  return if Gem.configuration.rubygems_api_key
@@ -27,6 +49,8 @@ module Gem::GemcutterUtilities
27
49
  host = ENV['RUBYGEMS_HOST'] if ENV['RUBYGEMS_HOST']
28
50
  uri = URI.parse "#{host}/#{path}"
29
51
 
52
+ say "Pushing gem to #{host}..."
53
+
30
54
  request_method = Net::HTTP.const_get method.to_s.capitalize
31
55
 
32
56
  Gem::RemoteFetcher.fetcher.request(uri, request_method, &block)
@@ -46,4 +70,13 @@ module Gem::GemcutterUtilities
46
70
  end
47
71
  end
48
72
 
73
+ def verify_api_key(key)
74
+ if Gem.configuration.api_keys.key? key then
75
+ Gem.configuration.api_keys[key]
76
+ else
77
+ alert_error "No such API key. You can add it with gem keys --add #{key}"
78
+ terminate_interaction 1
79
+ end
80
+ end
81
+
49
82
  end
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'rubygems/format'
3
+ require 'time'
3
4
 
4
5
  begin
5
6
  gem 'builder'
@@ -150,6 +150,9 @@ class Gem::Installer
150
150
 
151
151
  Gem.ensure_gem_subdirectories @gem_home
152
152
 
153
+ # Completely remove any previous gem files
154
+ FileUtils.rm_rf(@gem_dir) if File.exist?(@gem_dir)
155
+
153
156
  FileUtils.mkdir_p @gem_dir
154
157
 
155
158
  extract_files
@@ -173,10 +176,9 @@ class Gem::Installer
173
176
 
174
177
  write_require_paths_file_if_needed if Gem::QUICKLOADER_SUCKAGE
175
178
 
176
- # HACK remove? Isn't this done in multiple places?
177
- cached_gem = File.join @gem_home, "cache", @gem.split(/\//).pop
179
+ cached_gem = Gem.cache_gem(File.basename(@gem), @gem_home)
178
180
  unless File.exist? cached_gem then
179
- FileUtils.cp @gem, File.join(@gem_home, "cache")
181
+ FileUtils.cp @gem, Gem.cache_dir(@gem_home)
180
182
  end
181
183
 
182
184
  say @spec.post_install_message unless @spec.post_install_message.nil?
@@ -229,7 +231,7 @@ class Gem::Installer
229
231
  # specifications directory.
230
232
 
231
233
  def write_spec
232
- rubycode = @spec.to_ruby
234
+ rubycode = @spec.to_ruby_for_cache
233
235
 
234
236
  file_name = File.join @gem_home, 'specifications', @spec.spec_name
235
237
 
@@ -269,8 +271,10 @@ class Gem::Installer
269
271
  @spec.executables.each do |filename|
270
272
  filename.untaint
271
273
  bin_path = File.expand_path "#{@spec.bindir}/#{filename}", @gem_dir
272
- mode = File.stat(bin_path).mode | 0111
273
- File.chmod mode, bin_path
274
+ if File.exist?(bin_path)
275
+ mode = File.stat(bin_path).mode | 0111
276
+ File.chmod mode, bin_path
277
+ end
274
278
 
275
279
  if @wrappers then
276
280
  generate_bin_script filename, bindir
@@ -292,7 +296,7 @@ class Gem::Installer
292
296
 
293
297
  FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
294
298
 
295
- File.open bin_script_path, 'w', 0755 do |file|
299
+ File.open bin_script_path, 'wb', 0755 do |file|
296
300
  file.print app_script_text(filename)
297
301
  end
298
302
 
@@ -58,12 +58,15 @@ class Gem::InstallerTestCase < Gem::TestCase
58
58
  super
59
59
 
60
60
  @spec = quick_gem 'a'
61
+ util_make_exec @spec
61
62
 
62
63
  @gem = File.join @tempdir, @spec.file_name
63
64
 
64
65
  @installer = util_installer @spec, @gem, @gemhome
65
66
 
66
67
  @user_spec = quick_gem 'b'
68
+ util_make_exec @user_spec
69
+
67
70
  @user_gem = File.join @tempdir, @user_spec.file_name
68
71
 
69
72
  @user_installer = util_installer @user_spec, @user_gem, Gem.user_dir
@@ -71,31 +74,38 @@ class Gem::InstallerTestCase < Gem::TestCase
71
74
  @user_spec.full_name)
72
75
  end
73
76
 
74
- def util_gem_bindir(version = '2')
75
- File.join util_gem_dir(version), "bin"
77
+ def util_gem_bindir spec = @spec
78
+ File.join util_gem_dir(spec), "bin"
76
79
  end
77
80
 
78
- def util_gem_dir(version = '2')
79
- File.join @gemhome, "gems", "a-#{version}" # HACK
81
+ def util_gem_dir spec = @spec
82
+ File.join @gemhome, "gems", spec.full_name
80
83
  end
81
84
 
82
85
  def util_inst_bindir
83
86
  File.join @gemhome, "bin"
84
87
  end
85
88
 
86
- def util_make_exec(version = '2', shebang = "#!/usr/bin/ruby")
87
- @spec.executables = ["my_exec"]
89
+ def util_make_exec(spec = @spec, shebang = "#!/usr/bin/ruby")
90
+ spec.executables = %w[executable]
91
+ spec.files << 'bin/executable'
92
+
93
+ bindir = util_gem_bindir spec
94
+ FileUtils.mkdir_p bindir
95
+ exec_path = File.join bindir, 'executable'
96
+ open exec_path, 'w' do |io|
97
+ io.puts shebang
98
+ end
88
99
 
89
- FileUtils.mkdir_p util_gem_bindir(version)
90
- exec_path = File.join util_gem_bindir(version), "my_exec"
91
- File.open exec_path, 'w' do |f|
92
- f.puts shebang
100
+ temp_bin = File.join(@tempdir, 'bin')
101
+ FileUtils.mkdir_p temp_bin
102
+ open File.join(temp_bin, 'executable'), 'w' do |io|
103
+ io.puts shebang
93
104
  end
94
105
  end
95
106
 
96
107
  def util_setup_gem(ui = @ui) # HACK fix use_ui to make this automatic
97
- @spec.files = File.join('lib', 'code.rb')
98
- @spec.executables << 'executable'
108
+ @spec.files << File.join('lib', 'code.rb')
99
109
  @spec.extensions << File.join('ext', 'a', 'mkrf_conf.rb')
100
110
 
101
111
  Dir.chdir @tempdir do
@@ -121,9 +131,7 @@ class Gem::InstallerTestCase < Gem::TestCase
121
131
 
122
132
  def util_installer(spec, gem_path, gem_home)
123
133
  util_build_gem spec
124
- FileUtils.mv File.join(@gemhome, 'cache', spec.file_name),
125
- @tempdir
126
-
134
+ FileUtils.mv Gem.cache_gem(spec.file_name), @tempdir
127
135
  installer = Gem::Installer.new gem_path
128
136
  installer.gem_dir = util_gem_dir
129
137
  installer.gem_home = gem_home
@@ -31,7 +31,7 @@ class Gem::MockGemUi < Gem::StreamUI
31
31
  outs.extend TTY
32
32
  errs.extend TTY
33
33
 
34
- super ins, outs, errs
34
+ super ins, outs, errs, true
35
35
 
36
36
  @terminated = false
37
37
  end
@@ -71,6 +71,23 @@ class Gem::RemoteFetcher
71
71
  end
72
72
  end
73
73
 
74
+ ##
75
+ # Given a name and requirement, downloads this gem into cache and returns the
76
+ # filename. Returns nil if the gem cannot be located.
77
+ #--
78
+ # Should probably be integrated with #download below, but that will be a
79
+ # larger, more emcompassing effort. -erikh
80
+
81
+ def download_to_cache dependency
82
+ found = Gem::SpecFetcher.fetcher.fetch dependency
83
+
84
+ return if found.empty?
85
+
86
+ spec, source_uri = found.first
87
+
88
+ download spec, source_uri
89
+ end
90
+
74
91
  ##
75
92
  # Moves the gem +spec+ from +source_uri+ to the cache dir unless it is
76
93
  # already there. If the source_uri is local the gem cache dir copy is
@@ -80,9 +97,9 @@ class Gem::RemoteFetcher
80
97
  Gem.ensure_gem_subdirectories(install_dir) rescue nil
81
98
 
82
99
  if File.writable?(install_dir)
83
- cache_dir = File.join install_dir, 'cache'
100
+ cache_dir = Gem.cache_dir(install_dir)
84
101
  else
85
- cache_dir = File.join(Gem.user_dir, 'cache')
102
+ cache_dir = Gem.cache_dir(Gem.user_dir)
86
103
  end
87
104
 
88
105
  gem_file_name = spec.file_name
@@ -134,7 +151,7 @@ class Gem::RemoteFetcher
134
151
  path = source_uri.path
135
152
  path = File.dirname(path) if File.extname(path) == '.gem'
136
153
 
137
- remote_gem_path = File.join(path, 'gems', gem_file_name)
154
+ remote_gem_path = correct_for_windows_path(File.join(path, 'gems', gem_file_name))
138
155
 
139
156
  FileUtils.cp(remote_gem_path, local_gem_path)
140
157
  rescue Errno::EACCES
@@ -270,6 +287,14 @@ class Gem::RemoteFetcher
270
287
  raise FetchError.new(e.message, uri)
271
288
  end
272
289
 
290
+ def correct_for_windows_path(path)
291
+ if path[0].chr == '/' && path[1].chr =~ /[a-z]/i && path[2].chr == ':'
292
+ path = path[1..-1]
293
+ else
294
+ path
295
+ end
296
+ end
297
+
273
298
  ##
274
299
  # Read the data from the (source based) URI, but if it is a file:// URI,
275
300
  # read from the filesystem instead.
@@ -287,13 +312,7 @@ class Gem::RemoteFetcher
287
312
  end
288
313
 
289
314
  if uri.scheme == 'file'
290
- path = uri.path
291
-
292
- # Deal with leading slash on Windows paths
293
- if path[0].chr == '/' && path[1].chr =~ /[a-zA-Z]/ && path[2].chr == ':'
294
- path = path[1..-1]
295
- end
296
-
315
+ path = correct_for_windows_path(uri.path)
297
316
  return Gem.read_binary(path)
298
317
  end
299
318
 
@@ -102,7 +102,7 @@ class Gem::Requirement
102
102
  end
103
103
 
104
104
  def as_list # :nodoc:
105
- requirements.map { |op, version| "#{op} #{version}" }
105
+ requirements.map { |op, version| "#{op} #{version}" }.sort
106
106
  end
107
107
 
108
108
  def hash # :nodoc:
@@ -6,6 +6,7 @@
6
6
 
7
7
  require 'rubygems/exceptions'
8
8
  require 'rubygems/gem_openssl'
9
+ require 'fileutils'
9
10
 
10
11
  #
11
12
  # = Signed Gems README
@@ -125,7 +125,7 @@ class Gem::SourceIndex
125
125
  # Returns an Array specifications for the latest released versions
126
126
  # of each gem in this index.
127
127
 
128
- def latest_specs
128
+ def latest_specs(include_prerelease=false)
129
129
  result = Hash.new { |h,k| h[k] = [] }
130
130
  latest = {}
131
131
 
@@ -134,7 +134,7 @@ class Gem::SourceIndex
134
134
  curr_ver = spec.version
135
135
  prev_ver = latest.key?(name) ? latest[name].version : nil
136
136
 
137
- next if curr_ver.prerelease?
137
+ next if !include_prerelease && curr_ver.prerelease?
138
138
  next unless prev_ver.nil? or curr_ver >= prev_ver or
139
139
  latest[name].platform != Gem::Platform::RUBY
140
140
 
@@ -267,6 +267,7 @@ class Gem::SourceIndex
267
267
  when Gem::Dependency then
268
268
  only_platform = platform_only
269
269
  requirement = gem_pattern.requirement
270
+
270
271
  gem_pattern = if Regexp === gem_pattern.name then
271
272
  gem_pattern.name
272
273
  elsif gem_pattern.name.empty? then
@@ -70,7 +70,8 @@ class Gem::SpecFetcher
70
70
  # Returns the local directory to write +uri+ to.
71
71
 
72
72
  def cache_dir(uri)
73
- File.join @dir, "#{uri.host}%#{uri.port}", File.dirname(uri.path)
73
+ escaped_path = uri.path.sub(%r[^/([a-z]):/]i, '/\\1-/') # Correct for windows paths
74
+ File.join @dir, "#{uri.host}%#{uri.port}", File.dirname(escaped_path)
74
75
  end
75
76
 
76
77
  ##
@@ -94,6 +95,7 @@ class Gem::SpecFetcher
94
95
  end
95
96
 
96
97
  def fetch_spec(spec, source_uri)
98
+ source_uri = URI.parse source_uri if String === source_uri
97
99
  spec = spec - [nil, 'ruby', '']
98
100
  spec_file_name = "#{spec.join '-'}.gemspec"
99
101
 
@@ -333,7 +333,8 @@ class Gem::Specification
333
333
  # List of dependencies that will automatically be activated at runtime.
334
334
 
335
335
  def runtime_dependencies
336
- dependencies.select { |d| d.type == :runtime || d.type == nil }
336
+ # TODO: fix #type to return :runtime if nil
337
+ dependencies.select { |d| d.type == :runtime }
337
338
  end
338
339
 
339
340
  ##
@@ -678,6 +679,14 @@ class Gem::Specification
678
679
 
679
680
  alias eql? == # :nodoc:
680
681
 
682
+ ##
683
+ # A macro to yield cached gem path
684
+ #
685
+ def cache_gem
686
+ cache_name = File.join(Gem.dir, 'cache', file_name)
687
+ return File.exist?(cache_name) ? cache_name : nil
688
+ end
689
+
681
690
  ##
682
691
  # True if this gem has the same attributes as +other+.
683
692
 
@@ -791,21 +800,17 @@ class Gem::Specification
791
800
 
792
801
  result << " if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then"
793
802
 
794
- unless dependencies.empty? then
795
- dependencies.each do |dep|
796
- version_reqs_param = dep.requirements_list.inspect
797
- dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK
798
- result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{version_reqs_param})"
799
- end
803
+ dependencies.each do |dep|
804
+ req = dep.requirements_list.inspect
805
+ dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK
806
+ result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{req})"
800
807
  end
801
808
 
802
809
  result << " else"
803
810
 
804
- unless dependencies.empty? then
805
- dependencies.each do |dep|
806
- version_reqs_param = dep.requirements_list.inspect
807
- result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
808
- end
811
+ dependencies.each do |dep|
812
+ version_reqs_param = dep.requirements_list.inspect
813
+ result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
809
814
  end
810
815
 
811
816
  result << ' end'
@@ -823,6 +828,15 @@ class Gem::Specification
823
828
  result.join "\n"
824
829
  end
825
830
 
831
+ def to_ruby_for_cache
832
+ s = dup
833
+ # remove large blobs that aren't used at runtime:
834
+ s.files = nil
835
+ s.extra_rdoc_files = nil
836
+ s.rdoc_options = nil
837
+ s.to_ruby
838
+ end
839
+
826
840
  ##
827
841
  # Checks that the specification contains all required fields, and does a
828
842
  # very basic sanity check.
@@ -1520,4 +1534,32 @@ class Gem::Specification
1520
1534
  @extensions,
1521
1535
  ].flatten.uniq.compact
1522
1536
  end
1537
+
1538
+ def conflicts
1539
+ conflicts = {}
1540
+ Gem.loaded_specs.values.each do |spec|
1541
+ bad = self.runtime_dependencies.find_all { |dep|
1542
+ spec.name == dep.name and not spec.satisfies_requirement? dep
1543
+ }
1544
+
1545
+ conflicts[spec] = bad unless bad.empty?
1546
+ end
1547
+ conflicts
1548
+ end
1549
+
1550
+ def traverse trail = [], &b
1551
+ trail = trail + [self]
1552
+ runtime_dependencies.each do |dep|
1553
+ dep_specs = Gem.source_index.search dep, true
1554
+ dep_specs.each do |dep_spec|
1555
+ b[self, dep, dep_spec, trail + [dep_spec]]
1556
+ dep_spec.traverse(trail, &b) unless
1557
+ trail.map(&:name).include? dep_spec.name
1558
+ end
1559
+ end
1560
+ end
1561
+
1562
+ def dependent_specs
1563
+ runtime_dependencies.map { |dep| Gem.source_index.search dep, true }.flatten
1564
+ end
1523
1565
  end