packages feed

versions 3.5.1.1 → 3.5.2

raw patch · 4 files changed

+178/−62 lines, 4 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Data.Versions: PVP :: NonEmpty Word -> PVP
+ Data.Versions: [_pComponents] :: PVP -> NonEmpty Word
+ Data.Versions: instance Control.DeepSeq.NFData Data.Versions.PVP
+ Data.Versions: instance Data.Hashable.Class.Hashable Data.Versions.PVP
+ Data.Versions: instance Data.Versions.Semantic Data.Versions.PVP
+ Data.Versions: instance GHC.Base.Monoid Data.Versions.PVP
+ Data.Versions: instance GHC.Base.Semigroup Data.Versions.PVP
+ Data.Versions: instance GHC.Classes.Eq Data.Versions.PVP
+ Data.Versions: instance GHC.Classes.Ord Data.Versions.PVP
+ Data.Versions: instance GHC.Generics.Generic Data.Versions.PVP
+ Data.Versions: instance GHC.Show.Show Data.Versions.PVP
+ Data.Versions: newtype PVP
+ Data.Versions: prettyPVP :: PVP -> Text
+ Data.Versions: pvp :: Text -> Either ParsingError PVP
+ Data.Versions: pvp' :: Parsec Void Text PVP

Files

CHANGELOG.md view
@@ -1,5 +1,8 @@ # Changelog +## 3.5.2+- Added a new `PVP` type and parsers.+ ## 3.5.1.1 - GHC 8.8 compatibility. 
Data/Versions.hs view
@@ -1,14 +1,15 @@-{-# LANGUAGE CPP               #-}-{-# LANGUAGE DeriveAnyClass    #-}-{-# LANGUAGE DeriveGeneric     #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE Rank2Types        #-}+{-# LANGUAGE CPP                #-}+{-# LANGUAGE DeriveAnyClass     #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE Rank2Types         #-}  -- | -- Module    : Data.Versions--- Copyright : (c) Colin Woodbury, 2015 - 2019+-- Copyright : (c) Colin Woodbury, 2015 - 2020 -- License   : BSD3--- Maintainer: Colin Woodbury <colingw@gmail.com>+-- Maintainer: Colin Woodbury <colin@fosskers.ca> -- -- A library for parsing and comparing software version numbers. --@@ -30,53 +31,54 @@ -- -- == Using the Parsers -- In general, `versioning` is the function you want. It attempts to parse a--- given @Text@ using the three individual parsers, `semver`, `version` and+-- given `T.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`).  module Data.Versions-    (-      -- * Types-      Versioning(..)-    , SemVer(..)-    , Version(..)-    , Mess(..)-    , VUnit(..), digits, str-    , VChunk-    , VSep(..)-      -- * Parsing Versions-    , ParsingError-    , versioning, semver, version, mess-      -- ** Megaparsec Parsers-      -- | For when you'd like to mix version parsing into some larger parser.-    , versioning', semver', version', mess'-      -- * Pretty Printing-    , prettyV, prettySemVer, prettyVer, prettyMess, errorBundlePretty-      -- * Lenses-    , Lens'-    , Traversal'-    , Semantic(..)-      -- ** Traversing Text-      -- | When traversing `T.Text`, leveraging its `Semantic` instance will-      -- likely benefit you more than using these Traversals directly.-    , _Versioning, _SemVer, _Version, _Mess-      -- ** Versioning Traversals-    , _Ideal, _General, _Complex-      -- ** (General) Version Lenses-    , epoch-      -- ** Misc. Lenses / Traversals-    , _Digits, _Str-    ) where+  ( -- * Types+    Versioning(..)+  , SemVer(..)+  , PVP(..)+  , Version(..)+  , Mess(..)+  , VUnit(..), digits, str+  , VChunk+  , VSep(..)+    -- * Parsing Versions+  , ParsingError+  , versioning, semver, pvp, version, mess+    -- ** Megaparsec Parsers+    -- | For when you'd like to mix version parsing into some larger parser.+  , versioning', semver', pvp', version', mess'+    -- * Pretty Printing+  , prettyV, prettySemVer, prettyPVP, prettyVer, prettyMess, errorBundlePretty+    -- * Lenses+  , Lens'+  , Traversal'+  , Semantic(..)+    -- ** Traversing Text+    -- | When traversing `T.Text`, leveraging its `Semantic` instance will+    -- likely benefit you more than using these Traversals directly.+  , _Versioning, _SemVer, _Version, _Mess+    -- ** Versioning Traversals+  , _Ideal, _General, _Complex+    -- ** (General) Version Lenses+  , epoch+    -- ** Misc. Lenses / Traversals+  , _Digits, _Str+  ) where  import           Control.DeepSeq import           Data.Bool (bool) import           Data.Char (isAlpha)-import           Data.Hashable+import           Data.Hashable (Hashable) import           Data.List (intersperse)+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NEL import qualified Data.Text as T-import           Data.Void-import           Data.Word (Word)-import           GHC.Generics+import           Data.Void (Void)+import           GHC.Generics (Generic) import           Text.Megaparsec hiding (chunk) import           Text.Megaparsec.Char import qualified Text.Megaparsec.Char.Lexer as L@@ -92,7 +94,7 @@ -- composed. This is useful for specifying custom behaviour for when a certain -- parser fails. data Versioning = Ideal SemVer | General Version | Complex Mess-  deriving (Eq,Show,Generic,NFData,Hashable)+  deriving (Eq, Show, Generic, NFData, Hashable)  -- | Comparison of @Ideal@s is always well defined. --@@ -248,12 +250,15 @@   meta     = _Versioning . meta   semantic = _SemVer +--------------------------------------------------------------------------------+-- (Ideal) 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+-- Example: @1.2.3-r1+commithash@ -- -- Extra Rules: --@@ -264,11 +269,14 @@ -- 3. PREREL and META strings may only contain ASCII alphanumerics. -- -- For more information, see http://semver.org-data SemVer = SemVer { _svMajor  :: Word-                     , _svMinor  :: Word-                     , _svPatch  :: Word-                     , _svPreRel :: [VChunk]-                     , _svMeta   :: [VChunk] } deriving (Show,Generic,NFData,Hashable)+data SemVer = SemVer+  { _svMajor  :: Word+  , _svMinor  :: Word+  , _svPatch  :: Word+  , _svPreRel :: [VChunk]+  , _svMeta   :: [VChunk] }+  deriving stock (Show, Generic)+  deriving anyclass (NFData, Hashable)  -- | Two SemVers are equal if all fields except metadata are equal. instance Eq SemVer where@@ -320,7 +328,9 @@ -- | A single unit of a Version. May be digits or a string of characters. Groups -- of these are called `VChunk`s, and are the identifiers separated by periods -- in the source.-data VUnit = Digits Word | Str T.Text deriving (Eq,Show,Read,Ord,Generic,NFData,Hashable)+data VUnit = Digits Word | Str T.Text+  deriving stock (Eq, Show, Read, Ord, Generic)+  deriving anyclass (NFData, Hashable)  instance Semigroup VUnit where   Digits n <> Digits m = Digits $ n + m@@ -357,6 +367,74 @@ -- and numbers. type VChunk = [VUnit] +--------------------------------------------------------------------------------+-- (Haskell) PVP++-- | A PVP version number specific to the Haskell ecosystem. Like SemVer this is+-- a prescriptive scheme, and follows <https://pvp.haskell.org/ the PVP spec>.+--+-- Legal PVP values are of the form: MAJOR(.MAJOR.MINOR)+--+-- Example: @1.2.3@+--+-- Extra Rules:+--+-- 1. Each component must be a number.+--+-- 2. Only the first MAJOR component is actually necessary. Otherwise, there can+--    be any number of components. @1.2.3.4.5.6.7@ is legal.+--+-- 3. Unlike SemVer there are two MAJOR components, and both indicate a breaking+--    change. The spec otherwise designates no special meaning to components+--    past the MINOR position.+newtype PVP = PVP { _pComponents :: NonEmpty Word }+  deriving stock (Eq, Ord, Show, Generic)+  deriving anyclass (NFData, Hashable)++instance Semigroup PVP where+  PVP (m :| r) <> PVP (m' :| r') = PVP $ (m + m') :| f r r'+    where+      f a []          = a+      f [] b          = b+      f (a:as) (b:bs) = (a + b) : f as bs++instance Monoid PVP where+  mempty = PVP (0 :| [])++#if __GLASGOW_HASKELL__ < 841+  mappend = (<>)+#endif++instance Semantic PVP where+  major f (PVP (m :| rs)) = (\ma -> PVP $ ma :| rs) <$> f m+  {-# INLINE major #-}++  minor f (PVP (m :| mi : rs)) = (\mi' -> PVP $ m :| mi' : rs) <$> f mi+  minor f (PVP (m :| []))      = (\mi' -> PVP $ m :| [mi']) <$> f 0+  {-# INLINE minor #-}++  patch f (PVP (m :| mi : pa : rs)) = (\pa' -> PVP $ m :| mi : pa' : rs) <$> f pa+  patch f (PVP (m :| mi : []))      = (\pa' -> PVP $ m :| mi : [pa']) <$> f 0+  patch f (PVP (m :| []))           = (\pa' -> PVP $ m :| 0 : [pa']) <$> f 0+  {-# INLINE patch #-}++  release f p = const p <$> f []+  {-# INLINE release #-}++  meta f p = const p <$> f []+  {-# INLINE meta #-}++  semantic f (PVP (m :| rs)) = (\(SemVer ma mi pa _ _) -> PVP $ ma :| [mi, pa]) <$> f s+    where+      s = case rs of+        mi : pa : _ -> SemVer m mi pa [] []+        mi : _      -> SemVer m mi 0  [] []+        []          -> SemVer m 0 0   [] []+  {-# INLINE semantic #-}++--------------------------------------------------------------------------------+-- (General) Version+ -- | A (General) Version. -- Not quite as ideal as a `SemVer`, but has some internal consistancy -- from version to version.@@ -364,9 +442,12 @@ -- 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-data Version = Version { _vEpoch  :: Maybe Word-                       , _vChunks :: [VChunk]-                       , _vRel    :: [VChunk] } deriving (Eq,Show,Generic,NFData,Hashable)+data Version = Version+  { _vEpoch  :: Maybe Word+  , _vChunks :: [VChunk]+  , _vRel    :: [VChunk] }+  deriving stock (Eq, Show, Generic)+  deriving anyclass (NFData, Hashable)  instance Semigroup Version where   Version e c r <> Version e' c' r' = Version ((+) <$> e <*> e') (c ++ c') (r ++ r')@@ -468,6 +549,9 @@ epoch f v = fmap (\ve -> v { _vEpoch = ve }) (f $ _vEpoch v) {-# INLINE epoch #-} +--------------------------------------------------------------------------------+-- (Complex) Mess+ -- | A (Complex) Mess. This is a /descriptive/ parser, based on examples of -- stupidly crafted version numbers used in the wild. --@@ -479,7 +563,9 @@ -- -- Not guaranteed to have well-defined ordering (@Ord@) behaviour, but so far -- internal tests show consistency.-data Mess = VLeaf [T.Text] | VNode [T.Text] VSep Mess deriving (Eq,Show,Generic,NFData,Hashable)+data Mess = VLeaf [T.Text] | VNode [T.Text] VSep Mess+  deriving stock (Eq, Show, Generic)+  deriving anyclass (NFData, Hashable)  instance Ord Mess where   compare (VLeaf l1) (VLeaf l2)     = compare l1 l2@@ -529,8 +615,13 @@ -- * 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.-data VSep = VColon | VHyphen | VPlus | VUnder deriving (Eq,Show,Generic,NFData,Hashable)+data VSep = VColon | VHyphen | VPlus | VUnder+  deriving stock (Eq, Show, Generic)+  deriving anyclass (NFData, Hashable) +--------------------------------------------------------------------------------+-- Parsing+ -- | A synonym for the more verbose `megaparsec` error type. type ParsingError = ParseErrorBundle T.Text Void @@ -593,6 +684,14 @@ sunit :: Parsec Void T.Text VUnit sunit = Str . T.pack <$> some letterChar +-- | Parse a (Haskell) `PVP`, as defined above.+pvp :: T.Text -> Either ParsingError PVP+pvp = parse (pvp' <* eof) "PVP"++-- | Internal megaparsec parser of `pvp`.+pvp' :: Parsec Void T.Text PVP+pvp' = L.lexeme space (PVP . NEL.fromList <$> L.decimal `sepBy` char '.')+ -- | Parse a (General) `Version`, as defined above. version :: T.Text -> Either ParsingError Version version = parse (version' <* eof) "Version"@@ -645,6 +744,10 @@   where ver = intersperse "." [ showt ma, showt mi, showt pa ]         pr' = foldable [] ("-" :) $ intersperse "." (chunksAsT pr)         me' = foldable [] ("+" :) $ intersperse "." (chunksAsT me)++-- | Convert a `PVP` back to its textual representation.+prettyPVP :: PVP -> T.Text+prettyPVP (PVP (m :| rs)) = T.intercalate "." . map showt $ m : rs  -- | Convert a `Version` back to its textual representation. prettyVer :: Version -> T.Text
test/Test.hs view
@@ -92,7 +92,7 @@ -- Logically, these are the same package, but for those 5 packages, they -- aren't. cabalOrd :: [T.Text]-cabalOrd = [ "0.2", "0.2.0", "0.2.0.0" ]+cabalOrd = [ "0", "0.2", "0.2.0", "0.2.0.0" ]  versionOrd :: [T.Text] versionOrd = [ "0.9.9.9", "1.0.0.0", "1.0.0.1", "2" ]@@ -102,8 +102,8 @@   [ testGroup "Property Tests"     [ testGroup "SemVer - Monoid" $       map (uncurry testProperty) . unbatch $ monoid (SemVer 1 2 3 [] [])-    , testProperty "SemVer - Arbitrary" $ \a -> isRight . fmap (== a) $ semver (prettySemVer a)-    , testProperty "Version - Arbitrary" $ \a -> isRight . fmap (== a) $ version (prettyVer a)+    , testProperty "SemVer - Arbitrary" $ \a -> semver (prettySemVer a) == Right a+    , testProperty "Version - Arbitrary" $ \a -> version (prettyVer a) == Right a     -- , testGroup "Version - Monoid" $     --   map (\(name, test) -> testProperty name test) . unbatch $ monoid (Version (Just 1) [[digits 2], [digits 3]])     , testGroup "VUnit - Monoid" $@@ -125,6 +125,13 @@         [ testCase "1.2.3-1[ ]" $ parse semver' "semver whitespace" "1.2.3-1 " @?= Right (SemVer 1 2 3 [[Digits 1]] [])         ]       ]+    , testGroup "(Haskell) PVP"+      [ testGroup "Good PVPs" $+        map (\s -> testCase (T.unpack s) $ isomorphPVP s) cabalOrd+      , testGroup "Comparisons" $+        map (\(a,b) -> testCase (T.unpack $ a <> " < " <> b) $ comp pvp a b)+        (zip cabalOrd $ tail cabalOrd)+      ]     , testGroup "(General) Versions"       [ testGroup "Good Versions" $         map (\s -> testCase (T.unpack s) $ isomorphV s) goodVers@@ -190,6 +197,9 @@ -- | Does pretty-printing return a SemVer to its original form? isomorphSV :: T.Text -> Assertion isomorphSV t = Right t @=? (prettySemVer <$> semver t)++isomorphPVP :: T.Text -> Assertion+isomorphPVP t = Right t @=? (prettyPVP <$> pvp t)  isomorphM :: T.Text -> Assertion isomorphM t =  Right t @=? (prettyMess <$> mess t)
versions.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.2 name:               versions-version:            3.5.1.1+version:            3.5.2 synopsis:           Types and parsers for software version numbers. description:   A library for parsing and comparing software version numbers. We like to give@@ -38,7 +38,7 @@     -Wincomplete-uni-patterns    build-depends:-    , base        >=4.8 && <4.14+    , base        >=4.10 && <4.14     , megaparsec  >=7     , text        >=1.2