Skip to content

Commit d923c4c

Browse files
authored
Merge pull request #2115 from ruby/mutex-m
mutex_m support
2 parents b8fa0ea + 383026d commit d923c4c

File tree

4 files changed

+305
-10
lines changed

4 files changed

+305
-10
lines changed

lib/rbs/collection/config.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ def repo_path_data
6666
def sources
6767
@sources ||= [
6868
Sources::Rubygems.instance,
69-
Sources::Stdlib.instance,
70-
*@data['sources'].map { |c| Sources.from_config_entry(c, base_directory: @config_path.dirname) }
69+
*@data['sources'].map { |c| Sources.from_config_entry(c, base_directory: @config_path.dirname) },
70+
Sources::Stdlib.instance
7171
]
7272
end
7373

lib/rbs/collection/config/lockfile_generator.rb

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ module RBS
44
module Collection
55
class Config
66
class LockfileGenerator
7+
ALUMNI_STDLIBS = { "mutex_m" => ">= 0.3.0" }
8+
79
class GemfileLockMismatchError < StandardError
810
def initialize(expected:, actual:)
911
@expected = expected
@@ -58,9 +60,10 @@ def initialize(config:, definition:, with_lockfile:)
5860

5961
def generate
6062
config.gems.each do |gem|
61-
if Sources::Stdlib.instance.has?(gem["name"], nil) || gem.dig("source", "type") == "stdlib"
63+
case
64+
when gem.dig("source", "type") == "stdlib"
6265
unless gem.fetch("ignore", false)
63-
assign_stdlib(name: gem["name"], from_gem: nil)
66+
assign_stdlib(name: gem["name"])
6467
end
6568
else
6669
assign_gem(name: gem["name"], version: gem["version"])
@@ -113,6 +116,11 @@ def generate
113116
find_source(name: name)
114117
end
115118

119+
if source.is_a?(Sources::Stdlib)
120+
assign_stdlib(name: name)
121+
return
122+
end
123+
116124
if source
117125
installed_version = version
118126
best_version = find_best_version(version: installed_version, versions: source.versions(name))
@@ -149,16 +157,37 @@ def generate
149157
end
150158
end
151159

152-
private def assign_stdlib(name:, from_gem:)
160+
private def assign_stdlib(name:, from_gem: nil)
153161
return if lockfile.gems.key?(name)
154162

155163
case name
156164
when 'rubygems', 'set'
157165
msg = "`#{name}` has been moved to core library, so it is always loaded. Remove explicit loading `#{name}`"
158166
msg << " from `#{from_gem}`" if from_gem
159-
RBS.logger.warn msg
160-
167+
msg << "."
161168
return
169+
when *ALUMNI_STDLIBS.keys
170+
version = ALUMNI_STDLIBS.fetch(name)
171+
if from_gem
172+
# From `dependencies:` of a `manifest.yaml` of a gem
173+
source = find_source(name: name) or raise
174+
if source.is_a?(Sources::Stdlib)
175+
RBS.logger.warn {
176+
"`#{name}` is included in the RBS dependencies of `#{from_gem}`, but the type definition as a stdlib in rbs-gem is deprecated. Add `#{name}` (#{version}) to the dependency of your Ruby program to use the gem-bundled type definition."
177+
}
178+
else
179+
RBS.logger.info {
180+
"`#{name}` is included in the RBS dependencies of `#{from_gem}`, but the type definition as a stdlib in rbs-gem is deprecated. Delete `#{name}` from the RBS dependencies of `#{from_gem}`."
181+
}
182+
assign_gem(name: name, version: nil)
183+
return
184+
end
185+
else
186+
# From `gems:` of a `rbs_collection.yaml`
187+
RBS.logger.warn {
188+
"`#{name}` as a stdlib in rbs-gem is deprecated. Add `#{name}` (#{version}) to the dependency of your Ruby program to use the gem-bundled type definition."
189+
}
190+
end
162191
end
163192

164193
source = Sources::Stdlib.instance

sig/collection/config/lockfile_generator.rbs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ module RBS
22
module Collection
33
class Config
44
class LockfileGenerator
5+
# Name of stdlibs that was rbs-bundled stdlib but is now a gem.
6+
#
7+
ALUMNI_STDLIBS: Hash[String, String]
8+
59
class GemfileLockMismatchError < StandardError
610
@expected: Pathname
711

@@ -43,7 +47,11 @@ module RBS
4347
#
4448
def assign_gem: (name: String, version: String?, ?skip: bool) -> void
4549

46-
def assign_stdlib: (name: String, from_gem: String?) -> void
50+
# Assign a gem from stdlib to lockfile
51+
#
52+
# `from_gem` is a String when the stdlib is assigned through the `dependencies:` in `manifest.yaml` of a gem.
53+
#
54+
def assign_stdlib: (name: String, ?from_gem: String) -> void
4755

4856
# Find a source of a gem from ones registered in `config.sources`
4957
#

test/rbs/cli_test.rb

Lines changed: 260 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def run_rbs_collection(*commands, bundler:)
3636
rbs_path << (":" + rblib)
3737
end
3838

39-
Open3.capture3({ "RUBYLIB" => rbs_path }, *bundle_exec, "#{__dir__}/../../exe/rbs", "collection", *commands, chdir: Dir.pwd)
39+
Open3.capture3({ "RUBYLIB" => rbs_path }, *bundle_exec, "#{__dir__}/../../exe/rbs", "--log-level=debug", "collection", *commands, chdir: Dir.pwd)
4040
end
4141

4242
if block_given?
@@ -55,7 +55,11 @@ def bundle_install(*gems)
5555
if gem == :gemspec
5656
"gemspec"
5757
else
58-
"gem '#{gem}'"
58+
if gem.is_a?(Array)
59+
"gem #{gem.map(&:inspect).join(", ")}"
60+
else
61+
"gem '#{gem}'"
62+
end
5963
end
6064
end
6165

@@ -1288,6 +1292,260 @@ def test_collection_install_gemspec
12881292
end
12891293
end
12901294

1295+
def test_collection_install__mutex_m__config__bundled
1296+
Dir.mktmpdir do |dir|
1297+
Dir.chdir(dir) do
1298+
dir = Pathname(dir)
1299+
1300+
(dir + RBS::Collection::Config::PATH).write(<<~YAML)
1301+
sources:
1302+
- name: ruby/gem_rbs_collection
1303+
remote: https://github.com/ruby/gem_rbs_collection.git
1304+
revision: b4d3b346d9657543099a35a1fd20347e75b8c523
1305+
repo_dir: gems
1306+
1307+
path: #{dir.join('gem_rbs_collection')}
1308+
1309+
gems:
1310+
- name: mutex_m
1311+
YAML
1312+
1313+
bundle_install(["mutex_m", ">= 0.3.0"])
1314+
_stdout, stderr = run_rbs_collection("install", bundler: true)
1315+
1316+
refute_match(/`mutex_m` as a stdlib in rbs-gem is deprecated./, stderr)
1317+
1318+
lockfile = RBS::Collection::Config::Lockfile.from_lockfile(
1319+
lockfile_path: dir + "rbs_collection.lock.yaml",
1320+
data: YAML.safe_load((dir + "rbs_collection.lock.yaml").read)
1321+
)
1322+
1323+
assert_instance_of RBS::Collection::Sources::Rubygems, lockfile.gems["mutex_m"][:source]
1324+
end
1325+
end
1326+
end
1327+
1328+
def test_collection_install__mutex_m__config__no_bundled
1329+
Dir.mktmpdir do |dir|
1330+
Dir.chdir(dir) do
1331+
dir = Pathname(dir)
1332+
1333+
(dir + RBS::Collection::Config::PATH).write(<<~YAML)
1334+
sources:
1335+
- name: ruby/gem_rbs_collection
1336+
remote: https://github.com/ruby/gem_rbs_collection.git
1337+
revision: b4d3b346d9657543099a35a1fd20347e75b8c523
1338+
repo_dir: gems
1339+
1340+
path: #{dir.join('gem_rbs_collection')}
1341+
1342+
gems:
1343+
- name: mutex_m
1344+
YAML
1345+
1346+
bundle_install(["mutex_m", "0.2.0"])
1347+
_stdout, stderr = run_rbs_collection("install", bundler: true)
1348+
1349+
assert_include stderr, '`mutex_m` as a stdlib in rbs-gem is deprecated.'
1350+
assert_include stderr, 'Add `mutex_m` (>= 0.3.0) to the dependency of your Ruby program to use the gem-bundled type definition.'
1351+
1352+
lockfile = RBS::Collection::Config::Lockfile.from_lockfile(
1353+
lockfile_path: dir + "rbs_collection.lock.yaml",
1354+
data: YAML.safe_load((dir + "rbs_collection.lock.yaml").read)
1355+
)
1356+
1357+
assert_instance_of RBS::Collection::Sources::Stdlib, lockfile.gems["mutex_m"][:source]
1358+
end
1359+
end
1360+
end
1361+
1362+
def test_collection_install__mutex_m__config__stdlib_source
1363+
Dir.mktmpdir do |dir|
1364+
Dir.chdir(dir) do
1365+
dir = Pathname(dir)
1366+
1367+
(dir + RBS::Collection::Config::PATH).write(<<~YAML)
1368+
sources:
1369+
- name: ruby/gem_rbs_collection
1370+
remote: https://github.com/ruby/gem_rbs_collection.git
1371+
revision: b4d3b346d9657543099a35a1fd20347e75b8c523
1372+
repo_dir: gems
1373+
1374+
path: #{dir.join('gem_rbs_collection')}
1375+
1376+
gems:
1377+
- name: mutex_m
1378+
source:
1379+
type: stdlib
1380+
YAML
1381+
1382+
bundle_install
1383+
_stdout, stderr = run_rbs_collection("install", bundler: true)
1384+
1385+
assert_include stderr, '`mutex_m` as a stdlib in rbs-gem is deprecated.'
1386+
assert_include stderr, 'Add `mutex_m` (>= 0.3.0) to the dependency of your Ruby program to use the gem-bundled type definition.'
1387+
1388+
lockfile = RBS::Collection::Config::Lockfile.from_lockfile(
1389+
lockfile_path: dir + "rbs_collection.lock.yaml",
1390+
data: YAML.safe_load((dir + "rbs_collection.lock.yaml").read)
1391+
)
1392+
1393+
assert_instance_of RBS::Collection::Sources::Stdlib, lockfile.gems["mutex_m"][:source]
1394+
end
1395+
end
1396+
end
1397+
1398+
def test_collection_install__mutex_m__bundled
1399+
Dir.mktmpdir do |dir|
1400+
Dir.chdir(dir) do
1401+
dir = Pathname(dir)
1402+
1403+
(dir + RBS::Collection::Config::PATH).write(<<~YAML)
1404+
sources:
1405+
- name: ruby/gem_rbs_collection
1406+
remote: https://github.com/ruby/gem_rbs_collection.git
1407+
revision: b4d3b346d9657543099a35a1fd20347e75b8c523
1408+
repo_dir: gems
1409+
1410+
path: #{dir.join('gem_rbs_collection')}
1411+
YAML
1412+
1413+
bundle_install(["mutex_m", ">= 0.3.0"])
1414+
_stdout, stderr = run_rbs_collection("install", bundler: true)
1415+
1416+
refute_match(/`mutex_m` as a stdlib in rbs-gem is deprecated./, stderr)
1417+
1418+
lockfile = RBS::Collection::Config::Lockfile.from_lockfile(
1419+
lockfile_path: dir + "rbs_collection.lock.yaml",
1420+
data: YAML.safe_load((dir + "rbs_collection.lock.yaml").read)
1421+
)
1422+
1423+
assert_instance_of RBS::Collection::Sources::Rubygems, lockfile.gems["mutex_m"][:source]
1424+
end
1425+
end
1426+
end
1427+
1428+
def test_collection_install__mutex_m__no_bundled
1429+
Dir.mktmpdir do |dir|
1430+
Dir.chdir(dir) do
1431+
dir = Pathname(dir)
1432+
1433+
(dir + RBS::Collection::Config::PATH).write(<<~YAML)
1434+
sources:
1435+
- name: ruby/gem_rbs_collection
1436+
remote: https://github.com/ruby/gem_rbs_collection.git
1437+
revision: b4d3b346d9657543099a35a1fd20347e75b8c523
1438+
repo_dir: gems
1439+
1440+
path: #{dir.join('gem_rbs_collection')}
1441+
YAML
1442+
1443+
bundle_install(["mutex_m", "0.2.0"])
1444+
_stdout, stderr = run_rbs_collection("install", bundler: true)
1445+
1446+
assert_include stderr, '`mutex_m` as a stdlib in rbs-gem is deprecated.'
1447+
assert_include stderr, 'Add `mutex_m` (>= 0.3.0) to the dependency of your Ruby program to use the gem-bundled type definition.'
1448+
1449+
lockfile = RBS::Collection::Config::Lockfile.from_lockfile(
1450+
lockfile_path: dir + "rbs_collection.lock.yaml",
1451+
data: YAML.safe_load((dir + "rbs_collection.lock.yaml").read)
1452+
)
1453+
1454+
assert_instance_of RBS::Collection::Sources::Stdlib, lockfile.gems["mutex_m"][:source]
1455+
end
1456+
end
1457+
end
1458+
1459+
def test_collection_install__mutex_m__dependency_no_bundled
1460+
Dir.mktmpdir do |dir|
1461+
Dir.chdir(dir) do
1462+
dir = Pathname(dir)
1463+
1464+
(dir + RBS::Collection::Config::PATH).write(<<~YAML)
1465+
sources:
1466+
- type: local
1467+
path: repo
1468+
1469+
path: #{dir.join('gem_rbs_collection')}
1470+
YAML
1471+
1472+
(dir/"repo/true_string/0").mkpath
1473+
(dir/"repo/true_string/0/manifest.yaml").write(<<~YAML)
1474+
dependencies:
1475+
- name: mutex_m
1476+
YAML
1477+
1478+
bundle_install("true_string") # true_string is a soutaro's gem that doesn't have sig directory
1479+
1480+
_stdout, stderr = run_rbs_collection("install", bundler: true)
1481+
1482+
assert_include stderr, '`mutex_m` is included in the RBS dependencies of `true_string`, but the type definition as a stdlib in rbs-gem is deprecated.'
1483+
assert_include stderr, 'Add `mutex_m` (>= 0.3.0) to the dependency of your Ruby program to use the gem-bundled type definition.'
1484+
1485+
lockfile = RBS::Collection::Config::Lockfile.from_lockfile(
1486+
lockfile_path: dir + "rbs_collection.lock.yaml",
1487+
data: YAML.safe_load((dir + "rbs_collection.lock.yaml").read)
1488+
)
1489+
1490+
assert_instance_of RBS::Collection::Sources::Stdlib, lockfile.gems["mutex_m"][:source]
1491+
end
1492+
end
1493+
end
1494+
1495+
def test_collection_install__mutex_m__rbs_dependency_and__gem_dependency
1496+
Dir.mktmpdir do |dir|
1497+
Dir.chdir(dir) do
1498+
dir = Pathname(dir)
1499+
1500+
(dir/"gem").mkpath
1501+
(dir/"gem/hola.gemspec").write(<<~RUBY)
1502+
Gem::Specification.new do |s|
1503+
s.name = "hola"
1504+
s.version = "0.0.0"
1505+
s.summary = "Hola!"
1506+
s.description = "A simple hello world gem"
1507+
s.authors = ["Nick Quaranto"]
1508+
s.email = "[email protected]"
1509+
s.files = ["lib/hola.rb", "sig/hola.rbs"]
1510+
s.homepage =
1511+
"https://rubygems.org/gems/hola"
1512+
s.license = "MIT"
1513+
s.add_runtime_dependency "mutex_m", ">= 0.3.0"
1514+
end
1515+
RUBY
1516+
(dir/"gem/sig").mkpath
1517+
(dir/"gem/sig/manifest.yaml").write(<<~YAML)
1518+
dependencies:
1519+
- name: mutex_m
1520+
YAML
1521+
1522+
bundle_install(["hola", { path: "gem" }])
1523+
1524+
(dir + RBS::Collection::Config::PATH).write(<<~YAML)
1525+
sources:
1526+
- name: ruby/gem_rbs_collection
1527+
remote: https://github.com/ruby/gem_rbs_collection.git
1528+
revision: b4d3b346d9657543099a35a1fd20347e75b8c523
1529+
repo_dir: gems
1530+
1531+
path: #{dir.join('gem_rbs_collection')}
1532+
YAML
1533+
1534+
_stdout, stderr = run_rbs_collection("install", bundler: true)
1535+
1536+
assert_include stderr, '`mutex_m` is included in the RBS dependencies of `hola`, but the type definition as a stdlib in rbs-gem is deprecated.'
1537+
assert_include stderr, 'Delete `mutex_m` from the RBS dependencies of `hola`.'
1538+
1539+
lockfile = RBS::Collection::Config::Lockfile.from_lockfile(
1540+
lockfile_path: dir + "rbs_collection.lock.yaml",
1541+
data: YAML.safe_load((dir + "rbs_collection.lock.yaml").read)
1542+
)
1543+
1544+
assert_instance_of RBS::Collection::Sources::Rubygems, lockfile.gems["mutex_m"][:source]
1545+
end
1546+
end
1547+
end
1548+
12911549
def test_subtract
12921550
Dir.mktmpdir do |dir|
12931551
dir = Pathname(dir)

0 commit comments

Comments
 (0)