dart-lang / pub

The pub command line tool
https://dart.dev/tools/pub/cmd
BSD 3-Clause "New" or "Revised" License
1.04k stars 224 forks source link

Add solve-suggestions when failing to upgrade to latest version #3685

Open maximveksler opened 1 year ago

maximveksler commented 1 year ago

Environment

Flutter Environment:

flutter --version
Flutter 3.3.9 • channel stable • https://github.com/flutter/flutter.git
Framework • revision b8f7f1f986 (2 weeks ago) • 2022-11-23 06:43:51 +0900
Engine • revision 8f2221fbef
Tools • Dart 2.18.5 • DevTools 2.15.0

Problem

Bug

Running the following sequence of events would install firebase_core: ^0.4.2+2

flutter create bug
cd bug
flutter pub add -d mocktail --verbose > log_pubadd_dev.txt 2>&1
flutter pub add firebase_core google_sign_in --verbose > log_pubadd.txt 2>&1
m@m-inspiron5567:/tmp/bug$ cat pubspec.yaml | grep firebase_core                                       
  firebase_core: ^0.4.2+2

Works

Running the following sequence of events would install firebase_core: ^2.3.0

flutter create works
cd works
flutter pub add firebase_core google_sign_in --verbose > log_pubadd.txt 2>&1
flutter pub add -d mocktail --verbose > log_pubadd_dev.txt 2>&1
m@m-inspiron5567:/tmp/works$ cat pubspec.yaml | grep firebase_core                                       
  firebase_core: ^2.3.0

Debug

m@m-inspiron5567:/tmp$ diff /tmp/bug/pubspec.yaml /tmp/works/pubspec.yaml -Naur
--- /tmp/bug/pubspec.yaml       2022-12-07 11:28:01.468494250 +0200
+++ /tmp/works/pubspec.yaml     2022-12-07 11:29:39.281944992 +0200
@@ -1,4 +1,4 @@
-name: bug
+name: works
 description: A new Flutter project.

 # The following line prevents the package from being accidentally published to
@@ -36,8 +36,8 @@
   # The following adds the Cupertino Icons font to your application.
   # Use with the CupertinoIcons class for iOS style icons.
   cupertino_icons: ^1.0.2
-  firebase_core: ^0.4.2+2
-  google_sign_in: ^4.0.16
+  firebase_core: ^2.3.0
+  google_sign_in: ^5.4.2

 dev_dependencies:
   flutter_test:

Attached bug & works directories (with the verbose logs) for reference.

Expected behavior

The SLVR would produce the same package dependency graph, picking the lastest stable of each dependency.

Actual behavior

The SLVR picks the lowest possible version of firebase_core.

sigurdm commented 1 year ago

In general we don't expect the solver to give the best solution, only a solution with the heuristic of trying the newest version of a package first.

The issue here however seems that there is an actual incompatibility in the transitive dependencies, and dart pub add is trying its best to avoid unlocking locked dependencies.

If you add firebase_core first, it resolves with firebase_core 2.3.0 -> firebase_core_web 2.0.1 -> flutter_web_plugins (from sdk) -> js 0.6.4 So because the flutter_web_plugins sdk package is pinned to js. v. 0.6.4 you get that as a transitive dependency.

However if you add mocktail first you get you mocktail 0.3.0 -> test 1.21.4 -> package:js v. 0.6.5. Because you didn't need the sdk package flutter_web_plugins you avoid the pinned package js.

flutter pub add will try find a solution for firebase_core without unlocking current packages, and because firebase_core v. 0.4.2+2 doesn't have the transitive dependency on the flutter_web_plugins package that is what you get.

This is both confusing and unfortunate - but unlocking and downgrading transitive dependencies in pub add is also surprising behaviour.

@jonasfj do you have some good ideas here?

There might be something we can do to at least explain better why a specific version cannot be obtained, but the best UI here is still a bit unclear to me. Maybe something along the lines of https://github.com/dart-lang/pub/pull/3569 but expanded to the case of successful pub add and pub upgrade where you did not get the newest version.

maximveksler commented 1 year ago

@sigurdm thanks for explaining the logic, yes I see where the root casue is.

This is both confusing and unfortunate - but unlocking and downgrading transitive dependencies in pub add is also surprising behaviour.

No, I'd say that if unlocking and downgrading a patch (or even a minor) of a transitive dependency results in major for the direct dependecy being added than it should weight more to tip the solver towards that case. From my perspective seems like a logic bug.

In addition please note that running flutter pub upgrade will still not fix the issue. However applying flutter pub upgrade --major-versions does result in firebase_core: ^2.4.0