Skip to content

Dependency conflict resolution contains false positives #267

@FredKSchott

Description

@FredKSchott

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 requires v1.x.x versions of its dependencies all the way down
  • top level dependency apple-pie requires v2.x.x versions of its dependencies all the way down, including pie-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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions