Hello everyone!
Huge fan as I believe y'all know 💚
tldr;Â Would be great to have something like `mix deps.update --conservative` that updates as few dependencies as it can, as opposed to the normal behavior that updates all the transitive dependencies
Current Behavior
`mix deps.update dependency` will update transitive dependencies as well, sometimes resulting in 6+ dependencies updated
Wished for behavior
In short: minimalÂ
If dependency A depends on dependency B with ~> 1.0 and I currently have B installed at 1.0.0 then an update to A (that still has B ~> 1.0) with a `--conservative` (or similar) flag should keep B at 1.0.0 even if `1.0.1` or `1.1.0` are already out.
However, let's say I have A 1.0 installed and A 2.0 bumped its dependency to B ~> 1.1 then `--conservative` should of course update B to 1.1. However, if B has a dependency C that is still satisfied, we shouldn't update C as well.
Naturally naming for such a flag could be many more:
* minimum
* required
* ...
Prior Art
This was first raised in
#7030Â ~9 years ago and ultimately solved by
documenting the `mix deps.unlock dep; mix deps.get` workaround.
I thought it may be worth discussing again because:
* quite a lot of time has passed and through features like the dependency cooldown (thank you for that!) we're a bit more cautious around updating dependencies due to supply chain attacks
* a downside of the workaround wasn't discussed (imo) - if the new version needs a bump in dependency the resolver will fail - then you have to either unlock multiple dependencies or use normal `mix deps.update` with transitive updates again (or temporarlily "lock" them inside your mix.exs when you don't want them to change)
* personally, the scenario pops up a lot with automatic dependency updaters which are a lot more common these days (
example, one library update results in 6 dependency updates - 5 after I pinned a breaking one)
* we have a new dependency solver on hex since the original issue was opened, which might make things easier/better (I don't know)
Other package managers
*
cargo update just works like this by default, i.e. the docs say:
If packages are specified with spec, then a conservative update of the lockfile will be performed. This means that only the dependency specified by SPEC will be updated. Its transitive dependencies will be updated only if SPEC cannot be updated without updating dependencies. All other dependencies will remain locked at their currently recorded versions.
The `--recursive` options opts it in to the more aggressive/update all transitive dependencies behavior.
From my reading npm always re-resolves the entire tree while yarn tries to only update the specified dependency. But the JS dependency ecosystem and resolution is different enough that I didn't want to dive too deep there.
--------
Any which way, thank you all for your work as usual! 💚
Tobi