dart-lang / pub

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

Allow maintainers to update version constraints of already published packages #4015

Open rrousselGit opened 1 year ago

rrousselGit commented 1 year ago

Hello!

Problem

One common issue I've seen is, upperbounds of version constraints (both SDK constraints and dependencies) often tend to be wrong – especially when considering that Dart/Flutter do not respect semver.

This can have negative impact on features such as pub downgrade. Cf https://github.com/dart-lang/sdk/issues/52627 for more discussion on the topic.

For example, since Dart 3, some pkg:watcher versions may trigger the following compilation error:

./../../../../../.puro/shared/pub_cache/hosted/pub.dev/watcher-1.0.2/lib/src/constructable_file_system_event.dart:7:57: Error: The class 'FileSystemEvent' can't be extended, implemented, or mixed in outside of its library because it's a sealed class.

That is because the resolved version is a version that used to subclass a now "final" class (since Dart 3). Yet that watcher version, according to its constraints, is Dart 3 compatible. So even though that 1.0.2 version of watcher should claim to be incompatible with Dart 3, pub get still works.

This is not a unique aspect of watcher, nor unique to Dart 3. For example, in a Dart 2 minor release, a new flag was added to the File interface. This broke pkg:file because it "implemented' the interface (at least that's what I remember from the error).

Proposal

Could admins of a package override the version constraints of already published packages?

Say a package a is published at version 1.0.0 with the SDK constraint >=3<4, and Dart releases a new version. If a's 1.0.0 is determined to be incompatible with that new Dart version, would it be possible to flag it directly in the admin panel?

Such that users of the new Dart version would not incorrectly download a v1.0.0.

sigurdm commented 1 year ago

We have talked about this before (https://github.com/dart-lang/pub/issues/3051#issuecomment-1004204411)

This feature could be seen as a generalization of package retraction.

It could have similar semantics. New incompatibilities could be published for (say) 7 days after a version is published, and the incompatibilities would not affect package-versions already locked in a pubspec.lock.

We have some worries that it would be complex for package authors to get the constraints right.

No current roadmap for a feature like this.

rrousselGit commented 1 year ago

I don't think the 7 days deadline should apply here.
This is generally used as a reaction to an incompatibility with a new SDK/dependency version. Chances are those 7 days are already passed by that point.

Unless that's 7 day after a new SDK/dependency release?

jakemac53 commented 1 year ago

Definitely agreed with @rrousselGit that the 7 day deadline should not apply. The typical use case for this is something happens long after you published the package, making previously declared constraints no longer correct.

My pitch for this feature would be a way to add "additional constraints" to existing package versions. The pubspecs of those versions would not be directly altered, these would just be additional semver constraints that should be added for any future version solves of those versions. Ideally there would be a way to attach these additional constraints to ranges of versions as well. These constraints should be "merged" with the original constraints (if present) taking the intersection of the ranges as the new constraint (and not allow for instance expanding the range).

We still regularly get issues filed about the watcher breakage even though that happened a long time ago (see https://github.com/dart-lang/build/issues/3604 for the latest one). This would also help a lot for packages that rely on SDK tooling (see this ongoing discussion https://github.com/dart-lang/webdev/pull/2263#discussion_r1371936224).

In general, there is no way at all to recover from a previously published over-broad constraint and it causes significant pain when it comes up.