Skip to content

Cache only bundle and stdlib gems by default - #1342

Open
apiology wants to merge 4 commits into
castwide:masterfrom
apiology:cache-gems-from-bundle
Open

Cache only bundle and stdlib gems by default#1342
apiology wants to merge 4 commits into
castwide:masterfrom
apiology:cache-gems-from-bundle

Conversation

@apiology

@apiology apiology commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Problem: solargraph gems with no arguments builds documentation for every gem version RubyGems can see, rather than the ones the workspace can actually load. Outside bundle exec on one developer box that is 575 installed specs across 370 unique names, 205 of them stale versions nothing in the project can require.

$ solargraph gems
...
Documentation cached for all 575 gems.

Under bundle exec the figure is smaller — 141 here — but still includes gems the bundle does not resolve, and each one pays for a YARD build and an RBS collection lookup.

Solution: Select from the workspace instead — the gemspecs its bundle resolves, plus the standard libraries of the running Ruby that resolve to a gemspec here — which is 121 in this repo, at the cost that a gem installed outside the bundle now has to be named explicitly.

🤖 Generated with Claude Code

apiology and others added 4 commits September 5, 2026 23:35
`solargraph gems` with no arguments walked `Gem::Specification.to_a`,
which is every gem version installed on the machine. On one developer
box that is 575 specs across 370 unique names, so 205 of them are
stale versions the workspace can never load. Each one still paid for a
YARD build and an RBS collection lookup.

Select from the workspace instead: the gemspecs its bundle resolves,
plus the standard libraries of the running Ruby that resolve to a
gemspec here. In this repo that is 121 gemspecs rather than the 133
`Gem::Specification` reports under `bundle exec`, and far fewer when
run outside a restricted bundle.

`Workspace#gemspecs_to_cache` performs the selection and
`PinCache.possible_stdlibs` lists the standard library candidates, so
both are testable without building any pins.

This narrows coverage on purpose. A gem installed on the machine but
absent from the workspace's bundle is no longer cached by a bare
`solargraph gems`; name it explicitly to cache it. In a directory with
no resolvable bundle the selection falls back to standard libraries
alone rather than to everything installed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QRZoPdBqpztWbGk7KmkgBX
`solargraph gems core` raises NoMethodError: Shell#gems calls
PinCache.cache_core, which is defined on RbsMap::CoreMap and nowhere on
PinCache. The comment above the call claiming both it and PinCache.core?
are dynamically defined is wrong; nothing defines either.

Assert the behaviour that should hold, marked pending so it fails
silently now and breaks the build the day the defect is fixed, which is
what forces the marker out. The assertion targets CoreMap.cache_core
having been called, so it holds whether the fix delegates from PinCache
or calls CoreMap directly.
cache_core is an instance method on RbsMap::CoreMap, so stubbing it on
the class meant the expectation could never be satisfied and the pending
marker would never flip. Stub CoreMap.new instead.

Verified both directions: the example still fails at shell.rb:194 today
and is reported pending, and applying the fix locally turns it FIXED and
fails the suite, which is what forces the marker out.
Scoping to the bundle silently removed the ability to work outside one.
In a directory with no Gemfile, all_gemspecs_from_external_bundle rescues
BundleNotFoundError to an empty list and nothing put the installed set
back, so gemspecs_to_cache returned 1 gemspec where master cached 1021,
and references to any installed gem stopped resolving.

Fall back to every installed gemspec when the bundle yields nothing.
Keying on the empty result rather than on the presence of a Gemfile
covers both the no-Gemfile case and a bundle that resolves to nothing,
and needs no new predicate.

The spec added with the original change asserted the fallback never
happened, which is why nothing caught this; it now describes the bundled
case, alongside a new example for the unbundled one.
@apiology
apiology marked this pull request as ready for review September 7, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant