Pub: Introduce a `pub upgrade --(no)-allow-prereleases` flag.

Created on 30 Apr 2020  路  6Comments  路  Source: dart-lang/pub

It is somewhat surprising that the solver will use pre-releases for dependencies.
See eg. https://github.com/dart-lang/pub/issues/2446

Ideally this would be off by default - but that might be a breaking change.

If solving without prereleases fails we should probably report that a solution exists with prereleases and mention the flag.

enhancement

Most helpful comment

Probably want to allow explicitly chosen pre-releases from the root pubspec.

I agree that this is probably the most desirable behavior, with a small tweak which is that we allow explicit pre-release dependencies in pre-release packages always. This way an explicit pre-release dependency in the root package is allowed to itself have pre-release deps without any warnings.

Reasoning

  • Transitive prerelease dependencies are surprising and should always be flagged whether they are explicit or not.

    • Unless they are the result of an explicit root package pre-release dep, then it isn't surprising.

  • Ultimately we don't want people to release stable versions of a package if they have any immediate prerelease dependencies anyways, so this just encourages that.
  • Assuming everybody follows this policy there can be no explicit prerelease dep (even transitively) without a prerelease dep in the root pubspec.

All 6 comments

One question we have not answered:
Probably want to allow explicitly chosen pre-releases from the root pubspec.

dependencies:
  foo: 1.0.0-dev # just get me that prerelease!

But it is not clear how to generalize this. (Should we allow that also transitively - what does ^1.0.0-dev mean...)

The use case I feel the most strongly about is the one where a pubspec.yaml lists a package and a stable version (single or range), and the solver ends up resolving that to a pre-release. Consider this example:

  • package foo is published in one version:

    • foo 1.0.0 which depends on bar: ^1.0.0

  • package bar is published in one version:

    • bar 1.0.0 with no dependencies

The developer starts with this pubspec.yaml:

   foo: ^1.0.0
   bar: ^1.0.0
````

Running `pub get`, the developers gets locked on `foo 1.0.0` and `bar 1.0.0` as expected.

Updates are now published on pub.dev:

* package `foo` is published in two versions:
  * `foo 1.0.0` which depends on `bar: ^1.0.0`
  * `foo 2.0.0` which depends on `bar: ^1.1.0-dev`
* package `bar` is published in two versions:
   * `bar 1.0.0` with no dependencies
   * `bar 1.1.0-dev-1.0` with no dependencies

The developer now hears about `foo 2.0.0` and it has something they need, so they update their pubspec.yaml to:

foo: ^2.0.0
bar: ^1.0.0
````

The developer runs pub get with an intention of picking up foo 2.0.0. They are not aware that foo itself depends on a pre-release bar, and they generally have a policy to only use stable versions. So when they later debug a bug in their app, and realize it's coming from bar and that they had been locked on foo 2.0.0 and bar 1.1.0-dev-1.0 they get angry.

I suggest that a pub get/upgrade without an --allow-pre-release flag should have failed and reported something like:

Could not resolve, foo 2.0.0 requires bar >=1.1.0-dev and your pubspec allows only stable versions of bar >=1.0.0 <2.0.0. Update your dependency on bar to allow a pre-release, or opt-in to selecting pre-release by passing the flag --allow-pre-releases.

They can then either use the flag, or change pubspec.yaml to:

```
foo: ^2.0.0
bar: ^1.1.0-dev-1.0
````

Probably want to allow explicitly chosen pre-releases from the root pubspec.

I agree that this is probably the most desirable behavior, with a small tweak which is that we allow explicit pre-release dependencies in pre-release packages always. This way an explicit pre-release dependency in the root package is allowed to itself have pre-release deps without any warnings.

Reasoning

  • Transitive prerelease dependencies are surprising and should always be flagged whether they are explicit or not.

    • Unless they are the result of an explicit root package pre-release dep, then it isn't surprising.

  • Ultimately we don't want people to release stable versions of a package if they have any immediate prerelease dependencies anyways, so this just encourages that.
  • Assuming everybody follows this policy there can be no explicit prerelease dep (even transitively) without a prerelease dep in the root pubspec.

Ultimately we don't want people to release stable versions of a package if they have any immediate prerelease dependencies anyways, so this just encourages that.

@sigurdm recently did a warning to discourage this too.

Assuming everybody follows this policy there can be no explicit prerelease dep (even transitively) without a prerelease dep in the root pubspec.

We could enforce this, but I'm not sure we need to be this strict.


If solving without prereleases fails we should probably report that a solution exists with prereleases and mention the flag.

That, or we could print a warning if we use pre-releases in the solution.

So 1st try to solve without pre-releases (except those allowed by root pubspec.yaml, or transitively from there), then try to solve with pre-releases if that doesn't work. And print a warning if we had to do a second resolution.

If we go with the solution suggested by @jakemac53 two more questions came up while @jonasfj and i discussed this a bit:

  • If

    • the root package depends on foo: 1.0.0 and bar: 1.0.0-dev and
    • foo 1.0.0 depends on baz: ^1.0.0
    • bar 1.0.0-dev depends on baz: ^1.1.0-dev
    • baz exists in 1.0.0 and 1.1.0-dev
      Should this resolve?
  • Another interesting case:

    • A stable package foo: 1.0.0 depends on bar: 1.0.0-dev.
    • The root package depends on foo.
      Should this resolve?

My suggestion: Without the -allow-pre-release flag, we simple disallow / filter away all pre-release versions. We could allow-list any packages in the pubspec.yaml listed with pre-release versions. That seems like a simple to understand solution?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nex3 picture nex3  路  21Comments

Andersmholmgren picture Andersmholmgren  路  45Comments

wh120 picture wh120  路  24Comments

pq picture pq  路  24Comments

JSanford42 picture JSanford42  路  21Comments