rubygems-update 0.9.4 → 0.9.5
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/ChangeLog +587 -0
- data/README +0 -1
- data/Rakefile +39 -12
- data/TODO +0 -5
- data/bin/gem +7 -7
- data/bin/update_rubygems +1 -1
- data/examples/application/an-app.gemspec +1 -1
- data/gemspecs/cgikit-1.1.0.gemspec +1 -2
- data/gemspecs/jabber4r.gemspec +1 -1
- data/gemspecs/linguistics.gemspec +1 -1
- data/gemspecs/ook.gemspec +1 -1
- data/gemspecs/progressbar.gemspec +1 -1
- data/gemspecs/redcloth.gemspec +1 -1
- data/gemspecs/rublog.gemspec +1 -1
- data/gemspecs/ruby-doom.gemspec +1 -1
- data/gemspecs/rubyjdwp.gemspec +1 -1
- data/gemspecs/statistics.gemspec +1 -1
- data/lib/rubygems.rb +167 -105
- data/lib/rubygems/builder.rb +12 -10
- data/lib/rubygems/command.rb +177 -60
- data/lib/rubygems/command_manager.rb +30 -38
- data/lib/rubygems/commands/build_command.rb +42 -46
- data/lib/rubygems/commands/cert_command.rb +72 -69
- data/lib/rubygems/commands/check_command.rb +63 -63
- data/lib/rubygems/commands/cleanup_command.rb +25 -7
- data/lib/rubygems/commands/contents_command.rb +70 -62
- data/lib/rubygems/commands/dependency_command.rb +131 -86
- data/lib/rubygems/commands/environment_command.rb +67 -46
- data/lib/rubygems/commands/fetch_command.rb +62 -0
- data/lib/rubygems/commands/generate_index_command.rb +57 -0
- data/lib/rubygems/commands/help_command.rb +163 -73
- data/lib/rubygems/commands/install_command.rb +114 -128
- data/lib/rubygems/commands/list_command.rb +10 -8
- data/lib/rubygems/commands/lock_command.rb +101 -0
- data/lib/rubygems/commands/mirror_command.rb +105 -0
- data/lib/rubygems/commands/outdated_command.rb +24 -15
- data/lib/rubygems/commands/pristine_command.rb +118 -88
- data/lib/rubygems/commands/query_command.rb +109 -77
- data/lib/rubygems/commands/rdoc_command.rb +13 -10
- data/lib/rubygems/commands/search_command.rb +10 -8
- data/lib/rubygems/commands/server_command.rb +48 -0
- data/lib/rubygems/commands/sources_command.rb +104 -83
- data/lib/rubygems/commands/specification_command.rb +65 -51
- data/lib/rubygems/commands/uninstall_command.rb +17 -12
- data/lib/rubygems/commands/unpack_command.rb +68 -68
- data/lib/rubygems/commands/update_command.rb +72 -25
- data/lib/rubygems/commands/which_command.rb +86 -0
- data/lib/rubygems/config_file.rb +202 -78
- data/lib/rubygems/custom_require.rb +7 -88
- data/lib/rubygems/dependency.rb +65 -0
- data/lib/rubygems/dependency_installer.rb +232 -0
- data/lib/rubygems/dependency_list.rb +133 -105
- data/lib/rubygems/digest/md5.rb +4 -1
- data/lib/rubygems/digest/sha2.rb +1 -1
- data/lib/rubygems/doc_manager.rb +41 -19
- data/lib/rubygems/exceptions.rb +63 -0
- data/lib/rubygems/ext.rb +18 -0
- data/lib/rubygems/ext/builder.rb +56 -0
- data/lib/rubygems/ext/configure_builder.rb +24 -0
- data/lib/rubygems/ext/ext_conf_builder.rb +23 -0
- data/lib/rubygems/ext/rake_builder.rb +27 -0
- data/lib/rubygems/format.rb +16 -6
- data/lib/rubygems/gem_openssl.rb +43 -6
- data/lib/rubygems/gem_path_searcher.rb +84 -0
- data/lib/rubygems/gem_runner.rb +20 -5
- data/lib/rubygems/indexer.rb +163 -0
- data/lib/rubygems/indexer/abstract_index_builder.rb +80 -0
- data/lib/rubygems/indexer/marshal_index_builder.rb +17 -0
- data/lib/rubygems/indexer/master_index_builder.rb +53 -0
- data/lib/rubygems/indexer/quick_index_builder.rb +48 -0
- data/lib/rubygems/install_update_options.rb +87 -0
- data/lib/rubygems/installer.rb +316 -562
- data/lib/rubygems/local_remote_options.rb +106 -0
- data/lib/rubygems/old_format.rb +5 -13
- data/lib/rubygems/open-uri.rb +2 -0
- data/lib/rubygems/package.rb +28 -32
- data/lib/rubygems/platform.rb +187 -0
- data/lib/rubygems/remote_fetcher.rb +46 -29
- data/lib/rubygems/remote_installer.rb +11 -18
- data/lib/rubygems/requirement.rb +157 -0
- data/lib/rubygems/rubygems_version.rb +1 -1
- data/lib/rubygems/security.rb +715 -457
- data/lib/rubygems/server.rb +77 -59
- data/lib/rubygems/source_index.rb +154 -83
- data/lib/rubygems/source_info_cache.rb +73 -30
- data/lib/rubygems/source_info_cache_entry.rb +12 -3
- data/lib/rubygems/specification.rb +378 -145
- data/lib/rubygems/uninstaller.rb +183 -0
- data/lib/rubygems/user_interaction.rb +38 -9
- data/lib/rubygems/validator.rb +53 -24
- data/lib/rubygems/version.rb +126 -289
- data/lib/rubygems/version_option.rb +49 -0
- data/pkgs/sources/lib/sources.rb +1 -4
- data/pkgs/sources/sources.gemspec +3 -3
- data/scripts/gemdoc.rb +0 -1
- data/setup.rb +166 -1505
- data/test/bogussources.rb +0 -1
- data/test/data/gem-private_key.pem +27 -0
- data/test/data/gem-public_cert.pem +20 -0
- data/test/functional.rb +3 -105
- data/test/gemutilities.rb +145 -24
- data/test/insure_session.rb +0 -1
- data/test/{test_datadir.rb → test_config.rb} +7 -13
- data/test/test_gem.rb +360 -9
- data/test/test_gem_builder.rb +34 -0
- data/test/{test_command.rb → test_gem_command.rb} +119 -62
- data/test/{test_parse_commands.rb → test_gem_command_manager.rb} +64 -40
- data/test/test_gem_commands_build_command.rb +75 -0
- data/test/test_gem_commands_cert_command.rb +122 -0
- data/test/test_gem_commands_check_command.rb +25 -0
- data/test/test_gem_commands_contents_command.rb +92 -0
- data/test/test_gem_commands_dependency_command.rb +108 -0
- data/test/test_gem_commands_environment_command.rb +117 -0
- data/test/test_gem_commands_fetch_command.rb +34 -0
- data/test/test_gem_commands_generate_index_command.rb +32 -0
- data/test/test_gem_commands_install_command.rb +160 -0
- data/test/test_gem_commands_mirror_command.rb +56 -0
- data/test/test_gem_commands_pristine_command.rb +100 -0
- data/test/test_gem_commands_query_command.rb +82 -0
- data/test/test_gem_commands_sources_command.rb +147 -0
- data/test/test_gem_commands_specification_command.rb +93 -0
- data/test/test_gem_commands_unpack_command.rb +55 -0
- data/test/test_gem_config_file.rb +210 -0
- data/test/test_gem_dependency.rb +89 -0
- data/test/test_gem_dependency_installer.rb +542 -0
- data/test/test_gem_dependency_list.rb +212 -0
- data/test/test_gem_doc_manager.rb +32 -0
- data/test/test_gem_ext_configure_builder.rb +13 -17
- data/test/test_gem_ext_ext_conf_builder.rb +9 -9
- data/test/test_gem_ext_rake_builder.rb +23 -11
- data/test/test_gem_format.rb +69 -0
- data/test/test_gem_gem_path_searcher.rb +57 -0
- data/test/test_gem_gem_runner.rb +35 -0
- data/test/test_gem_indexer.rb +119 -0
- data/test/test_gem_install_update_options.rb +40 -0
- data/test/test_gem_installer.rb +796 -0
- data/test/test_gem_local_remote_options.rb +84 -0
- data/test/test_gem_outdated_command.rb +11 -9
- data/test/test_gem_platform.rb +240 -0
- data/test/{test_remote_fetcher.rb → test_gem_remote_fetcher.rb} +124 -55
- data/test/{test_remote_installer.rb → test_gem_remote_installer.rb} +3 -4
- data/test/test_gem_requirement.rb +223 -0
- data/test/test_gem_server.rb +71 -0
- data/test/test_gem_source_index.rb +429 -0
- data/test/test_gem_source_info_cache.rb +79 -17
- data/test/test_gem_source_info_cache_entry.rb +11 -9
- data/test/test_gem_specification.rb +738 -0
- data/test/test_gem_stream_ui.rb +117 -0
- data/test/test_gem_validator.rb +70 -0
- data/test/test_gem_version.rb +191 -0
- data/test/test_gem_version_option.rb +77 -0
- data/test/{test_require_gem.rb → test_kernel.rb} +19 -12
- data/test/test_open_uri.rb +1 -2
- data/test/test_package.rb +45 -34
- metadata +116 -141
- data/Releases +0 -127
- data/bin/gem_mirror +0 -73
- data/bin/gem_server +0 -6
- data/bin/gemlock +0 -127
- data/bin/gemri +0 -24
- data/bin/gemwhich +0 -89
- data/bin/index_gem_repository.rb +0 -302
- data/lib/gemconfigure.rb +0 -24
- data/lib/rubygems/gem_commands.rb +0 -273
- data/pkgs/sources/sources-0.0.1.gem +0 -0
- data/post-install.rb +0 -121
- data/test/brokenbuildgem.rb +0 -35
- data/test/data/PostMessage-0.0.1.gem +0 -0
- data/test/data/a-0.0.1.gem +0 -0
- data/test/data/a-0.0.2.gem +0 -0
- data/test/data/b-0.0.2.gem +0 -0
- data/test/data/broken-1.0.0.gem +0 -0
- data/test/data/broken_build/broken-build.gemspec +0 -20
- data/test/data/broken_build/ext/extconf.rb +0 -3
- data/test/data/broken_build/ext/foo.c +0 -1
- data/test/data/c-1.2.gem +0 -0
- data/test/data/gemhome/cache/a-0.0.1.gem +0 -0
- data/test/data/gemhome/cache/a-0.0.2.gem +0 -0
- data/test/data/gemhome/cache/b-0.0.2.gem +0 -0
- data/test/data/gemhome/cache/c-1.2.gem +0 -0
- data/test/data/gemhome/gems/a-0.0.1/lib/code.rb +0 -1
- data/test/data/gemhome/gems/a-0.0.2/lib/code.rb +0 -1
- data/test/data/gemhome/gems/b-0.0.2/lib/code.rb +0 -1
- data/test/data/gemhome/gems/c-1.2/lib/code.rb +0 -1
- data/test/data/gemhome/specifications/a-0.0.1.gemspec +0 -8
- data/test/data/gemhome/specifications/a-0.0.2.gemspec +0 -8
- data/test/data/gemhome/specifications/b-0.0.2.gemspec +0 -8
- data/test/data/gemhome/specifications/c-1.2.gemspec +0 -8
- data/test/data/legacy/keyedlist-0.4.0.ruby +0 -11
- data/test/data/legacy/keyedlist-0.4.0.yaml +0 -16
- data/test/data/lib/code.rb +0 -1
- data/test/data/one/README.one +0 -1
- data/test/data/one/lib/one.rb +0 -9
- data/test/data/one/one-0.0.1.gem +0 -0
- data/test/data/one/one.gemspec +0 -17
- data/test/data/one/one.yaml +0 -40
- data/test/data/post_install.gemspec +0 -19
- data/test/functional_extension_gems.rb +0 -48
- data/test/functional_generate_yaml_index.rb +0 -104
- data/test/gemenvironment.rb +0 -59
- data/test/io_capture.rb +0 -33
- data/test/mock/gems/gems/sources-0.0.1/lib/sources.rb +0 -11
- data/test/mock/gems/specifications/sources-0.0.1.gemspec +0 -8
- data/test/onegem.rb +0 -35
- data/test/test_builder.rb +0 -34
- data/test/test_check_command.rb +0 -34
- data/test/test_configfile.rb +0 -42
- data/test/test_dependency_list.rb +0 -169
- data/test/test_file_list.rb +0 -101
- data/test/test_format.rb +0 -49
- data/test/test_gem_sources_command.rb +0 -135
- data/test/test_gemloadpaths.rb +0 -51
- data/test/test_gempaths.rb +0 -170
- data/test/test_installer.rb +0 -369
- data/test/test_loadmanager.rb +0 -48
- data/test/test_process_commands.rb +0 -52
- data/test/test_source_index.rb +0 -231
- data/test/test_specific_extras.rb +0 -46
- data/test/test_specification.rb +0 -565
- data/test/test_user_interaction.rb +0 -48
- data/test/test_validator.rb +0 -59
- data/test/test_version_comparison.rb +0 -321
- data/test/testgem.rc +0 -7
- data/test/user_capture.rb +0 -7
- data/test/yaml_data.rb +0 -63
data/lib/rubygems/server.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
Gem.manage_gems
|
3
1
|
require 'webrick'
|
4
|
-
require 'yaml'
|
5
|
-
require 'optparse'
|
6
2
|
require 'rdoc/template'
|
3
|
+
require 'yaml'
|
4
|
+
require 'zlib'
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
7
|
|
8
|
+
##
|
8
9
|
# Gem::Server and allows users to serve gems for consumption by
|
9
10
|
# `gem --remote-install`.
|
10
|
-
#
|
11
|
+
#
|
11
12
|
# gem_server starts an HTTP server on the given port and serves the folowing:
|
12
13
|
# * "/" - Browsing of gem spec files for installed gems
|
13
|
-
# * "/
|
14
|
+
# * "/Marshal" - Full SourceIndex dump of metadata for installed gems
|
15
|
+
# * "/yaml" - YAML dump of metadata for installed gems - deprecated
|
14
16
|
# * "/gems" - Direct access to download the installable gems
|
15
17
|
#
|
16
18
|
# == Usage
|
17
19
|
#
|
18
|
-
#
|
20
|
+
# gem server [-p portnum] [-d gem_path]
|
19
21
|
#
|
20
22
|
# port_num:: The TCP port the HTTP server will bind to
|
21
23
|
# gem_path::
|
@@ -23,6 +25,8 @@ require 'rdoc/template'
|
|
23
25
|
# subdirectories.
|
24
26
|
class Gem::Server
|
25
27
|
|
28
|
+
include Gem::UserInteraction
|
29
|
+
|
26
30
|
DOC_TEMPLATE = <<-WEBPAGE
|
27
31
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
28
32
|
<!DOCTYPE html
|
@@ -33,7 +37,7 @@ class Gem::Server
|
|
33
37
|
<head>
|
34
38
|
<title>RubyGems Documentation Index</title>
|
35
39
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
36
|
-
<link rel="stylesheet" href="rdoc-style.css" type="text/css" media="screen" />
|
40
|
+
<link rel="stylesheet" href="gem-server-rdoc-style.css" type="text/css" media="screen" />
|
37
41
|
</head>
|
38
42
|
<body>
|
39
43
|
<div id="fileHeader">
|
@@ -71,13 +75,13 @@ IFNOT:rdoc_installed
|
|
71
75
|
<span title="rdoc not installed">[rdoc]</span>
|
72
76
|
ENDIF:rdoc_installed
|
73
77
|
IF:homepage
|
74
|
-
<a href="%homepage%"
|
78
|
+
<a href="%homepage%" title="%homepage%">[www]</a>
|
75
79
|
ENDIF:homepage
|
76
80
|
IFNOT:homepage
|
77
81
|
<span title="no homepage available">[www]</span>
|
78
82
|
ENDIF:homepage
|
79
83
|
IF:has_deps
|
80
|
-
- depends on
|
84
|
+
- depends on
|
81
85
|
START:dependencies
|
82
86
|
IFNOT:is_last
|
83
87
|
<a href="#%name%" title="%version%">%name%</a>,
|
@@ -337,75 +341,89 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
|
337
341
|
.ruby-value { color: #7fffd4; background: transparent; }
|
338
342
|
RDOCCSS
|
339
343
|
|
340
|
-
def self.
|
341
|
-
options = {}
|
342
|
-
options[:port] = 8808
|
343
|
-
options[:gemdir] = Gem.dir
|
344
|
-
options[:daemon] = false
|
345
|
-
|
346
|
-
opts = OptionParser.new do |opts|
|
347
|
-
opts.on_tail("--help", "show this message") do
|
348
|
-
puts opts
|
349
|
-
exit
|
350
|
-
end
|
351
|
-
|
352
|
-
opts.on('-p', '--port=PORT', "Specify the port to listen on") do |port|
|
353
|
-
options[:port] = port
|
354
|
-
end
|
355
|
-
|
356
|
-
opts.on('-d', '--dir=GEMDIR',
|
357
|
-
"Specify the directory from which to serve Gems") do |gemdir|
|
358
|
-
options[:gemdir] = gemdir
|
359
|
-
end
|
360
|
-
|
361
|
-
opts.on( '--daemon', "Run as a daemon") do |daemon|
|
362
|
-
options[:daemon] = daemon
|
363
|
-
end
|
364
|
-
|
365
|
-
end
|
366
|
-
|
367
|
-
opts.parse! args
|
368
|
-
|
369
|
-
options
|
370
|
-
end
|
371
|
-
|
372
|
-
def self.run(args = ARGV)
|
373
|
-
options = process_args args
|
344
|
+
def self.run(options)
|
374
345
|
new(options[:gemdir], options[:port], options[:daemon]).run
|
375
346
|
end
|
376
347
|
|
377
348
|
def initialize(gemdir, port, daemon)
|
378
|
-
Socket.do_not_reverse_lookup=true
|
349
|
+
Socket.do_not_reverse_lookup = true
|
379
350
|
|
380
351
|
@gemdir = gemdir
|
381
352
|
@port = port
|
382
353
|
@daemon = daemon
|
354
|
+
logger = WEBrick::Log.new nil, WEBrick::BasicLog::FATAL
|
355
|
+
@server = WEBrick::HTTPServer.new :DoNotListen => true, :Logger => logger
|
356
|
+
|
357
|
+
@spec_dir = File.join @gemdir, "specifications"
|
358
|
+
@source_index = Gem::SourceIndex.from_gems_in @spec_dir
|
359
|
+
end
|
360
|
+
|
361
|
+
def quick(req, res)
|
362
|
+
res['content-type'] = 'text/plain'
|
363
|
+
res['date'] = File.stat(@spec_dir).mtime
|
364
|
+
|
365
|
+
case req.request_uri.request_uri
|
366
|
+
when '/quick/index' then
|
367
|
+
res.body << @source_index.map { |name,_| name }.join("\n")
|
368
|
+
when '/quick/index.rz' then
|
369
|
+
index = @source_index.map { |name,_| name }.join("\n")
|
370
|
+
res.body << Zlib::Deflate.deflate(index)
|
371
|
+
when %r|^/quick/(.*)-([0-9.]+)\.gemspec(\.marshal)?\.rz$| then
|
372
|
+
specs = @source_index.search $1, $2
|
373
|
+
if specs.empty? then
|
374
|
+
res.status = 404
|
375
|
+
elsif specs.length > 1 then
|
376
|
+
res.status = 500
|
377
|
+
elsif $3 # marshal quickindex instead of YAML
|
378
|
+
res.body << Zlib::Deflate.deflate(Marshal.dump(specs.first))
|
379
|
+
else # deprecated YAML format
|
380
|
+
res.body << Zlib::Deflate.deflate(specs.first.to_yaml)
|
381
|
+
end
|
382
|
+
else
|
383
|
+
res.status = 404
|
384
|
+
end
|
383
385
|
end
|
384
386
|
|
385
387
|
def run
|
386
|
-
|
388
|
+
@server.listen nil, @port
|
389
|
+
|
390
|
+
say "Starting gem server on http://localhost:#{@port}/"
|
387
391
|
|
388
|
-
|
392
|
+
WEBrick::Daemon.start if @daemon
|
389
393
|
|
390
|
-
|
394
|
+
@server.mount_proc("/yaml") do |req, res|
|
395
|
+
res['content-type'] = 'text/plain'
|
396
|
+
res['date'] = File.stat(@spec_dir).mtime
|
397
|
+
if req.request_method == 'HEAD' then
|
398
|
+
res['content-length'] = @source_index.to_yaml.length
|
399
|
+
else
|
400
|
+
res.body << @source_index.to_yaml
|
401
|
+
end
|
402
|
+
end
|
391
403
|
|
392
|
-
|
404
|
+
@server.mount_proc("/Marshal") do |req, res|
|
393
405
|
res['content-type'] = 'text/plain'
|
394
|
-
res['date'] = File.stat(spec_dir).mtime
|
395
|
-
|
406
|
+
res['date'] = File.stat(@spec_dir).mtime
|
407
|
+
if req.request_method == 'HEAD' then
|
408
|
+
res['content-length'] = Marshal.dump(@source_index).length
|
409
|
+
else
|
410
|
+
res.body << Marshal.dump(@source_index)
|
411
|
+
end
|
396
412
|
end
|
397
413
|
|
398
|
-
|
414
|
+
@server.mount_proc("/quick/", &method(:quick))
|
415
|
+
|
416
|
+
@server.mount_proc("/gem-server-rdoc-style.css") do |req, res|
|
399
417
|
res['content-type'] = 'text/css'
|
400
|
-
res['date'] = File.stat(spec_dir).mtime
|
418
|
+
res['date'] = File.stat(@spec_dir).mtime
|
401
419
|
res.body << RDOC_CSS
|
402
420
|
end
|
403
421
|
|
404
|
-
|
422
|
+
@server.mount_proc("/") do |req, res|
|
405
423
|
specs = []
|
406
424
|
total_file_count = 0
|
407
425
|
|
408
|
-
|
426
|
+
@source_index.each do |path, spec|
|
409
427
|
total_file_count += spec.files.size
|
410
428
|
deps = spec.dependencies.collect { |dep|
|
411
429
|
{ "name" => dep.name,
|
@@ -472,14 +490,14 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
|
472
490
|
|
473
491
|
paths = { "/gems" => "/cache/", "/doc_root" => "/doc/" }
|
474
492
|
paths.each do |mount_point, mount_dir|
|
475
|
-
|
493
|
+
@server.mount(mount_point, WEBrick::HTTPServlet::FileHandler,
|
476
494
|
File.join(@gemdir, mount_dir), true)
|
477
495
|
end
|
478
496
|
|
479
|
-
trap("INT") {
|
480
|
-
trap("TERM") {
|
497
|
+
trap("INT") { @server.shutdown; exit! }
|
498
|
+
trap("TERM") { @server.shutdown; exit! }
|
481
499
|
|
482
|
-
|
500
|
+
@server.start
|
483
501
|
end
|
484
502
|
|
485
503
|
end
|
@@ -4,12 +4,11 @@
|
|
4
4
|
# See LICENSE.txt for permissions.
|
5
5
|
#++
|
6
6
|
|
7
|
-
require 'rubygems/user_interaction'
|
8
|
-
require 'rubygems/remote_fetcher'
|
9
|
-
require 'rubygems/digest/sha2'
|
10
|
-
|
11
7
|
require 'forwardable'
|
12
|
-
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'rubygems/user_interaction'
|
11
|
+
require 'rubygems/specification'
|
13
12
|
|
14
13
|
module Gem
|
15
14
|
|
@@ -30,8 +29,6 @@ module Gem
|
|
30
29
|
|
31
30
|
include Gem::UserInteraction
|
32
31
|
|
33
|
-
INCREMENTAL_THRESHHOLD = 50
|
34
|
-
|
35
32
|
# Class Methods. -------------------------------------------------
|
36
33
|
class << self
|
37
34
|
include Gem::UserInteraction
|
@@ -89,7 +86,7 @@ module Gem
|
|
89
86
|
def load_specification(file_name)
|
90
87
|
begin
|
91
88
|
spec_code = File.read(file_name).untaint
|
92
|
-
gemspec = eval
|
89
|
+
gemspec = eval spec_code, binding, file_name
|
93
90
|
if gemspec.is_a?(Gem::Specification)
|
94
91
|
gemspec.loaded_from = file_name
|
95
92
|
return gemspec
|
@@ -134,18 +131,24 @@ module Gem
|
|
134
131
|
# Returns a Hash of name => Specification of the latest versions of each
|
135
132
|
# gem in this index.
|
136
133
|
def latest_specs
|
137
|
-
|
134
|
+
result, latest = Hash.new { |h,k| h[k] = [] }, {}
|
138
135
|
|
139
|
-
each do |
|
136
|
+
self.each do |_, spec| # SourceIndex is not a hash, so we're stuck with each
|
140
137
|
name = spec.name
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
138
|
+
curr_ver = spec.version
|
139
|
+
prev_ver = latest[name]
|
140
|
+
|
141
|
+
next unless prev_ver.nil? or curr_ver >= prev_ver
|
142
|
+
|
143
|
+
if prev_ver.nil? or curr_ver > prev_ver then
|
144
|
+
result[name].clear
|
145
|
+
latest[name] = curr_ver
|
145
146
|
end
|
147
|
+
|
148
|
+
result[name] << spec
|
146
149
|
end
|
147
150
|
|
148
|
-
|
151
|
+
result.values.flatten
|
149
152
|
end
|
150
153
|
|
151
154
|
# Add a gem specification to the source index.
|
@@ -159,10 +162,7 @@ module Gem
|
|
159
162
|
end
|
160
163
|
|
161
164
|
# Iterate over the specifications in the source index.
|
162
|
-
#
|
163
|
-
# &block:: [yields gem.full_name, Gem::Specification]
|
164
|
-
#
|
165
|
-
def each(&block)
|
165
|
+
def each(&block) # :yields: gem.full_name, gem
|
166
166
|
@gems.each(&block)
|
167
167
|
end
|
168
168
|
|
@@ -174,18 +174,22 @@ module Gem
|
|
174
174
|
# The signature for the source index. Changes in the signature
|
175
175
|
# indicate a change in the index.
|
176
176
|
def index_signature
|
177
|
+
require 'rubygems/digest/sha2'
|
178
|
+
|
177
179
|
Gem::SHA256.new.hexdigest(@gems.keys.sort.join(',')).to_s
|
178
180
|
end
|
179
181
|
|
180
182
|
# The signature for the given gem specification.
|
181
183
|
def gem_signature(gem_full_name)
|
184
|
+
require 'rubygems/digest/sha2'
|
185
|
+
|
182
186
|
Gem::SHA256.new.hexdigest(@gems[gem_full_name].to_yaml).to_s
|
183
187
|
end
|
184
188
|
|
185
189
|
def_delegators :@gems, :size, :length
|
186
190
|
|
187
191
|
# Find a gem by an exact match on the short name.
|
188
|
-
def find_name(gem_name, version_requirement=
|
192
|
+
def find_name(gem_name, version_requirement = Gem::Requirement.default)
|
189
193
|
search(/^#{gem_name}$/, version_requirement)
|
190
194
|
end
|
191
195
|
|
@@ -195,22 +199,46 @@ module Gem
|
|
195
199
|
# [String] a partial for the (short) name of the gem, or
|
196
200
|
# [Regex] a pattern to match against the short name
|
197
201
|
# version_requirement::
|
198
|
-
# [String | default=
|
202
|
+
# [String | default=Gem::Requirement.default] version to
|
199
203
|
# find
|
200
204
|
# return::
|
201
205
|
# [Array] list of Gem::Specification objects in sorted (version)
|
202
206
|
# order. Empty if not found.
|
203
207
|
#
|
204
|
-
def search(gem_pattern,
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
208
|
+
def search(gem_pattern, platform_only_or_version_req = false)
|
209
|
+
version_requirement = nil
|
210
|
+
only_platform = false
|
211
|
+
|
212
|
+
case gem_pattern
|
213
|
+
when Regexp then
|
214
|
+
version_requirement = platform_only_or_version_req ||
|
215
|
+
Gem::Requirement.default
|
216
|
+
when Gem::Dependency then
|
217
|
+
only_platform = platform_only_or_version_req
|
218
|
+
version_requirement = gem_pattern.version_requirements
|
219
|
+
gem_pattern = gem_pattern.name.empty? ? // : /^#{gem_pattern.name}$/
|
220
|
+
else
|
221
|
+
version_requirement = platform_only_or_version_req ||
|
222
|
+
Gem::Requirement.default
|
223
|
+
gem_pattern = /#{gem_pattern}/i
|
224
|
+
end
|
225
|
+
|
226
|
+
unless Gem::Requirement === version_requirement then
|
227
|
+
version_requirement = Gem::Requirement.create version_requirement
|
211
228
|
end
|
212
|
-
|
213
|
-
|
229
|
+
|
230
|
+
specs = @gems.values.select do |spec|
|
231
|
+
spec.name =~ gem_pattern and
|
232
|
+
version_requirement.satisfied_by? spec.version
|
233
|
+
end
|
234
|
+
|
235
|
+
if only_platform then
|
236
|
+
specs = specs.select do |spec|
|
237
|
+
Gem::Platform.match spec.platform
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
specs.sort_by { |s| s.sort_obj }
|
214
242
|
end
|
215
243
|
|
216
244
|
# Refresh the source index from the local file system.
|
@@ -224,15 +252,20 @@ module Gem
|
|
224
252
|
# Returns an Array of Gem::Specifications that are not up to date.
|
225
253
|
#
|
226
254
|
def outdated
|
227
|
-
|
255
|
+
dep = Gem::Dependency.new '', Gem::Requirement.default
|
256
|
+
|
257
|
+
remotes = Gem::SourceInfoCache.search dep, true
|
258
|
+
|
228
259
|
outdateds = []
|
229
|
-
|
260
|
+
|
261
|
+
latest_specs.each do |local|
|
230
262
|
name = local.name
|
231
263
|
remote = remotes.select { |spec| spec.name == name }.
|
232
|
-
sort_by { |spec| spec.version }.
|
264
|
+
sort_by { |spec| spec.version.to_ints }.
|
233
265
|
last
|
234
266
|
outdateds << name if remote and local.version < remote.version
|
235
267
|
end
|
268
|
+
|
236
269
|
outdateds
|
237
270
|
end
|
238
271
|
|
@@ -243,58 +276,89 @@ module Gem
|
|
243
276
|
gem_names = fetch_quick_index source_uri
|
244
277
|
remove_extra gem_names
|
245
278
|
missing_gems = find_missing gem_names
|
246
|
-
|
279
|
+
|
280
|
+
return false if missing_gems.size.zero?
|
281
|
+
|
282
|
+
say "missing #{missing_gems.size} gems" if
|
283
|
+
missing_gems.size > 0 and Gem.configuration.really_verbose
|
284
|
+
|
285
|
+
use_incremental = missing_gems.size <= Gem.configuration.bulk_threshold
|
247
286
|
rescue Gem::OperationNotSupportedError => ex
|
287
|
+
alert_error "Falling back to bulk fetch: #{ex.message}" if
|
288
|
+
Gem.configuration.really_verbose
|
248
289
|
use_incremental = false
|
249
290
|
end
|
250
291
|
|
251
292
|
if use_incremental then
|
252
|
-
update_with_missing
|
293
|
+
update_with_missing(source_uri, missing_gems)
|
253
294
|
else
|
254
|
-
new_index = fetch_bulk_index
|
255
|
-
@gems.replace
|
295
|
+
new_index = fetch_bulk_index(source_uri)
|
296
|
+
@gems.replace(new_index.gems)
|
256
297
|
end
|
257
298
|
|
258
|
-
|
299
|
+
true
|
259
300
|
end
|
260
|
-
|
301
|
+
|
261
302
|
def ==(other) # :nodoc:
|
262
303
|
self.class === other and @gems == other.gems
|
263
304
|
end
|
264
305
|
|
306
|
+
def dump
|
307
|
+
Marshal.dump(self)
|
308
|
+
end
|
309
|
+
|
265
310
|
protected
|
266
311
|
|
267
312
|
attr_reader :gems
|
268
313
|
|
269
314
|
private
|
270
315
|
|
271
|
-
# Convert the yamlized string spec into a real spec (actually, these are
|
272
|
-
# hashes of specs.).
|
273
|
-
def convert_specs(yaml_spec)
|
274
|
-
YAML.load(reduce_specs(yaml_spec)) or
|
275
|
-
raise "Didn't get a valid YAML document"
|
276
|
-
end
|
277
|
-
|
278
316
|
def fetcher
|
317
|
+
require 'rubygems/remote_fetcher'
|
318
|
+
|
279
319
|
Gem::RemoteFetcher.fetcher
|
280
320
|
end
|
281
321
|
|
282
|
-
def
|
283
|
-
|
322
|
+
def fetch_index_from(source_uri)
|
323
|
+
@fetch_error = nil
|
284
324
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
325
|
+
indexes = %W[
|
326
|
+
Marshal.#{Gem.marshal_version}.Z
|
327
|
+
Marshal.#{Gem.marshal_version}
|
328
|
+
yaml.Z
|
329
|
+
yaml
|
330
|
+
]
|
331
|
+
|
332
|
+
indexes.each do |name|
|
333
|
+
spec_data = nil
|
289
334
|
begin
|
290
|
-
|
335
|
+
spec_data = fetcher.fetch_path("#{source_uri}/#{name}")
|
336
|
+
spec_data = unzip(spec_data) if name =~ /\.Z$/
|
337
|
+
if name =~ /Marshal/ then
|
338
|
+
return Marshal.load(spec_data)
|
339
|
+
else
|
340
|
+
return YAML.load(spec_data)
|
341
|
+
end
|
291
342
|
rescue => e
|
292
|
-
|
293
|
-
|
343
|
+
if Gem.configuration.really_verbose then
|
344
|
+
alert_error "Unable to fetch #{name}: #{e.message}"
|
345
|
+
end
|
346
|
+
@fetch_error = e
|
294
347
|
end
|
295
348
|
end
|
349
|
+
nil
|
350
|
+
end
|
296
351
|
|
297
|
-
|
352
|
+
def fetch_bulk_index(source_uri)
|
353
|
+
say "Bulk updating Gem source index for: #{source_uri}"
|
354
|
+
|
355
|
+
index = fetch_index_from(source_uri)
|
356
|
+
if index.nil? then
|
357
|
+
raise Gem::RemoteSourceException,
|
358
|
+
"Error fetching remote gem cache: #{@fetch_error}"
|
359
|
+
end
|
360
|
+
@fetch_error = nil
|
361
|
+
index
|
298
362
|
end
|
299
363
|
|
300
364
|
# Get the quick index needed for incremental updates.
|
@@ -313,26 +377,6 @@ module Gem
|
|
313
377
|
}
|
314
378
|
end
|
315
379
|
|
316
|
-
# This reduces the source spec in size so that YAML bugs with large data
|
317
|
-
# sets will be dodged. Obviously this is a workaround, but it allows Gems
|
318
|
-
# to continue to work until the YAML bug is fixed.
|
319
|
-
def reduce_specs(yaml_spec)
|
320
|
-
result = ""
|
321
|
-
state = :copy
|
322
|
-
yaml_spec.each do |line|
|
323
|
-
if state == :copy && line =~ /^\s+files:\s*$/
|
324
|
-
state = :skip
|
325
|
-
result << line.sub(/$/, " []")
|
326
|
-
elsif state == :skip
|
327
|
-
if line !~ /^\s+-/
|
328
|
-
state = :copy
|
329
|
-
end
|
330
|
-
end
|
331
|
-
result << line if state == :copy
|
332
|
-
end
|
333
|
-
result
|
334
|
-
end
|
335
|
-
|
336
380
|
def remove_extra(spec_names)
|
337
381
|
dictionary = spec_names.inject({}) { |h, k| h[k] = true; h }
|
338
382
|
each do |name, spec|
|
@@ -346,20 +390,47 @@ module Gem
|
|
346
390
|
Zlib::Inflate.inflate(string)
|
347
391
|
end
|
348
392
|
|
393
|
+
# Tries to fetch Marshal representation first, then YAML
|
394
|
+
def fetch_single_spec(source_uri, spec_name)
|
395
|
+
@fetch_error = nil
|
396
|
+
begin
|
397
|
+
marshal_uri = source_uri + "/quick/Marshal.#{Gem.marshal_version}/#{spec_name}.gemspec.rz"
|
398
|
+
zipped = fetcher.fetch_path marshal_uri
|
399
|
+
return Marshal.load(unzip(zipped))
|
400
|
+
rescue => ex
|
401
|
+
@fetch_error = ex
|
402
|
+
if Gem.configuration.really_verbose then
|
403
|
+
say "unable to fetch marshal gemspec #{marshal_uri}: #{ex.class} - #{ex}"
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
begin
|
408
|
+
yaml_uri = source_uri + "/quick/#{spec_name}.gemspec.rz"
|
409
|
+
zipped = fetcher.fetch_path yaml_uri
|
410
|
+
return YAML.load(unzip(zipped))
|
411
|
+
rescue => ex
|
412
|
+
@fetch_error = ex
|
413
|
+
if Gem.configuration.really_verbose then
|
414
|
+
say "unable to fetch YAML gemspec #{yaml_uri}: #{ex.class} - #{ex}"
|
415
|
+
end
|
416
|
+
end
|
417
|
+
nil
|
418
|
+
end
|
419
|
+
|
349
420
|
# Update the cached source index with the missing names.
|
350
421
|
def update_with_missing(source_uri, missing_names)
|
351
422
|
progress = ui.progress_reporter(missing_names.size,
|
352
|
-
"
|
423
|
+
"Updating metadata for #{missing_names.size} gems from #{source_uri}")
|
353
424
|
missing_names.each do |spec_name|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
425
|
+
gemspec = fetch_single_spec(source_uri, spec_name)
|
426
|
+
if gemspec.nil? then
|
427
|
+
ui.say "Failed to download spec #{spec_name} from #{source_uri}:\n" \
|
428
|
+
"\t#{@fetch_error.message}"
|
429
|
+
else
|
358
430
|
add_spec gemspec
|
359
431
|
progress.updated spec_name
|
360
|
-
rescue RuntimeError => ex
|
361
|
-
ui.say "Failed to download spec for #{spec_name} from #{source_uri}"
|
362
432
|
end
|
433
|
+
@fetch_error = nil
|
363
434
|
end
|
364
435
|
progress.done
|
365
436
|
progress.count
|