packages feed

versions 1.1.0 → 2.0.0

raw patch · 5 files changed

+136/−26 lines, 5 filesdep +megaparsecdep −parsec

Dependencies added: megaparsec

Dependencies removed: parsec

Files

CHANGELOG.md view
@@ -1,6 +1,12 @@ Changelog ========= +2.0.0+-----+- Switched to `megaparsec` to perform all parsing as `Text`+- Support for legacy `String` removed+- Added more Traversals and INLINE'd all Lenses/Traversals+ 1.1.0 ----- - Added Lenses and Traversals (no `lens` dependency)
Data/Versions.hs view
@@ -45,11 +45,8 @@     , VParser(..)       -- * Parsers     , semver-    , semver'     , version-    , version'     , mess-    , mess'       -- ** Wrapped Parsers     , parseV     , semverP@@ -61,8 +58,11 @@     , prettyVer     , prettyMess       -- * Lenses-      -- ** Top-level Traversals+      -- **  Traversing Text     , _Versioning+    , _SemVer+    , _Version+      -- ** Versioning Traversals     , _Ideal     , _General     , _Complex@@ -82,7 +82,8 @@ import Data.List (intersperse) import Data.Semigroup import Data.Text (Text,pack,unpack,snoc)-import Text.ParserCombinators.Parsec+import Text.Megaparsec.Text+import Text.Megaparsec  --- @@ -100,21 +101,39 @@ -- > ("1.2.3" & _Versioning . _Ideal . svPatch %~ (+ 1)) == "1.2.4" _Versioning :: Applicative f => (Versioning -> f Versioning) -> Text -> f Text _Versioning f t = either (const (pure t)) (fmap prettyV . f) $ parseV t+{-# INLINE _Versioning #-} +-- | Traverse some Text for its inner SemVer.+--+-- > _SemVer :: Traversal' Text SemVer+_SemVer :: Applicative f => (SemVer -> f SemVer) -> Text -> f Text+_SemVer f t = either (const (pure t)) (fmap prettySemVer . f) $ semver t+{-# INLINE _SemVer #-}++-- | Traverse some Text for its inner Version.+--+-- > _Version :: Traversal' Text Version+_Version :: Applicative f => (Version -> f Version) -> Text -> f Text+_Version f t = either (const (pure t)) (fmap prettyVer . f) $ version t+{-# INLINE _Version #-}+ -- | > _Ideal :: Traversal' Versioning SemVer _Ideal :: Applicative f => (SemVer -> f SemVer) -> Versioning -> f Versioning _Ideal f (Ideal s) = Ideal <$> f s _Ideal _ v = pure v+{-# INLINE _Ideal #-}  -- | > _General :: Traversal' Versioning Version _General :: Applicative f => (Version -> f Version) -> Versioning -> f Versioning _General f (General v) = General <$> f v _General _ v = pure v+{-# INLINE _General #-}  -- | > _Complex :: Traversal' Versioning Mess _Complex :: Applicative f => (Mess -> f Mess) -> Versioning -> f Versioning _Complex f (Complex m) = Complex <$> f m _Complex _ v = pure v+{-# INLINE _Complex #-}  -- | Comparison of @Ideal@s is always well defined. --@@ -167,22 +186,27 @@ -- | > svMajor :: Lens' SemVer Int svMajor :: Functor f => (Int -> f Int) -> SemVer -> f SemVer svMajor f sv = fmap (\ma -> sv { _svMajor = ma }) (f $ _svMajor sv)+{-# INLINE svMajor #-}  -- | > svMinor :: Lens' SemVer Int svMinor :: Functor f => (Int -> f Int) -> SemVer -> f SemVer svMinor f sv = fmap (\mi -> sv { _svMinor = mi }) (f $ _svMinor sv)+{-# INLINE svMinor #-}  -- | > svPatch :: Lens' SemVer Int svPatch :: Functor f => (Int -> f Int) -> SemVer -> f SemVer svPatch f sv = fmap (\pa -> sv { _svPatch = pa }) (f $ _svPatch sv)+{-# INLINE svPatch #-}  -- | > svPreRel :: Lens' SemVer Int svPreRel :: Functor f => ([VChunk] -> f [VChunk]) -> SemVer -> f SemVer svPreRel f sv = fmap (\pa -> sv { _svPreRel = pa }) (f $ _svPreRel sv)+{-# INLINE svPreRel #-}  -- | > svMeta :: Lens' SemVer Int svMeta :: Functor f => ([VChunk] -> f [VChunk]) -> SemVer -> f SemVer svMeta f sv = fmap (\pa -> sv { _svMeta = pa }) (f $ _svMeta sv)+{-# INLINE svMeta #-}  -- | Two SemVers are equal if all fields except metadata are equal. instance Eq SemVer where@@ -210,11 +234,13 @@ _Digits :: Applicative f => (Int -> f Int) -> VUnit -> f VUnit _Digits f (Digits i) = Digits <$> f i _Digits _ v = pure v+{-# INLINE _Digits #-}  -- | > _Str :: Traversal' VUnit Text _Str :: Applicative f => (Text -> f Text) -> VUnit -> f VUnit _Str f (Str t) = Str <$> f t _Str _ v = pure v+{-# INLINE _Str #-}  -- | A logical unit of a version number. Can consist of multiple letters -- and numbers.@@ -232,10 +258,12 @@ -- | > vChunks :: Lens' Version [VChunk] vChunks :: Functor f => ([VChunk] -> f [VChunk]) -> Version -> f Version vChunks f v = fmap (\vc -> v { _vChunks = vc }) (f $ _vChunks v)+{-# INLINE vChunks #-}  -- | > vRel :: Lens' Version [VChunk] vRel :: Functor f => ([VChunk] -> f [VChunk]) -> Version -> f Version vRel f v = fmap (\vc -> v { _vRel = vc }) (f $ _vRel v)+{-# INLINE vRel #-}  -- | A (Complex) Mess. -- This is a /descriptive/ parser, based on examples of stupidly@@ -288,11 +316,7 @@  -- | Parse a (Ideal) Semantic Version. semver :: Text -> Either ParseError SemVer-semver = semver' . unpack---- | Parse a Semantic Version, as a legacy String.-semver' :: String -> Either ParseError SemVer-semver' = parse semanticVersion "Semantic Version"+semver = parse semanticVersion "Semantic Version"  semanticVersion :: Parser SemVer semanticVersion = p <* eof@@ -300,7 +324,7 @@  -- | Parse a group of digits, which can't be lead by a 0, unless it is 0. digits :: Parser Int-digits = read <$> (string "0" <|> many1 digit)+digits = read <$> (string "0" <|> some digitChar)  major :: Parser Int major = digits <* char '.'@@ -322,10 +346,10 @@   where oneZero = (:[]) . Digits . read <$> string "0"  iunit :: Parser VUnit-iunit = Digits . read <$> many1 digit+iunit = Digits . read <$> some digitChar  sunit :: Parser VUnit-sunit = Str . pack <$> many1 letter+sunit = Str . pack <$> some letterChar  -- | A wrapped `Version` parser. Can be composed with other parsers. versionP :: VParser@@ -333,11 +357,7 @@  -- | Parse a (General) `Version`, as defined above. version :: Text -> Either ParseError Version-version = version' . unpack---- | Parse a `Version`, where the input is a legacy String.-version' :: String -> Either ParseError Version-version' = parse versionNum "Version"+version = parse versionNum "Version"  versionNum :: Parser Version versionNum = Version <$> chunks <*> preRel <* eof@@ -348,11 +368,7 @@  -- | Parse a (Complex) `Mess`, as defined above.  mess :: Text -> Either ParseError Mess-mess = mess' . unpack---- | Parse a `Mess`, where the input is a legacy String.-mess' :: String -> Either ParseError Mess-mess' = parse messNumber "Mess"+mess = parse messNumber "Mess"  messNumber :: Parser Mess messNumber = try node <|> leaf@@ -364,7 +380,7 @@ node = VNode <$> tchunks <*> sep <*> messNumber  tchunks :: Parser [Text]-tchunks = (pack <$> many1 (letter <|> digit)) `sepBy` char '.'+tchunks = (pack <$> some (letterChar <|> digitChar)) `sepBy` char '.'  sep :: Parser VSep sep = choice [ VColon  <$ char ':'
+ README.md view
@@ -0,0 +1,81 @@+versions+========++[![Build Status](https://travis-ci.org/aurapm/haskell-versions.svg?branch=master)](https://travis-ci.org/aurapm/haskell-versions)+[![Coverage Status](https://coveralls.io/repos/github/aurapm/haskell-versions/badge.svg?branch=master)](https://coveralls.io/github/aurapm/haskell-versions?branch=master)++A Haskell library for parsing and comparing software version numbers.++About+-----+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](http://semver.org) if you aren't+currently using it. It provides consistency in version incrementing and has+the best constraints on comparisons.++Usage+-----+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`).++#### Lenses and Traversals+The parse result types have Lenses/Traversals for accessing their data+fields. For instance, to increment the patch number of a parsed SemVer, you+could:++```haskell+incPatch :: SemVer -> SemVer+incPatch s = s & svPatch %~ (+ 1)+```++Or, something more involved:++```haskell+-- | Get all major versions of legally parsed SemVers.+majors :: [Text] -> [Int]+majors vs = vs ^.. each . to semver . _Right . svMajor+```++The `to semver . _Right` is clunky, so we provide some direct `Text`+Traverals inspired by+([micro](http://hackage.haskell.org/package/microlens-aeson))+[lens-aeson](http://hackage.haskell.org/package/lens-aeson):++```haskell+-- | Get all major versions of legally parsed SemVers.+majors :: [Text] -> [Int]+majors vs = vs ^.. each . _SemVer . svMajor+```++Note that `_SemVer` only attempts to parse as true Semantic Versioning. If+the package versions you're parsing don't agree to a standard, you can+achieve a similar result via:++```haskell+-- | Get all major versions of potentially parsed SemVers.+majors :: [Text] -> [Int]+majors vs = vs ^.. each . _Versioning . _Ideal . svMajor+```++We can also use these `Text` Traversals to increment versions, as above:++```haskell+incPatch :: Text -> Text+incPatch s = s & _SemVer . svPatch %~ (+ 1)++> incPatch "1.2.3"+"1.2.4"+```
test/Test.hs view
@@ -109,6 +109,7 @@     , testGroup "Lenses and Traversals"       [ testCase "SemVer - Increment Patch" incPatch       , testCase "SemVer - Increment Patch from Text" incFromT+      , testCase "SemVer - Get patches" patches       , testCase "Traverse `General` as `Ideal`" noInc       ]   ]@@ -158,6 +159,10 @@  incFromT :: Assertion incFromT = ("1.2.3" & _Versioning . _Ideal . svPatch %~ (+ 1)) @?= "1.2.4"++patches :: Assertion+patches = ps @?= [3,4,5]+  where ps = ["1.2.3","2.3.4","3.4.5"] ^.. each . _SemVer . svPatch  {-} -- Need to submit patch for these, as well as Maybe instance.
versions.cabal view
@@ -1,5 +1,5 @@ name:                versions-version:             1.1.0+version:             2.0.0 synopsis:            Types and parsers for software version numbers. description:         A library for parsing and comparing software version numbers.                      .@@ -29,6 +29,7 @@ cabal-version:       >=1.10  extra-source-files:    CHANGELOG.md+                     , README.md  source-repository head   type:     git@@ -40,7 +41,7 @@   other-extensions:    OverloadedStrings    build-depends:       base >=4.8 && <4.9-                     , parsec >=3.1 && <3.2+                     , megaparsec >= 4 && < 5                      , semigroups >= 0.16.2.2                      , text >=1.2 && <1.3 @@ -61,3 +62,4 @@   hs-source-dirs:      test   main-is:             Test.hs   default-language:    Haskell2010+  ghc-options: -Wall -threaded