Skip to content

vers: HighestSatisfying helper for resolver-style picks#17

Merged
andrew merged 1 commit into
mainfrom
highest-satisfying
May 12, 2026
Merged

vers: HighestSatisfying helper for resolver-style picks#17
andrew merged 1 commit into
mainfrom
highest-satisfying

Conversation

@andrew
Copy link
Copy Markdown
Contributor

@andrew andrew commented May 12, 2026

Summary

Adds `vers.HighestSatisfying(versions []string, constraint, scheme string) (string, error)`. Common shape of a package-manager resolver:

```go
parsed, _ := vers.ParseNative(constraint, scheme)
var best string
for _, v := range versions {
if !parsed.Contains(v) {
continue
}
if best == "" || vers.CompareWithScheme(v, best, scheme) > 0 {
best = v
}
}
```

Becomes:

```go
best, err := vers.HighestSatisfying(versions, constraint, scheme)
```

Behaviour

  • Empty `scheme` parses `constraint` as a vers URI; non-empty parses as native syntax (same dispatch as `Satisfies`).
  • Versions that fail to parse are skipped — registry data is messy in practice; a single bad entry shouldn't abort the walk.
  • Returns `("", nil)` when no version satisfies, distinct from `("", err)` when the constraint itself fails to parse.
  • Ordering uses `CompareWithScheme` so scheme-specific precedence rules (npm pre-release ordering, etc.) apply.

Tests

Five: npm constraint coverage (caret, tilde, range, intersection, no-match), order independence on the input slice, garbage-version skipping, vers-URI mode via empty scheme, and the empty-input case.

The common shape of a package-manager resolver: fetch the list of
available versions from the registry, then pick the highest one that
still satisfies the user's manifest constraint. Callers all wrote
the same loop:

    parsed, _ := vers.ParseNative(constraint, scheme)
    var best string
    for _, v := range versions {
        if !parsed.Contains(v) {
            continue
        }
        if best == "" || vers.CompareWithScheme(v, best, scheme) > 0 {
            best = v
        }
    }

Surfaces it as one call:

    best, err := vers.HighestSatisfying(versions, constraint, scheme)

Empty scheme parses constraint as a vers URI; non-empty scheme parses
it as native syntax (the same dispatch Satisfies uses). Versions that
fail to parse are skipped, not fatal — pulling messy registry data
through HighestSatisfying doesn't need a pre-filter pass.
@andrew andrew merged commit f2cee8f into main May 12, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant