salve 0.0.5 → 0.0.6
raw patch · 3 files changed
+118/−34 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Salve.Internal: SCAnd :: SimpleConstraint -> SimpleConstraint -> SimpleConstraint
+ Salve.Internal: SCEQ :: Version -> SimpleConstraint
+ Salve.Internal: SCGT :: Version -> SimpleConstraint
+ Salve.Internal: SCLT :: Version -> SimpleConstraint
+ Salve.Internal: SCOr :: SimpleConstraint -> SimpleConstraint -> SimpleConstraint
+ Salve.Internal: data SimpleConstraint
+ Salve.Internal: instance GHC.Classes.Eq Salve.Internal.SimpleConstraint
+ Salve.Internal: instance GHC.Show.Show Salve.Internal.SimpleConstraint
+ Salve.Internal: mkV :: Word -> Word -> Word -> Version
+ Salve.Internal: satisfiesSC :: SimpleConstraint -> Version -> Bool
+ Salve.Internal: scGE :: Version -> SimpleConstraint
+ Salve.Internal: scLE :: Version -> SimpleConstraint
+ Salve.Internal: toSC :: Constraint -> SimpleConstraint
Files
- library/Salve.hs +53/−1
- library/Salve/Internal.hs +64/−32
- salve.cabal +1/−1
library/Salve.hs view
@@ -30,7 +30,59 @@ -- >>> satisfiesConstraint <$> parseConstraint ">1.2.0" <*> parseVersion "1.2.3" -- Just True +-- * Cheat sheet+-- | If you're coming from Cabal, you might not be familiar with npm's version+-- range syntax. This table shows you how npm version ranges map to Cabal's+-- version constraints.+--+-- > Salve | Cabal | Notes+-- > ----- | ----- | -----+-- > <1.2.3 | <1.2.3 | -+-- > <=1.2.3 | <=1.2.3 | -+-- > =1.2.3 | ==1.2.3 | equals sign is optional+-- > >=1.2.3 | >=1.2.3 | -+-- > >1.2.3 | >1.2.3 | -+-- > 1.2.3 || >1.2.3 | ==1.2.3 || >1.2.3 | lower precedence than and+-- > >=1.2.3 <2.0.0 | >=1.2.3 && <2.0.0 | higher precedence than or+-- > 1.2.3 - 2.3.4 | >=1.2.3 && <=2.3.4 | inclusive ranges+-- > 1.2.x | ==1.2.* | can use X or * instead of x+-- > 1.x.x | ==1.* | -+-- > x.x.x | ==* | same as -any+-- > ~1.2.3 | ^>=1.2.3 | same as >=1.2.3 && <1.3.0+-- > ^1.2.3 | >=1.2.3 && <2 | -+-- > ^0.2.3 | >=0.2.3 && <0.3 | -+-- > ^0.0.3 | >=0.0.3 && <0.0.4 | -+ -- * Rationale++-- ** The PVP+-- | Haskell's <https://pvp.haskell.org/ Package Versioning Policy> (PVP)+-- defines three things:+--+-- 1. A spec for versioning your package, which includes how version numbers+-- look and how to encode breaking changes.+-- 2. A spec for constraining the versions of your dependencies, which+-- incldues how version ranges look.+-- 3. A prescription for how to constrain the versions of your dependencies,+-- which includes how the ranges of your dependencies should be.+--+-- By comparison, Semantic Versioning only deals with the first thing. npm's+-- version ranges only deal with the second thing. This module deals with the+-- first and second things but leaves the third up to you.+--+-- Looking at the first point, why might you want to use SemVer instead of the+-- PVP? The PVP has many problems, as described by the+-- <http://taylor.fausak.me/2016/12/28/problematic-versioning-policy/ Problematic versioning policy>+-- blog post. In short, the PVP is too flexible and it's unique to Haskell,+-- which causes unnecessary friction with developers from other languages.+--+-- Moving on to the second point, why should we use npm's version ranges+-- instead of the PVP's? This is a less clear cut. The two syntaxes are broadly+-- compatible. Really the only gains here are compatibility with a widely-used+-- syntax and convenient shorthand for common constraints (like hyphens+-- @1.2.3 - 2.3.4@, tildes @~1.2.3@, and carets @^1.2.3@).++-- ** Other modules -- | There are already a few modules that provide version numbers. Why do we -- need another one? Let's take a look at the options. --@@ -75,7 +127,7 @@ -- - Intentially allows weird versions. -- - Does not support constraints. ----- By comparison, Salve:+-- By comparison, this module: -- -- - Does not expose constructors. Any version you create can be rendered and -- parsed without issue.
library/Salve/Internal.hs view
@@ -452,29 +452,7 @@ -- >>> satisfiesConstraint <$> parseConstraint ">1.2.0" <*> parseVersion "1.2.3" -- Just True satisfiesConstraint :: Constraint -> Version -> Bool-satisfiesConstraint c v = case c of- ConstraintOperator o w -> case o of- OperatorLT -> v < w- OperatorLE -> v <= w- OperatorEQ -> compare v w == EQ- OperatorGE -> v >= w- OperatorGT -> v > w- OperatorTilde -> (v >= w) && (v < makeVersion (versionMajor w) (versionMinor w + 1) 0 [] [])- OperatorCaret ->- let u =- if versionMajor w == 0- then if versionMinor w == 0- then makeVersion (versionMajor w) (versionMinor w) (versionPatch w + 1) [] []- else makeVersion (versionMajor w) (versionMinor w + 1) 0 [] []- else makeVersion (versionMajor w + 1) 0 0 [] []- in (v >= w) && (v < u)- ConstraintHyphen l r -> (l <= v) && (v <= r)- ConstraintWildcard w -> case w of- WildcardMajor -> True- WildcardMinor m -> (makeVersion m 0 0 [] [] <= v) && (v < makeVersion (m + 1) 0 0 [] [])- WildcardPatch m n -> (makeVersion m n 0 [] [] <= v) && (v < makeVersion m (n + 1) 0 [] [])- ConstraintAnd l r -> satisfiesConstraint l v && satisfiesConstraint r v- ConstraintOr l r -> satisfiesConstraint l v || satisfiesConstraint r v+satisfiesConstraint c v = satisfiesSC (toSC c) v -- | Focuses on the major version number. --@@ -800,15 +778,6 @@ spacesP :: ReadP.ReadP () spacesP = Monad.void (ReadP.munch (== ' ')) --- *** Helpers--parse :: ReadP.ReadP a -> String -> Maybe a-parse p s =- let p' = ReadP.readP_to_S p- in Maybe.listToMaybe (do- (x, "") <- p' s- pure x)- -- ** Rendering renderPreReleases :: [PreRelease] -> String@@ -834,3 +803,66 @@ isWildcard :: Char -> Bool isWildcard c = (c == 'x') || (c == '*') || (c == 'X')++parse :: ReadP.ReadP a -> String -> Maybe a+parse p s =+ let p' = ReadP.readP_to_S p+ in Maybe.listToMaybe (do+ (x, "") <- p' s+ pure x)++-- * Simple constraints+-- | Simple constraints are just as expressive as 'Constraint's, but they are+-- easier to reason about. You can think of them as the desugared version of+-- 'Constraint's.++data SimpleConstraint+ = SCLT Version+ | SCEQ Version+ | SCGT Version+ | SCAnd SimpleConstraint SimpleConstraint+ | SCOr SimpleConstraint SimpleConstraint+ deriving (Eq, Show)++mkV :: Word -> Word -> Word -> Version+mkV m n p = makeVersion m n p [] []++satisfiesSC :: SimpleConstraint -> Version -> Bool+satisfiesSC c v = case c of+ SCLT u -> v < u+ -- This uses `compare` rather than `==` to ignore build metadata.+ SCEQ u -> compare v u == EQ+ SCGT u -> v > u+ SCAnd l r -> satisfiesSC l v && satisfiesSC r v+ SCOr l r -> satisfiesSC l v || satisfiesSC r v++scLE :: Version -> SimpleConstraint+scLE v = SCOr (SCLT v) (SCEQ v)++scGE :: Version -> SimpleConstraint+scGE v = SCOr (SCGT v) (SCEQ v)++toSC :: Constraint -> SimpleConstraint+toSC c = case c of+ ConstraintOperator o v -> case o of+ OperatorLT -> SCLT v+ OperatorLE -> scLE v+ OperatorEQ -> SCEQ v+ OperatorGE -> scGE v+ OperatorGT -> SCGT v+ OperatorTilde -> SCAnd+ (scGE v)+ (SCLT (mkV (versionMajor v) (versionMinor v + 1) 0))+ OperatorCaret -> SCAnd+ (scGE v)+ (SCLT (case (versionMajor v, versionMinor v, versionPatch v) of+ (0, 0, p) -> mkV 0 0 (p + 1)+ (0, n, _) -> mkV 0 (n + 1) 0+ (m, _, _) -> mkV (m + 1) 0 0))+ ConstraintHyphen l h -> SCAnd (scGE l) (scLE h)+ ConstraintWildcard w -> case w of+ WildcardMajor -> scGE initialVersion+ WildcardMinor m -> SCAnd (scGE (mkV m 0 0)) (SCLT (mkV (m + 1) 0 0))+ WildcardPatch m n -> SCAnd (scGE (mkV m n 0)) (SCLT (mkV m (n + 1) 0))+ ConstraintAnd l r -> SCAnd (toSC l) (toSC r)+ ConstraintOr l r -> SCOr (toSC l) (toSC r)
salve.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack name: salve-version: 0.0.5+version: 0.0.6 synopsis: Semantic version numbers and constraints. description: Salve provides semantic version (SemVer) numbers and constraints (ranges). category: Distribution