packages feed

semver 0.1.2 → 0.2.0

raw patch · 3 files changed

+114/−57 lines, 3 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

- Data.SemVer: Delimiters :: !Char -> !Char -> !Char -> !Char -> !Char -> Delimiters
- Data.SemVer: INum :: !Int -> Identifier
- Data.SemVer: IText :: !Text -> Identifier
- Data.SemVer: Version :: !Int -> !Int -> !Int -> [Identifier] -> [Identifier] -> Version
- Data.SemVer: _delimIdent :: Delimiters -> !Char
- Data.SemVer: _delimMeta :: Delimiters -> !Char
- Data.SemVer: _delimMinor :: Delimiters -> !Char
- Data.SemVer: _delimPatch :: Delimiters -> !Char
- Data.SemVer: _delimRelease :: Delimiters -> !Char
- Data.SemVer: _versionMajor :: Version -> !Int
- Data.SemVer: _versionMeta :: Version -> [Identifier]
- Data.SemVer: _versionMinor :: Version -> !Int
- Data.SemVer: _versionPatch :: Version -> !Int
- Data.SemVer: _versionRelease :: Version -> [Identifier]
- Data.SemVer: defaultDelimiters :: Delimiters
- Data.SemVer: defaultVersion :: Version
- Data.SemVer: instance Constructor C1_0Delimiters
- Data.SemVer: instance Constructor C1_0Identifier
- Data.SemVer: instance Constructor C1_0Version
- Data.SemVer: instance Constructor C1_1Identifier
- Data.SemVer: instance Datatype D1Delimiters
- Data.SemVer: instance Datatype D1Identifier
- Data.SemVer: instance Datatype D1Version
- Data.SemVer: instance Generic Delimiters
- Data.SemVer: instance Generic Identifier
- Data.SemVer: instance Generic Version
- Data.SemVer: instance Read Delimiters
- Data.SemVer: instance Read Identifier
- Data.SemVer: instance Read Version
- Data.SemVer: instance Selector S1_0_0Delimiters
- Data.SemVer: instance Selector S1_0_0Version
- Data.SemVer: instance Selector S1_0_1Delimiters
- Data.SemVer: instance Selector S1_0_1Version
- Data.SemVer: instance Selector S1_0_2Delimiters
- Data.SemVer: instance Selector S1_0_2Version
- Data.SemVer: instance Selector S1_0_3Delimiters
- Data.SemVer: instance Selector S1_0_3Version
- Data.SemVer: instance Selector S1_0_4Delimiters
- Data.SemVer: instance Selector S1_0_4Version
- Data.SemVer: instance Typeable Delimiters
- Data.SemVer: instance Typeable Identifier
- Data.SemVer: instance Typeable Version
+ Data.SemVer: _Numeric :: Applicative f => (Int -> f Int) -> Identifier -> f Identifier
+ Data.SemVer: _Textual :: Applicative f => (Text -> f Text) -> Identifier -> f Identifier
+ Data.SemVer: delimiters :: Delimiters
+ Data.SemVer: initial :: Version
+ Data.SemVer: numeric :: Int -> Identifier
+ Data.SemVer: textual :: Text -> Maybe Identifier
+ Data.SemVer: version :: Int -> Int -> Int -> [Identifier] -> [Identifier] -> Version

Files

semver.cabal view
@@ -1,5 +1,5 @@ name:                  semver-version:               0.1.2+version:               0.2.0 synopsis:              Representation, manipulation, and de/serialisation of Semantic Versions. homepage:              https://github.com/brendanhay/semver license:               OtherLicense
src/Data/SemVer.hs view
@@ -1,7 +1,5 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric      #-}-{-# LANGUAGE OverloadedStrings  #-}-{-# LANGUAGE RecordWildCards    #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards   #-}  -- Module      : Data.SemVer -- Copyright   : (c) 2014 Brendan Hay <brendan.g.hay@gmail.com>@@ -17,56 +15,62 @@ -- <http://semver.org>. -- -- A canonical 'Version' type and functions representing behaviour as outlined--- in the specification are defined alongside additional lenses,+-- in the specification are defined alongside additional lenses, traversals, -- common manipulations, and serialisation primitives. module Data.SemVer     (     -- * Version-      Identifier (..)-    , Version    (..)-    , defaultVersion-+      Version+    -- ** Constructors+    , version+    , initial     -- ** Lenses+    -- $lenses     , versionMajor     , versionMinor     , versionPatch     , versionRelease     , versionMeta-     -- ** Incrementing+    -- $incrementing     , incrementMajor     , incrementMinor     , incrementPatch-     -- ** Predicates     , isDevelopment     , isPublic-     -- ** Encoding     , toString     , toText     , toLazyText     , toBuilder-     -- ** Decoding     , fromText     , fromLazyText     , parser -    -- * Delimiters-    , Delimiters (..)-    , defaultDelimiters+    -- * Identifiers+    , Identifier+    -- ** Constructors+    , numeric+    , textual+    -- ** Prisms+    , _Numeric+    , _Textual +    -- * Delimiters+    -- $delimiters+    , Delimiters+    -- ** Constructor+    , delimiters     -- ** Lenses     , delimMinor     , delimPatch     , delimRelease     , delimMeta     , delimIdent-     -- ** Encoding     , toDelimitedBuilder-     -- ** Decoding     , delimitedParser     ) where@@ -85,8 +89,6 @@ import           Data.Text.Lazy.Builder     (Builder) import qualified Data.Text.Lazy.Builder     as Build import qualified Data.Text.Lazy.Builder.Int as Build-import           Data.Typeable              (Typeable)-import           GHC.Generics import           Prelude                    hiding (takeWhile)  -- | A type representing an individual identifier from the release@@ -95,11 +97,35 @@ -- * The 'Ord' instance implements precedence according to the semantic version -- specification, with numeric identifiers being of /lower/ precedence than -- textual identifiers, otherwise lexicographic ordering is used.+--+-- The functions 'numeric' and 'textual' can be used to construct an 'Identifier'. data Identifier     = INum  !Int     | IText !Text-      deriving (Eq, Read, Show, Generic, Typeable)+      deriving (Eq, Show) +-- | Safely construct a numeric identifier.+numeric :: Int -> Identifier+numeric = INum+{-# INLINE numeric #-}++-- | Construct an identifier from the given 'Text', returning 'Nothing' if+-- neither a numeric or valid textual input is supplied.+textual :: Text -> Maybe Identifier+textual = either (const Nothing) Just+    . parseOnly (identifierParser endOfInput <* endOfInput)+{-# INLINE textual #-}++_Numeric :: Applicative f => (Int -> f Int) -> Identifier -> f Identifier+_Numeric f (INum x) = INum <$> f x+_Numeric _ x        = pure x+{-# INLINE _Numeric #-}++_Textual :: Applicative f => (Text -> f Text) -> Identifier -> f Identifier+_Textual f (IText x) = IText <$> f x+_Textual _ x         = pure x+{-# INLINE _Textual #-}+ instance Ord Identifier where     compare a b = case (a, b) of         (INum  x, INum  y) -> x `compare` y@@ -111,31 +137,38 @@     rnf (INum  n) = rnf n     rnf (IText t) = rnf t --- | A type representing a successfully decoded or constructed semantic version.+-- | An opaque type representing a successfully decoded or constructed+-- semantic version. See the related functions and lenses for modification and+-- update. -- -- * The 'Eq' instance represents exhaustive equality with all -- components considered. -- -- * The 'Ord' instance implements the precedence rules from the semantic--- version specification with metadata ('_versionMeta') being ignored.+-- version specification with metadata being ignored. data Version = Version     { _versionMajor   :: !Int-     -- ^ The major version component.     , _versionMinor   :: !Int-      -- ^ The minor version component.     , _versionPatch   :: !Int-      -- ^ The patch level component.     , _versionRelease :: [Identifier]-      -- ^ A (potentially empty) list of release identifiers.     , _versionMeta    :: [Identifier]-      -- ^ A (potentially empty) list of metadata.-    } deriving (Eq, Read, Show, Generic, Typeable)+    } deriving (Eq, Show) +-- | Smart constructor fully specifying all available version components.+version :: Int          -- ^ Major version component.+        -> Int          -- ^ Minor version component.+        -> Int          -- ^ Patch version component.+        -> [Identifier] -- ^ Release identifiers.+        -> [Identifier] -- ^ Metadata identifiers.+        -> Version+version = Version+{-# INLINE version #-}+ -- | A default 'Version' which can be used to signify initial development. -- -- Note: Equivalent to @0.0.0@-defaultVersion :: Version-defaultVersion = Version 0 0 0 [] []+initial :: Version+initial = version 0 0 0 [] []  instance Ord Version where     compare a b = on compare versions a b <> on compare _versionRelease a b@@ -154,18 +187,27 @@         `seq` rnf _versionRelease         `seq` rnf _versionMeta +-- $lenses+--+-- Something about using lenses to construct versions and increments to update+-- the version components due to the modification of all version according to spec++-- | Lens for the major version component. versionMajor :: Functor f => (Int -> f Int) -> Version -> f Version versionMajor f x = (\y -> x { _versionMajor = y }) <$> f (_versionMajor x) {-# INLINE versionMajor #-} +-- | Lens for minor version component. versionMinor :: Functor f => (Int -> f Int) -> Version -> f Version versionMinor f x = (\y -> x { _versionMinor = y }) <$> f (_versionMinor x) {-# INLINE versionMinor #-} +-- | Lens for the patch version component. versionPatch :: Functor f => (Int -> f Int) -> Version -> f Version versionPatch f x = (\y -> x { _versionPatch = y }) <$> f (_versionPatch x) {-# INLINE versionPatch #-} +-- | Lens for the list of release identifiers. versionRelease :: Functor f                => ([Identifier] -> f [Identifier])                -> Version@@ -173,6 +215,7 @@ versionRelease f x = (\y -> x { _versionRelease = y }) <$> f (_versionRelease x) {-# INLINE versionRelease #-} +-- | Lens for the list of metadata identifiers. versionMeta :: Functor f             => ([Identifier] -> f [Identifier])             -> Version@@ -180,15 +223,18 @@ versionMeta f x = (\y -> x { _versionMeta = y }) <$> f (_versionMeta x) {-# INLINE versionMeta #-} --- | A set of delimiters used to encode/decode a 'Version' and specifyc+-- $delimiters+--+-- A set of delimiters is used to encode/decode a 'Version' and specify -- alternative serialisation strategies. ----- Example: using alpha characters to encode the version as a valid--- DNS CNAME, such as:+-- Lenses can be used to modify the default delimiter set, as in the following+-- example - using alpha characters to encode the version as a valid+-- DNS CNAME: -- -- @ -- let Right v = fromText "1.2.3+40"--- let alpha   = Delimiters \'m\' \'p\' \'r\' \'d\' \'i\'+-- let alpha = delimiters & delimMajor .= \'m\' & delimPatch .= \'p\' & delimRelease .= \'r\' & delimMeta .= \'d\' & delimIdent .= \'i\' -- -- Data.Text.Lazy.Builder.toLazyText (\"app01-\" <> toDelimitedBuilder alpha v <> \".dmz.internal\") -- @@@ -201,13 +247,16 @@ -- -- Using the same 'Delimiters' set with 'delimitedParser' would ensure -- correct decoding behaviour.++-- | An opaque set representing the seperators used to delimit semantic+-- version components. data Delimiters = Delimiters     { _delimMinor   :: !Char     , _delimPatch   :: !Char     , _delimRelease :: !Char     , _delimMeta    :: !Char     , _delimIdent   :: !Char-    } deriving (Eq, Ord, Read, Show, Generic, Typeable)+    } deriving (Eq, Ord, Show)  -- | The default set of delimiters used in the semantic version specification. --@@ -217,8 +266,8 @@ -- @ -- 1.2.3-alpha.1+sha.exp.12ab3d9 -- @-defaultDelimiters :: Delimiters-defaultDelimiters = Delimiters+delimiters :: Delimiters+delimiters = Delimiters     { _delimMinor   = '.'     , _delimPatch   = '.'     , _delimRelease = '-'@@ -234,26 +283,36 @@         `seq` rnf _delimMeta         `seq` rnf _delimIdent +-- | Lens for the minor version delimiter. Default: @.@ delimMinor :: Functor f => (Char -> f Char) -> Delimiters -> f Delimiters delimMinor f x = (\y -> x { _delimMinor = y }) <$> f (_delimMinor x) {-# INLINE delimMinor #-} +-- | Lens for the patch version delimiter. Default: @.@ delimPatch :: Functor f => (Char -> f Char) -> Delimiters -> f Delimiters delimPatch f x = (\y -> x { _delimPatch = y }) <$> f (_delimPatch x) {-# INLINE delimPatch #-} +-- | Lens for the release component delimiter. Default: @-@ delimRelease :: Functor f => (Char -> f Char) -> Delimiters -> f Delimiters delimRelease f x = (\y -> x { _delimRelease = y }) <$> f (_delimRelease x) {-# INLINE delimRelease #-} +-- | Lens for the metadata component delimiter. Default: @+@ delimMeta :: Functor f => (Char -> f Char) -> Delimiters -> f Delimiters delimMeta f x = (\y -> x { _delimMeta = y }) <$> f (_delimMeta x) {-# INLINE delimMeta #-} +-- | Lens for the individual identifier delimiter. Default: @.@ delimIdent :: Functor f => (Char -> f Char) -> Delimiters -> f Delimiters delimIdent f x = (\y -> x { _delimIdent = y }) <$> f (_delimIdent x) {-# INLINE delimIdent #-} +-- $increments+--+-- Mention the usage of increments to correctly adjust version components+-- according to spec.+ -- | Increment the major component of a 'Version' by 1, resetting the minor -- and patch components. --@@ -326,7 +385,7 @@ -- Note: This is optimised for cases where you wish to use a 'String' and -- as such is faster than the semantically equivalent @unpack . toLazyText@. toString :: Version -> String-toString = toMonoid (:[]) show Text.unpack defaultDelimiters+toString = toMonoid (:[]) show Text.unpack delimiters  -- | Convert a 'Version' to a strict 'Text' representation. --@@ -345,7 +404,7 @@  -- | Convert a 'Version' to a 'Builder'. toBuilder :: Version -> Builder-toBuilder = toDelimitedBuilder defaultDelimiters+toBuilder = toDelimitedBuilder delimiters  -- | Convert a 'Version' to a 'Builder' using the specified 'Delimiters' set. toDelimitedBuilder :: Delimiters -> Version -> Builder@@ -390,7 +449,7 @@  -- | A greedy attoparsec 'Parser' which requires the entire 'Text' input to match. parser :: Parser Version-parser = delimitedParser defaultDelimiters+parser = delimitedParser delimiters  -- | A greedy attoparsec 'Parser' using the specified 'Delimiters' set -- which requires the entire 'Text' input to match.@@ -403,20 +462,18 @@     <*> option [] (try (char _delimMeta)    *> identifiers)     <*  endOfInput   where-    nonNegative :: (Show a, Integral a) => Parser a-    nonNegative = do-        n <- decimal-        when (n < 0) $-            fail ("Numeric value must be non-negative: " ++ show n)-        return n-     identifiers :: Parser [Identifier]-    identifiers = many (num <|> text)+    identifiers = many (identifierParser $ void (char _delimIdent)) -    num = INum-        <$> nonNegative-        <*  (void (char _delimIdent) <|> endOfInput)+identifierParser :: Parser () -> Parser Identifier+identifierParser end = num <|> text+  where+    num  = INum  <$> nonNegative <* (end <|> endOfInput)+    text = IText <$> takeWhile1 (inClass "0-9A-Za-z-") <* optional end -    text = IText-        <$> takeWhile1 (inClass "0-9A-Za-z-")-        <*  optional (char _delimIdent)+nonNegative :: (Show a, Integral a) => Parser a+nonNegative = do+    n <- decimal+    when (n < 0) $+        fail ("Numeric value must be non-negative: " ++ show n)+    return n
test/Main.hs view
@@ -59,7 +59,7 @@  sv000, sv100, sv100alpha, sv100alpha1, sv101   :: Version sv110, sv200, sv123sha2ac, sv123beta1shaexpdc2 :: Version-sv000               = defaultVersion+sv000               = initial sv100               = sv "1.0.0" sv100alpha          = sv "1.0.0-alpha" sv100alpha1         = sv "1.0.0-alpha.1"