rubygems-update 1.8.30 → 2.0.0.preview2
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 +6 -6
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +3 -0
- data/.autotest +6 -3
- data/History.txt +137 -63
- data/LICENSE.txt +1 -5
- data/Manifest.txt +69 -32
- data/README.rdoc +11 -9
- data/Rakefile +24 -38
- data/bin/gem +0 -9
- data/bin/update_rubygems +1 -0
- data/lib/rubygems.rb +193 -405
- data/lib/rubygems/available_set.rb +95 -0
- data/lib/rubygems/command.rb +88 -45
- data/lib/rubygems/command_manager.rb +67 -40
- data/lib/rubygems/commands/build_command.rb +5 -23
- data/lib/rubygems/commands/cert_command.rb +199 -57
- data/lib/rubygems/commands/check_command.rb +14 -39
- data/lib/rubygems/commands/cleanup_command.rb +9 -1
- data/lib/rubygems/commands/contents_command.rb +30 -12
- data/lib/rubygems/commands/dependency_command.rb +3 -8
- data/lib/rubygems/commands/environment_command.rb +13 -8
- data/lib/rubygems/commands/fetch_command.rb +3 -16
- data/lib/rubygems/commands/generate_index_command.rb +7 -47
- data/lib/rubygems/commands/help_command.rb +1 -1
- data/lib/rubygems/commands/install_command.rb +69 -36
- data/lib/rubygems/commands/list_command.rb +6 -4
- data/lib/rubygems/commands/lock_command.rb +1 -1
- data/lib/rubygems/commands/mirror_command.rb +17 -0
- data/lib/rubygems/commands/outdated_command.rb +6 -3
- data/lib/rubygems/commands/owner_command.rb +13 -5
- data/lib/rubygems/commands/pristine_command.rb +19 -4
- data/lib/rubygems/commands/push_command.rb +12 -1
- data/lib/rubygems/commands/query_command.rb +43 -27
- data/lib/rubygems/commands/rdoc_command.rb +23 -28
- data/lib/rubygems/commands/search_command.rb +4 -18
- data/lib/rubygems/commands/server_command.rb +1 -1
- data/lib/rubygems/commands/setup_command.rb +124 -38
- data/lib/rubygems/commands/sources_command.rb +16 -16
- data/lib/rubygems/commands/specification_command.rb +11 -13
- data/lib/rubygems/commands/uninstall_command.rb +24 -7
- data/lib/rubygems/commands/unpack_command.rb +7 -3
- data/lib/rubygems/commands/update_command.rb +22 -36
- data/lib/rubygems/commands/yank_command.rb +98 -0
- data/lib/rubygems/compatibility.rb +51 -0
- data/lib/rubygems/config_file.rb +82 -54
- data/lib/rubygems/core_ext/kernel_gem.rb +53 -0
- data/lib/rubygems/core_ext/kernel_require.rb +119 -0
- data/lib/rubygems/defaults.rb +10 -21
- data/lib/rubygems/dependency.rb +61 -10
- data/lib/rubygems/dependency_installer.rb +157 -69
- data/lib/rubygems/dependency_list.rb +11 -19
- data/lib/rubygems/dependency_resolver.rb +562 -0
- data/lib/rubygems/deprecate.rb +40 -40
- data/lib/rubygems/errors.rb +77 -24
- data/lib/rubygems/exceptions.rb +25 -7
- data/lib/rubygems/ext/builder.rb +20 -23
- data/lib/rubygems/ext/configure_builder.rb +2 -2
- data/lib/rubygems/ext/ext_conf_builder.rb +5 -45
- data/lib/rubygems/ext/rake_builder.rb +2 -2
- data/lib/rubygems/gem_runner.rb +3 -16
- data/lib/rubygems/gemcutter_utilities.rb +22 -7
- data/lib/rubygems/indexer.rb +6 -159
- data/lib/rubygems/install_message.rb +12 -0
- data/lib/rubygems/install_update_options.rb +56 -18
- data/lib/rubygems/installer.rb +244 -134
- data/lib/rubygems/installer_test_case.rb +71 -19
- data/lib/rubygems/mock_gem_ui.rb +17 -0
- data/lib/rubygems/name_tuple.rb +110 -0
- data/lib/rubygems/package.rb +514 -43
- data/lib/rubygems/package/digest_io.rb +64 -0
- data/lib/rubygems/package/old.rb +147 -0
- data/lib/rubygems/package/tar_header.rb +18 -55
- data/lib/rubygems/package/tar_reader.rb +20 -3
- data/lib/rubygems/package/tar_writer.rb +63 -7
- data/lib/rubygems/package_task.rb +3 -4
- data/lib/rubygems/path_support.rb +14 -7
- data/lib/rubygems/platform.rb +19 -26
- data/lib/rubygems/rdoc.rb +316 -0
- data/lib/rubygems/remote_fetcher.rb +117 -54
- data/lib/rubygems/request_set.rb +182 -0
- data/lib/rubygems/requirement.rb +63 -26
- data/lib/rubygems/security.rb +295 -555
- data/lib/rubygems/security/policies.rb +115 -0
- data/lib/rubygems/security/policy.rb +227 -0
- data/lib/rubygems/security/signer.rb +136 -0
- data/lib/rubygems/security/trust_dir.rb +104 -0
- data/lib/rubygems/server.rb +45 -55
- data/lib/rubygems/source.rb +144 -0
- data/lib/rubygems/source_list.rb +87 -0
- data/lib/rubygems/source_local.rb +92 -0
- data/lib/rubygems/source_specific_file.rb +28 -0
- data/lib/rubygems/spec_fetcher.rb +116 -184
- data/lib/rubygems/specification.rb +731 -335
- data/lib/rubygems/ssl_certs/AddTrustExternalCARoot.pem +88 -30
- data/lib/rubygems/ssl_certs/Entrust_net-Secure-Server-Certification-Authority.pem +90 -0
- data/lib/rubygems/ssl_certs/VerisignClass3PublicPrimaryCertificationAuthority-G2.pem +57 -0
- data/lib/rubygems/syck_hack.rb +2 -0
- data/lib/rubygems/test_case.rb +199 -109
- data/lib/rubygems/test_utilities.rb +25 -5
- data/lib/rubygems/uninstaller.rb +62 -20
- data/lib/rubygems/user_interaction.rb +10 -0
- data/lib/rubygems/validator.rb +33 -40
- data/lib/rubygems/version.rb +19 -8
- data/setup.rb +8 -1
- data/test/rubygems/alternate_cert.pem +9 -0
- data/test/rubygems/alternate_cert_32.pem +9 -0
- data/test/rubygems/alternate_key.pem +9 -0
- data/test/rubygems/bad_rake.rb +1 -0
- data/test/rubygems/child_cert.pem +9 -0
- data/test/rubygems/child_cert_32.pem +9 -0
- data/test/rubygems/child_key.pem +9 -0
- data/test/rubygems/data/null-type.gemspec.rz +0 -0
- data/test/rubygems/expired_cert.pem +9 -0
- data/test/rubygems/future_cert.pem +9 -0
- data/test/rubygems/future_cert_32.pem +9 -0
- data/test/rubygems/good_rake.rb +1 -0
- data/test/rubygems/grandchild_cert.pem +9 -0
- data/test/rubygems/grandchild_cert_32.pem +9 -0
- data/test/rubygems/grandchild_key.pem +9 -0
- data/test/rubygems/invalid_issuer_cert.pem +9 -0
- data/test/rubygems/invalid_issuer_cert_32.pem +9 -0
- data/test/rubygems/invalid_key.pem +9 -0
- data/test/rubygems/invalid_signer_cert.pem +9 -0
- data/test/rubygems/invalid_signer_cert_32.pem +9 -0
- data/test/rubygems/invalidchild_cert.pem +9 -0
- data/test/rubygems/invalidchild_cert_32.pem +9 -0
- data/test/rubygems/invalidchild_key.pem +9 -0
- data/test/rubygems/plugin/exception/rubygems_plugin.rb +1 -1
- data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +1 -1
- data/test/rubygems/private_key.pem +7 -25
- data/test/rubygems/public_cert.pem +8 -18
- data/test/rubygems/public_cert_32.pem +10 -0
- data/test/rubygems/public_key.pem +4 -0
- data/test/rubygems/rubygems/commands/crash_command.rb +1 -1
- data/test/rubygems/test_config.rb +4 -6
- data/test/rubygems/test_deprecate.rb +76 -0
- data/test/rubygems/test_gem.rb +318 -83
- data/test/rubygems/test_gem_available_set.rb +106 -0
- data/test/rubygems/test_gem_command.rb +10 -0
- data/test/rubygems/test_gem_command_manager.rb +55 -9
- data/test/rubygems/test_gem_commands_build_command.rb +11 -19
- data/test/rubygems/test_gem_commands_cert_command.rb +441 -42
- data/test/rubygems/test_gem_commands_cleanup_command.rb +29 -1
- data/test/rubygems/test_gem_commands_contents_command.rb +23 -0
- data/test/rubygems/test_gem_commands_dependency_command.rb +5 -0
- data/test/rubygems/test_gem_commands_fetch_command.rb +19 -20
- data/test/rubygems/test_gem_commands_generate_index_command.rb +2 -83
- data/test/rubygems/test_gem_commands_help_command.rb +2 -1
- data/test/rubygems/test_gem_commands_install_command.rb +647 -48
- data/test/rubygems/test_gem_commands_mirror.rb +32 -0
- data/test/rubygems/test_gem_commands_owner_command.rb +4 -8
- data/test/rubygems/test_gem_commands_pristine_command.rb +99 -4
- data/test/rubygems/test_gem_commands_push_command.rb +62 -8
- data/test/rubygems/test_gem_commands_query_command.rb +51 -0
- data/test/rubygems/test_gem_commands_search_command.rb +25 -0
- data/test/rubygems/test_gem_commands_setup_command.rb +45 -0
- data/test/rubygems/test_gem_commands_sources_command.rb +21 -6
- data/test/rubygems/test_gem_commands_specification_command.rb +33 -1
- data/test/rubygems/test_gem_commands_uninstall_command.rb +91 -31
- data/test/rubygems/test_gem_commands_unpack_command.rb +3 -3
- data/test/rubygems/test_gem_commands_update_command.rb +56 -38
- data/test/rubygems/test_gem_commands_which_command.rb +4 -4
- data/test/rubygems/test_gem_commands_yank_command.rb +97 -0
- data/test/rubygems/test_gem_config_file.rb +66 -21
- data/test/rubygems/test_gem_dependency.rb +46 -0
- data/test/rubygems/test_gem_dependency_installer.rb +228 -18
- data/test/rubygems/test_gem_dependency_list.rb +0 -9
- data/test/rubygems/test_gem_dependency_resolver.rb +327 -0
- data/test/rubygems/test_gem_ext_configure_builder.rb +4 -4
- data/test/rubygems/test_gem_ext_ext_conf_builder.rb +21 -49
- data/test/rubygems/test_gem_ext_rake_builder.rb +13 -13
- data/test/rubygems/test_gem_gem_runner.rb +27 -5
- data/test/rubygems/test_gem_gemcutter_utilities.rb +19 -0
- data/test/rubygems/test_gem_indexer.rb +14 -227
- data/test/rubygems/test_gem_install_update_options.rb +83 -3
- data/test/rubygems/test_gem_installer.rb +211 -236
- data/test/rubygems/test_gem_local_remote_options.rb +8 -2
- data/test/rubygems/test_gem_name_tuple.rb +15 -0
- data/test/rubygems/test_gem_package.rb +547 -0
- data/test/rubygems/test_gem_package_old.rb +37 -0
- data/test/rubygems/test_gem_package_tar_reader.rb +32 -0
- data/test/rubygems/test_gem_package_tar_writer.rb +84 -1
- data/test/rubygems/test_gem_path_support.rb +4 -30
- data/test/rubygems/test_gem_platform.rb +3 -6
- data/test/rubygems/test_gem_rdoc.rb +245 -0
- data/test/rubygems/test_gem_remote_fetcher.rb +51 -5
- data/test/rubygems/test_gem_request_set.rb +70 -0
- data/test/rubygems/test_gem_requirement.rb +53 -24
- data/test/rubygems/test_gem_security.rb +189 -43
- data/test/rubygems/test_gem_security_policy.rb +376 -0
- data/test/rubygems/test_gem_security_signer.rb +184 -0
- data/test/rubygems/test_gem_security_trust_dir.rb +94 -0
- data/test/rubygems/test_gem_server.rb +31 -36
- data/test/rubygems/test_gem_silent_ui.rb +2 -2
- data/test/rubygems/test_gem_source.rb +188 -0
- data/test/rubygems/test_gem_source_list.rb +87 -0
- data/test/rubygems/test_gem_source_local.rb +83 -0
- data/test/rubygems/test_gem_source_specific_file.rb +33 -0
- data/test/rubygems/test_gem_spec_fetcher.rb +91 -255
- data/test/rubygems/test_gem_specification.rb +293 -39
- data/test/rubygems/test_gem_uninstaller.rb +136 -13
- data/test/rubygems/test_gem_validator.rb +14 -41
- data/test/rubygems/test_gem_version.rb +15 -21
- data/test/rubygems/test_require.rb +193 -0
- data/test/rubygems/wrong_key_cert.pem +9 -0
- data/test/rubygems/wrong_key_cert_32.pem +9 -0
- metadata +171 -83
- metadata.gz.sig +1 -0
- data/CVE-2013-4287.txt +0 -36
- data/CVE-2013-4363.txt +0 -45
- data/ci_build.sh +0 -27
- data/cruise_config.rb +0 -32
- data/lib/rbconfig/datadir.rb +0 -13
- data/lib/rubygems/builder.rb +0 -99
- data/lib/rubygems/custom_require.rb +0 -69
- data/lib/rubygems/doc_manager.rb +0 -243
- data/lib/rubygems/format.rb +0 -82
- data/lib/rubygems/gem_openssl.rb +0 -90
- data/lib/rubygems/gem_path_searcher.rb +0 -172
- data/lib/rubygems/old_format.rb +0 -153
- data/lib/rubygems/package/f_sync_dir.rb +0 -23
- data/lib/rubygems/package/tar_input.rb +0 -234
- data/lib/rubygems/package/tar_output.rb +0 -146
- data/lib/rubygems/require_paths_builder.rb +0 -18
- data/lib/rubygems/source_index.rb +0 -406
- data/lib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem +0 -25
- data/lib/rubygems/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
- data/lib/rubygems/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +0 -23
- data/lib/rubygems/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
- data/lib/rubygems/ssl_certs/GeoTrustGlobalCA.pem +0 -20
- data/test/rubygems/test_bundled_ca.rb +0 -59
- data/test/rubygems/test_gem_builder.rb +0 -44
- data/test/rubygems/test_gem_doc_manager.rb +0 -32
- data/test/rubygems/test_gem_ext_builder.rb +0 -58
- data/test/rubygems/test_gem_format.rb +0 -88
- data/test/rubygems/test_gem_gem_path_searcher.rb +0 -94
- data/test/rubygems/test_gem_package_tar_input.rb +0 -129
- data/test/rubygems/test_gem_package_tar_output.rb +0 -101
- data/test/rubygems/test_gem_source_index.rb +0 -250
- data/util/update_bundled_ca_certificates.rb +0 -103
@@ -6,11 +6,26 @@ class Gem::Installer
|
|
6
6
|
##
|
7
7
|
# Available through requiring rubygems/installer_test_case
|
8
8
|
|
9
|
+
attr_writer :bin_dir
|
10
|
+
|
11
|
+
##
|
12
|
+
# Available through requiring rubygems/installer_test_case
|
13
|
+
|
14
|
+
attr_writer :build_args
|
15
|
+
|
16
|
+
##
|
17
|
+
# Available through requiring rubygems/installer_test_case
|
18
|
+
|
9
19
|
attr_writer :gem_dir
|
10
20
|
|
11
21
|
##
|
12
22
|
# Available through requiring rubygems/installer_test_case
|
13
23
|
|
24
|
+
attr_writer :force
|
25
|
+
|
26
|
+
##
|
27
|
+
# Available through requiring rubygems/installer_test_case
|
28
|
+
|
14
29
|
attr_writer :format
|
15
30
|
|
16
31
|
##
|
@@ -54,47 +69,68 @@ end
|
|
54
69
|
|
55
70
|
class Gem::InstallerTestCase < Gem::TestCase
|
56
71
|
|
72
|
+
##
|
73
|
+
# Creates the following instance variables:
|
74
|
+
#
|
75
|
+
# @spec::
|
76
|
+
# a spec named 'a', intended for regular installs
|
77
|
+
# @user_spec::
|
78
|
+
# a spec named 'b', intended for user installs
|
79
|
+
|
80
|
+
# @gem::
|
81
|
+
# the path to a built gem from @spec
|
82
|
+
# @user_spec::
|
83
|
+
# the path to a built gem from @user_spec
|
84
|
+
#
|
85
|
+
# @installer::
|
86
|
+
# a Gem::Installer for the @spec that installs into @gemhome
|
87
|
+
# @user_installer::
|
88
|
+
# a Gem::Installer for the @user_spec that installs into Gem.user_dir
|
89
|
+
|
57
90
|
def setup
|
58
91
|
super
|
59
92
|
|
60
|
-
@
|
61
|
-
|
93
|
+
@spec = quick_gem 'a' do |spec|
|
94
|
+
util_make_exec spec
|
95
|
+
end
|
62
96
|
|
63
|
-
|
64
|
-
|
97
|
+
@user_spec = quick_gem 'b' do |spec|
|
98
|
+
util_make_exec spec
|
99
|
+
end
|
65
100
|
|
66
|
-
@spec = quick_gem 'a'
|
67
|
-
util_make_exec @spec
|
68
101
|
util_build_gem @spec
|
69
|
-
@gem = @spec.cache_file
|
70
|
-
|
71
|
-
@user_spec = quick_gem 'b'
|
72
|
-
util_make_exec @user_spec
|
73
102
|
util_build_gem @user_spec
|
74
|
-
@user_gem = @user_spec.cache_file
|
75
103
|
|
76
|
-
|
104
|
+
@gem = @spec.cache_file
|
105
|
+
@user_gem = @user_spec.cache_file
|
77
106
|
|
78
107
|
@installer = util_installer @spec, @gemhome
|
79
108
|
@user_installer = util_installer @user_spec, Gem.user_dir, :user
|
80
|
-
|
81
|
-
Gem.use_paths @gemhome
|
82
109
|
end
|
83
110
|
|
84
|
-
def util_gem_bindir spec = @spec
|
111
|
+
def util_gem_bindir spec = @spec # :nodoc:
|
85
112
|
# TODO: deprecate
|
86
113
|
spec.bin_dir
|
87
114
|
end
|
88
115
|
|
89
|
-
def util_gem_dir spec = @spec
|
116
|
+
def util_gem_dir spec = @spec # :nodoc:
|
90
117
|
# TODO: deprecate
|
91
118
|
spec.gem_dir
|
92
119
|
end
|
93
120
|
|
121
|
+
##
|
122
|
+
# The path where installed executables live
|
123
|
+
|
94
124
|
def util_inst_bindir
|
95
125
|
File.join @gemhome, "bin"
|
96
126
|
end
|
97
127
|
|
128
|
+
##
|
129
|
+
# Adds an executable named "executable" to +spec+ with the given +shebang+.
|
130
|
+
#
|
131
|
+
# The executable is also written to the bin dir in @tmpdir and the installed
|
132
|
+
# gem directory for +spec+.
|
133
|
+
|
98
134
|
def util_make_exec(spec = @spec, shebang = "#!/usr/bin/ruby")
|
99
135
|
spec.executables = %w[executable]
|
100
136
|
spec.files << 'bin/executable'
|
@@ -110,6 +146,14 @@ class Gem::InstallerTestCase < Gem::TestCase
|
|
110
146
|
end
|
111
147
|
end
|
112
148
|
|
149
|
+
##
|
150
|
+
# Builds the @spec gem and returns an installer for it. The built gem
|
151
|
+
# includes:
|
152
|
+
#
|
153
|
+
# bin/executable
|
154
|
+
# lib/code.rb
|
155
|
+
# ext/a/mkrf_conf.rb
|
156
|
+
|
113
157
|
def util_setup_gem(ui = @ui) # HACK fix use_ui to make this automatic
|
114
158
|
@spec.files << File.join('lib', 'code.rb')
|
115
159
|
@spec.extensions << File.join('ext', 'a', 'mkrf_conf.rb')
|
@@ -129,16 +173,24 @@ class Gem::InstallerTestCase < Gem::TestCase
|
|
129
173
|
end
|
130
174
|
|
131
175
|
use_ui ui do
|
132
|
-
FileUtils.
|
176
|
+
FileUtils.rm_f @gem
|
133
177
|
|
134
|
-
@gem = Gem::
|
178
|
+
@gem = Gem::Package.build @spec
|
135
179
|
end
|
136
180
|
end
|
137
181
|
|
138
182
|
@installer = Gem::Installer.new @gem
|
139
183
|
end
|
140
184
|
|
185
|
+
##
|
186
|
+
# Creates an installer for +spec+ that will install into +gem_home+. If
|
187
|
+
# +user+ is true a user-install will be performed.
|
188
|
+
|
141
189
|
def util_installer(spec, gem_home, user=false)
|
142
|
-
Gem::Installer.new
|
190
|
+
Gem::Installer.new(spec.cache_file,
|
191
|
+
:install_dir => gem_home,
|
192
|
+
:user_install => user)
|
143
193
|
end
|
194
|
+
|
144
195
|
end
|
196
|
+
|
data/lib/rubygems/mock_gem_ui.rb
CHANGED
@@ -6,6 +6,17 @@ require 'rubygems/user_interaction'
|
|
6
6
|
# retrieval during tests.
|
7
7
|
|
8
8
|
class Gem::MockGemUi < Gem::StreamUI
|
9
|
+
##
|
10
|
+
# Raised when you haven't provided enough input to your MockGemUi
|
11
|
+
|
12
|
+
class InputEOFError < RuntimeError
|
13
|
+
|
14
|
+
def initialize question
|
15
|
+
super "Out of input for MockGemUi on #{question.inspect}"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
9
20
|
class TermError < RuntimeError
|
10
21
|
attr_reader :exit_code
|
11
22
|
|
@@ -44,6 +55,12 @@ class Gem::MockGemUi < Gem::StreamUI
|
|
44
55
|
@terminated = false
|
45
56
|
end
|
46
57
|
|
58
|
+
def ask question
|
59
|
+
raise InputEOFError, question if @ins.eof?
|
60
|
+
|
61
|
+
super
|
62
|
+
end
|
63
|
+
|
47
64
|
def input
|
48
65
|
@ins.string
|
49
66
|
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
# Represents a gem of name +name+ at +version+ of +platform+. These
|
4
|
+
# wrap the data returned from the indexes.
|
5
|
+
|
6
|
+
require 'rubygems/platform'
|
7
|
+
|
8
|
+
class Gem::NameTuple
|
9
|
+
def initialize(name, version, platform="ruby")
|
10
|
+
@name = name
|
11
|
+
@version = version
|
12
|
+
|
13
|
+
unless platform.kind_of? Gem::Platform
|
14
|
+
platform = "ruby" if !platform or platform.empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
@platform = platform
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :name, :version, :platform
|
21
|
+
|
22
|
+
##
|
23
|
+
# Turn an array of [name, version, platform] into an array of
|
24
|
+
# NameTuple objects.
|
25
|
+
|
26
|
+
def self.from_list list
|
27
|
+
list.map { |t| new(*t) }
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Turn an array of NameTuple objects back into an array of
|
32
|
+
# [name, version, platform] tuples.
|
33
|
+
|
34
|
+
def self.to_basic list
|
35
|
+
list.map { |t| t.to_a }
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# A null NameTuple, ie name=nil, version=0
|
40
|
+
|
41
|
+
def self.null
|
42
|
+
new nil, Gem::Version.new(0), nil
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Indicate if this NameTuple matches the current platform.
|
47
|
+
|
48
|
+
def match_platform?
|
49
|
+
Gem::Platform.match @platform
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Indicate if this NameTuple is for a prerelease version.
|
54
|
+
def prerelease?
|
55
|
+
@version.prerelease?
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Return the name that the gemspec file would be
|
60
|
+
|
61
|
+
def spec_name
|
62
|
+
case @platform
|
63
|
+
when nil, 'ruby', ''
|
64
|
+
"#{@name}-#{@version}.gemspec"
|
65
|
+
else
|
66
|
+
"#{@name}-#{@version}-#{@platform}.gemspec"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Convert back to the [name, version, platform] tuple
|
72
|
+
|
73
|
+
def to_a
|
74
|
+
[@name, @version, @platform]
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_s
|
78
|
+
"#<Gem::NameTuple #{@name}, #{@version}, #{@platform}>"
|
79
|
+
end
|
80
|
+
|
81
|
+
def <=> other
|
82
|
+
to_a <=> other.to_a
|
83
|
+
end
|
84
|
+
|
85
|
+
include Comparable
|
86
|
+
|
87
|
+
##
|
88
|
+
# Compare with +other+. Supports another NameTuple or an Array
|
89
|
+
# in the [name, version, platform] format.
|
90
|
+
|
91
|
+
def == other
|
92
|
+
case other
|
93
|
+
when self.class
|
94
|
+
@name == other.name and
|
95
|
+
@version == other.version and
|
96
|
+
@platform == other.platform
|
97
|
+
when Array
|
98
|
+
to_a == other
|
99
|
+
else
|
100
|
+
false
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
alias_method :eql?, :==
|
105
|
+
|
106
|
+
def hash
|
107
|
+
to_a.hash
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
data/lib/rubygems/package.rb
CHANGED
@@ -3,16 +3,54 @@
|
|
3
3
|
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
|
4
4
|
# See LICENSE.txt for additional licensing information.
|
5
5
|
#++
|
6
|
+
#
|
7
|
+
# Example using a Gem::Package
|
8
|
+
#
|
9
|
+
# Builds a .gem file given a Gem::Specification. A .gem file is a tarball
|
10
|
+
# which contains a data.tar.gz and metadata.gz, and possibly signatures.
|
11
|
+
#
|
12
|
+
# require 'rubygems'
|
13
|
+
# require 'rubygems/package'
|
14
|
+
#
|
15
|
+
# spec = Gem::Specification.new do |s|
|
16
|
+
# s.summary = "Ruby based make-like utility."
|
17
|
+
# s.name = 'rake'
|
18
|
+
# s.version = PKG_VERSION
|
19
|
+
# s.requirements << 'none'
|
20
|
+
# s.files = PKG_FILES
|
21
|
+
# s.description = <<-EOF
|
22
|
+
# Rake is a Make-like program implemented in Ruby. Tasks
|
23
|
+
# and dependencies are specified in standard Ruby syntax.
|
24
|
+
# EOF
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# Gem::Package.build spec
|
28
|
+
#
|
29
|
+
# Reads a .gem file.
|
30
|
+
#
|
31
|
+
# require 'rubygems'
|
32
|
+
# require 'rubygems/package'
|
33
|
+
#
|
34
|
+
# the_gem = Gem::Package.new(path_to_dot_gem)
|
35
|
+
# the_gem.contents # get the files in the gem
|
36
|
+
# the_gem.extract_files destination_directory # extract the gem into a directory
|
37
|
+
# the_gem.spec # get the spec out of the gem
|
38
|
+
# the_gem.verify # check the gem is OK (contains valid gem specification, contains a not corrupt contents archive)
|
39
|
+
#
|
40
|
+
# #files are the files in the .gem tar file, not the ruby files in the gem
|
41
|
+
# #extract_files and #contents automatically call #verify
|
6
42
|
|
43
|
+
require 'rubygems/security'
|
7
44
|
require 'rubygems/specification'
|
45
|
+
require 'rubygems/user_interaction'
|
46
|
+
require 'zlib'
|
8
47
|
|
9
|
-
|
48
|
+
class Gem::Package
|
49
|
+
|
50
|
+
include Gem::UserInteraction
|
51
|
+
|
52
|
+
class Error < Gem::Exception; end
|
10
53
|
|
11
|
-
class Error < StandardError; end
|
12
|
-
class NonSeekableIO < Error; end
|
13
|
-
class ClosedIO < Error; end
|
14
|
-
class BadCheckSum < Error; end
|
15
|
-
class TooLongFileName < Error; end
|
16
54
|
class FormatError < Error
|
17
55
|
attr_reader :path
|
18
56
|
|
@@ -26,57 +64,490 @@ module Gem::Package
|
|
26
64
|
|
27
65
|
end
|
28
66
|
|
67
|
+
class PathError < Error
|
68
|
+
def initialize destination, destination_dir
|
69
|
+
super "installing into parent path %s of %s is not allowed" %
|
70
|
+
[destination, destination_dir]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class NonSeekableIO < Error; end
|
75
|
+
|
76
|
+
class TooLongFileName < Error; end
|
77
|
+
|
29
78
|
##
|
30
79
|
# Raised when a tar file is corrupt
|
31
80
|
|
32
81
|
class TarInvalidError < Error; end
|
33
82
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
83
|
+
attr_accessor :build_time # :nodoc:
|
84
|
+
|
85
|
+
##
|
86
|
+
# Checksums for the contents of the package
|
87
|
+
|
88
|
+
attr_reader :checksums
|
89
|
+
|
90
|
+
##
|
91
|
+
# The files in this package. This is not the contents of the gem, just the
|
92
|
+
# files in the top-level container.
|
93
|
+
|
94
|
+
attr_reader :files
|
95
|
+
|
96
|
+
##
|
97
|
+
# The security policy used for verifying the contents of this package.
|
98
|
+
|
99
|
+
attr_accessor :security_policy
|
100
|
+
|
101
|
+
##
|
102
|
+
# Sets the Gem::Specification to use to build this package.
|
103
|
+
|
104
|
+
attr_writer :spec
|
105
|
+
|
106
|
+
def self.build spec, skip_validation=false
|
107
|
+
gem_file = spec.file_name
|
108
|
+
|
109
|
+
package = new gem_file
|
110
|
+
package.spec = spec
|
111
|
+
package.build skip_validation
|
112
|
+
|
113
|
+
gem_file
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# Creates a new Gem::Package for the file at +gem+.
|
118
|
+
#
|
119
|
+
# If +gem+ is an existing file in the old format a Gem::Package::Old will be
|
120
|
+
# returned.
|
121
|
+
|
122
|
+
def self.new gem
|
123
|
+
return super unless Gem::Package == self
|
124
|
+
return super unless File.exist? gem
|
125
|
+
|
126
|
+
start = File.read gem, 20
|
127
|
+
|
128
|
+
return super unless start
|
129
|
+
return super unless start.include? 'MD5SUM ='
|
130
|
+
|
131
|
+
Gem::Package::Old.new gem
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# Creates a new package that will read or write to the file +gem+.
|
136
|
+
|
137
|
+
def initialize gem # :notnew:
|
138
|
+
@gem = gem
|
139
|
+
|
140
|
+
@build_time = Time.now
|
141
|
+
@checksums = {}
|
142
|
+
@contents = nil
|
143
|
+
@digests = Hash.new { |h, algorithm| h[algorithm] = {} }
|
144
|
+
@files = nil
|
145
|
+
@security_policy = nil
|
146
|
+
@signatures = {}
|
147
|
+
@signer = nil
|
148
|
+
@spec = nil
|
149
|
+
end
|
150
|
+
|
151
|
+
##
|
152
|
+
# Adds a checksum for each entry in the gem to checksums.yaml.gz.
|
153
|
+
|
154
|
+
def add_checksums tar
|
155
|
+
Gem.load_yaml
|
156
|
+
|
157
|
+
checksums_by_algorithm = Hash.new { |h, algorithm| h[algorithm] = {} }
|
158
|
+
|
159
|
+
@checksums.each do |name, digests|
|
160
|
+
digests.each do |algorithm, digest|
|
161
|
+
checksums_by_algorithm[algorithm][name] = digest.hexdigest
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
tar.add_file_signed 'checksums.yaml.gz', 0444, @signer do |io|
|
166
|
+
gzip_to io do |gz_io|
|
167
|
+
YAML.dump checksums_by_algorithm, gz_io
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
##
|
173
|
+
# Adds the files listed in the packages's Gem::Specification to data.tar.gz
|
174
|
+
# and adds this file to the +tar+.
|
175
|
+
|
176
|
+
def add_contents tar # :nodoc:
|
177
|
+
digests = tar.add_file_signed 'data.tar.gz', 0444, @signer do |io|
|
178
|
+
gzip_to io do |gz_io|
|
179
|
+
Gem::Package::TarWriter.new gz_io do |data_tar|
|
180
|
+
add_files data_tar
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
@checksums['data.tar.gz'] = digests
|
186
|
+
end
|
187
|
+
|
188
|
+
##
|
189
|
+
# Adds files included the package's Gem::Specification to the +tar+ file
|
190
|
+
|
191
|
+
def add_files tar # :nodoc:
|
192
|
+
@spec.files.each do |file|
|
193
|
+
stat = File.stat file
|
194
|
+
|
195
|
+
tar.add_file_simple file, stat.mode, stat.size do |dst_io|
|
196
|
+
open file, 'rb' do |src_io|
|
197
|
+
dst_io.write src_io.read 16384 until src_io.eof?
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
##
|
204
|
+
# Adds the package's Gem::Specification to the +tar+ file
|
205
|
+
|
206
|
+
def add_metadata tar # :nodoc:
|
207
|
+
digests = tar.add_file_signed 'metadata.gz', 0444, @signer do |io|
|
208
|
+
gzip_to io do |gz_io|
|
209
|
+
gz_io.write @spec.to_yaml
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
@checksums['metadata.gz'] = digests
|
214
|
+
end
|
215
|
+
|
216
|
+
##
|
217
|
+
# Builds this package based on the specification set by #spec=
|
218
|
+
|
219
|
+
def build skip_validation = false
|
220
|
+
Gem.load_yaml
|
221
|
+
require 'rubygems/security'
|
222
|
+
|
223
|
+
@spec.validate unless skip_validation
|
224
|
+
@spec.mark_version
|
225
|
+
|
226
|
+
setup_signer
|
227
|
+
|
228
|
+
open @gem, 'wb' do |gem_io|
|
229
|
+
Gem::Package::TarWriter.new gem_io do |gem|
|
230
|
+
add_metadata gem
|
231
|
+
add_contents gem
|
232
|
+
add_checksums gem
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
say <<-EOM
|
237
|
+
Successfully built RubyGem
|
238
|
+
Name: #{@spec.name}
|
239
|
+
Version: #{@spec.version}
|
240
|
+
File: #{File.basename @spec.cache_file}
|
241
|
+
EOM
|
242
|
+
ensure
|
243
|
+
@signer = nil
|
244
|
+
end
|
245
|
+
|
246
|
+
##
|
247
|
+
# A list of file names contained in this gem
|
248
|
+
|
249
|
+
def contents
|
250
|
+
return @contents if @contents
|
251
|
+
|
252
|
+
verify unless @spec
|
253
|
+
|
254
|
+
@contents = []
|
255
|
+
|
256
|
+
open @gem, 'rb' do |io|
|
257
|
+
gem_tar = Gem::Package::TarReader.new io
|
258
|
+
|
259
|
+
gem_tar.each do |entry|
|
260
|
+
next unless entry.full_name == 'data.tar.gz'
|
261
|
+
|
262
|
+
open_tar_gz entry do |pkg_tar|
|
263
|
+
pkg_tar.each do |contents_entry|
|
264
|
+
@contents << contents_entry.full_name
|
68
265
|
end
|
69
266
|
end
|
267
|
+
|
268
|
+
return @contents
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
##
|
274
|
+
# Creates a digest of the TarEntry +entry+ from the digest algorithm set by
|
275
|
+
# the security policy.
|
276
|
+
|
277
|
+
def digest entry # :nodoc:
|
278
|
+
return unless @checksums
|
279
|
+
|
280
|
+
@checksums.each_key do |algorithm|
|
281
|
+
digester = OpenSSL::Digest.new algorithm
|
282
|
+
|
283
|
+
digester << entry.read(16384) until entry.eof?
|
284
|
+
|
285
|
+
entry.rewind
|
286
|
+
|
287
|
+
@digests[algorithm][entry.full_name] = digester
|
288
|
+
end
|
289
|
+
|
290
|
+
@digests
|
291
|
+
end
|
292
|
+
|
293
|
+
##
|
294
|
+
# Extracts the files in this package into +destination_dir+
|
295
|
+
|
296
|
+
def extract_files destination_dir
|
297
|
+
verify unless @spec
|
298
|
+
|
299
|
+
FileUtils.mkdir_p destination_dir
|
300
|
+
|
301
|
+
open @gem, 'rb' do |io|
|
302
|
+
reader = Gem::Package::TarReader.new io
|
303
|
+
|
304
|
+
reader.each do |entry|
|
305
|
+
next unless entry.full_name == 'data.tar.gz'
|
306
|
+
|
307
|
+
extract_tar_gz entry, destination_dir
|
308
|
+
|
309
|
+
return # ignore further entries
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
##
|
315
|
+
# Extracts all the files in the gzipped tar archive +io+ into
|
316
|
+
# +destination_dir+.
|
317
|
+
#
|
318
|
+
# If an entry in the archive contains a relative path above
|
319
|
+
# +destination_dir+ or an absolute path is encountered an exception is
|
320
|
+
# raised.
|
321
|
+
|
322
|
+
def extract_tar_gz io, destination_dir # :nodoc:
|
323
|
+
open_tar_gz io do |tar|
|
324
|
+
tar.each do |entry|
|
325
|
+
destination = install_location entry.full_name, destination_dir
|
326
|
+
|
327
|
+
FileUtils.rm_rf destination
|
328
|
+
|
329
|
+
FileUtils.mkdir_p File.dirname destination
|
330
|
+
|
331
|
+
open destination, 'wb', entry.header.mode do |out|
|
332
|
+
out.write entry.read
|
333
|
+
out.fsync rescue nil # for filesystems without fsync(2)
|
334
|
+
end
|
335
|
+
|
336
|
+
say destination if Gem.configuration.really_verbose
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
##
|
342
|
+
# Gzips content written to +gz_io+ to +io+.
|
343
|
+
#--
|
344
|
+
# Also sets the gzip modification time to the package build time to ease
|
345
|
+
# testing.
|
346
|
+
|
347
|
+
def gzip_to io # :yields: gz_io
|
348
|
+
gz_io = Zlib::GzipWriter.new io, Zlib::BEST_COMPRESSION
|
349
|
+
gz_io.mtime = @build_time
|
350
|
+
|
351
|
+
yield gz_io
|
352
|
+
ensure
|
353
|
+
gz_io.close
|
354
|
+
end
|
355
|
+
|
356
|
+
##
|
357
|
+
# Returns the full path for installing +filename+.
|
358
|
+
#
|
359
|
+
# If +filename+ is not inside +destination_dir+ an exception is raised.
|
360
|
+
|
361
|
+
def install_location filename, destination_dir # :nodoc:
|
362
|
+
raise Gem::Package::PathError.new(filename, destination_dir) if
|
363
|
+
filename.start_with? '/'
|
364
|
+
|
365
|
+
destination = File.join destination_dir, filename
|
366
|
+
destination = File.expand_path destination
|
367
|
+
|
368
|
+
raise Gem::Package::PathError.new(destination, destination_dir) unless
|
369
|
+
destination.start_with? destination_dir
|
370
|
+
|
371
|
+
destination.untaint
|
372
|
+
destination
|
373
|
+
end
|
374
|
+
|
375
|
+
##
|
376
|
+
# Loads a Gem::Specification from the TarEntry +entry+
|
377
|
+
|
378
|
+
def load_spec entry # :nodoc:
|
379
|
+
case entry.full_name
|
380
|
+
when 'metadata' then
|
381
|
+
@spec = Gem::Specification.from_yaml entry.read
|
382
|
+
when 'metadata.gz' then
|
383
|
+
args = [entry]
|
384
|
+
args << { :external_encoding => Encoding::UTF_8 } if
|
385
|
+
Object.const_defined? :Encoding
|
386
|
+
|
387
|
+
Zlib::GzipReader.wrap(*args) do |gzio|
|
388
|
+
@spec = Gem::Specification.from_yaml gzio.read
|
389
|
+
end
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
##
|
394
|
+
# Opens +io+ as a gzipped tar archive
|
395
|
+
|
396
|
+
def open_tar_gz io # :nodoc:
|
397
|
+
Zlib::GzipReader.wrap io do |gzio|
|
398
|
+
tar = Gem::Package::TarReader.new gzio
|
399
|
+
|
400
|
+
yield tar
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
##
|
405
|
+
# Reads and loads checksums.yaml.gz from the tar file +gem+
|
406
|
+
|
407
|
+
def read_checksums gem
|
408
|
+
Gem.load_yaml
|
409
|
+
|
410
|
+
@checksums = gem.seek 'checksums.yaml.gz' do |entry|
|
411
|
+
Zlib::GzipReader.wrap entry do |gz_io|
|
412
|
+
YAML.load gz_io.read
|
413
|
+
end
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
##
|
418
|
+
# Prepares the gem for signing and checksum generation. If a signing
|
419
|
+
# certificate and key are not present only checksum generation is set up.
|
420
|
+
|
421
|
+
def setup_signer
|
422
|
+
if @spec.signing_key then
|
423
|
+
@signer = Gem::Security::Signer.new @spec.signing_key, @spec.cert_chain
|
424
|
+
@spec.signing_key = nil
|
425
|
+
@spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_s }
|
426
|
+
else
|
427
|
+
@signer = Gem::Security::Signer.new nil, nil
|
428
|
+
@spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_pem } if
|
429
|
+
@signer.cert_chain
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
##
|
434
|
+
# The spec for this gem.
|
435
|
+
#
|
436
|
+
# If this is a package for a built gem the spec is loaded from the
|
437
|
+
# gem and returned. If this is a package for a gem being built the provided
|
438
|
+
# spec is returned.
|
439
|
+
|
440
|
+
def spec
|
441
|
+
verify unless @spec
|
442
|
+
|
443
|
+
@spec
|
444
|
+
end
|
445
|
+
|
446
|
+
##
|
447
|
+
# Verifies that this gem:
|
448
|
+
#
|
449
|
+
# * Contains a valid gem specification
|
450
|
+
# * Contains a contents archive
|
451
|
+
# * The contents archive is not corrupt
|
452
|
+
#
|
453
|
+
# After verification the gem specification from the gem is available from
|
454
|
+
# #spec
|
455
|
+
|
456
|
+
def verify
|
457
|
+
@files = []
|
458
|
+
@spec = nil
|
459
|
+
|
460
|
+
open @gem, 'rb' do |io|
|
461
|
+
Gem::Package::TarReader.new io do |reader|
|
462
|
+
read_checksums reader
|
463
|
+
|
464
|
+
verify_files reader
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
verify_checksums @digests, @checksums
|
469
|
+
|
470
|
+
@security_policy.verify_signatures @spec, @digests, @signatures if
|
471
|
+
@security_policy
|
472
|
+
|
473
|
+
true
|
474
|
+
rescue Errno::ENOENT => e
|
475
|
+
raise Gem::Package::FormatError.new e.message
|
476
|
+
rescue Gem::Package::TarInvalidError => e
|
477
|
+
raise Gem::Package::FormatError.new e.message, @gem
|
478
|
+
end
|
479
|
+
|
480
|
+
##
|
481
|
+
# Verifies the +checksums+ against the +digests+. This check is not
|
482
|
+
# cryptographically secure. Missing checksums are ignored.
|
483
|
+
|
484
|
+
def verify_checksums digests, checksums # :nodoc:
|
485
|
+
return unless checksums
|
486
|
+
|
487
|
+
checksums.sort.each do |algorithm, gem_digests|
|
488
|
+
gem_digests.sort.each do |file_name, gem_hexdigest|
|
489
|
+
computed_digest = digests[algorithm][file_name]
|
490
|
+
|
491
|
+
unless computed_digest.hexdigest == gem_hexdigest then
|
492
|
+
raise Gem::Package::FormatError.new \
|
493
|
+
"#{algorithm} checksum mismatch for #{file_name}", @gem
|
494
|
+
end
|
70
495
|
end
|
71
496
|
end
|
72
497
|
end
|
73
498
|
|
499
|
+
##
|
500
|
+
# Verifies the files of the +gem+
|
501
|
+
|
502
|
+
def verify_files gem
|
503
|
+
gem.each do |entry|
|
504
|
+
file_name = entry.full_name
|
505
|
+
@files << file_name
|
506
|
+
|
507
|
+
case file_name
|
508
|
+
when /\.sig$/ then
|
509
|
+
@signatures[$`] = entry.read if @security_policy
|
510
|
+
next
|
511
|
+
when 'checksums.yaml.gz' then
|
512
|
+
next # already handled
|
513
|
+
else
|
514
|
+
digest entry
|
515
|
+
end
|
516
|
+
|
517
|
+
case file_name
|
518
|
+
when /^metadata(.gz)?$/ then
|
519
|
+
load_spec entry
|
520
|
+
when 'data.tar.gz' then
|
521
|
+
verify_gz entry
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
unless @spec then
|
526
|
+
raise Gem::Package::FormatError.new 'package metadata is missing', @gem
|
527
|
+
end
|
528
|
+
|
529
|
+
unless @files.include? 'data.tar.gz' then
|
530
|
+
raise Gem::Package::FormatError.new \
|
531
|
+
'package content (data.tar.gz) is missing', @gem
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
##
|
536
|
+
# Verifies that +entry+ is a valid gzipped file.
|
537
|
+
|
538
|
+
def verify_gz entry # :nodoc:
|
539
|
+
Zlib::GzipReader.wrap entry do |gzio|
|
540
|
+
gzio.read 16384 until gzio.eof? # gzip checksum verification
|
541
|
+
end
|
542
|
+
rescue Zlib::GzipFile::Error => e
|
543
|
+
raise Gem::Package::FormatError.new(e.message, entry.full_name)
|
544
|
+
end
|
545
|
+
|
74
546
|
end
|
75
547
|
|
76
|
-
require 'rubygems/package/
|
548
|
+
require 'rubygems/package/digest_io'
|
549
|
+
require 'rubygems/package/old'
|
77
550
|
require 'rubygems/package/tar_header'
|
78
|
-
require 'rubygems/package/tar_input'
|
79
|
-
require 'rubygems/package/tar_output'
|
80
551
|
require 'rubygems/package/tar_reader'
|
81
552
|
require 'rubygems/package/tar_reader/entry'
|
82
553
|
require 'rubygems/package/tar_writer'
|