versions 3.0.2.1 → 3.1.0
raw patch · 5 files changed
+53/−25 lines, 5 files
Files
- CHANGELOG.md +8/−1
- Data/Versions.hs +40/−14
- README.md +0/−1
- test/Test.hs +4/−6
- versions.cabal +1/−3
CHANGELOG.md view
@@ -1,9 +1,16 @@ Changelog ========= -3.0.2+3.1.0 -----+- Added support for *epoch* numbers in the `Version` type. These are numbers+ like the `1:` in `1:2.3.4`. These are used in Arch Linux in rare cases where+ packages change their versioning scheme, but need a reliable integer prefix+ to establish ordering. The `Version` type has been given a new field,+ `_vEpoch :: Maybe Int`, and a corresponding lens, `vEpoch`. +3.0.2+----- - Expose internal parsers so that they could be used in other parser programs that parse version numbers in larger files.
Data/Versions.hs view
@@ -79,6 +79,7 @@ , svPreRel , svMeta -- ** (General) Version Lenses+ , vEpoch , vChunks , vRel -- ** Misc. Lenses / Traversals@@ -121,11 +122,12 @@ -- | Convert a `SemVer` to a `Version`. vFromS :: SemVer -> Version-vFromS (SemVer m i p r _) = Version [[Digits m], [Digits i], [Digits p]] r+vFromS (SemVer m i p r _) = Version Nothing [[Digits m], [Digits i], [Digits p]] r -- | Convert a `Version` to a `Mess`. mFromV :: Version -> Mess-mFromV (Version v r) = VNode (chunksAsT v) VHyphen $ VLeaf (chunksAsT r)+mFromV (Version e v r) = maybe affix (\a -> VNode [showt a] VColon affix) e+ where affix = VNode (chunksAsT v) VHyphen $ VLeaf (chunksAsT r) -- | Traverse some Text for its inner versioning. --@@ -259,31 +261,47 @@ -- | 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.+-- 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-data Version = Version { _vChunks :: [VChunk]+-- Examples of @Version@ that are not @SemVer@: 0.25-2, 8.u51-1, 20150826-1, 1:2.3.4+data Version = Version { _vEpoch :: Maybe Int+ , _vChunks :: [VChunk] , _vRel :: [VChunk] } deriving (Eq,Show) +-- | Set a `Version`'s epoch to `Nothing`.+wipe :: Version -> Version+wipe v = v { _vEpoch = Nothing }+ -- | Customized. instance Ord Version where -- | The obvious base case.- compare (Version [] []) (Version [] []) = EQ+ compare (Version _ [] []) (Version _ [] []) = EQ + -- | For the purposes of Versions with epochs, `Nothing` is the same as `Just 0`,+ -- so we need to compare their actual version numbers.+ compare v0@(Version (Just 0) _ _) v1@(Version Nothing _ _) = compare (wipe v0) v1+ compare v0@(Version Nothing _ _) v1@(Version (Just 0) _ _) = compare v0 (wipe v1)++ -- | If two epochs are equal, we need to compare their actual version numbers.+ -- Otherwise, the comparison of the epochs is the only thing that matters.+ compare v0@(Version (Just n) _ _) v1@(Version (Just m) _ _) | n == m = compare (wipe v0) (wipe v1)+ | otherwise = compare n m+ -- | 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' [])+ compare (Version _ [] rs) (Version _ [] rs') = compare (Version Nothing rs []) (Version Nothing 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+ 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')+ compare (Version _ (a:as) rs) (Version _ (b:bs) rs') = case f a b of+ EQ -> compare (Version Nothing as rs) (Version Nothing bs rs') res -> res where f [] [] = EQ @@ -306,6 +324,10 @@ f (Digits _ :_) (Str _ :_) = GT f (Str _ :_ ) (Digits _ :_) = LT +-- | > vEpoch :: Lens' Version (Maybe Int)+vEpoch :: Functor f => (Maybe Int -> f (Maybe Int)) -> Version -> f Version+vEpoch f v = fmap (\ve -> v { _vEpoch = ve }) (f $ _vEpoch v)+ -- | > vChunks :: Lens' Version [VChunk] vChunks :: Functor f => ([VChunk] -> f [VChunk]) -> Version -> f Version vChunks f v = fmap (\vc -> v { _vChunks = vc }) (f $ _vChunks v)@@ -313,7 +335,7 @@ -- | > vRel :: Lens' Version [VChunk] vRel :: Functor f => ([VChunk] -> f [VChunk]) -> Version -> f Version-vRel f v = fmap (\vc -> v { _vRel = vc }) (f $ _vRel v)+vRel f v = fmap (\vr -> v { _vRel = vr }) (f $ _vRel v) {-# INLINE vRel #-} -- | A (Complex) Mess.@@ -429,8 +451,11 @@ -- | Internal megaparsec parser of 'versionP'. version' :: Parser Version-version' = Version <$> chunks <*> preRel+version' = Version <$> optional (try epoch) <*> chunks <*> preRel +epoch :: Parser Int+epoch = read <$> (some digitChar <* char ':')+ -- | A wrapped `Mess` parser. Can be composed with other parsers. messP :: VParser messP = VParser $ fmap Complex . mess@@ -479,9 +504,10 @@ -- | Convert a `Version` back to its textual representation. prettyVer :: Version -> Text-prettyVer (Version cs pr) = mconcat $ ver <> pr'+prettyVer (Version ep cs pr) = ep' <> mconcat (ver <> pr') where ver = intersperse "." $ chunksAsT cs pr' = foldable [] ("-" :) $ intersperse "." (chunksAsT pr)+ ep' = maybe "" (\e -> showt e <> ":") ep -- | Convert a `Mess` back to its textual representation. prettyMess :: Mess -> Text
README.md view
@@ -2,7 +2,6 @@ ======== [](https://travis-ci.org/fosskers/versions)-[](https://coveralls.io/github/aurapm/haskell-versions?branch=master) [](https://hackage.haskell.org/package/versions) [](http://stackage.org/nightly/package/versions) [](http://stackage.org/lts/package/versions)
test/Test.hs view
@@ -14,13 +14,11 @@ -- | These don't need to parse as a SemVer. goodVers :: [Text] 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"+ , "0.25-2", "8.u51-1", "21-2", "7.1p1-1", "20150826-1", "1:0.10.16-3" ] messes :: [Text]-messes = [ "10.2+0.93+1-1", "003.03-3", "002.000-7", "1:0.10.16-3"- , "20.26.1_0-2"- ]+messes = [ "10.2+0.93+1-1", "003.03-3", "002.000-7", "20.26.1_0-2" ] messComps :: [Text] messComps = [ "10.2+0.93+1-1", "10.2+0.93+1-2", "10.2+0.93+2-1"@@ -91,8 +89,8 @@ , testCase "1.2.3-1+1 is SemVer" $ check $ isSemVer <$> parseV "1.2.3-1+1" , testCase "1.2.3r1 is Version" $ check $ isVersion <$> parseV "1.2.3r1" , testCase "0.25-2 is Version" $ check $ isVersion <$> parseV "0.25-2"+ , testCase "1:1.2.3-1 is Version" $ check $ isVersion <$> parseV "1:1.2.3-1" , testCase "1.2.3+1-1 is Mess" $ check $ isMess <$> parseV "1.2.3+1-1"- , testCase "1:1.2.3-1 is Mess" $ check $ isMess <$> parseV "1:1.2.3-1" , testCase "000.007-1 is Mess" $ check $ isMess <$> parseV "000.007-1" , testCase "20.26.1_0-2 is Mess" $ check $ isMess <$> parseV "20.26.1_0-2" ]@@ -155,7 +153,7 @@ -- | Nothing should happen. noInc :: Assertion noInc = (v & _Ideal . svPatch %~ (+ 1)) @?= v- where v = General $ Version [] []+ where v = General $ Version Nothing [] [] incFromT :: Assertion incFromT = ("1.2.3" & _Versioning . _Ideal . svPatch %~ (+ 1)) @?= "1.2.4"
versions.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack name: versions-version: 3.0.2.1+version: 3.1.0 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@@ -41,8 +41,6 @@ library exposed-modules: Data.Versions- other-modules:- Paths_versions build-depends: base >=4.8 && <4.10 , text >=1.2 && <1.3