packages feed

versions 3.5.3 → 3.5.4

raw patch · 6 files changed

+142/−39 lines, 6 filesdep −base-preludedep −checkerssetup-changed

Dependencies removed: base-prelude, checkers

Files

CHANGELOG.md view
@@ -1,5 +1,18 @@ # Changelog +## 3.5.4 (2020-05-12)++#### Added++- The functions `isIdeal`, `isGeneral`, and `isComplex` for `Bool`-based+  inspection of parse results.+- `messMajor`, `messMinor`, `messPatch`, and `messPatchChunk` for improved+  introspection into `Mess` values.++#### Changed++- Improved `Mess` comparison logic.+ ## 3.5.3 - GHC 8.10 support. 
Data/Versions.hs view
@@ -37,11 +37,11 @@  module Data.Versions   ( -- * Types-    Versioning(..)+    Versioning(..), isIdeal, isGeneral, isComplex   , SemVer(..)   , PVP(..)   , Version(..)-  , Mess(..)+  , Mess(..), messMajor, messMinor, messPatch, messPatchChunk   , VUnit(..), digits, str   , VChunk   , VSep(..)@@ -96,6 +96,21 @@ data Versioning = Ideal SemVer | General Version | Complex Mess   deriving (Eq, Show, Generic, NFData, Hashable) +-- | Short-hand for detecting a `SemVer`.+isIdeal :: Versioning -> Bool+isIdeal (Ideal _) = True+isIdeal _         = False++-- | Short-hand for detecting a `Version`.+isGeneral :: Versioning -> Bool+isGeneral (General _) = True+isGeneral _           = False++-- | Short-hand for detecting a `Mess`.+isComplex :: Versioning -> Bool+isComplex (Complex _) = True+isComplex _           = False+ -- | Comparison of @Ideal@s is always well defined. -- -- If comparison of @General@s is well-defined, then comparison of @Ideal@ and@@ -106,15 +121,15 @@ -- and @Complex@ is well defined for the same reason. This implies comparison of -- @Ideal@ and @Complex@ is also well-defined. instance Ord Versioning where-  compare (Ideal s)     (Ideal s')    = compare s s'-  compare (General v)   (General v')  = compare v v'-  compare (Complex m)   (Complex m')  = compare m m'-  compare (Ideal s)     (General v)   = compare (vFromS s) v-  compare (General v)   (Ideal s)     = opposite $ compare (vFromS s) v-  compare (General v)   (Complex m)   = compare (mFromV v) m-  compare (Complex m)   (General v)   = opposite $ compare (mFromV v) m-  compare (Ideal s)     m@(Complex _) = compare (General $ vFromS s) m-  compare m@(Complex _) (Ideal s)     = compare m (General $ vFromS s)+  compare (Ideal s)     (Ideal s')   = compare s s'+  compare (General v)   (General v') = compare v v'+  compare (Complex m)   (Complex m') = compare m m'+  compare (Ideal s)     (General v)  = compare (vFromS s) v+  compare (General v)   (Ideal s)    = opposite $ compare (vFromS s) v+  compare (General v)   (Complex m)  = compare (mFromV v) m+  compare (Complex m)   (General v)  = opposite $ compare (mFromV v) m+  compare (Ideal s)     (Complex m)  = semverAndMess s m+  compare (Complex m) (Ideal s)      = opposite $ semverAndMess s m  -- | Convert a `SemVer` to a `Version`. vFromS :: SemVer -> Version@@ -123,8 +138,40 @@ -- | Convert a `Version` to a `Mess`. mFromV :: Version -> Mess mFromV (Version e v r) = maybe affix (\a -> VNode [showt a] VColon affix) e-  where affix = VNode (chunksAsT v) VHyphen $ VLeaf (chunksAsT r)+  where+    affix :: Mess+    affix = VNode (chunksAsT v) VHyphen $ VLeaf (chunksAsT r) +-- | Special logic for when semver-like values can be extracted from a `Mess`.+-- This avoids having to "downcast" the `SemVer` into a `Mess` before comparing,+-- and in some cases can offer better comparison results.+semverAndMess :: SemVer -> Mess -> Ordering+semverAndMess s@(SemVer ma mi pa _ _) m = case compare ma <$> messMajor m of+  Nothing -> fallback+  Just LT -> LT+  Just GT -> GT+  Just EQ -> case compare mi <$> messMinor m of+    Nothing -> fallback+    Just LT -> LT+    Just GT -> GT+    Just EQ -> case compare pa <$> messPatch m of+      Just LT -> LT+      Just GT -> GT+      -- If they've been equal up to this point, the `Mess`+      -- will by definition have more to it, meaning that+      -- it's more likely to be newer, despite its poor shape.+      Just EQ -> fallback+      Nothing -> case messPatchChunk m of+        Nothing             -> fallback+        Just (Digits pa':_) -> case compare pa pa' of+          LT -> LT+          GT -> GT+          EQ -> GT  -- This follows semver's rule!+        Just _ -> fallback+  where+    fallback :: Ordering+    fallback = compare (General $ vFromS s) (Complex m)+ instance Semantic Versioning where   major f (Ideal v)   = Ideal   <$> major f v   major f (General v) = General <$> major f v@@ -302,7 +349,7 @@ instance Monoid SemVer where   mempty = SemVer 0 0 0 [] [] -#if __GLASGOW_HASKELL__ < 841+#if !MIN_VERSION_base(4,11,0)   mappend = (<>) #endif @@ -341,7 +388,7 @@ instance Monoid VUnit where   mempty = Str "" -#if __GLASGOW_HASKELL__ < 841+#if !MIN_VERSION_base(4,11,0)   mappend = (<>) #endif @@ -401,7 +448,7 @@ instance Monoid PVP where   mempty = PVP (0 :| []) -#if __GLASGOW_HASKELL__ < 841+#if !MIN_VERSION_base(4,11,0)   mappend = (<>) #endif @@ -455,7 +502,7 @@ instance Monoid Version where   mempty = Version Nothing [] [] -#if __GLASGOW_HASKELL__ < 841+#if !MIN_VERSION_base(4,11,0)   mappend = (<>) #endif @@ -561,12 +608,44 @@ -- Unfortunately, @VChunk@s cannot be used here, as some developers have numbers -- like @1.003.04@ which make parsers quite sad. --+-- Some `Mess` values have a shape that is tantalizingly close to a `SemVer`.+-- Example: @1.6.0a+2014+m872b87e73dfb-1@. For values like these, we can extract+-- the semver-compatible values out with `messMajor`, etc.+-- -- Not guaranteed to have well-defined ordering (@Ord@) behaviour, but so far--- internal tests show consistency.+-- internal tests show consistency. `messMajor`, etc., are used internally where+-- appropriate to enhance accuracy. data Mess = VLeaf [T.Text] | VNode [T.Text] VSep Mess   deriving stock (Eq, Show, Generic)   deriving anyclass (NFData, Hashable) +-- | Try to extract the "major" version number from `Mess`, as if it were a+-- `SemVer`.+messMajor :: Mess -> Maybe Word+messMajor (VNode (m:_) _ _) = hush $ parse (digitsP <* eof) "Major" m+messMajor _                 = Nothing++-- | Try to extract the "minor" version number from `Mess`, as if it were a+-- `SemVer`.+messMinor :: Mess -> Maybe Word+messMinor (VNode (_:m:_) _ _) = hush $ parse (digitsP <* eof) "Minor" m+messMinor _                   = Nothing++-- | Try to extract the "patch" version number from `Mess`, as if it were a+-- `SemVer`.+messPatch :: Mess -> Maybe Word+messPatch (VNode (_:_:p:_) _ _) = hush $ parse (digitsP <* eof) "Patch" p+messPatch _                     = Nothing++-- | Okay, fine, say `messPatch` couldn't find a nice value. But some `Mess`es+-- have a "proper" patch-plus-release-candidate value in their patch position,+-- which is parsable as a `VChunk`.+--+-- Example: @1.6.0a+2014+m872b87e73dfb-1@ We should be able to extract @0a@ safely.+messPatchChunk :: Mess -> Maybe VChunk+messPatchChunk (VNode (_:_:p:_) _ _) = hush $ parse chunk "Chunk" p+messPatchChunk _                     = Nothing+ instance Ord Mess where   compare (VLeaf l1) (VLeaf l2)     = compare l1 l2   compare (VNode t1 _ _) (VLeaf t2) = compare t1 t2@@ -782,3 +861,7 @@ -- Yes, `text-show` exists, but this reduces external dependencies. showt :: Show a => a -> T.Text showt = T.pack . show++hush :: Either a b -> Maybe b+hush (Left _)  = Nothing+hush (Right b) = Just b
README.md view
@@ -1,6 +1,7 @@ versions ======== +![](https://github.com/fosskers/versions/workflows/Tests/badge.svg) [![Hackage](https://img.shields.io/hackage/v/versions.svg?style=flat)](https://hackage.haskell.org/package/versions) [![Stackage Nightly](http://stackage.org/package/versions/badge/nightly)](http://stackage.org/nightly/package/versions) [![Stackage LTS](http://stackage.org/package/versions/badge/lts)](http://stackage.org/lts/package/versions)
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
test/Test.hs view
@@ -1,17 +1,18 @@-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-}  {-# OPTIONS_GHC -fno-warn-orphans #-}  module Main where -import           BasePrelude hiding (Version, try)+import           Data.Char (chr)+import           Data.Either (isLeft)+import           Data.Foldable (fold)+import           Data.List (groupBy) import qualified Data.Text as T import           Data.Versions+import           Data.Void (Void) import           Lens.Micro import           Test.QuickCheck-import           Test.QuickCheck.Checkers-import           Test.QuickCheck.Classes import           Test.Tasty import           Test.Tasty.HUnit import           Test.Tasty.QuickCheck@@ -33,16 +34,10 @@         f (Str _) (Str _)       = True         f _ _                   = False -instance EqProp SemVer where-  a =-= b = eq a b- instance Arbitrary VUnit where   arbitrary = frequency [ (1, Digits . (+ 1) <$> arbitrary) , (1, s) ]     where s = Str . T.pack . map unletter <$> resize 10 (listOf1 arbitrary) -instance EqProp VUnit where-  a =-= b = eq a b- -- | An ASCII letter. newtype Letter = Letter { unletter :: Char } @@ -52,9 +47,6 @@ instance Arbitrary Version where   arbitrary = Version <$> arbitrary <*> chunks <*> chunks -instance EqProp Version where-  a =-= b = eq a b- -- | These don't need to parse as a SemVer. goodVers :: [T.Text] goodVers = [ "1", "1.2", "1.0rc0", "1.0rc1", "1.1rc1", "1.58.0-3",  "44.0.2403.157-1"@@ -100,14 +92,10 @@ suite :: TestTree suite = testGroup "Tests"   [ testGroup "Property Tests"-    [ testGroup "SemVer - Monoid" $-      map (uncurry testProperty) . unbatch $ monoid (SemVer 1 2 3 [] [])-    , testProperty "SemVer - Arbitrary" $ \a -> semver (prettySemVer a) == Right 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" $-      map (uncurry testProperty) . unbatch $ monoid (Digits 0)     ]   , testGroup "Unit Tests"     [ testGroup "(Ideal) Semantic Versioning"@@ -150,6 +138,18 @@       , testGroup "Comparisons" $         map (\(a,b) -> testCase (T.unpack $ a <> " < " <> b) $ comp mess a b) $         zip messComps (tail messComps)+      , testGroup "SemVer-like Value Extraction"+        [ testCase "messMajor" $+          (hush (mess "1.6.0a+2014+m872b87e73dfb-1") >>= messMajor) @?= Just 1+        , testCase "messMinor" $+          (hush (mess "1.6.0a+2014+m872b87e73dfb-1") >>= messMinor) @?= Just 6+        , testCase "messPatch - Good" $+          (hush (mess "1.6.0+2014+m872b87e73dfb-1") >>= messPatch) @?= Just 0+        , testCase "messPatch - Bad" $+          (hush (mess "1.6.0a+2014+m872b87e73dfb-1") >>= messPatch) @?= Nothing+        , testCase "messPatchChunk" $+          (hush (mess "1.6.0a+2014+m872b87e73dfb-1") >>= messPatchChunk) @?= Just [Digits 0, Str "a"]+        ]       ]     , testGroup "Mixed Versioning"       [ testGroup "Identification"@@ -171,6 +171,8 @@         , testCase "1.2.3-1   < 2+0007-1"  $ comp versioning "1.2.3-1" "2+0007-1"         , testCase "1.2.3r1-1 < 2+0007-1"  $ comp versioning "1.2.3r1-1" "2+0007-1"         , testCase "1.2-5 < 1.2.3-1"       $ comp versioning "1.2-5" "1.2.3-1"+        , testCase "1.6.0a+2014+m872b87e73dfb-1 < 1.6.0-1"+          $ comp versioning "1.6.0a+2014+m872b87e73dfb-1" "1.6.0-1"         ]       ]     , testGroup "Lenses and Traversals"@@ -250,3 +252,7 @@ versionGrab = manyTill anySingle (try finished) *> ver   where finished = char '-' *> lookAhead digitChar         ver = fmap Ideal semver' <|> fmap General version' <|> fmap Complex mess'++hush :: Either a b -> Maybe b+hush (Left _)  = Nothing+hush (Right b) = Just b
versions.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.2 name:               versions-version:            3.5.3+version:            3.5.4 synopsis:           Types and parsers for software version numbers. description:   A library for parsing and comparing software version numbers. We like to give@@ -21,7 +21,7 @@   the best constraints on comparisons.  category:           Data-homepage:           https://gitlab.com/fosskers/versions+homepage:           https://github.com/fosskers/versions author:             Colin Woodbury maintainer:         colin@fosskers.ca license:            BSD-3-Clause@@ -56,8 +56,6 @@   hs-source-dirs: test   ghc-options:    -threaded -with-rtsopts=-N   build-depends:-    , base-prelude-    , checkers          >=0.4     , microlens         >=0.4     , QuickCheck        >=2.9     , tasty             >=0.10.1.2