Skip to content

fix(core): a bare Dart version is exact to pub and a caret range to this tree, so a pubspec pin is never reported #149

Description

@justin13888

A pubspec.yaml line foo: 6.0.5 is an exact version to pub: pub reads a
bare version as ==6.0.5, and the caret range is spelled ^6.0.5. This tree
reads it as a caret range, so dependable tree reports unknown for a
dependency the manifest resolved, and dependable check reports it satisfied by
every later 6.x release.

Found while reviewing #120 (feat/107-exact-pin-version), which added
exact_pin and made tree report a version wherever a manifest already named
one release. #120 ships that for Cargo =1.2.3, PEP 440 ==2.28.1, NuGet
[1.2.3], and bare Maven/Gradle and Hex versions. Dart is not in that set, and
this is why.

Mechanism

to_semver_constraint (crates/dependable-core/src/semver/normalize.rs) routes
by ecosystem:

match ecosystem {
    Ecosystem::Python => pep440_constraint_to_semver(constraint),
    Ecosystem::CSharp => nuget_constraint_to_semver(constraint),
    Ecosystem::Elixir => hex_constraint_to_semver(constraint),
    Ecosystem::Jvm    => maven_constraint_to_semver(constraint),
    _ => normalize_constraint(constraint),
}

Ecosystem::Dart falls through to normalize_constraint, which is Cargo/npm
semantics: a bare version is a caret range. exact_pin consults exactly that
translation and reports a pin only where it yields a single = comparator, so
exact_pin("6.0.5", Ecosystem::Dart) is None — asserted as such today in
crates/dependable-core/src/semver/pin.rs, which is the record of the current
reading rather than an endorsement of it.

crates/dependable-core/src/semver/pin.rs also carries the rule this violates:
"'exact' is the ecosystem's reading, not the string's shape."

Why this is the mirror image of #113

#113 is the same class of defect for NuGet, in the opposite direction: NuGet
reads a bare Version="13.0.1" as an inclusive minimum and this tree agrees
with it, which makes every C# dependency permanently UpToDate. Dart reads a
bare version as exact and this tree disagrees with it, which makes every Dart
dependency permanently loose. Both are one translator disagreeing with its
ecosystem about the one spelling that ecosystem's manifests overwhelmingly use.

Nothing in the tree covers Dart's reading at all: pin.rs asserts the current
(wrong) verdict, and there is no Dart constraint translator to test.

Scope — read this before widening it

Go is adjacent but genuinely uncertain and must not be lumped in. A
go.mod require x v1.6.0 is not a pin in the same sense: under MVS it is a
minimum that the module graph may raise, and go.sum / the build list is what
actually resolves it. Whether tree should report v1.6.0 for such a line is a
separate judgement about what MVS means for a manifest-only graph, and it
deserves its own issue and its own evidence. This issue is Dart only.

Hex is already handled (hex_constraint_to_semver), and PHP/Composer reads a
bare version as exact too — but Composer's own docs treat 1.2.3 as an exact
constraint while the ecosystem convention is ^1.2.3, so it is worth a separate
look rather than being folded in here.

Acceptance

  • A dart_constraint_to_semver (or an explicit Ecosystem::Dart arm) reads a
    bare version as =x.y.z and leaves ^, >=, <, and any as they are.
  • exact_pin("6.0.5", Ecosystem::Dart) is Some("6.0.5"); exact_pin("^1.1.0", Ecosystem::Dart) stays None. The two rows in pin.rs's table flip and stay
    asserted.
  • A graph-level test over a pubspec.yaml asserts a bare-version dependency
    reports that version, and a ^ one reports none.
  • check on a bare Dart version reports an update when pub.dev publishes a newer
    release, rather than calling it satisfied.

Related: #113 (the same disagreement for NuGet, inverted), #120 (where this was
found).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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