Fix only_update_to_newer_versions regression#6708
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 |
f2c8d3b to
71f0a0c
Compare
greysteil
left a comment
There was a problem hiding this comment.
This looks good to me - nice catch! And the test looks solid.
lib/bundler/definition.rb
Outdated
| return [] unless @locked_gems && Bundler.feature_flag.only_update_to_newer_versions? | ||
| dependencies_by_name = dependencies.group_by(&:name) | ||
| dependencies_by_name = dependencies.each_with_object({}) {|dep, memo| memo[dep.name] = dep } | ||
| all_locked_deps = @locked_gems.dependencies |
There was a problem hiding this comment.
I'd rather lose this assignment and use the @locked_gems.dependencies directly in the loop
lib/bundler/definition.rb
Outdated
| def additional_base_requirements_for_resolve | ||
| return [] unless @locked_gems && Bundler.feature_flag.only_update_to_newer_versions? | ||
| dependencies_by_name = dependencies.group_by(&:name) | ||
| dependencies_by_name = dependencies.each_with_object({}) {|dep, memo| memo[dep.name] = dep } |
There was a problem hiding this comment.
We don't have each_with_object in Ruby 1.8.7, so this will need to use reduce
71f0a0c to
21a12c5
Compare
|
I've incorporated your comments |
|
@bundlerbot r+ |
6708: Fix only_update_to_newer_versions regression r=greysteil a=theflow This is my attempt to fix #6529 ### What was the end-user problem that led to this PR? Running `bundle update` with `BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS: "true"` resulted in a gem getting downgraded to a really old version in a certain edge case. Ironically it wouldn't get downgraded when `BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS` was set to false. ### What was your diagnosis of the problem? My diagnosis was that 47256d2 tried to solve the problem of still allowing manual downgrades in the Gemfile while `only_update_to_newer_versions` is true. But introduced a regression that prevented the `additional_base_requirements_for_resolve` method to work as intended: This is the relevant change from that commit that tries to avoid adding the `>=` requirement if the requirement in the Gemfile is different than the requirement in the lockfile (as far as I understand it): ```ruby next requirements if @locked_deps[name] != dependencies_by_name[name] ``` I identified two problems 1. `dependencies_by_name[name]` returns an array of `Bundler::Dependency`, where as `@locked_deps[name]` just returns a single `Bundler::Dependency`. Comparing the two will always be false. 1. `@locked_deps` is always empty in case of `bundle update`. See: https://github.com/bundler/bundler/blob/3d9e6167a7df9ca89a030dfe95c7cdff293e74a9/lib/bundler/definition.rb#L95 ### What is your fix for the problem, implemented in this PR? My fixes: 1. Make sure `dependencies_by_name` is a hash with `Bundler::Dependency` as values 1. Fetch the `@locked_gems.dependencies` again instead of using `@locked_deps` 1. The existing test worked for me with and without the `only_update_to_newer_versions` set to true, I replaced it with a reproduction of the edge case I was investigating (this is as minimal as I could make it) 1. I've added a test for the manual downgrading case. ### Why did you choose this fix out of the possible options? This is the only way I could make these cases work. It's possible there are other edge cases I don't understand. Co-authored-by: Florian Munz <surf@theflow.de>
Build succeeded |
|
Thanks for this @theflow! 🎉 |
|
Thanks so much for this! |
6708: Fix only_update_to_newer_versions regression r=greysteil a=theflow This is my attempt to fix #6529 ### What was the end-user problem that led to this PR? Running `bundle update` with `BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS: "true"` resulted in a gem getting downgraded to a really old version in a certain edge case. Ironically it wouldn't get downgraded when `BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS` was set to false. ### What was your diagnosis of the problem? My diagnosis was that 47256d2 tried to solve the problem of still allowing manual downgrades in the Gemfile while `only_update_to_newer_versions` is true. But introduced a regression that prevented the `additional_base_requirements_for_resolve` method to work as intended: This is the relevant change from that commit that tries to avoid adding the `>=` requirement if the requirement in the Gemfile is different than the requirement in the lockfile (as far as I understand it): ```ruby next requirements if @locked_deps[name] != dependencies_by_name[name] ``` I identified two problems 1. `dependencies_by_name[name]` returns an array of `Bundler::Dependency`, where as `@locked_deps[name]` just returns a single `Bundler::Dependency`. Comparing the two will always be false. 1. `@locked_deps` is always empty in case of `bundle update`. See: https://github.com/bundler/bundler/blob/3d9e6167a7df9ca89a030dfe95c7cdff293e74a9/lib/bundler/definition.rb#L95 ### What is your fix for the problem, implemented in this PR? My fixes: 1. Make sure `dependencies_by_name` is a hash with `Bundler::Dependency` as values 1. Fetch the `@locked_gems.dependencies` again instead of using `@locked_deps` 1. The existing test worked for me with and without the `only_update_to_newer_versions` set to true, I replaced it with a reproduction of the edge case I was investigating (this is as minimal as I could make it) 1. I've added a test for the manual downgrading case. ### Why did you choose this fix out of the possible options? This is the only way I could make these cases work. It's possible there are other edge cases I don't understand. Co-authored-by: Florian Munz <surf@theflow.de> (cherry picked from commit 8501b1e)
6708: Fix only_update_to_newer_versions regression r=greysteil a=theflow This is my attempt to fix #6529 ### What was the end-user problem that led to this PR? Running `bundle update` with `BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS: "true"` resulted in a gem getting downgraded to a really old version in a certain edge case. Ironically it wouldn't get downgraded when `BUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS` was set to false. ### What was your diagnosis of the problem? My diagnosis was that 47256d2 tried to solve the problem of still allowing manual downgrades in the Gemfile while `only_update_to_newer_versions` is true. But introduced a regression that prevented the `additional_base_requirements_for_resolve` method to work as intended: This is the relevant change from that commit that tries to avoid adding the `>=` requirement if the requirement in the Gemfile is different than the requirement in the lockfile (as far as I understand it): ```ruby next requirements if @locked_deps[name] != dependencies_by_name[name] ``` I identified two problems 1. `dependencies_by_name[name]` returns an array of `Bundler::Dependency`, where as `@locked_deps[name]` just returns a single `Bundler::Dependency`. Comparing the two will always be false. 1. `@locked_deps` is always empty in case of `bundle update`. See: https://github.com/bundler/bundler/blob/3d9e6167a7df9ca89a030dfe95c7cdff293e74a9/lib/bundler/definition.rb#L95 ### What is your fix for the problem, implemented in this PR? My fixes: 1. Make sure `dependencies_by_name` is a hash with `Bundler::Dependency` as values 1. Fetch the `@locked_gems.dependencies` again instead of using `@locked_deps` 1. The existing test worked for me with and without the `only_update_to_newer_versions` set to true, I replaced it with a reproduction of the edge case I was investigating (this is as minimal as I could make it) 1. I've added a test for the manual downgrading case. ### Why did you choose this fix out of the possible options? This is the only way I could make these cases work. It's possible there are other edge cases I don't understand. Co-authored-by: Florian Munz <surf@theflow.de> (cherry picked from commit 8501b1e)
* 1-16-stable: Version 1.16.6 with changelog fix uninitialized @use_gvp instance var warning no longer test Ruby 1.9.3 against rubygems master Merge #6708 Auto merge of #6697 - walf443:added_changelog_section, r=hsbt Merge #6687 Merge #6686 Auto merge of #6670 - bundler:colby/invite-stephanie-morillo, r=segiddins Auto merge of #6627 - agrim123:agr-fix-add-groups, r=deivid-rodriguez Auto merge of #6612 - hdf1986:readme-bundle-add, r=segiddins Auto merge of #6495 - bundler:segiddins/6491-extra-gem-platform-in-lockfile, r=segiddins Auto merge of #6493 - agrim123:agr-update-bundle-update-docs, r=colby-swandale Auto merge of #6310 - utilum:rescue_unspecified_exception, r=segiddins Auto merge of #6184 - arbonap:pa-check-in-gemfile-docs, r=indirect fix typo
This is my attempt to fix #6529
What was the end-user problem that led to this PR?
Running
bundle updatewithBUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONS: "true"resulted in a gem getting downgraded to a really old version in a certain edge case. Ironically it wouldn't get downgraded whenBUNDLE_ONLY_UPDATE_TO_NEWER_VERSIONSwas set to false.What was your diagnosis of the problem?
My diagnosis was that 47256d2 tried to solve the problem of still allowing manual downgrades in the Gemfile while
only_update_to_newer_versionsis true. But introduced a regression that prevented theadditional_base_requirements_for_resolvemethod to work as intended:This is the relevant change from that commit that tries to avoid adding the
>=requirement if the requirement in the Gemfile is different than the requirement in the lockfile (as far as I understand it):I identified two problems
dependencies_by_name[name]returns an array ofBundler::Dependency, where as@locked_deps[name]just returns a singleBundler::Dependency. Comparing the two will always be false.@locked_depsis always empty in case ofbundle update. See: https://github.com/bundler/bundler/blob/3d9e6167a7df9ca89a030dfe95c7cdff293e74a9/lib/bundler/definition.rb#L95What is your fix for the problem, implemented in this PR?
My fixes:
dependencies_by_nameis a hash withBundler::Dependencyas values@locked_gems.dependenciesagain instead of using@locked_depsonly_update_to_newer_versionsset to true, I replaced it with a reproduction of the edge case I was investigating (this is as minimal as I could make it)Why did you choose this fix out of the possible options?
This is the only way I could make these cases work. It's possible there are other edge cases I don't understand.