ecluse:ecluse-core
Safe HaskellNone
LanguageGHC2021

Ecluse.Core.Version

Description

Version identity and ordering.

A Version keeps the raw text verbatim, because version strings are embedded in artifact URLs and re-served. Ordering goes through compareVersions on the parsed VersionKey, which exists only when the raw text parses for its ecosystem, so non-canonical text can never reach a comparator. Parsing is per-ecosystem and the grammar modules stay private: callers build with mkVersion or parseVersionKey. See docs/architecture/domain-model.md, Version.

Synopsis

Versions

data Version Source #

A package version: the raw text as published, plus the parsed ordering key when the text parses. There is deliberately no Ord. Comparison goes through compareVersions.

Instances

Instances details
Show Version Source # 
Instance details

Defined in Ecluse.Core.Version

Eq Version Source # 
Instance details

Defined in Ecluse.Core.Version

Methods

(==) :: Version -> Version -> Bool #

(/=) :: Version -> Version -> Bool #

versionKey :: Version -> Maybe VersionKey Source #

The parsed, canonical ordering key. Nothing if the raw text did not parse for its ecosystem, in which case ordering rules abstain.

versionKeyIn :: Ecosystem -> Version -> Maybe VersionKey Source #

The version's key under an ecosystem's grammar, as mkVersion for that ecosystem builds it. It reuses the key the version carries when that key is the ecosystem's, and parses otherwise.

mkVersion :: Ecosystem -> Text -> Version Source #

Build a Version, parsing and evaluating a canonical key when possible. Total: an unparseable version is still represented, keyless, so a proxy never drops one over a parser gap.

renderVersion :: Version -> Text Source #

Render a version in wire form: the raw text, verbatim as published.

compareVersions :: Version -> Version -> Maybe Ordering Source #

Compare two versions by their canonical keys. Nothing when either version has no key, in which case an ordering-based rule abstains.

Canonical ordering keys

data VersionKey Source #

The parsed, canonical, comparable form of a version. The type is opaque and parseVersionKey is its only constructor, so the comparator cannot see non-canonical input.

parseVersionKey :: Ecosystem -> Text -> Either VersionError VersionKey Source #

Parse raw version text into a canonical VersionKey for its ecosystem, or report why it did not parse. The Ord on the result is meaningful only within one ecosystem.

newtype VersionError Source #

Why a version string failed to parse.

Constructors

VersionError 

Instances

Instances details
Show VersionError Source # 
Instance details

Defined in Ecluse.Core.Version

Eq VersionError Source # 
Instance details

Defined in Ecluse.Core.Version

isStable :: VersionKey -> Bool Source #

Whether a parsed version is a stable (final, non-prerelease) release, under its own ecosystem's notion of one.

>>> isStable <$> parseVersionKey Npm "1.0.0"
Right True
>>> isStable <$> parseVersionKey Npm "1.0.0-rc.1"
Right False
>>> isStable <$> parseVersionKey PyPI "1.0.post1"
Right True
>>> isStable <$> parseVersionKey PyPI "1.0a1.dev2"
Right False
>>> isStable <$> parseVersionKey RubyGems "1.0.0.pre"
Right False

Canonical PEP 440 spelling

canonicalPep440 :: Text -> Maybe Text Source #

The one spelling a PEP 440 version canonicalises to, which a PyPI projection keys by so two spellings of one release merge. The raw spelling survives per artifact through the filename.

>>> canonicalPep440 "1.0.0"
Just "1"
>>> canonicalPep440 "not-a-version"
Nothing

Resolving dist-tags.latest

selectLatest :: Maybe Version -> [Version] -> Maybe Version Source #

Resolve dist-tags.latest over the survivors the caller left, keeping chosen when it survives so a prerelease never displaces a maintainer's stable tag. The result is a survivor.