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.
- data.tar.gz.sig +2 -1
- data/History.txt +60 -9
- data/Manifest.txt +1 -1
- data/Rakefile +0 -2
- data/lib/rubygems.rb +142 -65
- data/lib/rubygems/commands/owner_command.rb +3 -2
- data/lib/rubygems/commands/pristine_command.rb +5 -3
- data/lib/rubygems/commands/push_command.rb +8 -4
- data/lib/rubygems/commands/setup_command.rb +1 -2
- data/lib/rubygems/commands/uninstall_command.rb +5 -0
- data/lib/rubygems/commands/unpack_command.rb +10 -16
- data/lib/rubygems/config_file.rb +12 -5
- data/lib/rubygems/custom_require.rb +27 -7
- data/lib/rubygems/dependency.rb +33 -8
- data/lib/rubygems/dependency_installer.rb +21 -6
- data/lib/rubygems/dependency_list.rb +35 -3
- data/lib/rubygems/doc_manager.rb +6 -4
- data/lib/rubygems/gem_path_searcher.rb +45 -1
- data/lib/rubygems/gemcutter_utilities.rb +33 -0
- data/lib/rubygems/indexer.rb +1 -0
- data/lib/rubygems/installer.rb +11 -7
- data/lib/rubygems/installer_test_case.rb +23 -15
- data/lib/rubygems/mock_gem_ui.rb +1 -1
- data/lib/rubygems/remote_fetcher.rb +29 -10
- data/lib/rubygems/requirement.rb +1 -1
- data/lib/rubygems/security.rb +1 -0
- data/lib/rubygems/source_index.rb +3 -2
- data/lib/rubygems/spec_fetcher.rb +3 -1
- data/lib/rubygems/specification.rb +54 -12
- data/lib/rubygems/test_case.rb +99 -28
- data/lib/rubygems/test_utilities.rb +11 -1
- data/lib/rubygems/uninstaller.rb +22 -11
- data/lib/rubygems/user_interaction.rb +50 -29
- data/lib/rubygems/validator.rb +1 -1
- data/test/rubygems/fix_openssl_warnings.rb +12 -0
- data/test/rubygems/plugin/load/rubygems_plugin.rb +3 -1
- data/test/rubygems/test_gem.rb +384 -38
- data/test/rubygems/test_gem_builder.rb +1 -1
- data/test/rubygems/test_gem_command_manager.rb +2 -2
- data/test/rubygems/test_gem_commands_build_command.rb +1 -1
- data/test/rubygems/test_gem_commands_cert_command.rb +2 -1
- data/test/rubygems/test_gem_commands_dependency_command.rb +6 -5
- data/test/rubygems/test_gem_commands_fetch_command.rb +4 -4
- data/test/rubygems/test_gem_commands_install_command.rb +21 -18
- data/test/rubygems/test_gem_commands_lock_command.rb +1 -1
- data/test/rubygems/test_gem_commands_outdated_command.rb +2 -5
- data/test/rubygems/test_gem_commands_owner_command.rb +42 -0
- data/test/rubygems/test_gem_commands_pristine_command.rb +28 -8
- data/test/rubygems/test_gem_commands_push_command.rb +31 -5
- data/test/rubygems/test_gem_commands_specification_command.rb +8 -8
- data/test/rubygems/test_gem_commands_stale_command.rb +4 -2
- data/test/rubygems/test_gem_commands_uninstall_command.rb +23 -4
- data/test/rubygems/test_gem_commands_unpack_command.rb +10 -8
- data/test/rubygems/test_gem_commands_update_command.rb +16 -13
- data/test/rubygems/test_gem_commands_which_command.rb +1 -1
- data/test/rubygems/test_gem_config_file.rb +14 -0
- data/test/rubygems/test_gem_dependency.rb +39 -0
- data/test/rubygems/test_gem_dependency_installer.rb +213 -92
- data/test/rubygems/test_gem_dependency_list.rb +37 -17
- data/test/rubygems/test_gem_doc_manager.rb +5 -4
- data/test/rubygems/test_gem_format.rb +2 -2
- data/test/rubygems/test_gem_gemcutter_utilities.rb +48 -0
- data/test/rubygems/test_gem_indexer.rb +11 -10
- data/test/rubygems/test_gem_install_update_options.rb +0 -2
- data/test/rubygems/test_gem_installer.rb +151 -78
- data/test/rubygems/test_gem_package_tar_output.rb +3 -0
- data/test/rubygems/test_gem_remote_fetcher.rb +23 -14
- data/test/rubygems/test_gem_requirement.rb +4 -0
- data/test/rubygems/test_gem_security.rb +1 -0
- data/test/rubygems/test_gem_source_index.rb +17 -16
- data/test/rubygems/test_gem_spec_fetcher.rb +6 -1
- data/test/rubygems/test_gem_specification.rb +81 -31
- data/test/rubygems/test_gem_stream_ui.rb +11 -1
- data/test/rubygems/test_gem_uninstaller.rb +70 -10
- data/test/rubygems/test_gem_validator.rb +1 -1
- data/test/rubygems/test_kernel.rb +1 -1
- metadata +7 -7
- metadata.gz.sig +0 -0
- data/ChangeLog +0 -5811
data/lib/rubygems/doc_manager.rb
CHANGED
@@ -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: #{
|
198
|
+
ui.errs.puts "... RDOC args: #{debug_args.join(' ')}"
|
197
199
|
ui.errs.puts "\t#{ex.backtrace.join "\n\t"}" if
|
198
|
-
|
199
|
-
|
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
|
-
|
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
|
data/lib/rubygems/indexer.rb
CHANGED
data/lib/rubygems/installer.rb
CHANGED
@@ -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
|
-
|
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,
|
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.
|
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
|
-
|
273
|
-
|
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, '
|
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
|
75
|
-
File.join util_gem_dir(
|
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
|
79
|
-
File.join @gemhome, "gems",
|
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(
|
87
|
-
|
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
|
-
|
90
|
-
|
91
|
-
File.
|
92
|
-
|
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
|
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
|
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
|
data/lib/rubygems/mock_gem_ui.rb
CHANGED
@@ -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 =
|
100
|
+
cache_dir = Gem.cache_dir(install_dir)
|
84
101
|
else
|
85
|
-
cache_dir =
|
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
|
|
data/lib/rubygems/requirement.rb
CHANGED
data/lib/rubygems/security.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
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
|
-
|
805
|
-
|
806
|
-
|
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
|