-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Compare sources using source's root #5817
Compare sources using source's root #5817
Conversation
Thanks for opening a pull request and helping make Bundler better! Someone from the Bundler team will take a look at your pull request shortly and leave any feedback. Please make sure that your pull request has tests for any changes or added functionality. We use Travis CI to test and make sure your change works functionally and uses acceptable conventions, you can review the current progress of Travis CI in the PR status window below. If you have any questions or concerns that you wish to ask, feel free to leave a comment in this PR or join our #bundler channel on Slack. For more information about contributing to the Bundler project feel free to review our CONTRIBUTING guide |
@segiddins pinging you only because you have touched this file recently... sorry if this is a bother Wanted to add a test for this change, but wasn't sure the best spot to add it... have any suggestions on where to put it? |
|
lib/bundler/source/path.rb
Outdated
@@ -65,7 +65,7 @@ def hash | |||
|
|||
def eql?(other) | |||
return unless other.class == self.class | |||
expand(@original_path) == expand(other.original_path) && | |||
expand(@original_path) == other.expanded_original_path && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expanded_original_path == other.expanded_original_path
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You know... that change would have made sense, huh... oops
I will update when I add a test for this as well. Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
491a0f8
to
b4e94d6
Compare
@@ -41,6 +41,13 @@ | |||
bundle! :install | |||
expect(the_bundle).to include_gem("a 1.0") | |||
end | |||
|
|||
# Make sure that we are properly comparing path based gems between the | |||
# parsed lockfile and the evaluated gemfile. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this one, it will fail in a blaze of glory (when using the old code) with something along the lines of the following outputted (trimmed down a bit for readability):
$ ruby -Ilib:spec -rsupport/hax -rsupport/artifice/fail exe/bundle install --no-color
Resolving dependencies...
Using a 1.0 from source at `../gems/a`
Using bundler 1.15.1
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
# $? => 0
$ ruby -Ilib:spec -rsupport/hax -rsupport/artifice/fail exe/bundle install --deployment --no-color
You are trying to install in deployment mode after changing
your Gemfile. Run `bundle install` elsewhere and add the
updated Gemfile.lock to version control.
The list of sources changed
The gemspecs for path gems changed
You have added to the Gemfile:
* source: source at `../gems/a`
# $? => 16
Not sure if it was worth adding all this as a comment to the spec, but leaving this hear for some context
@segiddins Added a unit test in there as well that contains a few light tests for the |
When doing the following: expand(other.original_path) inside a Bundler::Source::Path instance, the `@root_path` from the instance that is having eql? called on it, the other instance's root_path. This, in obscure cases, can cause a bug when you are doing an nested eval_gemfile or other calls when comparing the lockfile's locked path sources to the Bundler.definition's path sources. Creating the expanded_original_path method allows a public interface to be made available (and doesn't mess with any exiting functionality) that allows comparing the source path of one Source::Path's expand_path to another, where each uses their own root_path to resolve their full path, instead of sharing the base one and causing edge case bugs
b4e94d6
to
3db89ca
Compare
Thanks! |
📌 Commit 3db89ca has been approved by |
…, r=segiddins Compare sources using source's root ### What was the end-user problem that led to this PR? Given a setup where: 1. A project's Gemfile makes use of another project's Gemfile and the `eval_gemfile` method to share the dependencies. Something like: ```ruby # project_plugin's Gemfile eval_gemfile(File.expand_path("../../main_project/Gemfile", __FILE__)) ``` 2. The main project includes a path gem in it that is nested in the main project: ```ruby # main_project's Gemfile gem "foo_gem", :path => "vendor/foo_gem" ``` 3. A `bundle install` is followed by a `bundle install --deployment`, the second of which triggers a comparison of the `lockfile.sources` and the `Bundler.definition` A error will occur when comparing the specs, saying the the "foo_gem" source has been deleted: ```console $ bundle install ... $ bundle install --deployment You are trying to install in deployment mode after changing your Gemfile. Run `bundle install` elsewhere and add the updated Gemfile.lock to version control. the gemspecs for path gems changed You have deleted from the Gemfile: * source: source at `../main_project/vendor/foo_gem` ``` ### What was your diagnosis of the problem? (extracted from the commit message) When doing the following: expand(other.original_path) inside a `Bundler::Source::Path` instance, the `@root_path` from the instance that is having `eq?` called on it, the the `other` instance's `root_path`. This, in obscure cases, can cause a bug when you are doing an nested eval_gemfile or other calls when comparing the lockfile's locked path sources to the `Bundler.definition`'s path sources. ### What is your fix for the problem, implemented in this PR? Use a new public method, `Bundler::Source::Path#expanded_original_path`, in the `eq?` method instead of using's the instance's `#expand` method. ### Why did you choose this fix out of the possible options? (extracted from the commit message) Creating the `expanded_original_path` method allows a public interface to be made available (and doesn't mess with any exiting functionality) that allows comparing the source path of one `Source::Path`'s `expand_path` to another, where each uses their own `root_path` to resolve their full path, instead of sharing the base one and causing edge case bugs
☀️ Test successful - status-travis |
…, r=segiddins Compare sources using source's root ### What was the end-user problem that led to this PR? Given a setup where: 1. A project's Gemfile makes use of another project's Gemfile and the `eval_gemfile` method to share the dependencies. Something like: ```ruby # project_plugin's Gemfile eval_gemfile(File.expand_path("../../main_project/Gemfile", __FILE__)) ``` 2. The main project includes a path gem in it that is nested in the main project: ```ruby # main_project's Gemfile gem "foo_gem", :path => "vendor/foo_gem" ``` 3. A `bundle install` is followed by a `bundle install --deployment`, the second of which triggers a comparison of the `lockfile.sources` and the `Bundler.definition` A error will occur when comparing the specs, saying the the "foo_gem" source has been deleted: ```console $ bundle install ... $ bundle install --deployment You are trying to install in deployment mode after changing your Gemfile. Run `bundle install` elsewhere and add the updated Gemfile.lock to version control. the gemspecs for path gems changed You have deleted from the Gemfile: * source: source at `../main_project/vendor/foo_gem` ``` ### What was your diagnosis of the problem? (extracted from the commit message) When doing the following: expand(other.original_path) inside a `Bundler::Source::Path` instance, the `@root_path` from the instance that is having `eq?` called on it, the the `other` instance's `root_path`. This, in obscure cases, can cause a bug when you are doing an nested eval_gemfile or other calls when comparing the lockfile's locked path sources to the `Bundler.definition`'s path sources. ### What is your fix for the problem, implemented in this PR? Use a new public method, `Bundler::Source::Path#expanded_original_path`, in the `eq?` method instead of using's the instance's `#expand` method. ### Why did you choose this fix out of the possible options? (extracted from the commit message) Creating the `expanded_original_path` method allows a public interface to be made available (and doesn't mess with any exiting functionality) that allows comparing the source path of one `Source::Path`'s `expand_path` to another, where each uses their own `root_path` to resolve their full path, instead of sharing the base one and causing edge case bugs (cherry picked from commit fb33846)
What was the end-user problem that led to this PR?
Given a setup where:
eval_gemfile
method to share the dependencies. Something like:bundle install
is followed by abundle install --deployment
, the second of which triggers a comparison of thelockfile.sources
and theBundler.definition
A error will occur when comparing the specs, saying the the "foo_gem" source has been deleted:
What was your diagnosis of the problem?
(extracted from the commit message)
When doing the following:
inside a
Bundler::Source::Path
instance, the@root_path
from the instance that is havingeq?
called on it, the theother
instance'sroot_path
. This, in obscure cases, can cause a bug when you are doing an nested eval_gemfile or other calls when comparing the lockfile's locked path sources to theBundler.definition
's path sources.What is your fix for the problem, implemented in this PR?
Use a new public method,
Bundler::Source::Path#expanded_original_path
, in theeq?
method instead of using's the instance's#expand
method.Why did you choose this fix out of the possible options?
(extracted from the commit message)
Creating the
expanded_original_path
method allows a public interface to be made available (and doesn't mess with any exiting functionality) that allows comparing the source path of oneSource::Path
'sexpand_path
to another, where each uses their ownroot_path
to resolve their full path, instead of sharing the base one and causing edge case bugs