Skip to content

Commit d1fdb1b

Browse files
pockeclaude
andcommitted
Test that rbs collection clean removes unneeded directories
`rbs collection clean` built a `Collection::Cleaner` and never called `#clean` on it, so the command walked away with exit status 0 while leaving every directory in place. The bug dates back to 38fd8b2, the commit that introduced `rbs collection`, so the command had never once removed anything. `test/rbs/collection/cleaner_test.rb` exercises `Cleaner#clean` directly, which is why the missing call went unnoticed for so long. This test goes through `RBS::CLI#run` instead, so it covers the wiring between the subcommand and the cleaner. The lockfile lists `ast 2.4`. The collection directory also holds `ast 2.3` and `rainbow 3.0`, covering both reasons `Cleaner#needed?` rejects a directory: a gem locked at another version, and a gem absent from the lockfile. `ast/2.4/ast.rbs` is written so that the assertion on the version that survives shows its RBS files are left alone rather than only that a directory still exists. The collection is named with `--collection` rather than by changing the working directory. `Config.find_config_path` walks from the working directory up to the filesystem root, so a `Dir.chdir` based test stays inside its temporary directory only as long as the config file is written before `cli.run`. With `TMPDIR` pointed inside a real project, a reordering would let the search reach an ancestor's lockfile and delete that project's `.gem_rbs_collection`. `--collection` expands the path it is given and skips the search. The config file is written empty. `clean` reads `path` and `gems` from the lockfile and never opens the config, and `path` appears in both files, so giving the config a `path` of its own would suggest that the command consults it. Its one remaining job is to be what `--collection` names and what the lockfile path is derived from, which is why the lockfile is written through `Config.to_lockfile_path` instead of a hardcoded name that happens to match. The `source` block in the lockfile stays even though `Cleaner#needed?` does not read it. `Lockfile.from_lockfile` passes `gem["source"]` to `Sources.from_config_entry`, so a lockfile without it raises `NoMethodError` when read through `Lockfile` rather than `Config`. #3127 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HSq3kKMB8ULhZrnL5urD7y
1 parent a6b1e04 commit d1fdb1b

1 file changed

Lines changed: 36 additions & 0 deletions

File tree

test/rbs/cli_test.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,6 +1734,42 @@ def test_collection_install__set_pathname__manifest
17341734
end
17351735
end
17361736

1737+
def test_collection_clean
1738+
Dir.mktmpdir do |dir|
1739+
dir = Pathname(dir)
1740+
1741+
config_path = dir + RBS::Collection::Config::PATH
1742+
config_path.write("")
1743+
1744+
RBS::Collection::Config.to_lockfile_path(config_path).write(<<~YAML)
1745+
path: .gem_rbs_collection
1746+
gems:
1747+
- name: ast
1748+
version: "2.4"
1749+
source:
1750+
type: git
1751+
name: ruby/gem_rbs_collection
1752+
remote: https://github.com/ruby/gem_rbs_collection.git
1753+
revision: b4d3b346d9657543099a35a1fd20347e75b8c523
1754+
repo_dir: gems
1755+
YAML
1756+
1757+
collection_dir = dir + ".gem_rbs_collection"
1758+
(collection_dir + "ast/2.4").mkpath
1759+
(collection_dir + "ast/2.4/ast.rbs").write("class Ast end")
1760+
(collection_dir + "ast/2.3").mkpath
1761+
(collection_dir + "rainbow/3.0").mkpath
1762+
1763+
with_cli do |cli|
1764+
assert_cli_success cli.run(["--collection", config_path.to_s, "collection", "clean"])
1765+
end
1766+
1767+
assert_predicate(collection_dir + "ast/2.4/ast.rbs", :file?)
1768+
refute_predicate(collection_dir + "ast/2.3", :exist?)
1769+
refute_predicate(collection_dir + "rainbow/3.0", :exist?)
1770+
end
1771+
end
1772+
17371773
def test_subtract
17381774
Dir.mktmpdir do |dir|
17391775
dir = Pathname(dir)

0 commit comments

Comments
 (0)