staversion 0.1.4.0 → 0.2.0.0
raw patch · 5 files changed
+155/−38 lines, 5 filesdep ~aesondep ~megaparsecPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: aeson, megaparsec
API changes (from Hackage documentation)
- Staversion.Internal.Aggregate: aggPvp :: Aggregator
+ Staversion.Internal.Aggregate: aggPvpMajor :: Aggregator
+ Staversion.Internal.Aggregate: aggPvpMinor :: Aggregator
Files
- ChangeLog.md +11/−0
- src/Staversion/Internal/Aggregate.hs +37/−10
- src/Staversion/Internal/Command.hs +13/−4
- staversion.cabal +3/−3
- test/Staversion/Internal/AggregateSpec.hs +91/−21
ChangeLog.md view
@@ -1,5 +1,16 @@ # Revision history for staversion +## 0.2.0.0 -- 2017-05-14++* [breaking change] `pvp` aggregator now does "trailing-zero+ normalization". For example, it now assumes versions "2.2" and+ "2.2.0.0" are practically the same (#2).+* Add `pvp-major` aggregator, which is just an alias for `pvp`+ aggregator.+* Add `pvp-minor` aggregator, which is similar to `pvp-major` but it+ uses minor versions for upper bounds (#2).++ ## 0.1.4.0 -- 2017-04-08 * Add `--aggregate` option, which aggregates versions in different LTS resolvers.
src/Staversion/Internal/Aggregate.hs view
@@ -12,7 +12,8 @@ VersionRange, showVersionRange, aggOr,- aggPvp,+ aggPvpMajor,+ aggPvpMinor, -- * Utility groupAllPreservingOrderBy, -- * Low-level functions@@ -29,6 +30,7 @@ import Data.Maybe (fromJust) import Data.Monoid (mconcat, All(All)) import Data.List (lookup)+import qualified Data.List as List import Data.List.NonEmpty (NonEmpty(..)) import qualified Data.List.NonEmpty as NL import Data.Text (unpack)@@ -67,15 +69,40 @@ aggOr :: Aggregator aggOr = foldr1 V.unionVersionRanges . fmap V.thisVersion . NL.nub . NL.sort --- | Aggregate versions to the range that the versions cover in a--- (strict) PVP sense.-aggPvp :: Aggregator-aggPvp = V.simplifyVersionRange . foldr1 V.unionVersionRanges . fmap toRange . NL.nub . NL.sort where- toRange v = fromJust $ fmap V.fromVersionIntervals $ V.mkVersionIntervals [(V.LowerBound v V.InclusiveBound, V.UpperBound vu V.ExclusiveBound)] where- vu = makeVersion $ case V.versionBranch v of- [] -> error "versionBranch must not be empty."- [x] -> [x, 0]- (x : y : _) -> [x, y + 1]+-- | Aggregate versions to the range that the versions cover in a PVP+-- sense. This aggregator sets the upper bound to a major version,+-- which means it assumes major-version bump is not+-- backward-compatible.+aggPvpMajor :: Aggregator+aggPvpMajor = aggPvpGeneral $ makeUpper where+ makeUpper [] = error "version must not be empty."+ makeUpper [x] = [x, 1] -- because [x] and [x,0] is equivalent+ makeUpper (x : y : _) = [x, y + 1]++-- | Aggregate versions to the range that versions cover in a PVP+-- sense. This aggregator sets the upper bound to a minor version,+-- which means it assumes minor-version bump is not+-- backward-compatible.+aggPvpMinor :: Aggregator+aggPvpMinor = aggPvpGeneral $ makeUpper where+ makeUpper [] = error "version must not be empty."+ makeUpper [x] = [x, 0, 1]+ makeUpper [x,y] = [x, y, 1]+ makeUpper (x : y : z : _) = [x, y, z + 1]++aggPvpGeneral :: ([Int] -> [Int]) -> Aggregator+aggPvpGeneral makeUpper = V.simplifyVersionRange . foldr1 V.unionVersionRanges . fmap toRange . NL.nub . NL.sort where+ toRange v = fromJust $ fmap V.fromVersionIntervals $ V.mkVersionIntervals [(V.LowerBound norm_v V.InclusiveBound, V.UpperBound vu V.ExclusiveBound)] where+ norm_v = makeVersion $ normalizeTralingZeroes $ V.versionBranch v+ vu = makeVersion $ makeUpper $ V.versionBranch norm_v++normalizeTralingZeroes :: [Int] -> [Int]+normalizeTralingZeroes [] = []+normalizeTralingZeroes (head_v : rest) = head_v : (concat $ dropTrailingZeros $ List.group rest) where+ dropTrailingZeros [] = []+ dropTrailingZeros groups = if and $ map (== 0) $ last groups+ then init groups+ else groups -- | Aggregate 'Result's with the given 'Aggregator'. It first groups -- 'Result's based on its 'resultFor' field, and then each group is
src/Staversion/Internal/Command.hs view
@@ -123,10 +123,19 @@ aggregators :: [AggregatorSpec] aggregators = [ AggregatorSpec Agg.aggOr "or" "concatenate versions with (||).",- AggregatorSpec Agg.aggPvp "pvp" ( "aggregate versions to a range that is supposed to be "- ++ "compatible with the given versions "- ++ "in terms of PVP (Package Versioning Policy.)"- )+ AggregatorSpec Agg.aggPvpMajor "pvp-major"+ ( "aggregate versions to a range that is supposed to be "+ ++ "compatible with the given versions "+ ++ "in terms of PVP (Package Versioning Policy.) "+ ++ "Major versions are used for upper bounds."+ ),+ AggregatorSpec Agg.aggPvpMajor "pvp" "alias for 'pvp-major'",+ AggregatorSpec Agg.aggPvpMinor "pvp-minor"+ ( "aggregate versions to a range that is supposed to be "+ ++ "compatible with the given versions "+ ++ "in terms of PVP. "+ ++ "Minor versions are used for upper bounds, i.e. this is stricter than 'pvp-major'."+ ) ] parseAggregator :: String -> Maybe Aggregator
staversion.cabal view
@@ -1,5 +1,5 @@ name: staversion-version: 0.1.4.0+version: 0.2.0.0 author: Toshio Ito <debug.ito@gmail.com> maintainer: Toshio Ito <debug.ito@gmail.com> license: BSD3@@ -47,7 +47,7 @@ Staversion.Internal.HTTP build-depends: base >=4.8 && <4.10, unordered-containers >=0.2.3 && <0.3,- aeson >=0.8.0 && <1.2,+ aeson >=0.8.0 && <1.3, text >=0.11.3 && <1.3, bytestring >=0.10.0 && <0.11, yaml >=0.8.3 && <0.9,@@ -60,7 +60,7 @@ http-types >=0.8.6 && <0.10, transformers >=0.3.0 && <0.6, transformers-compat >=0.4.0 && <0.6,- megaparsec >=4.2.0 && <5.3,+ megaparsec >=4.2.0 && <5.4, semigroups >=0.18.0.1 && <0.19, Cabal >=1.22.6.0 && <1.25, pretty >=1.1.2.0 && <1.2,
test/Staversion/Internal/AggregateSpec.hs view
@@ -13,7 +13,8 @@ ( Aggregator, showVersionRange, aggOr,- aggPvp,+ aggPvpMajor,+ aggPvpMinor, aggregateResults, aggregatePackageVersions )@@ -36,7 +37,8 @@ spec_aggregateResults describe "Aggregators" $ do spec_or- spec_pvp+ spec_pvpMajor+ spec_pvpMinor vor :: V.VersionRange -> V.VersionRange -> V.VersionRange vor = V.unionVersionRanges@@ -88,34 +90,102 @@ vint vl vu = fromJust $ fmap V.fromVersionIntervals $ V.mkVersionIntervals [interval] where interval = (V.LowerBound (ver vl) V.InclusiveBound, V.UpperBound (ver vu) V.ExclusiveBound) -spec_pvp :: Spec-spec_pvp = describe "aggPvp" $ before (return aggPvp) $ do+spec_pvpMajor :: Spec+spec_pvpMajor = describe "aggPvpMajor" $ before (return aggPvpMajor) $ do testAgg [[1,2,0,7]] $ vint [1,2,0,7] [1,3]- testAgg [[1,2,0]] $ vint [1,2,0] [1,3]+ testAgg [[1,2,3,0]] $ vint [1,2,3] [1,3] -- trailing-zero+ testAgg [[1,2,0,0]] $ vint [1,2] [1,3] -- trailing-zeroes+ testAgg [[1,2,10]] $ vint [1,2,10] [1,3]+ testAgg [[1,2,0]] $ vint [1,2] [1,3] -- trailing-zero testAgg [[1,2]] $ vint [1,2] [1,3]- testAgg [[1]] $ vint [1] [1,0]- testAgg [[1,2,0,0], [1,2,3,0]] $ vint [1,2,0,0] [1,3]- testAgg [[1,2,0,0], [1,2,0,0]] $ vint [1,2,0,0] [1,3]- testAgg [[1,2,0,0], [1,3]] $ vint [1,2,0,0] [1,4]- testAgg [[1,2,0,0], [1,3,0]] $ vors' [ vint [1,2,0,0] [1,3],- vint [1,3,0] [1,4]+ testAgg [[1,0]] $ vint [1] [1,1] -- trailing-zero+ testAgg [[1,0,0,0]] $ vint [1] [1,1] -- traling-zeroes+ testAgg [[1]] $ vint [1] [1,1] -- because 1 and 1.0 are considered equivalent.+ testAgg [[0]] $ vint [0] [0,1]+ testAgg [[0,0]] $ vint [0] [0,1]+ testAgg [[0,0,0]] $ vint [0] [0,1]+ testAgg [[0,0,1]] $ vint [0,0,1] [0,1]+ testAgg [[1,2,0,7], [1,2,3,0]] $ vint [1,2,0,7] [1,3]+ testAgg [[1,2,0,7], [1,2,0,7]] $ vint [1,2,0,7] [1,3]+ testAgg [[1,2,0,7], [1,3]] $ vint [1,2,0,7] [1,4]+ testAgg [[1,2,0,7], [1,3,4]] $ vors' [ vint [1,2,0,7] [1,3],+ vint [1,3,4] [1,4] ]- testAgg [[1,3,0], [1,2,0,0]] $ vors' [ vint [1,2,0,0] [1,3],- vint [1,3,0] [1,4]+ testAgg [[1,2,0,7], [1,3,0]] $ vint [1,2,0,7] [1,4] -- trailing-zero+ testAgg [[1,3,4], [1,2,0,7]] $ vors' [ vint [1,2,0,7] [1,3],+ vint [1,3,4] [1,4] ]- testAgg [[1,2,0,0], [1,3,0,0]] $ vors' [ vint [1,2,0,0] [1,3],- vint [1,3,0,0] [1,4]+ testAgg [[1,3,0], [1,2,0,7]] $ vint [1,2,0,7] [1,4]+ testAgg [[1,2,0,7], [1,3,0,8]] $ vors' [ vint [1,2,0,7] [1,3],+ vint [1,3,0,8] [1,4] ]- testAgg [[1,3,0,0], [1,2,0,0]] $ vors' [ vint [1,2,0,0] [1,3],- vint [1,3,0,0] [1,4]+ testAgg [[1,2,0,0], [1,3,0,0]] $ vint [1,2] [1,4] -- trailing-zeroes+ testAgg [[1,3,0,8], [1,2,0,7]] $ vors' [ vint [1,2,0,7] [1,3],+ vint [1,3,0,8] [1,4] ]- testAgg [[1,2,0,0], [2]] $ vors' [ vint [1,2,0,0] [1,3],- vint [2] [2,0]+ testAgg [[1,2,0,7], [2]] $ vors' [ vint [1,2,0,7] [1,3],+ vint [2] [2,1] ]- testAgg [[2,2,0], [2,0], [3,5,0,1], [2,2,0,5]] $ vors' [ vint [2,0] [2,1],- vint [2,2,0] [2,3],+ testAgg [[2,2,0], [2,0], [3,5,0,1], [2,2,0,5]] $ vors' [ vint [2] [2,1],+ vint [2,2] [2,3], vint [3,5,0,1] [3,6] ]+++spec_pvpMinor :: Spec+spec_pvpMinor = describe "aggPvpMinor" $ before (return aggPvpMinor) $ do+ testAgg [[1,2,0,7]] $ vint [1,2,0,7] [1,2,1]+ testAgg [[1,2,3,0]] $ vint [1,2,3] [1,2,4] -- trailing-zero+ testAgg [[1,2,0,0]] $ vint [1,2] [1,2,1] -- trailing-zeroes+ testAgg [[1,2,10]] $ vint [1,2,10] [1,2,11]+ testAgg [[1,2,0]] $ vint [1,2] [1,2,1] -- trailing-zero+ testAgg [[1,2]] $ vint [1,2] [1,2,1]+ testAgg [[1,0]] $ vint [1] [1,0,1] -- trailing-zero+ testAgg [[1,0,0,0]] $ vint [1] [1,0,1] -- traling-zeroes+ testAgg [[1]] $ vint [1] [1,0,1] -- because 1 and 1.0 are considered equivalent.+ testAgg [[0]] $ vint [0] [0,0,1]+ testAgg [[0,0]] $ vint [0] [0,0,1]+ testAgg [[0,0,0]] $ vint [0] [0,0,1]+ testAgg [[0,0,1]] $ vint [0,0,1] [0,0,2]+ testAgg [[1,2,0,7], [1,2,3,0]] $ vors' [ vint [1,2,0,7] [1,2,1],+ vint [1,2,3] [1,2,4]+ ]+ testAgg [[1,2,0,7], [1,2,0,7]] $ vint [1,2,0,7] [1,2,1]+ testAgg [[1,2,0,7], [1,3]] $ vors' [ vint [1,2,0,7] [1,2,1],+ vint [1,3] [1,3,1]+ ]+ testAgg [[1,2,0,7], [1,3,4]] $ vors' [ vint [1,2,0,7] [1,2,1],+ vint [1,3,4] [1,3,5]+ ]+ testAgg [[1,2,0,7], [1,3,0]] $ vors' [ vint [1,2,0,7] [1,2,1],+ vint [1,3] [1,3,1]+ ]+ testAgg [[1,3,4], [1,2,0,7]] $ vors' [ vint [1,2,0,7] [1,2,1],+ vint [1,3,4] [1,3,5]+ ]+ testAgg [[1,3,0], [1,2,0,7]] $ vors' [ vint [1,2,0,7] [1,2,1],+ vint [1,3] [1,3,1]+ ]+ testAgg [[1,2,0,7], [1,3,0,8]] $ vors' [ vint [1,2,0,7] [1,2,1],+ vint [1,3,0,8] [1,3,1]+ ]+ testAgg [[1,2,0,0], [1,3,0,0]] $ vors' [ vint [1,2] [1,2,1],+ vint [1,3] [1,3,1]+ ]+ testAgg [[1,3,0,8], [1,2,0,7]] $ vors' [ vint [1,2,0,7] [1,2,1],+ vint [1,3,0,8] [1,3,1]+ ]+ testAgg [[1,2,0,7], [2]] $ vors' [ vint [1,2,0,7] [1,2,1],+ vint [2] [2,0,1]+ ]+ testAgg [[2,2,0], [2,0], [3,5,0,1], [2,2,0,5]] $ vors' [ vint [2] [2,0,1],+ vint [2,2] [2,2,1],+ vint [3,5,0,1] [3,5,1]+ ]+ testAgg [[1,2,2,4], [1,2,1,0], [1,2,0,4]] $ vors' [ vint [1,2,0,4] [1,2,2],+ vint [1,2,2,4] [1,2,3]+ ]+ testAgg :: [[Int]] -> V.VersionRange -> SpecWith Aggregator testAgg input expected = specify desc $ \agg -> agg input' `shouldBe` expected where