-
-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatic unlock on install and update #337
Conversation
e69effc
to
e679cac
Compare
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.
Indeed. The update
command should never really lock a dependency, but aim to keep all dependencies to be as close as possible of locked versions, yet never enforce them —I liked how the 'distance' idea of the SAT solver made it explicit.
However, I'm not fond of Bundler's behavior. I believe install
should always enforce locked versions. It accepts to add or remove a dependency as a convenience (unless production), but only if it doesn't affect the current dependencies. I think it's better to be upfront instead if silently updating the lock file, which can lead to some breakage because of unreviewed changes.
BTW: how does it behave with this change? Is it still as conservative as possible (as with the SAT solver) or is it kinda loose, possibly updating unrelated dependencies? |
I disagree. If I execute
But I do. To be honest, from all the dependency managers I use from any language, it's the one that always do exactly what I'm looking for. If I change explicitly the version in the
The command clearly says which dependencies are upgraded. I can always check the changes after the upgrade and revert changes if I don't like them. I'm sorry @ysbaddaden. Please, don't take this the wrong way. I loved the idea of the SAT solver, but in practice it didn't work. And I'm not planning to spend too much time innovating on this area. So my decision is to copy what actually works in real world. And bundler does. And we need something that works for when 1.0 arrives. After that we can continue doing experiments with other approaches. Dependency solvers algorithms are not deterministic. So, if there is a good reason, we could even have more that one algorithm embedded in Shards and let the user choose which one to use. |
This is how I prefer it too. At the very least it should never modify |
There must be a reason why bundler (Ruby), pub (Dart), mix (Elixir), yarn (JS) all behave the same way. The rationale is:
The Conservative Updating section of the Bundler documentation explain this. |
|
@waj that behaviour is fine in a development environment, since you're going to notice the lockfile diff when committing (you do all read your diffs before committing right?), but this is not the case when deploying to a production server. I guess it's a nitpick, but I'd like |
Of course, |
Oh this is already the case? I didn't realise. |
Isn't the logic wrong here? shards/src/commands/install.cr Line 49 in 134850e
It seems it fails if the installed version doesn't exactly match the lockfile and the installed version doesn't match the |
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.
This new behaviour looks good!
@@ -19,7 +19,7 @@ module Shards | |||
packages = handle_resolver_errors { solver.solve } | |||
return if packages.empty? | |||
|
|||
if lockfile? | |||
if lockfile? && Shards.production? |
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 if Shards.production?
checks can be removed down below now right?
@waj We agree. I said that update should never really enforce locked dependencies but aim to be as close as possible, which means that bar shouldn't be updated unless the foo -> * -> bar requirements need a new version of bar instead of introducing a conflict (i.e. the very purpose of this patch). I also really like Bundler, and modeled Shards after it. I'm just not fond of its update everything by default, and wish I didn't have to specify and understand a bunch of options ( |
I found it odd that nested dependencies that are not mentioned in shards.yml would need to be mentioned in the If I need a nested dependency to remain at a specific version for some reason, then it will become an explicit dependency in the shard.yml. Adding a command that will not bump nested dependencies can be added later if wanted. It is another feature. |
That behaviour (update only if needed) doesn't exist in molinillo, and I'm not sure if any other dependency manager works that way. If there is a lock, it will be respected, and raise a conflict if there is no solution. We can only decide what to unlock or not. In bundler, when you run Right now, with this PR, both |
@RX14 I think your comments mostly apply to the "production" mode and I didn't touch anything of that in this PR. I plan to do some refactors for production mode in a separate PR. |
If you'd like to work on that in a separate PR that's fine but it seems the bugfix (if I'm not mistaken about it being a bug) should make it into the release. |
Well, eventually it achieves kinda the same: solve with locked versions, unlock conflicting nested dependency, and try again (if I understood correctly). Maybe it's even better since it may reach directly for the latest patch, which ain't a bad idea. |
Yes, you're right. There seems to be a bug with some uncovered cases in production mode. But it's unrelated to this PR. |
This PR changes the way the content of
shards.lock
is used during dependency resolution. Instead of passing all o them blindly to the solver, they are traversed as a tree, starting from the dependencies specified explicitly inshards.yml
, only if the version still matches, and following each sub-dependency recursively.This fixes some issues:
shards.yml
is changed, runningshards
just does the update of that shard.shards update foo
, iffoo
has dependencybar
, now it's not needed to runshards update foo bar
to unlockbar
(unlessbar
is also inshards.yml
)The behavior of
shards
is now more similar tobundler
, and I think it's a good thing. Much more intuitive and simple to use.