-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
kpm's current semver resolution logic leads to false positives in transitive dependencies, requiring unnecessary user interaction. Conflict resolution may no longer be needed once dependent parents have been resolved out of the dependency graph. However these conflicts are still bubbled up to the user to be resolved, potentially incorrectly.
Contrived Example 🍎 🍰
"dependencies": {
"apple-pie": "^2.0.0",
"pie-crust": "^1.0.0"
}
$ kpm i --flat
kpm install v0.11.2
info No lockfile found.
[1/4] 🚚 Resolving and fetching packages...
We found a version in package pie-crust that we couldn't resolve
1. 1.0.0
2. 2.0.0
Please select a version you'd like to use?: 2
We found a version in package flour that we couldn't resolve
1. 1.0.0
2. 2.0.0
Please select a version you'd like to use?: 2
We found a version in package sugar that we couldn't resolve
1. 1.0.0
2. 2.0.0
Please select a version you'd like to use?: 2
We found a version in package butter that we couldn't resolve
1. 2.0.0
2. 1.0.0
Please select a version you'd like to use?: 2
[2/4] 🔗 Linking dependencies...
[3/4] 📃 Building fresh packages...
[4/4] ♻️ Cleaning modules...
success Saved lockfile to kpm.lock
✨ Done in 19.10s.
Based on a True Story
Here's an actual example of two conflicting npm dependencies with conflicting transitive dependencies if you'd like to see this in action. The above was contrived from this setup.
-─┬ @polymer/paper-behaviors@0.0.3
├─┬ @polymer/iron-behaviors@0.0.3
│ └── @polymer/iron-a11y-keys-behavior@0.0.3
├─┬ @polymer/iron-checked-element-behavior@0.0.3
│ ├── @polymer/iron-form-element-behavior@0.0.3
│ └─┬ @polymer/iron-validatable-behavior@0.0.3
│ └── @polymer/iron-meta@0.0.3
└── @polymer/paper-ripple@0.0.3
"dependencies": {
"@polymer/paper-behaviors": "^0.0.3",
"@polymer/iron-checked-element-behavior": "0.0.1"
}
What Happened?
- top level dependency
pie-crust
requiresv1.x.x
versions of its dependencies all the way down - top level dependency
apple-pie
requiresv2.x.x
versions of its dependencies all the way down, includingpie-crust@v2.x.x
- A full dependency tree was resolved for each top level dependency
- All unresolvable conflicts (4) between those two trees were detected
- The user was asked to resolve each of them
Expected user resolution prompts: pie-crust
Actual user resolution prompts: pie-crust, flour, sugar, butter
This is bad because only the top level resolution was needed/expected. Once pie-crust
was resolved to either v1.0.0
or v2.0.0
, all of its dependencies would have been transitively resolved as well. Resolving each of these manually can be tedious and potentially dangerous if the user accidentally resolves a constraint to a version that is no longer referenced anywhere in the flattened dependency graph. (ex: pie-crust@v2.0.0
& flour@v1.0.0
).
kpm will also display these conflicts in an undefined order, which can add to the confusion (user has to resolve a transitive dependency conflict before seeing the parent dependency conflict that caused it).