Conversation
@@ -37,6 +37,9 @@ def run | |||
Bundler.definition(:gems => gems, :sources => sources, :ruby => options[:ruby]) | |||
end | |||
|
|||
patch_level = [:major, :minor, :patch].detect { |v| options.keys.include?(v.to_s) } |
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.
What if multiple are specified?
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.
should favor left to right (maj, min, pat) ... specifying multiple wouldn't make sense internally. dunno if it should favor the last one specified by the user? e.g. --minor --patch
=> --patch
vs. --patch --minor
=> --minor
After rubocop, seeing good test results. 1 failing that's intentional on my part, 2 that seem unrelated. |
should_consv_resolve_and_include :patch, ["foo"], %w(foo-1.3.8 bar-2.0.3) | ||
end | ||
|
||
it "resolves foo only to latest patch - changing dependency case" do |
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.
just thinking through this - here's the potential design flaw. In all other cases, strict
means: ensure no unlocking gem gets past the patch
/minor
threshold. And accordingly, not specifying strict
means for unlocking gems, if one of them has to go past the patch
/minor
threshold to satisfy the dependency tree, then ... ok.
But in THIS case, the 'not specifying strict
' case means for unlocking gems and their dependencies ... and thus having to use strict
to get the expected behavior is a debatable flaw.
Compare this case to the prior spec: "resolves foo only to latest patch - same dependency case" - that should highlight the inconsistency.
I'm not sure there's an easy code fix for this case, though.
Another discussion point - bundler-patch also works in vulnerable gem updates based on ruby-advisory-db content. I presume the core team would consider this out of scope for Bundler proper? I probably would, and there's no reason bundler-patch couldn't continue to exist as a plugin with this behavior. |
# versions and I'd rather go from 1.0.2 to 1.0.3 instead of 1.0.45. But, we could consider killing the | ||
# minimal option altogether. If that's what you need, use the Gemfile dependency. | ||
should_consv_resolve_and_include [:minor, :minimal], [], %w(foo-1.4.4 bar-2.0.4) | ||
end |
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.
The --minimal
flag is also something bundler-patch has that has debatable value. Would love to hear opinions on it and could be easily swayed to remove it or keep it.
☔ The latest upstream changes (presumably #4618) made this pull request unmergeable. Please resolve the merge conflicts. |
b0a245d
to
5d87a15
Compare
@@ -94,7 +94,7 @@ def initialize(lockfile, dependencies, sources, unlock, ruby_version = nil, opti | |||
end | |||
@unlocking ||= @unlock[:ruby] || (!@locked_ruby_version ^ !@ruby_version) | |||
|
|||
@gem_version_promoter = GemVersionPromoter.new(@locked_specs, @unlock[:gems]) | |||
create_gem_version_promoter |
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 testing purposes, maybe make the assignment here instead of in create_gem_version_promoter
?
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.
Do you mean inline #create_gem_version_promoter? constructor already feels rather fat to me - I wanted to encapsulate that in its own method with the additional logic to re-capture the locked_specs. I tried to find a way to re-use the @locked_specs or locked local var rather than re-executing, but it didn't seem clean to me with the various conditionals.
But if that's not what you mean, I'm not understanding your comment ... ?
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.
no, I mean have @gem_version_promoter = create_gem_version_promoter
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.
oh right - yeah, I'm down with that.
|
sort_dep_specs(dep_specs, locked_spec) | ||
end.tap do |specs| | ||
if ENV["DEBUG_PATCH_RESOLVER"] # MODO: proper debug flag name, check and proper debug output | ||
STDERR.puts before_result |
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.
please use the Bundler.ui
debug methods here
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.
will do. I need to revisit that flag too, perhaps re-use DEBUG_RESOLVER
.
@indirect thx for the feedback - added a couple of more to the checklist |
|
@@ -206,6 +206,12 @@ def install | |||
"Update ruby specified in Gemfile.lock" | |||
method_option "bundler", :type => :string, :lazy_default => "> 0.a", :banner => | |||
"Update the locked version of bundler" | |||
method_option "patch", :type => :boolean, :banner => | |||
"Prefer updating only to next patch version" |
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.
isn't this only allow updating gems' patch versions
?
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.
there's a --strict
flag I hadn't added here yet I just realized ...
If --strict
is also used, then the code will actually remove versions fed back to Molinillo, but that can result in no updates happening or VersionConflict cases that report a version can't be found that actually does exist in the index, causing a very weird "looks like a bug" experience. (hmmm ... while I did see VersionConflict cases early on, I haven't seen one in a while ... I may need to try and recreate that in a spec -- maybe that was due to an early bug and shouldn't be possible).
So, not using --strict
is the default and it means the code will only sort to the front (not filter out) the patch versions first - which favors getting something done, but it's potentially not as conservative.
One challenge still existing is trying to give better output in these conservative cases, because sometimes no change will happen at all and there's no feedback to the user trying to explain "well, you wanted to go up to 1.8.3 from 1.8.2, but 1.8.3 needs a minor increment and you fed it --strict so it couldn't do anything" - but I've no idea if that's even plausible. It wouldn't be too unlike the Conflict output ... but these aren't cases of a Conflict.
I did think also there could be a way to detect increments beyond what was requested and warn those somehow.
#pascalsapology
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.
So, not using --strict is the default and it means the code will only sort to the front (not filter out) the patch versions first - which favors getting something done, but it's potentially not as conservative.
AHHH, this was the whole piece I was missing, sorry
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.
no worries - option isn't listed there yet.
@chrismo: we want to stop allowing |
i imagine it's a rare case, but if i need to bugfix |
Thinking on this more - I think the best balance is: (a) do NOT filter older versions from the non-strict case, and (b) remove older versions from the |
(For a real life case, bundler-patch itself started with slop v. 4, but that conflicted with any bundle including pry, which uses slop v. 3. So I released a newer version of bundler-patch that required an older version of slop). |
There's also an existing test that tests a regression: https://github.com/bundler/bundler/blob/master/spec/commands/install_spec.rb#L155-L168 - from activesupport 2.3.5 back to 2.3.2 |
Getting caught up on missing update_specs, realized `--strict` flagged wasn't being passed through. Fixed.
When I ported over specs from bundler-patch, I had a TODO on a combination that had no specs, so that's taken care of now.
This is the first behavior change from bundler-patch. Used to be older versions would never be an option, but Bundler proper has always supported this (if necessary to resolve the dependency tree) and there can be some legit cases for doing this. The `--strict` flag could be used to override this behavior, but I'm running into a Molinillo behavior that I'm not sure is correct, so the specs involving the strict option are failing right now. I'm going to push so @segiddins and I can discuss.
Also some pending specs cleanup. These may be added as new issues and addressed later.
segiddins and I are agreed there appears to be an issue with Molinillo in these cases, but they are unusual and for now we're looking to do an undocumented release of the new conservative updates, so we can start to get feedback. We'll revisit these cases.
I think I found the problem here. Should have commits soon. |
Not a common case, but glitch is triggered by new plugin integration tests when there's no Gemfile or .bundle directory. A GemfileNotFound exception is raised deeper down the call stack trying to access the cache_path when executed in a non-bundler dir. That case apparently is legit for plugins.
1b3d14d
to
263c187
Compare
@indirect or @segiddins - can you retry the auto-merge? |
@homu r+ |
📌 Commit 263c187 has been approved by |
⚡ Test exempted - status |
Conservative updates A port of bundler-patch to bundler proper. Core team questions: - [x] bundler-patch also works in vulnerable gem updates based on ruby-advisory-db content. I presume the core team would consider this out of scope for Bundler proper? I probably would, and there's no reason bundler-patch couldn't continue to exist as a plugin with this behavior. - [x] "resolves foo only to latest patch - changing dependency case" - more comments on that spec. It's a weird edge case. Hopefully the specs and comments make it clear. - [x] Name of new class: GemVersionPromoter. It's gone through a few renames already and every option I think of I hate now :) - [x] The `--minimal` flag is also something bundler-patch has that has debatable value. Would love to hear opinions on it and could be easily swayed to remove it or keep it. If I'm on 1.0.1, and both 1.0.2 and 1.0.15 exist, `--minimal` will resolve to `1.0.2` instead of the latest `1.0.15`. Dunno if there's value in that. - [x] even without `--strict` mode, this code will _remove_ older versions from the options handed back to Molinillo (in `--patch` and `--minor` cases). This is a weird case, but I have seen `bundle update` proper regress a gem version backwards if its parent gem changed to an older dependency (I guess in a bug fix case). I'm ok with this, but it could be considered an inconsistency with the default `--major` case. - [x] if we roll this out first as an undocumented feature, do we require a config option to toggle it on? We wouldn't have to have one, none of the new behavior will kick in until a new flag (`--patch` or `--minor`) is passed. --- Notes for issues to create that could be handled separately after this PR, esp. if we release undocumented/unsupported to begin with. - Updating `outdated` to use the new flags and resolution - adding some warnings when dependent updates go past --patch or --minor level (with an instruction to use --strict if they don’t want that) - adding a warning when an unlocked gem doesn't move (possibly w/ a reason why?). the lack of feedback otherwise can be disconcerting, like "did I not do it right?" - possibly adding a dry-run flag - though after looking at that today, that would make the most sense inside Installer, and make that flag an option for both install and update (drilling through all of the calls to push that option in looks like it would be annoying). - man page documentation
w00t - thx :) |
A port of bundler-patch to bundler proper.
Core team questions:
--minimal
flag is also something bundler-patch has that has debatable value. Would love to hear opinions on it and could be easily swayed to remove it or keep it. If I'm on 1.0.1, and both 1.0.2 and 1.0.15 exist,--minimal
will resolve to1.0.2
instead of the latest1.0.15
. Dunno if there's value in that.--strict
mode, this code will remove older versions from the options handed back to Molinillo (in--patch
and--minor
cases). This is a weird case, but I have seenbundle update
proper regress a gem version backwards if its parent gem changed to an older dependency (I guess in a bug fix case). I'm ok with this, but it could be considered an inconsistency with the default--major
case.--patch
or--minor
) is passed.Notes for issues to create that could be handled separately after this PR, esp. if we release undocumented/unsupported to begin with.
outdated
to use the new flags and resolution