rubygems-update 2.3.0 → 2.4.0
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.
Potentially problematic release.
This version of rubygems-update might be problematic. Click here for more details.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CONTRIBUTING +14 -2
- data/History.txt +63 -0
- data/Rakefile +68 -91
- data/lib/rubygems.rb +5 -3
- data/lib/rubygems/command_manager.rb +1 -0
- data/lib/rubygems/commands/contents_command.rb +23 -2
- data/lib/rubygems/commands/install_command.rb +8 -0
- data/lib/rubygems/commands/open_command.rb +1 -8
- data/lib/rubygems/commands/uninstall_command.rb +9 -1
- data/lib/rubygems/commands/update_command.rb +1 -1
- data/lib/rubygems/core_ext/kernel_gem.rb +8 -1
- data/lib/rubygems/core_ext/kernel_require.rb +12 -22
- data/lib/rubygems/defaults.rb +17 -5
- data/lib/rubygems/dependency.rb +7 -1
- data/lib/rubygems/dependency_installer.rb +3 -0
- data/lib/rubygems/ext/ext_conf_builder.rb +13 -11
- data/lib/rubygems/install_update_options.rb +13 -0
- data/lib/rubygems/installer.rb +36 -20
- data/lib/rubygems/installer_test_case.rb +2 -0
- data/lib/rubygems/local_remote_options.rb +1 -1
- data/lib/rubygems/name_tuple.rb +1 -1
- data/lib/rubygems/request_set.rb +14 -3
- data/lib/rubygems/request_set/gem_dependency_api.rb +12 -0
- data/lib/rubygems/request_set/lockfile.rb +3 -1
- data/lib/rubygems/resolver.rb +15 -0
- data/lib/rubygems/resolver/best_set.rb +28 -0
- data/lib/rubygems/resolver/conflict.rb +45 -7
- data/lib/rubygems/resolver/git_specification.rb +24 -0
- data/lib/rubygems/resolver/lock_specification.rb +22 -0
- data/lib/rubygems/source.rb +2 -0
- data/lib/rubygems/source/git.rb +1 -1
- data/lib/rubygems/source/installed.rb +2 -1
- data/lib/rubygems/specification.rb +16 -15
- data/lib/rubygems/test_case.rb +9 -5
- data/test/rubygems/test_gem.rb +72 -2
- data/test/rubygems/test_gem_commands_contents_command.rb +46 -3
- data/test/rubygems/test_gem_commands_install_command.rb +32 -0
- data/test/rubygems/test_gem_commands_uninstall_command.rb +18 -0
- data/test/rubygems/test_gem_dependency.rb +23 -0
- data/test/rubygems/test_gem_dependency_installer.rb +17 -0
- data/test/rubygems/test_gem_ext_builder.rb +12 -1
- data/test/rubygems/test_gem_ext_ext_conf_builder.rb +2 -2
- data/test/rubygems/test_gem_impossible_dependencies_error.rb +24 -8
- data/test/rubygems/test_gem_install_update_options.rb +16 -0
- data/test/rubygems/test_gem_installer.rb +52 -0
- data/test/rubygems/test_gem_local_remote_options.rb +13 -0
- data/test/rubygems/test_gem_package.rb +3 -1
- data/test/rubygems/test_gem_package_tar_header.rb +2 -0
- data/test/rubygems/test_gem_package_tar_reader.rb +11 -1
- data/test/rubygems/test_gem_package_tar_reader_entry.rb +17 -2
- data/test/rubygems/test_gem_package_tar_writer.rb +1 -0
- data/test/rubygems/test_gem_remote_fetcher.rb +24 -0
- data/test/rubygems/test_gem_request_set.rb +74 -4
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +9 -1
- data/test/rubygems/test_gem_request_set_lockfile.rb +3 -1
- data/test/rubygems/test_gem_requirement.rb +8 -0
- data/test/rubygems/test_gem_resolver.rb +39 -0
- data/test/rubygems/test_gem_resolver_best_set.rb +57 -0
- data/test/rubygems/test_gem_resolver_conflict.rb +22 -10
- data/test/rubygems/test_gem_resolver_git_specification.rb +12 -0
- data/test/rubygems/test_gem_source_git.rb +6 -2
- data/test/rubygems/test_gem_source_installed.rb +8 -0
- data/test/rubygems/test_gem_source_lock.rb +2 -2
- data/test/rubygems/test_gem_source_vendor.rb +4 -0
- data/test/rubygems/test_kernel.rb +6 -0
- data/test/rubygems/test_require.rb +60 -0
- metadata +5 -5
- metadata.gz.sig +0 -0
@@ -170,6 +170,45 @@ class TestGemResolver < Gem::TestCase
|
|
170
170
|
assert_empty reqs
|
171
171
|
end
|
172
172
|
|
173
|
+
def test_resolve_conservative
|
174
|
+
a1_spec = util_spec 'a', 1
|
175
|
+
a2_spec = util_spec 'a', 2 do |s|
|
176
|
+
s.add_dependency 'b', 2
|
177
|
+
s.add_dependency 'c'
|
178
|
+
end
|
179
|
+
b1_spec = util_spec 'b', 1
|
180
|
+
b2_spec = util_spec 'b', 2
|
181
|
+
c1_spec = util_spec 'c', 1 do |s| s.add_dependency 'd', 2 end
|
182
|
+
c2_spec = util_spec 'c', 2 do |s| s.add_dependency 'd', 2 end
|
183
|
+
d1_spec = util_spec 'd', 1 do |s| s.add_dependency 'e' end
|
184
|
+
d2_spec = util_spec 'd', 2 do |s| s.add_dependency 'e' end
|
185
|
+
e1_spec = util_spec 'e', 1
|
186
|
+
e2_spec = util_spec 'e', 2
|
187
|
+
|
188
|
+
a_dep = make_dep 'a', '= 2'
|
189
|
+
e_dep = make_dep 'e'
|
190
|
+
|
191
|
+
# When requesting to install:
|
192
|
+
# a-2, e
|
193
|
+
deps = [a_dep, e_dep]
|
194
|
+
|
195
|
+
s = set a1_spec, a2_spec, b1_spec, b2_spec, c1_spec, c2_spec, d1_spec, d2_spec, e1_spec, e2_spec
|
196
|
+
|
197
|
+
res = Gem::Resolver.new deps, s
|
198
|
+
|
199
|
+
# With the following gems already installed:
|
200
|
+
# a-1, b-1, c-1, e-1
|
201
|
+
res.skip_gems = {'a'=>[a1_spec], 'b'=>[b1_spec], 'c'=>[c1_spec], 'e'=>[e1_spec]}
|
202
|
+
|
203
|
+
# Make sure the following gems end up getting used/installed/upgraded:
|
204
|
+
# a-2 (upgraded)
|
205
|
+
# b-2 (upgraded), specific dependency from a-2
|
206
|
+
# c-1 (used, not upgraded), open dependency from a-2
|
207
|
+
# d-2 (installed), specific dependency from c-2
|
208
|
+
# e-1 (used, not upgraded), open dependency from request
|
209
|
+
assert_resolves_to [a2_spec, b2_spec, c1_spec, d2_spec, e1_spec], res
|
210
|
+
end
|
211
|
+
|
173
212
|
def test_resolve_development
|
174
213
|
a_spec = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end
|
175
214
|
b_spec = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end
|
@@ -32,6 +32,26 @@ class TestGemResolverBestSet < Gem::TestCase
|
|
32
32
|
assert_equal %w[a-1], found.map { |s| s.full_name }
|
33
33
|
end
|
34
34
|
|
35
|
+
def test_find_all_fallback
|
36
|
+
spec_fetcher do |fetcher|
|
37
|
+
fetcher.spec 'a', 1
|
38
|
+
end
|
39
|
+
|
40
|
+
set = @DR::BestSet.new
|
41
|
+
|
42
|
+
api_uri = URI(@gem_repo) + './api/v1/dependencies'
|
43
|
+
|
44
|
+
set.sets << Gem::Resolver::APISet.new(api_uri)
|
45
|
+
|
46
|
+
dependency = dep 'a', '~> 1'
|
47
|
+
|
48
|
+
req = @DR::DependencyRequest.new dependency, nil
|
49
|
+
|
50
|
+
found = set.find_all req
|
51
|
+
|
52
|
+
assert_equal %w[a-1], found.map { |s| s.full_name }
|
53
|
+
end
|
54
|
+
|
35
55
|
def test_find_all_local
|
36
56
|
spec_fetcher do |fetcher|
|
37
57
|
fetcher.spec 'a', 1
|
@@ -76,5 +96,42 @@ class TestGemResolverBestSet < Gem::TestCase
|
|
76
96
|
assert_empty set.sets
|
77
97
|
end
|
78
98
|
|
99
|
+
def test_replace_failed_api_set
|
100
|
+
set = @DR::BestSet.new
|
101
|
+
|
102
|
+
api_uri = URI(@gem_repo) + './api/v1/dependencies'
|
103
|
+
api_set = Gem::Resolver::APISet.new api_uri
|
104
|
+
|
105
|
+
set.sets << api_set
|
106
|
+
|
107
|
+
error_uri = api_uri + '?gems=a'
|
108
|
+
|
109
|
+
error = Gem::RemoteFetcher::FetchError.new 'bogus', error_uri
|
110
|
+
|
111
|
+
set.replace_failed_api_set error
|
112
|
+
|
113
|
+
assert_equal 1, set.sets.size
|
114
|
+
|
115
|
+
refute_includes set.sets, api_set
|
116
|
+
|
117
|
+
assert_kind_of Gem::Resolver::IndexSet, set.sets.first
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_replace_failed_api_set_no_api_set
|
121
|
+
set = @DR::BestSet.new
|
122
|
+
|
123
|
+
index_set = Gem::Resolver::IndexSet.new Gem::Source.new @gem_repo
|
124
|
+
|
125
|
+
set.sets << index_set
|
126
|
+
|
127
|
+
error = Gem::RemoteFetcher::FetchError.new 'bogus', @gem_repo
|
128
|
+
|
129
|
+
e = assert_raises Gem::RemoteFetcher::FetchError do
|
130
|
+
set.replace_failed_api_set error
|
131
|
+
end
|
132
|
+
|
133
|
+
assert_equal error, e
|
134
|
+
end
|
135
|
+
|
79
136
|
end
|
80
137
|
|
@@ -22,10 +22,17 @@ class TestGemResolverConflict < Gem::TestCase
|
|
22
22
|
Gem::Resolver::Conflict.new child, active
|
23
23
|
|
24
24
|
expected = <<-EXPECTED
|
25
|
-
Activated net-ssh-2.2.2
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
Activated net-ssh-2.2.2
|
26
|
+
which does not match conflicting dependency (>= 2.6.5)
|
27
|
+
|
28
|
+
Conflicting dependency chains:
|
29
|
+
net-ssh (>= 2.0.13), 2.2.2 activated
|
30
|
+
|
31
|
+
versus:
|
32
|
+
rye (= 0.9.8), 0.9.8 activated depends on
|
33
|
+
net-ssh (>= 2.0.13), 2.2.2 activated depends on
|
34
|
+
net-ssh (>= 2.6.5)
|
35
|
+
|
29
36
|
EXPECTED
|
30
37
|
|
31
38
|
assert_equal expected, conflict.explanation
|
@@ -44,10 +51,15 @@ class TestGemResolverConflict < Gem::TestCase
|
|
44
51
|
conflict = @DR::Conflict.new a1_req, activated
|
45
52
|
|
46
53
|
expected = <<-EXPECTED
|
47
|
-
Activated a-2
|
48
|
-
|
49
|
-
|
50
|
-
|
54
|
+
Activated a-2
|
55
|
+
which does not match conflicting dependency (= 1)
|
56
|
+
|
57
|
+
Conflicting dependency chains:
|
58
|
+
a (= 2), 2 activated
|
59
|
+
|
60
|
+
versus:
|
61
|
+
a (= 1)
|
62
|
+
|
51
63
|
EXPECTED
|
52
64
|
|
53
65
|
assert_equal expected, conflict.explanation
|
@@ -64,8 +76,8 @@ class TestGemResolverConflict < Gem::TestCase
|
|
64
76
|
Gem::Resolver::Conflict.new nil, nil
|
65
77
|
|
66
78
|
expected = [
|
67
|
-
'net-ssh
|
68
|
-
'rye
|
79
|
+
'net-ssh (>= 2.0.13), 2.2.2 activated',
|
80
|
+
'rye (= 0.9.8), 0.9.8 activated'
|
69
81
|
]
|
70
82
|
|
71
83
|
assert_equal expected, conflict.request_path(child.requester)
|
@@ -32,6 +32,18 @@ class TestGemResolverGitSpecification < Gem::TestCase
|
|
32
32
|
refute_equal g_spec_a, i_spec
|
33
33
|
end
|
34
34
|
|
35
|
+
def test_add_dependency
|
36
|
+
git_gem 'a', 1
|
37
|
+
|
38
|
+
git_spec = Gem::Resolver::GitSpecification.new @set, @spec
|
39
|
+
|
40
|
+
b_dep = dep 'b'
|
41
|
+
|
42
|
+
git_spec.add_dependency b_dep
|
43
|
+
|
44
|
+
assert_equal [b_dep], git_spec.dependencies
|
45
|
+
end
|
46
|
+
|
35
47
|
def test_install
|
36
48
|
git_gem 'a', 1
|
37
49
|
|
@@ -194,14 +194,18 @@ class TestGemSourceGit < Gem::TestCase
|
|
194
194
|
git = Gem::Source::Git.new 'a', 'git/a', 'master', false
|
195
195
|
remote = Gem::Source.new @gem_repo
|
196
196
|
installed = Gem::Source::Installed.new
|
197
|
+
vendor = Gem::Source::Vendor.new 'vendor/foo'
|
197
198
|
|
198
199
|
assert_equal( 0, git. <=>(git), 'git <=> git')
|
199
200
|
|
200
201
|
assert_equal( 1, git. <=>(remote), 'git <=> remote')
|
201
202
|
assert_equal(-1, remote. <=>(git), 'remote <=> git')
|
202
203
|
|
203
|
-
assert_equal( 1, installed
|
204
|
-
assert_equal(-1, git
|
204
|
+
assert_equal( 1, git. <=>(installed), 'git <=> installed')
|
205
|
+
assert_equal(-1, installed.<=>(git), 'installed <=> git')
|
206
|
+
|
207
|
+
assert_equal(-1, git. <=>(vendor), 'git <=> vendor')
|
208
|
+
assert_equal( 1, vendor. <=>(git), 'vendor <=> git')
|
205
209
|
end
|
206
210
|
|
207
211
|
def test_specs
|
@@ -11,6 +11,8 @@ class TestGemSourceInstalled < Gem::TestCase
|
|
11
11
|
specific = Gem::Source::SpecificFile.new a1.cache_file
|
12
12
|
installed = Gem::Source::Installed.new
|
13
13
|
local = Gem::Source::Local.new
|
14
|
+
git = Gem::Source::Git.new 'a', 'a', 'master'
|
15
|
+
vendor = Gem::Source::Vendor.new 'a'
|
14
16
|
|
15
17
|
assert_equal( 0, installed.<=>(installed), 'installed <=> installed')
|
16
18
|
|
@@ -22,6 +24,12 @@ class TestGemSourceInstalled < Gem::TestCase
|
|
22
24
|
|
23
25
|
assert_equal(-1, specific. <=>(installed), 'specific <=> installed')
|
24
26
|
assert_equal( 1, installed.<=>(specific), 'installed <=> specific')
|
27
|
+
|
28
|
+
assert_equal( 1, git. <=>(installed), 'git <=> installed')
|
29
|
+
assert_equal(-1, installed.<=>(git), 'installed <=> git')
|
30
|
+
|
31
|
+
assert_equal( 1, vendor. <=>(installed), 'vendor <=> installed')
|
32
|
+
assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor')
|
25
33
|
end
|
26
34
|
|
27
35
|
end
|
@@ -43,8 +43,8 @@ class TestGemSourceLock < Gem::TestCase
|
|
43
43
|
assert_equal( 0, i_lock.<=>(i_lock), 'i_lock <=> i_lock')
|
44
44
|
assert_equal( 0, v_lock.<=>(v_lock), 'v_lock <=> v_lock')
|
45
45
|
|
46
|
-
assert_equal(
|
47
|
-
assert_equal(
|
46
|
+
assert_equal( 1, g_lock.<=>(i_lock), 'g_lock <=> i_lock')
|
47
|
+
assert_equal(-1, i_lock.<=>(g_lock), 'i_lock <=> g_lock')
|
48
48
|
|
49
49
|
assert_equal(-1, g_lock.<=>(v_lock), 'g_lock <=> v_lock')
|
50
50
|
assert_equal( 1, v_lock.<=>(g_lock), 'v_lock <=> g_lock')
|
@@ -12,6 +12,7 @@ class TestGemSourceVendor < Gem::TestCase
|
|
12
12
|
def test_spaceship
|
13
13
|
vendor = Gem::Source::Vendor.new 'vendor/foo'
|
14
14
|
remote = Gem::Source.new @gem_repo
|
15
|
+
git = Gem::Source::Git.new 'a', 'a', 'master'
|
15
16
|
installed = Gem::Source::Installed.new
|
16
17
|
|
17
18
|
assert_equal( 0, vendor. <=>(vendor), 'vendor <=> vendor')
|
@@ -19,6 +20,9 @@ class TestGemSourceVendor < Gem::TestCase
|
|
19
20
|
assert_equal( 1, vendor. <=>(remote), 'vendor <=> remote')
|
20
21
|
assert_equal(-1, remote. <=>(vendor), 'remote <=> vendor')
|
21
22
|
|
23
|
+
assert_equal( 1, vendor. <=>(git), 'vendor <=> git')
|
24
|
+
assert_equal(-1, git. <=>(vendor), 'git <=> vendor')
|
25
|
+
|
22
26
|
assert_equal( 1, vendor. <=>(installed), 'vendor <=> installed')
|
23
27
|
assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor')
|
24
28
|
end
|
@@ -33,6 +33,12 @@ class TestKernel < Gem::TestCase
|
|
33
33
|
assert_equal 1, $:.select { |p| %r{a-1/lib} =~ p }.size
|
34
34
|
end
|
35
35
|
|
36
|
+
def test_gem_prerelease
|
37
|
+
quick_gem 'd', '1.1.a'
|
38
|
+
refute gem('d', '>= 1'), 'release requirement must not load prerelease'
|
39
|
+
assert gem('d', '>= 1.a'), 'prerelease requirement may load prerelease'
|
40
|
+
end
|
41
|
+
|
36
42
|
def test_gem_conflicting
|
37
43
|
assert gem('a', '= 1'), "Should load"
|
38
44
|
|
@@ -2,6 +2,26 @@ require 'rubygems/test_case'
|
|
2
2
|
require 'rubygems'
|
3
3
|
|
4
4
|
class TestGemRequire < Gem::TestCase
|
5
|
+
class Latch
|
6
|
+
def initialize count = 1
|
7
|
+
@count = count
|
8
|
+
@lock = Monitor.new
|
9
|
+
@cv = @lock.new_cond
|
10
|
+
end
|
11
|
+
|
12
|
+
def release
|
13
|
+
@lock.synchronize do
|
14
|
+
@count -= 1 if @count > 0
|
15
|
+
@cv.broadcast if @count.zero?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def await
|
20
|
+
@lock.synchronize do
|
21
|
+
@cv.wait_while { @count > 0 }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
5
25
|
|
6
26
|
def setup
|
7
27
|
super
|
@@ -17,6 +37,46 @@ class TestGemRequire < Gem::TestCase
|
|
17
37
|
assert require(path), "'#{path}' was already required"
|
18
38
|
end
|
19
39
|
|
40
|
+
def append_latch spec
|
41
|
+
dir = spec.gem_dir
|
42
|
+
Dir.chdir dir do
|
43
|
+
spec.files.each do |file|
|
44
|
+
File.open file, 'a' do |fp|
|
45
|
+
fp.puts "FILE_ENTERED_LATCH.release"
|
46
|
+
fp.puts "FILE_EXIT_LATCH.await"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_concurrent_require
|
53
|
+
Object.const_set :FILE_ENTERED_LATCH, Latch.new(2)
|
54
|
+
Object.const_set :FILE_EXIT_LATCH, Latch.new(1)
|
55
|
+
|
56
|
+
a1 = new_spec "a", "1", nil, "lib/a.rb"
|
57
|
+
b1 = new_spec "b", "1", nil, "lib/b.rb"
|
58
|
+
|
59
|
+
install_specs a1, b1
|
60
|
+
|
61
|
+
append_latch a1
|
62
|
+
append_latch b1
|
63
|
+
|
64
|
+
t1 = Thread.new { assert_require 'a' }
|
65
|
+
t2 = Thread.new { assert_require 'b' }
|
66
|
+
|
67
|
+
# wait until both files are waiting on the exit latch
|
68
|
+
FILE_ENTERED_LATCH.await
|
69
|
+
|
70
|
+
# now let them finish
|
71
|
+
FILE_EXIT_LATCH.release
|
72
|
+
|
73
|
+
assert t1.join, "thread 1 should exit"
|
74
|
+
assert t2.join, "thread 2 should exit"
|
75
|
+
ensure
|
76
|
+
Object.send :remove_const, :FILE_ENTERED_LATCH
|
77
|
+
Object.send :remove_const, :FILE_EXIT_LATCH
|
78
|
+
end
|
79
|
+
|
20
80
|
def test_require_is_not_lazy_with_exact_req
|
21
81
|
a1 = new_spec "a", "1", {"b" => "= 1"}, "lib/test_gem_require_a.rb"
|
22
82
|
b1 = new_spec "b", "1", nil, "lib/b/c.rb"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubygems-update
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Weirich
|
@@ -31,7 +31,7 @@ cert_chain:
|
|
31
31
|
pfkQPF5Ezsi73pEpFN93Fy21NKCYQH1jCwWeKUF29MIMGd6kE3ZmHW/7fz5GwKIM
|
32
32
|
Ls5SgY48a0l7Hw==
|
33
33
|
-----END CERTIFICATE-----
|
34
|
-
date: 2014-
|
34
|
+
date: 2014-07-17 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: minitest
|
@@ -39,14 +39,14 @@ dependencies:
|
|
39
39
|
requirements:
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '5.
|
42
|
+
version: '5.3'
|
43
43
|
type: :development
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '5.
|
49
|
+
version: '5.3'
|
50
50
|
- !ruby/object:Gem::Dependency
|
51
51
|
name: rdoc
|
52
52
|
requirement: !ruby/object:Gem::Requirement
|
@@ -548,7 +548,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
548
548
|
version: '0'
|
549
549
|
requirements: []
|
550
550
|
rubyforge_project: rubygems-update
|
551
|
-
rubygems_version: 2.
|
551
|
+
rubygems_version: 2.3.0
|
552
552
|
signing_key:
|
553
553
|
specification_version: 4
|
554
554
|
summary: RubyGems is a package management framework for Ruby
|
metadata.gz.sig
CHANGED
Binary file
|