versions 3.0.2 → 3.0.2.1
raw patch · 3 files changed
+59/−8 lines, 3 files
Files
- Data/Versions.hs +54/−4
- test/Test.hs +2/−1
- versions.cabal +3/−3
Data/Versions.hs view
@@ -263,8 +263,49 @@ -- -- Examples of @Version@ that are not @SemVer@: 0.25-2, 8.u51-1, 20150826-1 data Version = Version { _vChunks :: [VChunk]- , _vRel :: [VChunk] } deriving (Eq,Ord,Show)+ , _vRel :: [VChunk] } deriving (Eq,Show) +-- | Customized.+instance Ord Version where+ -- | The obvious base case.+ compare (Version [] []) (Version [] []) = EQ++ -- | If the two Versions were otherwise equal and recursed down this far,+ -- we need to compare them by their "release" values.+ compare (Version [] rs) (Version [] rs') = compare (Version rs []) (Version rs' [])++ -- | If one side has run out of chunks to compare but the other hasn't,+ -- the other must be newer.+ compare (Version _ _) (Version [] _) = GT+ compare (Version [] _) (Version _ _) = LT++ -- | The usual case. If first VChunks of each Version is equal, then we+ -- keep recursing. Otherwise, we don't need to check further. Consider @1.2@+ -- compared to @1.1.3.4.5.6@.+ compare (Version (a:as) rs) (Version (b:bs) rs') = case f a b of+ EQ -> compare (Version as rs) (Version bs rs')+ res -> res+ where f [] [] = EQ++ -- | Opposite of the above. If we've recursed this far and one side has+ -- fewer chunks, it must be the "greater" version. A Chunk break only occurs in+ -- a switch from digits to letters and vice versa, so anything "extra" must be+ -- an @rc@ marking or similar. Consider @1.1@ compared to @1.1rc1@.+ f [] _ = GT+ f _ [] = LT++ -- | The usual case.+ f (Digits n:ns) (Digits m:ms) | n > m = GT+ | n < m = LT+ | otherwise = f ns ms+ f (Str n:ns) (Str m:ms) | n > m = GT+ | n < m = LT+ | otherwise = f ns ms++ -- | An arbitrary decision to prioritize digits over letters.+ f (Digits _ :_) (Str _ :_) = GT+ f (Str _ :_ ) (Digits _ :_) = LT+ -- | > vChunks :: Lens' Version [VChunk] vChunks :: Functor f => ([VChunk] -> f [VChunk]) -> Version -> f Version vChunks f v = fmap (\vc -> v { _vChunks = vc }) (f $ _vChunks v)@@ -337,8 +378,7 @@ -- | Internal megaparsec parser of 'semverP'. semver' :: Parser SemVer-semver' = p- where p = SemVer <$> major <*> minor <*> patch <*> preRel <*> metaData+semver' = SemVer <$> major <*> minor <*> patch <*> preRel <*> metaData -- | Parse a group of digits, which can't be lead by a 0, unless it is 0. digits :: Parser Int@@ -360,8 +400,18 @@ metaData = (char '+' *> chunks) <|> pure [] chunks :: Parser [VChunk]-chunks = (oneZero <|> many (iunit <|> sunit)) `sepBy` char '.'+chunks = chunk `sepBy` char '.'++-- | Handling @0@ is a bit tricky. We can't allow runs of zeros in a chunk,+-- since a version like @1.000.1@ would parse as @1.0.1@.+chunk :: Parser VChunk+chunk = try zeroWithLetters <|> oneZero <|> many (iunit <|> sunit) where oneZero = (:[]) . Digits . read <$> string "0"+ zeroWithLetters = do+ z <- Digits . read <$> string "0"+ s <- some sunit+ c <- chunk+ pure $ (z : s) ++ c iunit :: Parser VUnit iunit = Digits . read <$> some digitChar
test/Test.hs view
@@ -13,7 +13,7 @@ -- | These don't need to parse as a SemVer. goodVers :: [Text]-goodVers = [ "1", "1.2", "1.58.0-3", "44.0.2403.157-1"+goodVers = [ "1", "1.2", "1.0rc0", "1.0rc1", "1.1rc1", "1.58.0-3", "44.0.2403.157-1" , "0.25-2", "8.u51-1", "21-2", "7.1p1-1", "20150826-1" ] @@ -73,6 +73,7 @@ map (\s -> testCase (unpack s) $ isomorphV s) goodVers , testGroup "Comparisons" $ testCase "1.2-5 < 1.2.3-1" (comp version "1.2-5" "1.2.3-1") :+ testCase "1.0rc1 < 1.0" (comp version "1.0rc1" "1.0") : map (\(a,b) -> testCase (unpack $ a <> " < " <> b) $ comp version a b) (zip cabalOrd (tail cabalOrd) <> zip versionOrd (tail versionOrd)) ]
versions.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack name: versions-version: 3.0.2+version: 3.0.2.1 synopsis: Types and parsers for software version numbers. description: A library for parsing and comparing software version numbers. We like to give version numbers to our software in a myriad of@@ -48,7 +48,7 @@ , text >=1.2 && <1.3 , megaparsec >=4 && <6 default-language: Haskell2010- ghc-options: -fwarn-unused-imports -fwarn-unused-binds+ ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches test-suite versions-test type: exitcode-stdio-1.0@@ -63,4 +63,4 @@ test main-is: Test.hs default-language: Haskell2010- ghc-options: -fwarn-unused-imports -fwarn-unused-binds -threaded+ ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -threaded