rubygems-update 0.8.10 → 0.8.11
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 +66 -0
- data/README +17 -3
- data/Rakefile +29 -11
- data/bin/gem_mirror +67 -0
- data/examples/application/an-app.gemspec +2 -0
- data/lib/rubygems.rb +18 -3
- data/lib/rubygems/builder.rb +14 -1
- data/lib/rubygems/cmd_manager.rb +2 -0
- data/lib/rubygems/command.rb +26 -2
- data/lib/rubygems/custom_require.rb +30 -21
- data/lib/rubygems/format.rb +4 -4
- data/lib/rubygems/gem_commands.rb +161 -9
- data/lib/rubygems/gem_openssl.rb +34 -0
- data/lib/rubygems/gem_runner.rb +5 -1
- data/lib/rubygems/installer.rb +117 -38
- data/lib/rubygems/package.rb +135 -25
- data/lib/rubygems/remote_installer.rb +59 -29
- data/lib/rubygems/rubygems_version.rb +1 -1
- data/lib/rubygems/security.rb +478 -0
- data/lib/rubygems/specification.rb +48 -28
- data/post-install.rb +2 -1
- data/scripts/gemdoc.rb +2 -2
- data/scripts/specdoc.rb +25 -24
- data/scripts/upload_gemdoc.rb +134 -0
- data/setup.rb +1 -1
- 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/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/specifications/a-0.0.1.gemspec +1 -1
- data/test/data/gemhome/specifications/a-0.0.2.gemspec +1 -1
- data/test/data/gemhome/specifications/b-0.0.2.gemspec +1 -1
- data/test/data/gemhome/specifications/c-1.2.gemspec +1 -1
- data/test/data/one/one-0.0.1.gem +0 -0
- data/test/fake_certlib/openssl.rb +1 -0
- data/test/functional.rb +49 -14
- data/test/gemutilities.rb +69 -5
- data/test/test_cached_fetcher.rb +5 -7
- data/test/test_file_list.rb +96 -0
- data/test/test_gempaths.rb +36 -34
- data/test/test_installer.rb +214 -0
- data/test/test_local_cache.rb +45 -102
- data/test/test_parse_commands.rb +3 -1
- data/test/test_remote_installer.rb +24 -5
- data/test/test_specific_extras.rb +40 -0
- data/test/test_specification.rb +106 -16
- metadata +14 -3
@@ -1,7 +1,13 @@
|
|
1
|
-
require '
|
1
|
+
require 'time'
|
2
2
|
require 'rubygems'
|
3
3
|
require 'rubygems/version'
|
4
4
|
|
5
|
+
class Time
|
6
|
+
def self.today
|
7
|
+
Time.parse Time.now.strftime("%Y-%m-%d")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
5
11
|
module Gem
|
6
12
|
|
7
13
|
##
|
@@ -74,6 +80,9 @@ module Gem
|
|
74
80
|
# List of _all_ attributes and default values: [[:name, nil], [:bindir, 'bin'], ...]
|
75
81
|
@@attributes = []
|
76
82
|
|
83
|
+
# List of array attributes
|
84
|
+
@@array_attributes = []
|
85
|
+
|
77
86
|
# Map of attribute names to default values.
|
78
87
|
@@default_value = {}
|
79
88
|
|
@@ -99,6 +108,10 @@ module Gem
|
|
99
108
|
@@required_attributes.include? name.to_sym
|
100
109
|
end
|
101
110
|
|
111
|
+
def self.array_attributes
|
112
|
+
@@array_attributes.dup
|
113
|
+
end
|
114
|
+
|
102
115
|
# ------------------------- Infrastructure class methods.
|
103
116
|
|
104
117
|
# A list of Specification instances that have been defined in this Ruby instance.
|
@@ -130,6 +143,7 @@ module Gem
|
|
130
143
|
# Same as :attribute, but ensures that values assigned to the
|
131
144
|
# attribute are array values by applying :to_a to the value.
|
132
145
|
def self.array_attribute(name)
|
146
|
+
@@array_attributes << name
|
133
147
|
@@attributes << [name, []]
|
134
148
|
@@default_value[name] = []
|
135
149
|
module_eval %{
|
@@ -222,6 +236,10 @@ module Gem
|
|
222
236
|
attribute :has_rdoc, false
|
223
237
|
attribute :required_ruby_version, Gem::Version::Requirement.default
|
224
238
|
attribute :platform, Gem::Platform::RUBY
|
239
|
+
|
240
|
+
attribute :signing_key, nil
|
241
|
+
attribute :cert_chain, nil
|
242
|
+
|
225
243
|
array_attribute :authors
|
226
244
|
array_attribute :files
|
227
245
|
array_attribute :test_files
|
@@ -276,23 +294,22 @@ module Gem
|
|
276
294
|
end
|
277
295
|
|
278
296
|
overwrite_accessor :date= do |date|
|
279
|
-
# We want to end up with a
|
280
|
-
#
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
297
|
+
# We want to end up with a Time object with one-day resolution. This is
|
298
|
+
# the cleanest, most-readable, faster-than-using-Date way to do it.
|
299
|
+
case date
|
300
|
+
when String then
|
301
|
+
@date = Time.parse date
|
302
|
+
when Time then
|
303
|
+
@date = Time.parse date.strftime("%Y-%m-%d")
|
304
|
+
when Date then
|
305
|
+
@date = Time.parse date.to_s
|
285
306
|
else
|
286
|
-
date =
|
307
|
+
@date = Time.today
|
287
308
|
end
|
288
|
-
@date = date || Date.today
|
289
309
|
end
|
290
310
|
|
291
311
|
overwrite_accessor :date do
|
292
|
-
|
293
|
-
unless @date.is_a? Date
|
294
|
-
self.date = @date
|
295
|
-
end
|
312
|
+
self.date = nil if @date.nil? # HACK Sets the default value for date
|
296
313
|
@date
|
297
314
|
end
|
298
315
|
|
@@ -352,15 +369,16 @@ module Gem
|
|
352
369
|
# ------------------------- Constructors.
|
353
370
|
|
354
371
|
##
|
355
|
-
# Specification constructor. Assigns the default values to the
|
356
|
-
# spec to the list of loaded specs (see
|
357
|
-
# further initialization.
|
372
|
+
# Specification constructor. Assigns the default values to the
|
373
|
+
# attributes, adds this spec to the list of loaded specs (see
|
374
|
+
# Specification.list), and yields itself for further initialization.
|
358
375
|
#
|
359
376
|
def initialize
|
360
|
-
# Each attribute has a default value (possibly nil). Here, we
|
361
|
-
# attributes to their default value. This is done
|
362
|
-
# methods, so special behaviours will be honored.
|
363
|
-
# _copy_ of the default so each specification
|
377
|
+
# Each attribute has a default value (possibly nil). Here, we
|
378
|
+
# initialize all attributes to their default value. This is done
|
379
|
+
# through the accessor methods, so special behaviours will be honored.
|
380
|
+
# Furthermore, we take a _copy_ of the default so each specification
|
381
|
+
# instance has its own empty
|
364
382
|
# arrays, etc.
|
365
383
|
@@attributes.each do |name, default|
|
366
384
|
self.send "#{name}=", copy_of(default)
|
@@ -430,11 +448,12 @@ module Gem
|
|
430
448
|
end
|
431
449
|
|
432
450
|
##
|
433
|
-
# Returns the full name (name-version) of this Gem. Platform information
|
434
|
-
# (name-version-platform) if it is specified (and not the
|
451
|
+
# Returns the full name (name-version) of this Gem. Platform information
|
452
|
+
# is included (name-version-platform) if it is specified (and not the
|
453
|
+
# default Ruby platform).
|
435
454
|
#
|
436
455
|
def full_name
|
437
|
-
if platform == Gem::Platform::RUBY
|
456
|
+
if platform == Gem::Platform::RUBY || platform.nil?
|
438
457
|
"#{@name}-#{@version}"
|
439
458
|
else
|
440
459
|
"#{@name}-#{@version}-#{platform}"
|
@@ -490,16 +509,17 @@ module Gem
|
|
490
509
|
|
491
510
|
# ------------------------- Export methods (YAML and Ruby code).
|
492
511
|
|
493
|
-
# Returns an array of attribute names to be used when generating a YAML
|
494
|
-
# of this object. If an attribute still has its default
|
512
|
+
# Returns an array of attribute names to be used when generating a YAML
|
513
|
+
# representation of this object. If an attribute still has its default
|
514
|
+
# value, it is omitted.
|
495
515
|
def to_yaml_properties
|
496
516
|
mark_version
|
497
517
|
@@attributes.map { |name, default| "@#{name}" }
|
498
518
|
end
|
499
519
|
|
500
|
-
# Returns a Ruby code representation of this specification, such that it
|
501
|
-
# eval'ed and reconstruct the same specification later. Attributes
|
502
|
-
# their default values are omitted.
|
520
|
+
# Returns a Ruby code representation of this specification, such that it
|
521
|
+
# can be eval'ed and reconstruct the same specification later. Attributes
|
522
|
+
# that still have their default values are omitted.
|
503
523
|
def to_ruby
|
504
524
|
mark_version
|
505
525
|
result = "Gem::Specification.new do |s|\n"
|
data/post-install.rb
CHANGED
@@ -51,7 +51,8 @@ def install_windows_batch_files
|
|
51
51
|
target = File.join(bindir, File.basename(f))
|
52
52
|
if is_windows_platform
|
53
53
|
File.open(target+".cmd", "w") do |file|
|
54
|
-
|
54
|
+
ruby_cmd = Gem.ruby rescue 'ruby'
|
55
|
+
file.puts %{@"#{ruby_cmd}" "#{target}" %1 %2 %3 %4 %5 %6 %7 %8 %9}
|
55
56
|
end
|
56
57
|
end
|
57
58
|
end
|
data/scripts/gemdoc.rb
CHANGED
@@ -35,7 +35,7 @@ def table_of_contents
|
|
35
35
|
out.gsub(/^\s+(\w+)/) {
|
36
36
|
cmd_name = $1
|
37
37
|
" [http://rubygems.rubyforge.org/wiki/wiki.pl?GemReference##{cmd_name} -] #{cmd_name}"
|
38
|
-
}
|
38
|
+
}
|
39
39
|
end
|
40
40
|
|
41
41
|
while line = gets
|
@@ -52,7 +52,7 @@ while line = gets
|
|
52
52
|
when "!toc"
|
53
53
|
puts table_of_contents()
|
54
54
|
when "!toc-link"
|
55
|
-
puts "
|
55
|
+
puts "\"Table of Contents\":http://docs.rubygems.org/read/chapter/10#toc"
|
56
56
|
when "!version"
|
57
57
|
puts Gem::RubyGemsPackageVersion
|
58
58
|
end
|
data/scripts/specdoc.rb
CHANGED
@@ -18,14 +18,14 @@ end
|
|
18
18
|
|
19
19
|
# Returns a link to the given anchor on the page.
|
20
20
|
def _link(attribute, text=nil)
|
21
|
-
link = "
|
22
|
-
"
|
21
|
+
link = "##{attribute}"
|
22
|
+
%{<a href="#{link}">#{text || attribute}</a>}
|
23
23
|
end
|
24
24
|
|
25
25
|
def _themed_toc_more_vspace
|
26
26
|
SECTIONS.each do |s|
|
27
|
-
puts "\n
|
28
|
-
puts s['attributes'].
|
27
|
+
puts "\n* *#{s['name']}*"
|
28
|
+
puts s['attributes'].collect { |a|
|
29
29
|
": #{_link(a, '#')} #{a}"
|
30
30
|
}
|
31
31
|
end
|
@@ -33,14 +33,13 @@ end
|
|
33
33
|
|
34
34
|
def _themed_toc_less_vspace
|
35
35
|
SECTIONS.each do |s|
|
36
|
-
puts "\n
|
37
|
-
|
38
|
-
puts s['attributes'].map { |a| _link(a) }.join(SEPSTRING)
|
36
|
+
puts "\n* *#{s['name']}:* "
|
37
|
+
puts s['attributes'].collect { |a| _link(a) }.join(SEPSTRING)
|
39
38
|
end
|
40
39
|
end
|
41
40
|
|
42
41
|
def timestamp
|
43
|
-
puts "
|
42
|
+
puts "p(((. <em>Last generated: #{Time.now.strftime '%Y-%m-%d %H:%M:%S %Z (%A)'}</em>"
|
44
43
|
end
|
45
44
|
|
46
45
|
# Prints a thematic table of contents, drawing from the structure in the YAML file.
|
@@ -51,24 +50,24 @@ end
|
|
51
50
|
# Prints an alphabetical table of contents in a fairly compact yet readable way, with all
|
52
51
|
# Wiki formatting included.
|
53
52
|
def alpha_toc
|
54
|
-
attributes = SECTIONS.
|
53
|
+
attributes = SECTIONS.collect { |s| s['attributes'] }.flatten
|
55
54
|
# -> ['author', 'autorequire', ...]
|
56
55
|
attr_map = attributes.partition_by { |a| a[0,1] }
|
57
56
|
# -> { 'a' => ['author', ...], 'b' => ... }
|
58
|
-
attributes = attr_map.
|
57
|
+
attributes = attr_map.collect { |letter, attrs|
|
59
58
|
[letter.upcase, attrs.sort]
|
60
59
|
}.sort_by { |l, _| l }
|
61
60
|
# -> [ ['A', ['author', ...], ...]
|
62
|
-
attributes = attributes.
|
63
|
-
"
|
61
|
+
attributes = attributes.collect { |letter, attrs|
|
62
|
+
"* *#{letter}* " << attrs.collect { |a| _link(a) }.join(SEPSTRING)
|
64
63
|
} # -> [ 'A author | autorequire', 'B bindir', ...]
|
65
|
-
puts attributes.join(
|
64
|
+
puts attributes.join("\n")
|
66
65
|
end
|
67
66
|
|
68
67
|
# Print the "important" table of contents, which consists of the attributes given as
|
69
68
|
# arguments.
|
70
69
|
def important_toc(*attributes)
|
71
|
-
puts attributes.
|
70
|
+
puts attributes.collect { |a| _link(a) }.join(SEPSTRING)
|
72
71
|
end
|
73
72
|
|
74
73
|
# Returns text like "Optional; default = 'bin'", with Wiki formatting.
|
@@ -76,9 +75,10 @@ def _metadata(attribute)
|
|
76
75
|
type = attribute.klass || "Unknown"
|
77
76
|
required =
|
78
77
|
case attribute.mandatory
|
79
|
-
when nil, false
|
80
|
-
|
81
|
-
else
|
78
|
+
when nil, false
|
79
|
+
'<em>Optional</em>'
|
80
|
+
else
|
81
|
+
'<em>Required</em>'
|
82
82
|
end
|
83
83
|
default_str =
|
84
84
|
case attribute.default
|
@@ -88,8 +88,8 @@ def _metadata(attribute)
|
|
88
88
|
else attribute.default.inspect
|
89
89
|
end
|
90
90
|
default_str = "; default = #{default_str}" unless default_str.empty?
|
91
|
-
result = sprintf "
|
92
|
-
result.gsub(/ /, ' ')
|
91
|
+
result = sprintf "<em>Type: %s; %s%s</em>", type, required, default_str
|
92
|
+
# result.gsub(/ /, ' ')
|
93
93
|
end
|
94
94
|
|
95
95
|
# Turns 'L(section)' into a link to that section.
|
@@ -103,13 +103,14 @@ end
|
|
103
103
|
# * the description, usage, and notes for that attribute
|
104
104
|
# * a link to the table of contents
|
105
105
|
def attribute_survey
|
106
|
-
heading = proc { |str|
|
107
|
-
subheading = proc { |str| "\n
|
106
|
+
heading = proc { |str| %{\n\nh3. <a name="#{str}">#{str}</a>\n\n} }
|
107
|
+
subheading = proc { |str| "\n\nh4. #{str}\n\n" }
|
108
108
|
pre = proc { |str| "<pre>\n#{str}\n</pre>\n" }
|
109
109
|
para = proc { |str| str.gsub(/\n/, "\n\n") }
|
110
|
-
toclink = "\n
|
110
|
+
toclink = "\n<em>Goto #{_link('toc', 'Table of Contents')}</em>"
|
111
111
|
ATTRIBUTES.sort_by { |a| a['name'] }.each do |a|
|
112
112
|
a = OpenStruct.new(a)
|
113
|
+
puts "\n----\n"
|
113
114
|
puts heading[a.name]
|
114
115
|
puts _metadata(a)
|
115
116
|
puts subheading['Description']
|
@@ -127,9 +128,9 @@ end
|
|
127
128
|
# Checks to see that all the attributes are documented. Warn on STDERR of any
|
128
129
|
# discrepencies.
|
129
130
|
def _check_attribute_completeness
|
130
|
-
documented_attributes = ATTRIBUTES.
|
131
|
+
documented_attributes = ATTRIBUTES.collect { |a| a['name'].to_s }
|
131
132
|
# ^ The attributes documented in specdoc.yaml.
|
132
|
-
coded_attributes = Gem::Specification.attribute_names.
|
133
|
+
coded_attributes = Gem::Specification.attribute_names.collect { |a| a.to_s }
|
133
134
|
# ^ The attributes defined in specification.rb.
|
134
135
|
missing = coded_attributes - documented_attributes
|
135
136
|
unless missing.empty?
|
@@ -0,0 +1,134 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'mechanize'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
DOC = {}
|
7
|
+
UPDATED = {}
|
8
|
+
MISSING = []
|
9
|
+
|
10
|
+
$page_count = 0
|
11
|
+
|
12
|
+
def save_page(page)
|
13
|
+
$page_count += 1
|
14
|
+
page_name = "logs/page_%03d.html" % $page_count
|
15
|
+
open(page_name, "w") do |f| f.puts page.body end
|
16
|
+
end
|
17
|
+
|
18
|
+
def read_document
|
19
|
+
open("scripts/gemdoc.hieraki") do |f|
|
20
|
+
name = nil
|
21
|
+
f.each do |line|
|
22
|
+
if line =~ /^==/
|
23
|
+
line =~ /gem\s+(\S+)/ or fail "Illformatted Document Line [#{line.chomp}]"
|
24
|
+
name = $1
|
25
|
+
DOC[name] = ''
|
26
|
+
else
|
27
|
+
next if name.nil?
|
28
|
+
DOC[name] << line
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_credentials
|
35
|
+
unless File.exist?(".hieraki_author.rb")
|
36
|
+
print "Hieraki Author Name: "
|
37
|
+
author = gets.chomp
|
38
|
+
print "Hieraki Password: "
|
39
|
+
password = gets.chomp
|
40
|
+
open(".hieraki_author.rb", "w") do |f|
|
41
|
+
f.puts "module Hieraki"
|
42
|
+
f.puts " Author = '#{author}'"
|
43
|
+
f.puts " Password = '#{password}'"
|
44
|
+
f.puts "end"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
load "./.hieraki_author.rb"
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_agent
|
52
|
+
FileUtils.mkdir "logs" unless File.exist?("logs")
|
53
|
+
logfile = open("logs/update_hieraki.log", "w")
|
54
|
+
$agent = WWW::Mechanize.new { |a| a.log = Logger.new(logfile) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def login_to_hieraki
|
58
|
+
puts "*** Getting Start Page"
|
59
|
+
start_page = $agent.get("http://docs.rubygems.org")
|
60
|
+
save_page(start_page)
|
61
|
+
|
62
|
+
puts "*** Going to Login Page"
|
63
|
+
login_link = start_page.links.find { |l| l.node.text =~ /login/i }
|
64
|
+
login_page = $agent.click(login_link)
|
65
|
+
save_page(login_page)
|
66
|
+
|
67
|
+
puts "*** Attempting to Log In"
|
68
|
+
login_form = login_page.forms.first
|
69
|
+
login_form.fields.find { |f| f.name == 'login' }.value = Hieraki::Author
|
70
|
+
login_form.fields.find { |f| f.name == 'password' }.value = Hieraki::Password
|
71
|
+
author_page = $agent.submit(login_form)
|
72
|
+
fail "Unsuccessful Login -- check .hieraki_author.rb file" if author_page.body =~ /unsuccessful/
|
73
|
+
save_page(author_page)
|
74
|
+
author_page
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def goto_command_reference_page(page)
|
79
|
+
puts "*** Going to Command Reference Book"
|
80
|
+
link = page.links.find { |l| l.node.text =~ /command reference/i }
|
81
|
+
ref_page = $agent.click(link)
|
82
|
+
save_page(ref_page)
|
83
|
+
|
84
|
+
puts "*** Going to Command Reference Chapter"
|
85
|
+
link = ref_page.links.find { |l| l.node.text =~ /command reference/i && l.href =~ /chapter/ }
|
86
|
+
cmdref_page = $agent.click(link)
|
87
|
+
save_page(cmdref_page)
|
88
|
+
cmdref_page
|
89
|
+
end
|
90
|
+
|
91
|
+
def update_command_docs(cmdref_page)
|
92
|
+
cmdref_page.links.select { |l| l.node.text == "edit" }.each do |l|
|
93
|
+
edit_page = $agent.click(l)
|
94
|
+
save_page(edit_page)
|
95
|
+
edit_form = edit_page.forms.first
|
96
|
+
title = edit_form.fields.find { |f| f.name = 'page_title'}.value
|
97
|
+
if title =~ /gem\s([a-z]+)/
|
98
|
+
name = $1
|
99
|
+
if DOC[name]
|
100
|
+
body_field = edit_form.fields.find { |f| f.name == 'page[body]'}
|
101
|
+
body_field.value = DOC[name]
|
102
|
+
puts "*** Updating gem #{name} page"
|
103
|
+
$agent.submit(edit_form)
|
104
|
+
UPDATED[name] = true
|
105
|
+
else
|
106
|
+
MISSING << name
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
def check_missing
|
114
|
+
(DOC.keys - UPDATED.keys).sort.each do |name|
|
115
|
+
puts "No page found for 'gem #{name}'"
|
116
|
+
end
|
117
|
+
MISSING.each do |name|
|
118
|
+
puts "No data found for 'gem #{name}' page"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def upload_gemdoc_main(args)
|
123
|
+
create_agent
|
124
|
+
get_credentials
|
125
|
+
read_document
|
126
|
+
page = login_to_hieraki
|
127
|
+
cmdref_page = goto_command_reference_page(page)
|
128
|
+
update_command_docs(cmdref_page)
|
129
|
+
check_missing
|
130
|
+
end
|
131
|
+
|
132
|
+
if __FILE__ == $0 then
|
133
|
+
upload_gemdoc_main(ARGV)
|
134
|
+
end
|
data/setup.rb
CHANGED
@@ -1142,8 +1142,8 @@ class Installer
|
|
1142
1142
|
w.print first.sub(/\A\#!\s*\S+/, '#! ' + config('rubypath'))
|
1143
1143
|
w.write r.read
|
1144
1144
|
}
|
1145
|
-
move_file tmpfile, File.basename(path)
|
1146
1145
|
}
|
1146
|
+
move_file tmpfile, File.basename(path)
|
1147
1147
|
ensure
|
1148
1148
|
File.unlink tmpfile if File.exist?(tmpfile)
|
1149
1149
|
end
|
data/test/data/a-0.0.1.gem
CHANGED
Binary file
|
data/test/data/a-0.0.2.gem
CHANGED
Binary file
|
data/test/data/b-0.0.2.gem
CHANGED
Binary file
|