rubygems-update 2.1.11 → 2.2.0.rc.1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.autotest +37 -12
- data/History.txt +99 -2
- data/MIT.txt +1 -0
- data/Manifest.txt +59 -19
- data/Rakefile +4 -6
- data/lib/gauntlet_rubygems.rb +1 -1
- data/lib/rubygems.rb +102 -80
- data/lib/rubygems/available_set.rb +2 -2
- data/lib/rubygems/basic_specification.rb +97 -8
- data/lib/rubygems/commands/install_command.rb +58 -15
- data/lib/rubygems/commands/list_command.rb +1 -7
- data/lib/rubygems/commands/outdated_command.rb +1 -1
- data/lib/rubygems/commands/pristine_command.rb +14 -1
- data/lib/rubygems/commands/push_command.rb +9 -4
- data/lib/rubygems/commands/query_command.rb +33 -17
- data/lib/rubygems/commands/search_command.rb +0 -6
- data/lib/rubygems/commands/specification_command.rb +1 -1
- data/lib/rubygems/commands/unpack_command.rb +1 -1
- data/lib/rubygems/commands/update_command.rb +4 -1
- data/lib/rubygems/commands/which_command.rb +5 -8
- data/lib/rubygems/compatibility.rb +3 -0
- data/lib/rubygems/core_ext/kernel_gem.rb +6 -0
- data/lib/rubygems/defaults.rb +19 -0
- data/lib/rubygems/dependency_installer.rb +28 -9
- data/lib/rubygems/doctor.rb +17 -11
- data/lib/rubygems/errors.rb +16 -3
- data/lib/rubygems/exceptions.rb +52 -5
- data/lib/rubygems/ext.rb +1 -2
- data/lib/rubygems/ext/build_error.rb +6 -0
- data/lib/rubygems/ext/builder.rb +50 -17
- data/lib/rubygems/ext/cmake_builder.rb +1 -1
- data/lib/rubygems/ext/configure_builder.rb +1 -3
- data/lib/rubygems/ext/ext_conf_builder.rb +9 -3
- data/lib/rubygems/ext/rake_builder.rb +2 -5
- data/lib/rubygems/gemcutter_utilities.rb +8 -1
- data/lib/rubygems/installer.rb +14 -4
- data/lib/rubygems/installer_test_case.rb +0 -5
- data/lib/rubygems/package.rb +11 -2
- data/lib/rubygems/psych_additions.rb +1 -1
- data/lib/rubygems/rdoc.rb +1 -1
- data/lib/rubygems/remote_fetcher.rb +3 -3
- data/lib/rubygems/request.rb +16 -8
- data/lib/rubygems/request_set.rb +133 -42
- data/lib/rubygems/request_set/gem_dependency_api.rb +493 -11
- data/lib/rubygems/request_set/lockfile.rb +579 -0
- data/lib/rubygems/requirement.rb +58 -30
- data/lib/rubygems/resolver.rb +471 -0
- data/lib/rubygems/resolver/activation_request.rb +165 -0
- data/lib/rubygems/resolver/api_set.rb +110 -0
- data/lib/rubygems/resolver/api_specification.rb +79 -0
- data/lib/rubygems/resolver/best_set.rb +31 -0
- data/lib/rubygems/resolver/composed_set.rb +39 -0
- data/lib/rubygems/resolver/conflict.rb +122 -0
- data/lib/rubygems/{dependency_resolver → resolver}/current_set.rb +1 -4
- data/lib/rubygems/{dependency_resolver → resolver}/dependency_request.rb +37 -7
- data/lib/rubygems/resolver/git_set.rb +119 -0
- data/lib/rubygems/resolver/git_specification.rb +35 -0
- data/lib/rubygems/resolver/index_set.rb +74 -0
- data/lib/rubygems/resolver/index_specification.rb +69 -0
- data/lib/rubygems/resolver/installed_specification.rb +40 -0
- data/lib/rubygems/{dependency_resolver → resolver}/installer_set.rb +18 -17
- data/lib/rubygems/resolver/local_specification.rb +16 -0
- data/lib/rubygems/resolver/lock_set.rb +78 -0
- data/lib/rubygems/resolver/lock_specification.rb +58 -0
- data/lib/rubygems/resolver/requirement_list.rb +81 -0
- data/lib/rubygems/resolver/set.rb +27 -0
- data/lib/rubygems/resolver/spec_specification.rb +58 -0
- data/lib/rubygems/resolver/specification.rb +89 -0
- data/lib/rubygems/resolver/stats.rb +44 -0
- data/lib/rubygems/resolver/vendor_set.rb +83 -0
- data/lib/rubygems/resolver/vendor_specification.rb +24 -0
- data/lib/rubygems/security/trust_dir.rb +16 -2
- data/lib/rubygems/source.rb +71 -18
- data/lib/rubygems/source/git.rb +218 -0
- data/lib/rubygems/source/installed.rb +8 -1
- data/lib/rubygems/source/local.rb +14 -8
- data/lib/rubygems/source/lock.rb +48 -0
- data/lib/rubygems/source/specific_file.rb +14 -3
- data/lib/rubygems/source/vendor.rb +27 -0
- data/lib/rubygems/source_list.rb +74 -12
- data/lib/rubygems/spec_fetcher.rb +36 -4
- data/lib/rubygems/specification.rb +214 -65
- data/lib/rubygems/stub_specification.rb +57 -1
- data/lib/rubygems/syck_hack.rb +3 -3
- data/lib/rubygems/test_case.rb +226 -59
- data/lib/rubygems/test_utilities.rb +198 -0
- data/lib/rubygems/uninstaller.rb +22 -10
- data/lib/rubygems/uri_formatter.rb +20 -0
- data/lib/rubygems/user_interaction.rb +193 -71
- data/lib/rubygems/util.rb +121 -0
- data/lib/rubygems/util/list.rb +4 -0
- data/lib/rubygems/util/stringio.rb +34 -0
- data/lib/rubygems/validator.rb +6 -2
- data/lib/rubygems/version.rb +4 -8
- data/test/rubygems/test_bundled_ca.rb +1 -1
- data/test/rubygems/test_gem.rb +137 -29
- data/test/rubygems/test_gem_available_set.rb +19 -0
- data/test/rubygems/test_gem_commands_build_command.rb +1 -1
- data/test/rubygems/test_gem_commands_cert_command.rb +2 -2
- data/test/rubygems/test_gem_commands_cleanup_command.rb +13 -13
- data/test/rubygems/test_gem_commands_dependency_command.rb +24 -34
- data/test/rubygems/test_gem_commands_fetch_command.rb +43 -48
- data/test/rubygems/test_gem_commands_install_command.rb +244 -279
- data/test/rubygems/test_gem_commands_list_command.rb +3 -3
- data/test/rubygems/test_gem_commands_outdated_command.rb +7 -12
- data/test/rubygems/test_gem_commands_pristine_command.rb +73 -27
- data/test/rubygems/test_gem_commands_push_command.rb +76 -8
- data/test/rubygems/test_gem_commands_query_command.rb +239 -49
- data/test/rubygems/test_gem_commands_sources_command.rb +10 -43
- data/test/rubygems/test_gem_commands_specification_command.rb +24 -47
- data/test/rubygems/test_gem_commands_stale_command.rb +2 -2
- data/test/rubygems/test_gem_commands_uninstall_command.rb +3 -3
- data/test/rubygems/test_gem_commands_unpack_command.rb +16 -30
- data/test/rubygems/test_gem_commands_update_command.rb +149 -134
- data/test/rubygems/test_gem_commands_which_command.rb +4 -2
- data/test/rubygems/test_gem_dependency_installer.rb +68 -0
- data/test/rubygems/test_gem_dependency_list.rb +17 -17
- data/test/rubygems/test_gem_dependency_resolution_error.rb +28 -0
- data/test/rubygems/test_gem_doctor.rb +1 -1
- data/test/rubygems/test_gem_ext_builder.rb +178 -8
- data/test/rubygems/test_gem_ext_cmake_builder.rb +1 -7
- data/test/rubygems/test_gem_ext_configure_builder.rb +8 -10
- data/test/rubygems/test_gem_ext_ext_conf_builder.rb +18 -21
- data/test/rubygems/test_gem_ext_rake_builder.rb +1 -3
- data/test/rubygems/test_gem_impossible_dependencies_error.rb +10 -6
- data/test/rubygems/test_gem_indexer.rb +6 -6
- data/test/rubygems/test_gem_installer.rb +29 -10
- data/test/rubygems/test_gem_local_remote_options.rb +1 -1
- data/test/rubygems/test_gem_package.rb +18 -0
- data/test/rubygems/test_gem_rdoc.rb +1 -1
- data/test/rubygems/test_gem_remote_fetcher.rb +1 -1
- data/test/rubygems/test_gem_request.rb +37 -10
- data/test/rubygems/test_gem_request_set.rb +271 -9
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +684 -0
- data/test/rubygems/test_gem_request_set_lockfile.rb +849 -0
- data/test/rubygems/test_gem_requirement.rb +21 -0
- data/test/rubygems/{test_gem_dependency_resolver.rb → test_gem_resolver.rb} +231 -70
- data/test/rubygems/test_gem_resolver_activation_request.rb +63 -0
- data/test/rubygems/test_gem_resolver_api_set.rb +167 -0
- data/test/rubygems/test_gem_resolver_api_specification.rb +104 -0
- data/test/rubygems/test_gem_resolver_best_set.rb +30 -0
- data/test/rubygems/test_gem_resolver_conflict.rb +75 -0
- data/test/rubygems/test_gem_resolver_dependency_request.rb +20 -0
- data/test/rubygems/test_gem_resolver_git_set.rb +148 -0
- data/test/rubygems/test_gem_resolver_git_specification.rb +100 -0
- data/test/rubygems/test_gem_resolver_index_set.rb +28 -0
- data/test/rubygems/test_gem_resolver_index_specification.rb +89 -0
- data/test/rubygems/test_gem_resolver_installed_specification.rb +49 -0
- data/test/rubygems/test_gem_resolver_installer_set.rb +22 -0
- data/test/rubygems/test_gem_resolver_local_specification.rb +45 -0
- data/test/rubygems/test_gem_resolver_lock_set.rb +57 -0
- data/test/rubygems/test_gem_resolver_lock_specification.rb +87 -0
- data/test/rubygems/test_gem_resolver_requirement_list.rb +20 -0
- data/test/rubygems/test_gem_resolver_specification.rb +32 -0
- data/test/rubygems/test_gem_resolver_vendor_set.rb +67 -0
- data/test/rubygems/test_gem_resolver_vendor_specification.rb +83 -0
- data/test/rubygems/test_gem_server.rb +4 -4
- data/test/rubygems/test_gem_source.rb +54 -64
- data/test/rubygems/test_gem_source_git.rb +231 -0
- data/test/rubygems/test_gem_source_list.rb +24 -0
- data/test/rubygems/test_gem_source_local.rb +1 -1
- data/test/rubygems/test_gem_source_lock.rb +114 -0
- data/test/rubygems/test_gem_source_vendor.rb +27 -0
- data/test/rubygems/test_gem_spec_fetcher.rb +116 -61
- data/test/rubygems/test_gem_specification.rb +526 -94
- data/test/rubygems/test_gem_stub_specification.rb +123 -10
- data/test/rubygems/test_gem_uninstaller.rb +28 -2
- data/test/rubygems/test_gem_util.rb +31 -0
- data/test/rubygems/test_gem_validator.rb +9 -0
- data/util/update_bundled_ca_certificates.rb +8 -1
- metadata +89 -29
- metadata.gz.sig +2 -4
- data/lib/rubygems/dependency_resolver.rb +0 -254
- data/lib/rubygems/dependency_resolver/activation_request.rb +0 -109
- data/lib/rubygems/dependency_resolver/api_set.rb +0 -65
- data/lib/rubygems/dependency_resolver/api_specification.rb +0 -39
- data/lib/rubygems/dependency_resolver/composed_set.rb +0 -18
- data/lib/rubygems/dependency_resolver/dependency_conflict.rb +0 -85
- data/lib/rubygems/dependency_resolver/index_set.rb +0 -64
- data/lib/rubygems/dependency_resolver/index_specification.rb +0 -60
- data/lib/rubygems/dependency_resolver/installed_specification.rb +0 -52
- data/test/rubygems/test_gem_dependency_resolver_api_specification.rb +0 -33
- data/test/rubygems/test_gem_dependency_resolver_dependency_conflict.rb +0 -36
- data/test/rubygems/test_gem_dependency_resolver_index_set.rb +0 -53
- data/test/rubygems/test_gem_dependency_resolver_index_specification.rb +0 -73
- data/test/rubygems/test_gem_dependency_resolver_installed_specification.rb +0 -19
- data/test/rubygems/test_gem_dependency_resolver_installer_set.rb +0 -28
@@ -101,6 +101,24 @@ class Gem::FakeFetcher
|
|
101
101
|
response
|
102
102
|
end
|
103
103
|
|
104
|
+
def pretty_print q # :nodoc:
|
105
|
+
q.group 2, '[FakeFetcher', ']' do
|
106
|
+
q.breakable
|
107
|
+
q.text 'URIs:'
|
108
|
+
|
109
|
+
q.breakable
|
110
|
+
q.pp @data.keys
|
111
|
+
|
112
|
+
unless @api_endpoints.empty? then
|
113
|
+
q.breakable
|
114
|
+
q.text 'API endpoints:'
|
115
|
+
|
116
|
+
q.breakable
|
117
|
+
q.pp @api_endpoints.keys
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
104
122
|
def fetch_size(path)
|
105
123
|
path = path.to_s
|
106
124
|
@paths << path
|
@@ -159,6 +177,179 @@ class Gem::RemoteFetcher
|
|
159
177
|
end
|
160
178
|
# :startdoc:
|
161
179
|
|
180
|
+
##
|
181
|
+
# The SpecFetcherSetup allows easy setup of a remote source in RubyGems tests:
|
182
|
+
#
|
183
|
+
# spec_fetcher do |f|
|
184
|
+
# f.gem 'a', 1
|
185
|
+
# f.spec 'a', 2
|
186
|
+
# f.gem 'b', 1' 'a' => '~> 1.0'
|
187
|
+
# f.clear
|
188
|
+
# end
|
189
|
+
#
|
190
|
+
# The above declaration creates two gems, a-1 and b-1, with a dependency from
|
191
|
+
# b to a. The declaration creates an additional spec a-2, but no gem for it
|
192
|
+
# (so it cannot be installed).
|
193
|
+
#
|
194
|
+
# After the gems are created they are removed from Gem.dir.
|
195
|
+
|
196
|
+
class Gem::TestCase::SpecFetcherSetup
|
197
|
+
|
198
|
+
##
|
199
|
+
# Executes a SpecFetcher setup block. Yields an instance then creates the
|
200
|
+
# gems and specifications defined in the instance.
|
201
|
+
|
202
|
+
def self.declare test, repository
|
203
|
+
setup = new test, repository
|
204
|
+
|
205
|
+
yield setup
|
206
|
+
|
207
|
+
setup.execute
|
208
|
+
end
|
209
|
+
|
210
|
+
def initialize test, repository # :nodoc:
|
211
|
+
@test = test
|
212
|
+
@repository = repository
|
213
|
+
|
214
|
+
@gems = {}
|
215
|
+
@installed = []
|
216
|
+
@operations = []
|
217
|
+
end
|
218
|
+
|
219
|
+
##
|
220
|
+
# Removes any created gems or specifications from Gem.dir (the default
|
221
|
+
# install location).
|
222
|
+
|
223
|
+
def clear
|
224
|
+
@operations << [:clear]
|
225
|
+
end
|
226
|
+
|
227
|
+
##
|
228
|
+
# Returns a Hash of created Specification full names and the corresponding
|
229
|
+
# Specification.
|
230
|
+
|
231
|
+
def created_specs
|
232
|
+
created = {}
|
233
|
+
|
234
|
+
@gems.keys.each do |spec|
|
235
|
+
created[spec.full_name] = spec
|
236
|
+
end
|
237
|
+
|
238
|
+
created
|
239
|
+
end
|
240
|
+
|
241
|
+
##
|
242
|
+
# Creates any defined gems or specifications
|
243
|
+
|
244
|
+
def execute # :nodoc:
|
245
|
+
execute_operations
|
246
|
+
|
247
|
+
setup_fetcher
|
248
|
+
|
249
|
+
created_specs
|
250
|
+
end
|
251
|
+
|
252
|
+
def execute_operations # :nodoc:
|
253
|
+
@operations.each do |operation, *arguments|
|
254
|
+
case operation
|
255
|
+
when :clear then
|
256
|
+
@test.util_clear_gems
|
257
|
+
@installed.clear
|
258
|
+
when :gem then
|
259
|
+
spec, gem = @test.util_gem(*arguments, &arguments.pop)
|
260
|
+
|
261
|
+
write_spec spec
|
262
|
+
|
263
|
+
@gems[spec] = gem
|
264
|
+
@installed << spec
|
265
|
+
when :spec then
|
266
|
+
spec = @test.util_spec(*arguments, &arguments.pop)
|
267
|
+
|
268
|
+
write_spec spec
|
269
|
+
|
270
|
+
@gems[spec] = nil
|
271
|
+
@installed << spec
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
##
|
277
|
+
# Creates a gem with +name+, +version+ and +deps+. The created gem can be
|
278
|
+
# downloaded and installed.
|
279
|
+
#
|
280
|
+
# The specification will be yielded before gem creation for customization,
|
281
|
+
# but only the block or the dependencies may be set, not both.
|
282
|
+
|
283
|
+
def gem name, version, dependencies = nil, &block
|
284
|
+
@operations << [:gem, name, version, dependencies, block]
|
285
|
+
end
|
286
|
+
|
287
|
+
##
|
288
|
+
# Creates a legacy platform spec with the name 'pl' and version 1
|
289
|
+
|
290
|
+
def legacy_platform
|
291
|
+
spec 'pl', 1 do |s|
|
292
|
+
s.platform = Gem::Platform.new 'i386-linux'
|
293
|
+
s.instance_variable_set :@original_platform, 'i386-linux'
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
def setup_fetcher # :nodoc:
|
298
|
+
require 'zlib'
|
299
|
+
require 'socket'
|
300
|
+
require 'rubygems/remote_fetcher'
|
301
|
+
|
302
|
+
unless @test.fetcher then
|
303
|
+
@test.fetcher = Gem::FakeFetcher.new
|
304
|
+
Gem::RemoteFetcher.fetcher = @test.fetcher
|
305
|
+
end
|
306
|
+
|
307
|
+
Gem::Specification.reset
|
308
|
+
|
309
|
+
begin
|
310
|
+
gem_repo, @test.gem_repo = @test.gem_repo, @repository
|
311
|
+
@test.uri = URI @repository
|
312
|
+
|
313
|
+
@test.util_setup_spec_fetcher(*@gems.keys)
|
314
|
+
ensure
|
315
|
+
@test.gem_repo = gem_repo
|
316
|
+
@test.uri = URI gem_repo
|
317
|
+
end
|
318
|
+
|
319
|
+
# This works around util_setup_spec_fetcher adding all created gems to the
|
320
|
+
# installed set.
|
321
|
+
Gem::Specification.reset
|
322
|
+
Gem::Specification.add_specs(*@installed)
|
323
|
+
|
324
|
+
@gems.each do |spec, gem|
|
325
|
+
next unless gem
|
326
|
+
|
327
|
+
@test.fetcher.data["#{@repository}gems/#{spec.file_name}"] =
|
328
|
+
Gem.read_binary(gem)
|
329
|
+
|
330
|
+
FileUtils.cp gem, spec.cache_file
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
##
|
335
|
+
# Creates a spec with +name+, +version+ and +deps+. The created gem can be
|
336
|
+
# downloaded and installed.
|
337
|
+
#
|
338
|
+
# The specification will be yielded before creation for customization,
|
339
|
+
# but only the block or the dependencies may be set, not both.
|
340
|
+
|
341
|
+
def spec name, version, dependencies = nil, &block
|
342
|
+
@operations << [:spec, name, version, dependencies, block]
|
343
|
+
end
|
344
|
+
|
345
|
+
def write_spec spec # :nodoc:
|
346
|
+
open spec.spec_file, 'w' do |io|
|
347
|
+
io.write spec.to_ruby_for_cache
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
end
|
352
|
+
|
162
353
|
##
|
163
354
|
# A StringIO duck-typed class that uses Tempfile instead of String as the
|
164
355
|
# backing store.
|
@@ -168,6 +359,10 @@ end
|
|
168
359
|
# This class was added to flush out problems in Rubinius' IO implementation.
|
169
360
|
|
170
361
|
class TempIO < Tempfile
|
362
|
+
|
363
|
+
##
|
364
|
+
# Creates a new TempIO that will be initialized to contain +string+.
|
365
|
+
|
171
366
|
def initialize(string = '')
|
172
367
|
super "TempIO"
|
173
368
|
binmode
|
@@ -175,6 +370,9 @@ class TempIO < Tempfile
|
|
175
370
|
rewind
|
176
371
|
end
|
177
372
|
|
373
|
+
##
|
374
|
+
# The content of the TempIO as a String.
|
375
|
+
|
178
376
|
def string
|
179
377
|
flush
|
180
378
|
Gem.read_binary path
|
data/lib/rubygems/uninstaller.rb
CHANGED
@@ -247,13 +247,10 @@ class Gem::Uninstaller
|
|
247
247
|
File.writable?(spec.base_dir)
|
248
248
|
|
249
249
|
FileUtils.rm_rf spec.full_gem_path
|
250
|
+
FileUtils.rm_rf spec.extension_dir
|
250
251
|
|
251
|
-
|
252
|
-
|
253
|
-
spec.version,
|
254
|
-
spec.original_platform].join '-'
|
255
|
-
|
256
|
-
gemspec = spec.spec_file
|
252
|
+
old_platform_name = spec.original_name
|
253
|
+
gemspec = spec.spec_file
|
257
254
|
|
258
255
|
unless File.exist? gemspec then
|
259
256
|
gemspec = File.join(File.dirname(gemspec), "#{old_platform_name}.gemspec")
|
@@ -284,18 +281,30 @@ class Gem::Uninstaller
|
|
284
281
|
full_path == spec.full_gem_path || original_path == spec.full_gem_path
|
285
282
|
end
|
286
283
|
|
287
|
-
|
284
|
+
##
|
285
|
+
# Returns true if it is OK to remove +spec+ or this is a forced
|
286
|
+
# uninstallation.
|
287
|
+
|
288
|
+
def dependencies_ok? spec # :nodoc:
|
288
289
|
return true if @force_ignore
|
289
290
|
|
290
291
|
deplist = Gem::DependencyList.from_specs
|
291
292
|
deplist.ok_to_remove?(spec.full_name, @check_dev)
|
292
293
|
end
|
293
294
|
|
294
|
-
|
295
|
+
##
|
296
|
+
# Should the uninstallation abort if a dependency will go unsatisfied?
|
297
|
+
#
|
298
|
+
# See ::new.
|
299
|
+
|
300
|
+
def abort_on_dependent? # :nodoc:
|
295
301
|
@abort_on_dependent
|
296
302
|
end
|
297
303
|
|
298
|
-
|
304
|
+
##
|
305
|
+
# Asks if it is OK to remove +spec+. Returns true if it is OK.
|
306
|
+
|
307
|
+
def ask_if_ok spec # :nodoc:
|
299
308
|
msg = ['']
|
300
309
|
msg << 'You have requested to uninstall the gem:'
|
301
310
|
msg << "\t#{spec.full_name}"
|
@@ -316,7 +325,10 @@ class Gem::Uninstaller
|
|
316
325
|
return ask_yes_no(msg.join("\n"), false)
|
317
326
|
end
|
318
327
|
|
319
|
-
|
328
|
+
##
|
329
|
+
# Returns the formatted version of the executable +filename+
|
330
|
+
|
331
|
+
def formatted_program_filename filename # :nodoc:
|
320
332
|
# TODO perhaps the installer should leave a small manifest
|
321
333
|
# of what it did for us to find rather than trying to recreate
|
322
334
|
# it again.
|
@@ -1,13 +1,30 @@
|
|
1
1
|
require 'cgi'
|
2
2
|
require 'uri'
|
3
3
|
|
4
|
+
##
|
5
|
+
# The UriFormatter handles URIs from user-input and escaping.
|
6
|
+
#
|
7
|
+
# uf = Gem::UriFormatter.new 'example.com'
|
8
|
+
#
|
9
|
+
# p uf.normalize #=> 'http://example.com'
|
10
|
+
|
4
11
|
class Gem::UriFormatter
|
12
|
+
|
13
|
+
##
|
14
|
+
# The URI to be formatted.
|
15
|
+
|
5
16
|
attr_reader :uri
|
6
17
|
|
18
|
+
##
|
19
|
+
# Creates a new URI formatter for +uri+.
|
20
|
+
|
7
21
|
def initialize uri
|
8
22
|
@uri = uri
|
9
23
|
end
|
10
24
|
|
25
|
+
##
|
26
|
+
# Escapes the #uri for use as a CGI parameter
|
27
|
+
|
11
28
|
def escape
|
12
29
|
return unless @uri
|
13
30
|
CGI.escape @uri
|
@@ -20,6 +37,9 @@ class Gem::UriFormatter
|
|
20
37
|
(@uri =~ /^(https?|ftp|file):/i) ? @uri : "http://#{@uri}"
|
21
38
|
end
|
22
39
|
|
40
|
+
##
|
41
|
+
# Unescapes the #uri which came from a CGI parameter
|
42
|
+
|
23
43
|
def unescape
|
24
44
|
return unless @uri
|
25
45
|
CGI.unescape @uri
|
@@ -4,6 +4,11 @@
|
|
4
4
|
# See LICENSE.txt for permissions.
|
5
5
|
#++
|
6
6
|
|
7
|
+
begin
|
8
|
+
require 'io/console'
|
9
|
+
rescue LoadError
|
10
|
+
end
|
11
|
+
|
7
12
|
##
|
8
13
|
# Module that defines the default UserInteraction. Any class including this
|
9
14
|
# module will have access to the +ui+ method that returns the default UI.
|
@@ -66,9 +71,13 @@ module Gem::DefaultUserInteraction
|
|
66
71
|
end
|
67
72
|
|
68
73
|
##
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
74
|
+
# UserInteraction allows RubyGems to interact with the user through standard
|
75
|
+
# methods that can be replaced with more-specific UI methods for different
|
76
|
+
# displays.
|
77
|
+
#
|
78
|
+
# Since UserInteraction dispatches to a concrete UI class you may need to
|
79
|
+
# reference other classes for specific behavior such as Gem::ConsoleUI or
|
80
|
+
# Gem::SilentUI.
|
72
81
|
#
|
73
82
|
# Example:
|
74
83
|
#
|
@@ -84,40 +93,69 @@ module Gem::UserInteraction
|
|
84
93
|
|
85
94
|
include Gem::DefaultUserInteraction
|
86
95
|
|
87
|
-
|
88
|
-
|
96
|
+
##
|
97
|
+
# Displays an alert +statement+. Asks a +question+ if given.
|
98
|
+
|
99
|
+
def alert statement, question = nil
|
100
|
+
ui.alert statement, question
|
89
101
|
end
|
90
102
|
|
91
|
-
|
92
|
-
|
103
|
+
##
|
104
|
+
# Displays an error +statement+ to the error output location. Asks a
|
105
|
+
# +question+ if given.
|
106
|
+
|
107
|
+
def alert_error statement, question = nil
|
108
|
+
ui.alert_error statement, question
|
93
109
|
end
|
94
110
|
|
95
|
-
|
96
|
-
|
111
|
+
##
|
112
|
+
# Displays a warning +statement+ to the warning output location. Asks a
|
113
|
+
# +question+ if given.
|
114
|
+
|
115
|
+
def alert_warning statement, question = nil
|
116
|
+
ui.alert_warning statement, question
|
97
117
|
end
|
98
118
|
|
99
|
-
|
100
|
-
|
119
|
+
##
|
120
|
+
# Asks a +question+ and returns the answer.
|
121
|
+
|
122
|
+
def ask question
|
123
|
+
ui.ask question
|
101
124
|
end
|
102
125
|
|
103
|
-
|
104
|
-
|
126
|
+
##
|
127
|
+
# Asks for a password with a +prompt+
|
128
|
+
|
129
|
+
def ask_for_password prompt
|
130
|
+
ui.ask_for_password prompt
|
105
131
|
end
|
106
132
|
|
107
|
-
|
108
|
-
|
133
|
+
##
|
134
|
+
# Asks a yes or no +question+. Returns true for yes, false for no.
|
135
|
+
|
136
|
+
def ask_yes_no question, default = nil
|
137
|
+
ui.ask_yes_no question, default
|
109
138
|
end
|
110
139
|
|
111
|
-
|
112
|
-
|
140
|
+
##
|
141
|
+
# Asks the user to answer +question+ with an answer from the given +list+.
|
142
|
+
|
143
|
+
def choose_from_list question, list
|
144
|
+
ui.choose_from_list question, list
|
113
145
|
end
|
114
146
|
|
115
|
-
|
116
|
-
|
147
|
+
##
|
148
|
+
# Displays the given +statement+ on the standard output (or equivalent).
|
149
|
+
|
150
|
+
def say statement = ''
|
151
|
+
ui.say statement
|
117
152
|
end
|
118
153
|
|
119
|
-
|
120
|
-
|
154
|
+
##
|
155
|
+
# Terminates the RubyGems process with the given +exit_code+
|
156
|
+
|
157
|
+
def terminate_interaction exit_code = 0
|
158
|
+
ui.terminate_interaction exit_code
|
121
159
|
end
|
122
160
|
end
|
123
161
|
|
@@ -126,7 +164,26 @@ end
|
|
126
164
|
|
127
165
|
class Gem::StreamUI
|
128
166
|
|
129
|
-
|
167
|
+
##
|
168
|
+
# The input stream
|
169
|
+
|
170
|
+
attr_reader :ins
|
171
|
+
|
172
|
+
##
|
173
|
+
# The output stream
|
174
|
+
|
175
|
+
attr_reader :outs
|
176
|
+
|
177
|
+
##
|
178
|
+
# The error stream
|
179
|
+
|
180
|
+
attr_reader :errs
|
181
|
+
|
182
|
+
##
|
183
|
+
# Creates a new StreamUI wrapping +in_stream+ for user input, +out_stream+
|
184
|
+
# for standard output, +err_stream+ for error output. If +usetty+ is true
|
185
|
+
# then special operations (like asking for passwords) will use the TTY
|
186
|
+
# commands to disable character echo.
|
130
187
|
|
131
188
|
def initialize(in_stream, out_stream, err_stream=STDERR, usetty=true)
|
132
189
|
@ins = in_stream
|
@@ -135,6 +192,9 @@ class Gem::StreamUI
|
|
135
192
|
@usetty = usetty
|
136
193
|
end
|
137
194
|
|
195
|
+
##
|
196
|
+
# Returns true if TTY methods should be used on this StreamUI.
|
197
|
+
|
138
198
|
def tty?
|
139
199
|
if RUBY_VERSION < '1.9.3' and RUBY_PLATFORM =~ /mingw|mswin/ then
|
140
200
|
@usetty
|
@@ -228,41 +288,27 @@ class Gem::StreamUI
|
|
228
288
|
result
|
229
289
|
end
|
230
290
|
|
231
|
-
|
232
|
-
|
233
|
-
# Ask for a password. Does not echo response to terminal.
|
234
|
-
|
235
|
-
def ask_for_password(question)
|
236
|
-
return nil if not tty?
|
237
|
-
|
238
|
-
require 'io/console'
|
239
|
-
|
240
|
-
@outs.print(question + " ")
|
241
|
-
@outs.flush
|
291
|
+
##
|
292
|
+
# Ask for a password. Does not echo response to terminal.
|
242
293
|
|
243
|
-
|
244
|
-
|
245
|
-
password
|
246
|
-
end
|
247
|
-
else
|
248
|
-
##
|
249
|
-
# Ask for a password. Does not echo response to terminal.
|
294
|
+
def ask_for_password(question)
|
295
|
+
return nil if not tty?
|
250
296
|
|
251
|
-
|
252
|
-
|
297
|
+
@outs.print(question, " ")
|
298
|
+
@outs.flush
|
253
299
|
|
254
|
-
|
255
|
-
|
300
|
+
password = _gets_noecho
|
301
|
+
@outs.puts
|
302
|
+
password.chomp! if password
|
303
|
+
password
|
304
|
+
end
|
256
305
|
|
257
|
-
|
306
|
+
if IO.method_defined?(:noecho) then
|
307
|
+
def _gets_noecho
|
308
|
+
@ins.noecho {@ins.gets}
|
258
309
|
end
|
259
|
-
|
260
|
-
|
261
|
-
# Asks for a password that works on windows. Ripped from the Heroku gem.
|
262
|
-
|
263
|
-
def ask_for_password_on_windows
|
264
|
-
return nil if not tty?
|
265
|
-
|
310
|
+
elsif Gem.win_platform?
|
311
|
+
def _gets_noecho
|
266
312
|
require "Win32API"
|
267
313
|
char = nil
|
268
314
|
password = ''
|
@@ -275,22 +321,16 @@ class Gem::StreamUI
|
|
275
321
|
password << char.chr
|
276
322
|
end
|
277
323
|
end
|
278
|
-
|
279
|
-
puts
|
280
324
|
password
|
281
325
|
end
|
282
|
-
|
283
|
-
|
284
|
-
# Asks for a password that works on unix
|
285
|
-
|
286
|
-
def ask_for_password_on_unix
|
287
|
-
return nil if not tty?
|
288
|
-
|
326
|
+
else
|
327
|
+
def _gets_noecho
|
289
328
|
system "stty -echo"
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
329
|
+
begin
|
330
|
+
@ins.gets
|
331
|
+
ensure
|
332
|
+
system "stty echo"
|
333
|
+
end
|
294
334
|
end
|
295
335
|
end
|
296
336
|
|
@@ -310,8 +350,7 @@ class Gem::StreamUI
|
|
310
350
|
end
|
311
351
|
|
312
352
|
##
|
313
|
-
# Display a warning
|
314
|
-
# ask +question+ if it is not nil.
|
353
|
+
# Display a warning on stderr. Will ask +question+ if it is not nil.
|
315
354
|
|
316
355
|
def alert_warning(statement, question=nil)
|
317
356
|
@errs.puts "WARNING: #{statement}"
|
@@ -364,14 +403,29 @@ class Gem::StreamUI
|
|
364
403
|
# An absolutely silent progress reporter.
|
365
404
|
|
366
405
|
class SilentProgressReporter
|
406
|
+
|
407
|
+
##
|
408
|
+
# The count of items is never updated for the silent progress reporter.
|
409
|
+
|
367
410
|
attr_reader :count
|
368
411
|
|
412
|
+
##
|
413
|
+
# Creates a silent progress reporter that ignores all input arguments.
|
414
|
+
|
369
415
|
def initialize(out_stream, size, initial_message, terminal_message = nil)
|
370
416
|
end
|
371
417
|
|
418
|
+
##
|
419
|
+
# Does not print +message+ when updated as this object has taken a vow of
|
420
|
+
# silence.
|
421
|
+
|
372
422
|
def updated(message)
|
373
423
|
end
|
374
424
|
|
425
|
+
##
|
426
|
+
# Does not print anything when complete as this object has taken a vow of
|
427
|
+
# silence.
|
428
|
+
|
375
429
|
def done
|
376
430
|
end
|
377
431
|
end
|
@@ -383,8 +437,16 @@ class Gem::StreamUI
|
|
383
437
|
|
384
438
|
include Gem::DefaultUserInteraction
|
385
439
|
|
440
|
+
##
|
441
|
+
# The number of progress items counted so far.
|
442
|
+
|
386
443
|
attr_reader :count
|
387
444
|
|
445
|
+
##
|
446
|
+
# Creates a new progress reporter that will write to +out_stream+ for
|
447
|
+
# +size+ items. Shows the given +initial_message+ when progress starts
|
448
|
+
# and the +terminal_message+ when it is complete.
|
449
|
+
|
388
450
|
def initialize(out_stream, size, initial_message,
|
389
451
|
terminal_message = "complete")
|
390
452
|
@out = out_stream
|
@@ -420,8 +482,16 @@ class Gem::StreamUI
|
|
420
482
|
|
421
483
|
include Gem::DefaultUserInteraction
|
422
484
|
|
485
|
+
##
|
486
|
+
# The number of progress items counted so far.
|
487
|
+
|
423
488
|
attr_reader :count
|
424
489
|
|
490
|
+
##
|
491
|
+
# Creates a new progress reporter that will write to +out_stream+ for
|
492
|
+
# +size+ items. Shows the given +initial_message+ when progress starts
|
493
|
+
# and the +terminal_message+ when it is complete.
|
494
|
+
|
425
495
|
def initialize(out_stream, size, initial_message,
|
426
496
|
terminal_message = 'complete')
|
427
497
|
@out = out_stream
|
@@ -468,15 +538,30 @@ class Gem::StreamUI
|
|
468
538
|
# An absolutely silent download reporter.
|
469
539
|
|
470
540
|
class SilentDownloadReporter
|
541
|
+
|
542
|
+
##
|
543
|
+
# The silent download reporter ignores all arguments
|
544
|
+
|
471
545
|
def initialize(out_stream, *args)
|
472
546
|
end
|
473
547
|
|
548
|
+
##
|
549
|
+
# The silent download reporter does not display +filename+ or care about
|
550
|
+
# +filesize+ because it is silent.
|
551
|
+
|
474
552
|
def fetch(filename, filesize)
|
475
553
|
end
|
476
554
|
|
555
|
+
##
|
556
|
+
# Nothing can update the silent download reporter.
|
557
|
+
|
477
558
|
def update(current)
|
478
559
|
end
|
479
560
|
|
561
|
+
##
|
562
|
+
# The silent download reporter won't tell you when the download is done.
|
563
|
+
# Because it is silent.
|
564
|
+
|
480
565
|
def done
|
481
566
|
end
|
482
567
|
end
|
@@ -485,13 +570,35 @@ class Gem::StreamUI
|
|
485
570
|
# A progress reporter that prints out messages about the current progress.
|
486
571
|
|
487
572
|
class VerboseDownloadReporter
|
488
|
-
|
573
|
+
|
574
|
+
##
|
575
|
+
# The current file name being displayed
|
576
|
+
|
577
|
+
attr_reader :file_name
|
578
|
+
|
579
|
+
##
|
580
|
+
# The total bytes in the file
|
581
|
+
|
582
|
+
attr_reader :total_bytes
|
583
|
+
|
584
|
+
##
|
585
|
+
# The current progress (0 to 100)
|
586
|
+
|
587
|
+
attr_reader :progress
|
588
|
+
|
589
|
+
##
|
590
|
+
# Creates a new verbose download reporter that will display on
|
591
|
+
# +out_stream+. The other arguments are ignored.
|
489
592
|
|
490
593
|
def initialize(out_stream, *args)
|
491
594
|
@out = out_stream
|
492
595
|
@progress = 0
|
493
596
|
end
|
494
597
|
|
598
|
+
##
|
599
|
+
# Tells the download reporter that the +file_name+ is being fetched and
|
600
|
+
# contains +total_bytes+.
|
601
|
+
|
495
602
|
def fetch(file_name, total_bytes)
|
496
603
|
@file_name = file_name
|
497
604
|
@total_bytes = total_bytes.to_i
|
@@ -500,6 +607,9 @@ class Gem::StreamUI
|
|
500
607
|
update_display(false)
|
501
608
|
end
|
502
609
|
|
610
|
+
##
|
611
|
+
# Updates the verbose download reporter for the given number of +bytes+.
|
612
|
+
|
503
613
|
def update(bytes)
|
504
614
|
new_progress = if @units == 'B' then
|
505
615
|
bytes
|
@@ -513,6 +623,9 @@ class Gem::StreamUI
|
|
513
623
|
update_display
|
514
624
|
end
|
515
625
|
|
626
|
+
##
|
627
|
+
# Indicates the download is complete.
|
628
|
+
|
516
629
|
def done
|
517
630
|
@progress = 100 if @units == '%'
|
518
631
|
update_display(true, true)
|
@@ -520,7 +633,7 @@ class Gem::StreamUI
|
|
520
633
|
|
521
634
|
private
|
522
635
|
|
523
|
-
def update_display(show_progress = true, new_line = false)
|
636
|
+
def update_display(show_progress = true, new_line = false) # :nodoc:
|
524
637
|
return unless @out.tty?
|
525
638
|
|
526
639
|
if show_progress then
|
@@ -538,6 +651,11 @@ end
|
|
538
651
|
# STDOUT, and STDERR.
|
539
652
|
|
540
653
|
class Gem::ConsoleUI < Gem::StreamUI
|
654
|
+
|
655
|
+
##
|
656
|
+
# The Console UI has no arguments as it defaults to reading input from
|
657
|
+
# stdin, output to stdout and warnings or errors to stderr.
|
658
|
+
|
541
659
|
def initialize
|
542
660
|
super STDIN, STDOUT, STDERR, true
|
543
661
|
end
|
@@ -547,6 +665,10 @@ end
|
|
547
665
|
# SilentUI is a UI choice that is absolutely silent.
|
548
666
|
|
549
667
|
class Gem::SilentUI < Gem::StreamUI
|
668
|
+
|
669
|
+
##
|
670
|
+
# The SilentUI has no arguments as it does not use any stream.
|
671
|
+
|
550
672
|
def initialize
|
551
673
|
reader, writer = nil, nil
|
552
674
|
|
@@ -561,11 +683,11 @@ class Gem::SilentUI < Gem::StreamUI
|
|
561
683
|
super reader, writer, writer, false
|
562
684
|
end
|
563
685
|
|
564
|
-
def download_reporter(*args)
|
686
|
+
def download_reporter(*args) # :nodoc:
|
565
687
|
SilentDownloadReporter.new(@outs, *args)
|
566
688
|
end
|
567
689
|
|
568
|
-
def progress_reporter(*args)
|
690
|
+
def progress_reporter(*args) # :nodoc:
|
569
691
|
SilentProgressReporter.new(@outs, *args)
|
570
692
|
end
|
571
693
|
end
|