versions-3.3.2: Types and parsers for software version numbers.

Copyright(c) Colin Woodbury 2015 - 2018
LicenseBSD3
MaintainerColin Woodbury <colingw@gmail.com>
Safe HaskellNone
LanguageHaskell2010

Data.Versions

Contents

Description

A library for parsing and comparing software version numbers.

We like to give version numbers to our software in a myriad of different ways. Some ways follow strict guidelines for incrementing and comparison. Some follow conventional wisdom and are generally self-consistent. Some are just plain asinine. This library provides a means of parsing and comparing any style of versioning, be it a nice Semantic Version like this:

1.2.3-r1+git123

...or a monstrosity like this:

2:10.2+0.0093r3+1-1

Please switch to Semantic Versioning if you aren't currently using it. It provides consistency in version incrementing and has the best constraints on comparisons.

Using the Parsers

In general, parseV is the function you want. It attempts to parse a given Text using the three individual parsers, semver, version and mess. If one fails, it tries the next. If you know you only want to parse one specific version type, use that parser directly (e.g. semver).

Synopsis

Types

data Versioning #

A top-level Versioning type. Acts as a wrapper for the more specific types. This allows each subtype to have its own parser, and for said parsers to be composed. This is useful for specifying custom behaviour for when a certain parser fails.

Instances

Eq Versioning # 
Ord Versioning #

Comparison of Ideals is always well defined.

If comparison of Generals is well-defined, then comparison of Ideal and General is well-defined, as there exists a perfect mapping from Ideal to General.

If comparison of Complexes is well-defined, then comparison of General and Complex is well defined for the same reason. This implies comparison of Ideal and Complex is also well-defined.

Show Versioning # 
Generic Versioning # 

Associated Types

type Rep Versioning :: * -> * #

NFData Versioning # 

Methods

rnf :: Versioning -> () #

Hashable Versioning # 
Semantic Versioning # 
type Rep Versioning # 

data SemVer #

An (Ideal) version number that conforms to Semantic Versioning. This is a prescriptive parser, meaning it follows the SemVer standard.

Legal semvers are of the form: MAJOR.MINOR.PATCH-PREREL+META

Example: 1.2.3-r1+commithash

Extra Rules:

  1. Pre-release versions have lower precedence than normal versions.
  2. Build metadata does not affect version precedence.
  3. PREREL and META strings may only contain ASCII alphanumerics.

For more information, see http://semver.org

Constructors

SemVer 

Instances

Eq SemVer #

Two SemVers are equal if all fields except metadata are equal.

Methods

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

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

Ord SemVer #

Build metadata does not affect version precedence.

Show SemVer # 
Generic SemVer # 

Associated Types

type Rep SemVer :: * -> * #

Methods

from :: SemVer -> Rep SemVer x #

to :: Rep SemVer x -> SemVer #

Semigroup SemVer # 
Monoid SemVer # 
NFData SemVer # 

Methods

rnf :: SemVer -> () #

Hashable SemVer # 

Methods

hashWithSalt :: Int -> SemVer -> Int #

hash :: SemVer -> Int #

Semantic SemVer # 
type Rep SemVer # 

data Version #

A (General) Version. Not quite as ideal as a SemVer, but has some internal consistancy from version to version. Generally conforms to the x.x.x-x pattern, and may optionally have an epoch. These are prefixes marked by a colon, like in 1:2.3.4.

Examples of Version that are not SemVer: 0.25-2, 8.u51-1, 20150826-1, 1:2.3.4

Constructors

Version 

Fields

Instances

Eq Version # 

Methods

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

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

Ord Version #

Customized.

Show Version # 
Generic Version # 

Associated Types

type Rep Version :: * -> * #

Methods

from :: Version -> Rep Version x #

to :: Rep Version x -> Version #

Semigroup Version # 
Monoid Version # 
NFData Version # 

Methods

rnf :: Version -> () #

Hashable Version # 

Methods

hashWithSalt :: Int -> Version -> Int #

hash :: Version -> Int #

Semantic Version # 
type Rep Version # 

data Mess #

A (Complex) Mess. This is a descriptive parser, based on examples of stupidly crafted version numbers used in the wild.

Groups of letters/numbers, separated by a period, can be further separated by the symbols _-+:

Unfortunately, VChunks cannot be used here, as some developers have numbers like 1.003.04 which make parsers quite sad.

Not guaranteed to have well-defined ordering (Ord) behaviour, but so far internal tests show consistency.

Constructors

VLeaf [Text] 
VNode [Text] VSep Mess 

Instances

Eq Mess # 

Methods

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

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

Ord Mess # 

Methods

compare :: Mess -> Mess -> Ordering #

(<) :: Mess -> Mess -> Bool #

(<=) :: Mess -> Mess -> Bool #

(>) :: Mess -> Mess -> Bool #

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

max :: Mess -> Mess -> Mess #

min :: Mess -> Mess -> Mess #

Show Mess # 

Methods

showsPrec :: Int -> Mess -> ShowS #

show :: Mess -> String #

showList :: [Mess] -> ShowS #

Generic Mess # 

Associated Types

type Rep Mess :: * -> * #

Methods

from :: Mess -> Rep Mess x #

to :: Rep Mess x -> Mess #

NFData Mess # 

Methods

rnf :: Mess -> () #

Hashable Mess # 

Methods

hashWithSalt :: Int -> Mess -> Int #

hash :: Mess -> Int #

Semantic Mess # 
type Rep Mess # 

data VUnit #

A single unit of a Version. May be digits or a string of characters. Groups of these are called VChunks, and are the identifiers separated by periods in the source.

Constructors

Digits Word 
Str Text 

Instances

Eq VUnit # 

Methods

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

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

Ord VUnit # 

Methods

compare :: VUnit -> VUnit -> Ordering #

(<) :: VUnit -> VUnit -> Bool #

(<=) :: VUnit -> VUnit -> Bool #

(>) :: VUnit -> VUnit -> Bool #

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

max :: VUnit -> VUnit -> VUnit #

min :: VUnit -> VUnit -> VUnit #

Read VUnit # 
Show VUnit # 

Methods

showsPrec :: Int -> VUnit -> ShowS #

show :: VUnit -> String #

showList :: [VUnit] -> ShowS #

Generic VUnit # 

Associated Types

type Rep VUnit :: * -> * #

Methods

from :: VUnit -> Rep VUnit x #

to :: Rep VUnit x -> VUnit #

Semigroup VUnit # 

Methods

(<>) :: VUnit -> VUnit -> VUnit #

sconcat :: NonEmpty VUnit -> VUnit #

stimes :: Integral b => b -> VUnit -> VUnit #

Monoid VUnit # 

Methods

mempty :: VUnit #

mappend :: VUnit -> VUnit -> VUnit #

mconcat :: [VUnit] -> VUnit #

NFData VUnit # 

Methods

rnf :: VUnit -> () #

Hashable VUnit # 

Methods

hashWithSalt :: Int -> VUnit -> Int #

hash :: VUnit -> Int #

type Rep VUnit # 

digits :: Word -> VUnit #

Smart constructor for a VUnit made of digits.

str :: Text -> Maybe VUnit #

Smart constructor for a VUnit made of letters.

type VChunk = [VUnit] #

A logical unit of a version number. Can consist of multiple letters and numbers.

data VSep #

Developers use a number of symbols to seperate groups of digits/letters in their version numbers. These are:

  • A colon (:). Often denotes an "epoch".
  • A hyphen (-).
  • A plus (+). Stop using this outside of metadata if you are. Example: 10.2+0.93+1-1
  • An underscore (_). Stop using this if you are.

Constructors

VColon 
VHyphen 
VPlus 
VUnder 

Instances

Eq VSep # 

Methods

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

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

Show VSep # 

Methods

showsPrec :: Int -> VSep -> ShowS #

show :: VSep -> String #

showList :: [VSep] -> ShowS #

Generic VSep # 

Associated Types

type Rep VSep :: * -> * #

Methods

from :: VSep -> Rep VSep x #

to :: Rep VSep x -> VSep #

NFData VSep # 

Methods

rnf :: VSep -> () #

Hashable VSep # 

Methods

hashWithSalt :: Int -> VSep -> Int #

hash :: VSep -> Int #

type Rep VSep # 
type Rep VSep = D1 * (MetaData "VSep" "Data.Versions" "versions-3.3.2-yn6t9CFWbFIiojtBmU6C4" False) ((:+:) * ((:+:) * (C1 * (MetaCons "VColon" PrefixI False) (U1 *)) (C1 * (MetaCons "VHyphen" PrefixI False) (U1 *))) ((:+:) * (C1 * (MetaCons "VPlus" PrefixI False) (U1 *)) (C1 * (MetaCons "VUnder" PrefixI False) (U1 *))))

Parsers

newtype VParser #

A wrapper for a parser function. Can be composed via their Monoid instance, such that a different parser can be tried if a previous one fails.

Constructors

VParser 

type ParsingError = ParseError (Token Text) Void #

A synonym for the more verbose megaparsec error type.

semver :: Text -> Either ParsingError SemVer #

Parse a (Ideal) Semantic Version.

version :: Text -> Either ParsingError Version #

Parse a (General) Version, as defined above.

mess :: Text -> Either ParsingError Mess #

Parse a (Complex) Mess, as defined above.

Wrapped Parsers

parseV :: Text -> Either ParsingError Versioning #

Parse a piece of Text into either an (Ideal) SemVer, a (General) Version, or a (Complex) Mess.

semverP :: VParser #

A wrapped SemVer parser. Can be composed with other parsers.

versionP :: VParser #

A wrapped Version parser. Can be composed with other parsers.

messP :: VParser #

A wrapped Mess parser. Can be composed with other parsers.

Megaparsec Parsers

For when you'd like to mix version parsing into some larger parser.

semver' :: Parsec Void Text SemVer #

Internal megaparsec parser of semverP.

version' :: Parsec Void Text Version #

Internal megaparsec parser of versionP.

mess' :: Parsec Void Text Mess #

Internal megaparsec parser of messP.

Pretty Printing

prettyV :: Versioning -> Text #

Convert any parsed Versioning type to its textual representation.

prettySemVer :: SemVer -> Text #

Convert a SemVer back to its textual representation.

prettyVer :: Version -> Text #

Convert a Version back to its textual representation.

prettyMess :: Mess -> Text #

Convert a Mess back to its textual representation.

parseErrorPretty #

Arguments

:: (Ord t, ShowToken t, ShowErrorComponent e) 
=> ParseError t e

Parse error to render

-> String

Result of rendering

Pretty-print a ParseError. The rendered String always ends with a newline.

Since: 5.0.0

Lenses

type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s #

Simple Lenses compatible with both lens and microlens.

type Traversal' s a = forall f. Applicative f => (a -> f a) -> s -> f s #

Simple Traversals compatible with both lens and microlens.

class Semantic v where #

Version types which sanely and safely yield SemVer-like information about themselves. For instances other than SemVer itself however, these optics may not yield anything, depending on the actual value being traversed. Hence, the optics here are all Traversal's.

Consider the Version 1.2.3.4.5. We can imagine wanting to increment the minor number:

λ "1.2.3.4.5" & minor %~ (+ 1)
"1.3.3.4.5"

But of course something like this would fail:

λ "1.e.3.4.5" & minor %~ (+ 1)
"1.e.3.4.5"

However!

λ "1.e.3.4.5" & major %~ (+ 1)
"2.e.3.4.5"

Minimal complete definition

major, minor, patch, release, meta, semantic

Methods

major :: Traversal' v Word #

MAJOR.minor.patch-prerel+meta

minor :: Traversal' v Word #

major.MINOR.patch-prerel+meta

patch :: Traversal' v Word #

major.minor.PATCH-prerel+meta

release :: Traversal' v [VChunk] #

major.minor.patch-PREREL+meta

meta :: Traversal' v [VChunk] #

major.minor.patch-prerel+META

semantic :: Traversal' v SemVer #

A Natural Transformation into an proper SemVer.

Traversing Text

When traversing Text, leveraging its Semantic instance will likely benefit you more than using these Traversals directly.

_Versioning :: Traversal' Text Versioning #

Traverse some Text for its inner versioning.

λ "1.2.3" & _Versioning . _Ideal . patch %~ (+ 1)  -- or just: "1.2.3" & patch %~ (+ 1)
"1.2.4"

_SemVer :: Traversal' Text SemVer #

Traverse some Text for its inner SemVer.

_Version :: Traversal' Text Version #

Traverse some Text for its inner Version.

_Mess :: Traversal' Text Mess #

Traverse some Text for its inner Mess.

Versioning Traversals

(General) Version Lenses

Misc. Lenses / Traversals