libgems 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +5811 -0
- data/History.txt +887 -0
- data/LICENSE.txt +51 -0
- data/README.md +87 -0
- data/Rakefile +113 -0
- data/lib/gauntlet_libgems.rb +50 -0
- data/lib/libgems.rb +1246 -0
- data/lib/libgems/builder.rb +102 -0
- data/lib/libgems/command.rb +534 -0
- data/lib/libgems/command_manager.rb +182 -0
- data/lib/libgems/commands/build_command.rb +53 -0
- data/lib/libgems/commands/cert_command.rb +86 -0
- data/lib/libgems/commands/check_command.rb +80 -0
- data/lib/libgems/commands/cleanup_command.rb +106 -0
- data/lib/libgems/commands/contents_command.rb +98 -0
- data/lib/libgems/commands/dependency_command.rb +195 -0
- data/lib/libgems/commands/environment_command.rb +133 -0
- data/lib/libgems/commands/fetch_command.rb +67 -0
- data/lib/libgems/commands/generate_index_command.rb +133 -0
- data/lib/libgems/commands/help_command.rb +172 -0
- data/lib/libgems/commands/install_command.rb +178 -0
- data/lib/libgems/commands/list_command.rb +35 -0
- data/lib/libgems/commands/lock_command.rb +110 -0
- data/lib/libgems/commands/mirror_command.rb +111 -0
- data/lib/libgems/commands/outdated_command.rb +33 -0
- data/lib/libgems/commands/owner_command.rb +75 -0
- data/lib/libgems/commands/pristine_command.rb +93 -0
- data/lib/libgems/commands/push_command.rb +56 -0
- data/lib/libgems/commands/query_command.rb +280 -0
- data/lib/libgems/commands/rdoc_command.rb +91 -0
- data/lib/libgems/commands/search_command.rb +31 -0
- data/lib/libgems/commands/server_command.rb +86 -0
- data/lib/libgems/commands/sources_command.rb +157 -0
- data/lib/libgems/commands/specification_command.rb +125 -0
- data/lib/libgems/commands/stale_command.rb +27 -0
- data/lib/libgems/commands/uninstall_command.rb +83 -0
- data/lib/libgems/commands/unpack_command.rb +121 -0
- data/lib/libgems/commands/update_command.rb +160 -0
- data/lib/libgems/commands/which_command.rb +86 -0
- data/lib/libgems/config_file.rb +345 -0
- data/lib/libgems/custom_require.rb +44 -0
- data/lib/libgems/defaults.rb +101 -0
- data/lib/libgems/dependency.rb +227 -0
- data/lib/libgems/dependency_installer.rb +286 -0
- data/lib/libgems/dependency_list.rb +208 -0
- data/lib/libgems/doc_manager.rb +242 -0
- data/lib/libgems/errors.rb +35 -0
- data/lib/libgems/exceptions.rb +91 -0
- data/lib/libgems/ext.rb +18 -0
- data/lib/libgems/ext/builder.rb +56 -0
- data/lib/libgems/ext/configure_builder.rb +25 -0
- data/lib/libgems/ext/ext_conf_builder.rb +24 -0
- data/lib/libgems/ext/rake_builder.rb +39 -0
- data/lib/libgems/format.rb +81 -0
- data/lib/libgems/gem_openssl.rb +92 -0
- data/lib/libgems/gem_path_searcher.rb +100 -0
- data/lib/libgems/gem_runner.rb +79 -0
- data/lib/libgems/gemcutter_utilities.rb +49 -0
- data/lib/libgems/indexer.rb +720 -0
- data/lib/libgems/install_update_options.rb +125 -0
- data/lib/libgems/installer.rb +604 -0
- data/lib/libgems/local_remote_options.rb +135 -0
- data/lib/libgems/old_format.rb +153 -0
- data/lib/libgems/package.rb +97 -0
- data/lib/libgems/package/f_sync_dir.rb +23 -0
- data/lib/libgems/package/tar_header.rb +266 -0
- data/lib/libgems/package/tar_input.rb +222 -0
- data/lib/libgems/package/tar_output.rb +144 -0
- data/lib/libgems/package/tar_reader.rb +106 -0
- data/lib/libgems/package/tar_reader/entry.rb +141 -0
- data/lib/libgems/package/tar_writer.rb +241 -0
- data/lib/libgems/package_task.rb +126 -0
- data/lib/libgems/platform.rb +183 -0
- data/lib/libgems/remote_fetcher.rb +414 -0
- data/lib/libgems/require_paths_builder.rb +18 -0
- data/lib/libgems/requirement.rb +153 -0
- data/lib/libgems/security.rb +814 -0
- data/lib/libgems/server.rb +872 -0
- data/lib/libgems/source_index.rb +597 -0
- data/lib/libgems/source_info_cache.rb +395 -0
- data/lib/libgems/source_info_cache_entry.rb +56 -0
- data/lib/libgems/spec_fetcher.rb +337 -0
- data/lib/libgems/specification.rb +1487 -0
- data/lib/libgems/test_utilities.rb +147 -0
- data/lib/libgems/text.rb +65 -0
- data/lib/libgems/uninstaller.rb +278 -0
- data/lib/libgems/user_interaction.rb +527 -0
- data/lib/libgems/validator.rb +240 -0
- data/lib/libgems/version.rb +316 -0
- data/lib/libgems/version_option.rb +65 -0
- data/lib/rbconfig/datadir.rb +20 -0
- data/test/bogussources.rb +8 -0
- data/test/data/gem-private_key.pem +27 -0
- data/test/data/gem-public_cert.pem +20 -0
- data/test/fake_certlib/openssl.rb +7 -0
- data/test/foo/discover.rb +0 -0
- data/test/gem_installer_test_case.rb +97 -0
- data/test/gem_package_tar_test_case.rb +132 -0
- data/test/gemutilities.rb +605 -0
- data/test/insure_session.rb +43 -0
- data/test/mockgemui.rb +56 -0
- data/test/plugin/exception/libgems_plugin.rb +2 -0
- data/test/plugin/load/libgems_plugin.rb +1 -0
- data/test/plugin/standarderror/libgems_plugin.rb +2 -0
- data/test/private_key.pem +27 -0
- data/test/public_cert.pem +20 -0
- data/test/rubygems_plugin.rb +21 -0
- data/test/simple_gem.rb +66 -0
- data/test/test_config.rb +12 -0
- data/test/test_gem.rb +780 -0
- data/test/test_gem_builder.rb +27 -0
- data/test/test_gem_command.rb +178 -0
- data/test/test_gem_command_manager.rb +207 -0
- data/test/test_gem_commands_build_command.rb +74 -0
- data/test/test_gem_commands_cert_command.rb +124 -0
- data/test/test_gem_commands_check_command.rb +18 -0
- data/test/test_gem_commands_contents_command.rb +156 -0
- data/test/test_gem_commands_dependency_command.rb +216 -0
- data/test/test_gem_commands_environment_command.rb +144 -0
- data/test/test_gem_commands_fetch_command.rb +76 -0
- data/test/test_gem_commands_generate_index_command.rb +135 -0
- data/test/test_gem_commands_install_command.rb +315 -0
- data/test/test_gem_commands_list_command.rb +36 -0
- data/test/test_gem_commands_lock_command.rb +68 -0
- data/test/test_gem_commands_mirror_command.rb +60 -0
- data/test/test_gem_commands_outdated_command.rb +40 -0
- data/test/test_gem_commands_owner_command.rb +105 -0
- data/test/test_gem_commands_pristine_command.rb +108 -0
- data/test/test_gem_commands_push_command.rb +81 -0
- data/test/test_gem_commands_query_command.rb +426 -0
- data/test/test_gem_commands_server_command.rb +59 -0
- data/test/test_gem_commands_sources_command.rb +209 -0
- data/test/test_gem_commands_specification_command.rb +139 -0
- data/test/test_gem_commands_stale_command.rb +38 -0
- data/test/test_gem_commands_uninstall_command.rb +83 -0
- data/test/test_gem_commands_unpack_command.rb +199 -0
- data/test/test_gem_commands_update_command.rb +207 -0
- data/test/test_gem_commands_which_command.rb +66 -0
- data/test/test_gem_config_file.rb +287 -0
- data/test/test_gem_dependency.rb +149 -0
- data/test/test_gem_dependency_installer.rb +661 -0
- data/test/test_gem_dependency_list.rb +230 -0
- data/test/test_gem_doc_manager.rb +31 -0
- data/test/test_gem_ext_configure_builder.rb +84 -0
- data/test/test_gem_ext_ext_conf_builder.rb +173 -0
- data/test/test_gem_ext_rake_builder.rb +81 -0
- data/test/test_gem_format.rb +70 -0
- data/test/test_gem_gem_path_searcher.rb +78 -0
- data/test/test_gem_gem_runner.rb +45 -0
- data/test/test_gem_gemcutter_utilities.rb +103 -0
- data/test/test_gem_indexer.rb +673 -0
- data/test/test_gem_install_update_options.rb +68 -0
- data/test/test_gem_installer.rb +857 -0
- data/test/test_gem_local_remote_options.rb +97 -0
- data/test/test_gem_package_tar_header.rb +130 -0
- data/test/test_gem_package_tar_input.rb +112 -0
- data/test/test_gem_package_tar_output.rb +97 -0
- data/test/test_gem_package_tar_reader.rb +46 -0
- data/test/test_gem_package_tar_reader_entry.rb +109 -0
- data/test/test_gem_package_tar_writer.rb +144 -0
- data/test/test_gem_package_task.rb +59 -0
- data/test/test_gem_platform.rb +264 -0
- data/test/test_gem_remote_fetcher.rb +740 -0
- data/test/test_gem_requirement.rb +292 -0
- data/test/test_gem_server.rb +356 -0
- data/test/test_gem_silent_ui.rb +113 -0
- data/test/test_gem_source_index.rb +461 -0
- data/test/test_gem_spec_fetcher.rb +410 -0
- data/test/test_gem_specification.rb +1334 -0
- data/test/test_gem_stream_ui.rb +218 -0
- data/test/test_gem_text.rb +43 -0
- data/test/test_gem_uninstaller.rb +146 -0
- data/test/test_gem_validator.rb +63 -0
- data/test/test_gem_version.rb +181 -0
- data/test/test_gem_version_option.rb +89 -0
- data/test/test_kernel.rb +59 -0
- metadata +402 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# -*- coding: iso-8859-1 -*-
|
|
2
|
+
#++
|
|
3
|
+
# Copyright (C) 2004 Mauricio Julio Fern�ndez Pradier
|
|
4
|
+
# See LICENSE.txt for additional licensing information.
|
|
5
|
+
#--
|
|
6
|
+
|
|
7
|
+
require 'zlib'
|
|
8
|
+
LibGems.load_yaml
|
|
9
|
+
|
|
10
|
+
class LibGems::Package::TarInput
|
|
11
|
+
|
|
12
|
+
include LibGems::Package::FSyncDir
|
|
13
|
+
include Enumerable
|
|
14
|
+
|
|
15
|
+
attr_reader :metadata
|
|
16
|
+
|
|
17
|
+
private_class_method :new
|
|
18
|
+
|
|
19
|
+
def self.open(io, security_policy = nil, &block)
|
|
20
|
+
is = new io, security_policy
|
|
21
|
+
|
|
22
|
+
yield is
|
|
23
|
+
ensure
|
|
24
|
+
is.close if is
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def initialize(io, security_policy = nil)
|
|
28
|
+
@io = io
|
|
29
|
+
@tarreader = LibGems::Package::TarReader.new @io
|
|
30
|
+
has_meta = false
|
|
31
|
+
|
|
32
|
+
data_sig, meta_sig, data_dgst, meta_dgst = nil, nil, nil, nil
|
|
33
|
+
dgst_algo = security_policy ? LibGems::Security::OPT[:dgst_algo] : nil
|
|
34
|
+
|
|
35
|
+
@tarreader.each do |entry|
|
|
36
|
+
case entry.full_name
|
|
37
|
+
when "metadata"
|
|
38
|
+
@metadata = load_gemspec entry.read
|
|
39
|
+
has_meta = true
|
|
40
|
+
when "metadata.gz"
|
|
41
|
+
begin
|
|
42
|
+
# if we have a security_policy, then pre-read the metadata file
|
|
43
|
+
# and calculate it's digest
|
|
44
|
+
sio = nil
|
|
45
|
+
if security_policy
|
|
46
|
+
LibGems.ensure_ssl_available
|
|
47
|
+
sio = StringIO.new(entry.read)
|
|
48
|
+
meta_dgst = dgst_algo.digest(sio.string)
|
|
49
|
+
sio.rewind
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
gzis = Zlib::GzipReader.new(sio || entry)
|
|
53
|
+
# YAML wants an instance of IO
|
|
54
|
+
@metadata = load_gemspec(gzis)
|
|
55
|
+
has_meta = true
|
|
56
|
+
ensure
|
|
57
|
+
gzis.close unless gzis.nil?
|
|
58
|
+
end
|
|
59
|
+
when 'metadata.gz.sig'
|
|
60
|
+
meta_sig = entry.read
|
|
61
|
+
when 'data.tar.gz.sig'
|
|
62
|
+
data_sig = entry.read
|
|
63
|
+
when 'data.tar.gz'
|
|
64
|
+
if security_policy
|
|
65
|
+
LibGems.ensure_ssl_available
|
|
66
|
+
data_dgst = dgst_algo.digest(entry.read)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if security_policy then
|
|
72
|
+
LibGems.ensure_ssl_available
|
|
73
|
+
|
|
74
|
+
# map trust policy from string to actual class (or a serialized YAML
|
|
75
|
+
# file, if that exists)
|
|
76
|
+
if String === security_policy then
|
|
77
|
+
if LibGems::Security::Policies.key? security_policy then
|
|
78
|
+
# load one of the pre-defined security policies
|
|
79
|
+
security_policy = LibGems::Security::Policies[security_policy]
|
|
80
|
+
elsif File.exist? security_policy then
|
|
81
|
+
# FIXME: this doesn't work yet
|
|
82
|
+
security_policy = YAML.load File.read(security_policy)
|
|
83
|
+
else
|
|
84
|
+
raise LibGems::Exception, "Unknown trust policy '#{security_policy}'"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
if data_sig && data_dgst && meta_sig && meta_dgst then
|
|
89
|
+
# the user has a trust policy, and we have a signed gem
|
|
90
|
+
# file, so use the trust policy to verify the gem signature
|
|
91
|
+
|
|
92
|
+
begin
|
|
93
|
+
security_policy.verify_gem(data_sig, data_dgst, @metadata.cert_chain)
|
|
94
|
+
rescue Exception => e
|
|
95
|
+
raise "Couldn't verify data signature: #{e}"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
begin
|
|
99
|
+
security_policy.verify_gem(meta_sig, meta_dgst, @metadata.cert_chain)
|
|
100
|
+
rescue Exception => e
|
|
101
|
+
raise "Couldn't verify metadata signature: #{e}"
|
|
102
|
+
end
|
|
103
|
+
elsif security_policy.only_signed
|
|
104
|
+
raise LibGems::Exception, "Unsigned gem"
|
|
105
|
+
else
|
|
106
|
+
# FIXME: should display warning here (trust policy, but
|
|
107
|
+
# either unsigned or badly signed gem file)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
@tarreader.rewind
|
|
112
|
+
@fileops = LibGems::FileOperations.new
|
|
113
|
+
|
|
114
|
+
raise LibGems::Package::FormatError, "No metadata found!" unless has_meta
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def close
|
|
118
|
+
@io.close
|
|
119
|
+
@tarreader.close
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def each(&block)
|
|
123
|
+
@tarreader.each do |entry|
|
|
124
|
+
next unless entry.full_name == "data.tar.gz"
|
|
125
|
+
is = zipped_stream entry
|
|
126
|
+
|
|
127
|
+
begin
|
|
128
|
+
LibGems::Package::TarReader.new is do |inner|
|
|
129
|
+
inner.each(&block)
|
|
130
|
+
end
|
|
131
|
+
ensure
|
|
132
|
+
is.close if is
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
@tarreader.rewind
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def extract_entry(destdir, entry, expected_md5sum = nil)
|
|
140
|
+
if entry.directory? then
|
|
141
|
+
dest = File.join destdir, entry.full_name
|
|
142
|
+
|
|
143
|
+
if File.directory? dest then
|
|
144
|
+
@fileops.chmod entry.header.mode, dest, :verbose => false
|
|
145
|
+
else
|
|
146
|
+
@fileops.mkdir_p dest, :mode => entry.header.mode, :verbose => false
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
fsync_dir dest
|
|
150
|
+
fsync_dir File.join(dest, "..")
|
|
151
|
+
|
|
152
|
+
return
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# it's a file
|
|
156
|
+
md5 = Digest::MD5.new if expected_md5sum
|
|
157
|
+
destdir = File.join destdir, File.dirname(entry.full_name)
|
|
158
|
+
@fileops.mkdir_p destdir, :mode => 0755, :verbose => false
|
|
159
|
+
destfile = File.join destdir, File.basename(entry.full_name)
|
|
160
|
+
@fileops.chmod 0600, destfile, :verbose => false rescue nil # Errno::ENOENT
|
|
161
|
+
|
|
162
|
+
open destfile, "wb", entry.header.mode do |os|
|
|
163
|
+
loop do
|
|
164
|
+
data = entry.read 4096
|
|
165
|
+
break unless data
|
|
166
|
+
# HACK shouldn't we check the MD5 before writing to disk?
|
|
167
|
+
md5 << data if expected_md5sum
|
|
168
|
+
os.write(data)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
os.fsync
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
@fileops.chmod entry.header.mode, destfile, :verbose => false
|
|
175
|
+
fsync_dir File.dirname(destfile)
|
|
176
|
+
fsync_dir File.join(File.dirname(destfile), "..")
|
|
177
|
+
|
|
178
|
+
if expected_md5sum && expected_md5sum != md5.hexdigest then
|
|
179
|
+
raise LibGems::Package::BadCheckSum
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Attempt to YAML-load a gemspec from the given _io_ parameter. Return
|
|
184
|
+
# nil if it fails.
|
|
185
|
+
def load_gemspec(io)
|
|
186
|
+
LibGems::Specification.from_yaml io
|
|
187
|
+
rescue LibGems::Exception
|
|
188
|
+
nil
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
##
|
|
192
|
+
# Return an IO stream for the zipped entry.
|
|
193
|
+
#
|
|
194
|
+
# NOTE: Originally this method used two approaches, Return a GZipReader
|
|
195
|
+
# directly, or read the GZipReader into a string and return a StringIO on
|
|
196
|
+
# the string. The string IO approach was used for versions of ZLib before
|
|
197
|
+
# 1.2.1 to avoid buffer errors on windows machines. Then we found that
|
|
198
|
+
# errors happened with 1.2.1 as well, so we changed the condition. Then
|
|
199
|
+
# we discovered errors occurred with versions as late as 1.2.3. At this
|
|
200
|
+
# point (after some benchmarking to show we weren't seriously crippling
|
|
201
|
+
# the unpacking speed) we threw our hands in the air and declared that
|
|
202
|
+
# this method would use the String IO approach on all platforms at all
|
|
203
|
+
# times. And that's the way it is.
|
|
204
|
+
|
|
205
|
+
def zipped_stream(entry)
|
|
206
|
+
if defined? Rubinius or defined? Maglev then
|
|
207
|
+
# these implementations have working Zlib
|
|
208
|
+
zis = Zlib::GzipReader.new entry
|
|
209
|
+
dis = zis.read
|
|
210
|
+
is = StringIO.new(dis)
|
|
211
|
+
else
|
|
212
|
+
# This is Jamis Buck's Zlib workaround for some unknown issue
|
|
213
|
+
entry.read(10) # skip the gzip header
|
|
214
|
+
zis = Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
|
215
|
+
is = StringIO.new(zis.inflate(entry.read))
|
|
216
|
+
end
|
|
217
|
+
ensure
|
|
218
|
+
zis.finish if zis
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
end
|
|
222
|
+
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#--
|
|
3
|
+
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
|
|
4
|
+
# See LICENSE.txt for additional licensing information.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# TarOutput is a wrapper to TarWriter that builds gem-format tar file.
|
|
9
|
+
#
|
|
10
|
+
# LibGems-format tar files contain the following files:
|
|
11
|
+
# [data.tar.gz] A gzipped tar file containing the files that compose the gem
|
|
12
|
+
# which will be extracted into the gem/ dir on installation.
|
|
13
|
+
# [metadata.gz] A YAML format LibGems::Specification.
|
|
14
|
+
# [data.tar.gz.sig] A signature for the gem's data.tar.gz.
|
|
15
|
+
# [metadata.gz.sig] A signature for the gem's metadata.gz.
|
|
16
|
+
#
|
|
17
|
+
# See TarOutput::open for usage details.
|
|
18
|
+
|
|
19
|
+
class LibGems::Package::TarOutput
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# Creates a new TarOutput which will yield a TarWriter object for the
|
|
23
|
+
# data.tar.gz portion of a gem-format tar file.
|
|
24
|
+
#
|
|
25
|
+
# See #initialize for details on +io+ and +signer+.
|
|
26
|
+
#
|
|
27
|
+
# See #add_gem_contents for details on adding metadata to the tar file.
|
|
28
|
+
|
|
29
|
+
def self.open(io, signer = nil, &block) # :yield: data_tar_writer
|
|
30
|
+
tar_outputter = new io, signer
|
|
31
|
+
tar_outputter.add_gem_contents(&block)
|
|
32
|
+
tar_outputter.add_metadata
|
|
33
|
+
tar_outputter.add_signatures
|
|
34
|
+
|
|
35
|
+
ensure
|
|
36
|
+
tar_outputter.close
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Creates a new TarOutput that will write a gem-format tar file to +io+. If
|
|
41
|
+
# +signer+ is given, the data.tar.gz and metadata.gz will be signed and
|
|
42
|
+
# the signatures will be added to the tar file.
|
|
43
|
+
|
|
44
|
+
def initialize(io, signer)
|
|
45
|
+
@io = io
|
|
46
|
+
@signer = signer
|
|
47
|
+
|
|
48
|
+
@tar_writer = LibGems::Package::TarWriter.new @io
|
|
49
|
+
|
|
50
|
+
@metadata = nil
|
|
51
|
+
|
|
52
|
+
@data_signature = nil
|
|
53
|
+
@meta_signature = nil
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
##
|
|
57
|
+
# Yields a TarWriter for the data.tar.gz inside a gem-format tar file.
|
|
58
|
+
# The yielded TarWriter has been extended with a #metadata= method for
|
|
59
|
+
# attaching a YAML format LibGems::Specification which will be written by
|
|
60
|
+
# add_metadata.
|
|
61
|
+
|
|
62
|
+
def add_gem_contents
|
|
63
|
+
@tar_writer.add_file "data.tar.gz", 0644 do |inner|
|
|
64
|
+
sio = @signer ? StringIO.new : nil
|
|
65
|
+
Zlib::GzipWriter.wrap(sio || inner) do |os|
|
|
66
|
+
|
|
67
|
+
LibGems::Package::TarWriter.new os do |data_tar_writer|
|
|
68
|
+
# :stopdoc:
|
|
69
|
+
def data_tar_writer.metadata() @metadata end
|
|
70
|
+
def data_tar_writer.metadata=(metadata) @metadata = metadata end
|
|
71
|
+
# :startdoc:
|
|
72
|
+
|
|
73
|
+
yield data_tar_writer
|
|
74
|
+
|
|
75
|
+
@metadata = data_tar_writer.metadata
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# if we have a signing key, then sign the data
|
|
80
|
+
# digest and return the signature
|
|
81
|
+
if @signer then
|
|
82
|
+
digest = LibGems::Security::OPT[:dgst_algo].digest sio.string
|
|
83
|
+
@data_signature = @signer.sign digest
|
|
84
|
+
inner.write sio.string
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
self
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
##
|
|
92
|
+
# Adds metadata.gz to the gem-format tar file which was saved from a
|
|
93
|
+
# previous #add_gem_contents call.
|
|
94
|
+
|
|
95
|
+
def add_metadata
|
|
96
|
+
return if @metadata.nil?
|
|
97
|
+
|
|
98
|
+
@tar_writer.add_file "metadata.gz", 0644 do |io|
|
|
99
|
+
begin
|
|
100
|
+
sio = @signer ? StringIO.new : nil
|
|
101
|
+
gzos = Zlib::GzipWriter.new(sio || io)
|
|
102
|
+
gzos.write @metadata
|
|
103
|
+
ensure
|
|
104
|
+
gzos.flush
|
|
105
|
+
gzos.finish
|
|
106
|
+
|
|
107
|
+
# if we have a signing key, then sign the metadata digest and return
|
|
108
|
+
# the signature
|
|
109
|
+
if @signer then
|
|
110
|
+
digest = LibGems::Security::OPT[:dgst_algo].digest sio.string
|
|
111
|
+
@meta_signature = @signer.sign digest
|
|
112
|
+
io.write sio.string
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
##
|
|
119
|
+
# Adds data.tar.gz.sig and metadata.gz.sig to the gem-format tar files if
|
|
120
|
+
# a LibGems::Security::Signer was sent to initialize.
|
|
121
|
+
|
|
122
|
+
def add_signatures
|
|
123
|
+
if @data_signature then
|
|
124
|
+
@tar_writer.add_file 'data.tar.gz.sig', 0644 do |io|
|
|
125
|
+
io.write @data_signature
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
if @meta_signature then
|
|
130
|
+
@tar_writer.add_file 'metadata.gz.sig', 0644 do |io|
|
|
131
|
+
io.write @meta_signature
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
##
|
|
137
|
+
# Closes the TarOutput.
|
|
138
|
+
|
|
139
|
+
def close
|
|
140
|
+
@tar_writer.close
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
end
|
|
144
|
+
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#--
|
|
3
|
+
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
|
|
4
|
+
# See LICENSE.txt for additional licensing information.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# TarReader reads tar files and allows iteration over their items
|
|
9
|
+
|
|
10
|
+
class LibGems::Package::TarReader
|
|
11
|
+
|
|
12
|
+
include LibGems::Package
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Raised if the tar IO is not seekable
|
|
16
|
+
|
|
17
|
+
class UnexpectedEOF < StandardError; end
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Creates a new TarReader on +io+ and yields it to the block, if given.
|
|
21
|
+
|
|
22
|
+
def self.new(io)
|
|
23
|
+
reader = super
|
|
24
|
+
|
|
25
|
+
return reader unless block_given?
|
|
26
|
+
|
|
27
|
+
begin
|
|
28
|
+
yield reader
|
|
29
|
+
ensure
|
|
30
|
+
reader.close
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Creates a new tar file reader on +io+ which needs to respond to #pos,
|
|
38
|
+
# #eof?, #read, #getc and #pos=
|
|
39
|
+
|
|
40
|
+
def initialize(io)
|
|
41
|
+
@io = io
|
|
42
|
+
@init_pos = io.pos
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Close the tar file
|
|
47
|
+
|
|
48
|
+
def close
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# Iterates over files in the tarball yielding each entry
|
|
53
|
+
|
|
54
|
+
def each
|
|
55
|
+
loop do
|
|
56
|
+
return if @io.eof?
|
|
57
|
+
|
|
58
|
+
header = LibGems::Package::TarHeader.from @io
|
|
59
|
+
return if header.empty?
|
|
60
|
+
|
|
61
|
+
entry = LibGems::Package::TarReader::Entry.new header, @io
|
|
62
|
+
size = entry.header.size
|
|
63
|
+
|
|
64
|
+
yield entry
|
|
65
|
+
|
|
66
|
+
skip = (512 - (size % 512)) % 512
|
|
67
|
+
pending = size - entry.bytes_read
|
|
68
|
+
|
|
69
|
+
begin
|
|
70
|
+
# avoid reading...
|
|
71
|
+
@io.seek pending, IO::SEEK_CUR
|
|
72
|
+
pending = 0
|
|
73
|
+
rescue Errno::EINVAL, NameError
|
|
74
|
+
while pending > 0 do
|
|
75
|
+
bytes_read = @io.read([pending, 4096].min).size
|
|
76
|
+
raise UnexpectedEOF if @io.eof?
|
|
77
|
+
pending -= bytes_read
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
@io.read skip # discard trailing zeros
|
|
82
|
+
|
|
83
|
+
# make sure nobody can use #read, #getc or #rewind anymore
|
|
84
|
+
entry.close
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
alias each_entry each
|
|
89
|
+
|
|
90
|
+
##
|
|
91
|
+
# NOTE: Do not call #rewind during #each
|
|
92
|
+
|
|
93
|
+
def rewind
|
|
94
|
+
if @init_pos == 0 then
|
|
95
|
+
raise LibGems::Package::NonSeekableIO unless @io.respond_to? :rewind
|
|
96
|
+
@io.rewind
|
|
97
|
+
else
|
|
98
|
+
raise LibGems::Package::NonSeekableIO unless @io.respond_to? :pos=
|
|
99
|
+
@io.pos = @init_pos
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
require 'libgems/package/tar_reader/entry'
|
|
106
|
+
|