Problem
The new version of bundler, 4.1.x, introduces a new override command. This allows a user to supply constraints on dependencies without necessarily making them concrete.
However, it is destructive, in that it removes any other constraints that other gems supply. Those constraints are probably there for a reason, and losing them should be a last resort.
However we do want the ability to supply constraints without declaring a concrete dependency. So either override should take a "replace" or "force" option, or we need an alternative to "override" like "constrain" or "resolve".
Steps to reproduce the problem
Consider this Gemfile:
source "https://rubygems.org"
gem "bootstrap", "4.6.2.1"
The resulting (simplified) lockfile looks like this:
GEM
remote: https://rubygems.org/
specs:
autoprefixer-rails (10.4.21.0)
execjs (~> 2)
bootstrap (4.6.2.1)
autoprefixer-rails (>= 9.1.0)
popper_js (>= 1.16.1, < 2)
execjs (2.10.2)
json (>= 2)
json (3.0.2)
popper_js (1.16.1)
DEPENDENCIES
bootstrap (= 4.6.2.1)
BUNDLED WITH
4.1.0.beta1
Note that the only DEPENDENCIES is bootstrap.
Now say we want to add a constraint that popper_js must be 1.16.1 or above (in my simple example this is forced by bootstrap, but say we wanted to). We have two official options:
- Use a pin. However this would add
popper_js as a concrete DEPENDENCIES.
source "https://rubygems.org"
gem "bootstrap", "4.6.2.1"
gem "popper_js", ">= 1.16.1", require: false # Now concrete! And even adding require: false does not help
- Use
override. However this is worse as it destroys the "< 2" constraint that bootstrap has for popper_js.
source "https://rubygems.org"
gem "bootstrap", "4.6.2.1"
override "popper_js", version: ">= 1.16.1" # `bundle update` produces `2.11.8` which won't work with bootstrap 4.x
What we need
We need a way to say "I want this gem, if it is ever brought into this lockfile, to obey this additional constraint, and all present constraints. If this gem is not there concretely or transitively, it should not be in the lockfile."
Possible solutions
We could do one of a few things:
- For now, my gem bundler-resolutions demonstrates a solution to the above need - but it uses patches and since
override is coming I'd like to see this functionality made official.
- Change
override to be non-destructive by default - the supplied version should be /additional/ to present constraints. Maybe a param force: true could be supplied to overwrite all constraints?
- Add an alternative command like
constraint or resolve.
source "https://rubygems.org"
gem "bootstrap", "4.6.2.1"
resolve "popper_js", version: ">= 1.16.1"
I think I prefer option 3. Maybe even make that the only new DSL, and add a force: true param to that command?
This relates to #9517 and #8021
Problem
The new version of
bundler, 4.1.x, introduces a newoverridecommand. This allows a user to supply constraints on dependencies without necessarily making them concrete.However, it is destructive, in that it removes any other constraints that other gems supply. Those constraints are probably there for a reason, and losing them should be a last resort.
However we do want the ability to supply constraints without declaring a concrete dependency. So either
overrideshould take a "replace" or "force" option, or we need an alternative to "override" like "constrain" or "resolve".Steps to reproduce the problem
Consider this
Gemfile:The resulting (simplified) lockfile looks like this:
Note that the only
DEPENDENCIESisbootstrap.Now say we want to add a constraint that
popper_jsmust be 1.16.1 or above (in my simple example this is forced by bootstrap, but say we wanted to). We have two official options:popper_jsas a concreteDEPENDENCIES.override. However this is worse as it destroys the "< 2" constraint thatbootstraphas forpopper_js.What we need
We need a way to say "I want this gem, if it is ever brought into this lockfile, to obey this additional constraint, and all present constraints. If this gem is not there concretely or transitively, it should not be in the lockfile."
Possible solutions
We could do one of a few things:
overrideis coming I'd like to see this functionality made official.overrideto be non-destructive by default - the suppliedversionshould be /additional/ to present constraints. Maybe a paramforce: truecould be supplied to overwrite all constraints?constraintorresolve.I think I prefer option 3. Maybe even make that the only new DSL, and add a
force: trueparam to that command?This relates to #9517 and #8021