Don't require source plugins to be installed to parse a lockfile#9620
Open
hsbt wants to merge 3 commits into
Open
Don't require source plugins to be installed to parse a lockfile#9620hsbt wants to merge 3 commits into
hsbt wants to merge 3 commits into
Conversation
Unlike real plugin sources, where each type is handled by its own class, every unloaded source shares this single class, so the class+uri comparison inherited from API::Source would conflate two different plugin types pointing at the same remote. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Third-party tools like bundler-audit read lockfiles through Bundler::LockfileParser without evaluating the Gemfile, and a PLUGIN SOURCE block whose plugin isn't installed locally aborted the whole parse with UnknownSourceError, taking even DEPENDENCIES down with it. Fall back to the inert UnloadedSource placeholder instead, which also lets bundle install converge away a plugin source that was removed from the Gemfile. #9614 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adjusts Bundler’s plugin-source lockfile handling so that third-party tools (and Bundler itself during recovery scenarios) can parse a lockfile containing PLUGIN SOURCE blocks even when the corresponding source plugin is not installed locally, by falling back to Bundler::Plugin::UnloadedSource instead of raising.
Changes:
- Update
Bundler::Plugin.from_lockto returnUnloadedSourcewhen a plugin source type is not registered/installed, avoidingUnknownSourceErrorduring lockfile parsing. - Refine
UnloadedSource#==/#hashto incorporate the plugin sourcetype, preventing different plugin-source types with the same remote from being treated as the same source. - Add specs covering successful parsing of dependencies/specs from lockfiles with missing plugin source handlers.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| spec/bundler/plugin_spec.rb | Adds coverage for Plugin.from_lock returning UnloadedSource when the source plugin is missing. |
| spec/bundler/lockfile_parser_spec.rb | Adds coverage ensuring lockfile parsing still succeeds (deps + specs) with an uninstalled plugin source type. |
| bundler/lib/bundler/plugin/unloaded_source.rb | Updates equality/hash semantics to differentiate unloaded sources by plugin source type. |
| bundler/lib/bundler/plugin.rb | Changes plugin source instantiation from lockfiles to fall back to UnloadedSource when the plugin isn’t installed. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+11
to
+22
| # Unlike real plugin sources, where the handling class encodes the | ||
| # source type, all unloaded sources share this class, so the type must | ||
| # be compared explicitly. | ||
| def ==(other) | ||
| super && options["type"] == other.options["type"] | ||
| end | ||
|
|
||
| alias_method :eql?, :== | ||
|
|
||
| def hash | ||
| [super, options["type"]].hash | ||
| end |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was the end-user or developer problem that led to this PR?
Third-party tools like
bundler-auditread lockfiles throughBundler::LockfileParser.new(contents)without evaluating the Gemfile.When a lockfile contains a
PLUGIN SOURCEblock whose plugin is not installed locally,Plugin.from_lockraisedBundler::Plugin::UnknownSourceErrorand aborted the whole parse, so evenDEPENDENCIEScould not be read. The same raise also preventedbundle installfrom recovering when a plugin source was removed from the Gemfile but still present in the lockfile.Fixes #9614
What is your fix for the problem, implemented in this PR?
Plugin.from_locknow falls back to the inertUnloadedSourceplaceholder when the plugin handling the source type is not installed, so the lockfile can still be parsed and the specs under that source remain readable.Regular
bundle installis unaffected because plugins are installed during the plugin-install-from-gemfile phase before the main lockfile parse, and a Gemfile that still declares the source keeps raising from the DSL as before.Since all unloaded sources share a single class,
UnloadedSource#==and#hashnow also compare the source type so that two plugin sources with the same remote but different types are not conflated.Make sure the following tasks are checked