yarn-lock 0.3.4 → 0.4.0
raw patch · 7 files changed
+37/−30 lines, 7 files
Files
- CHANGELOG.md +5/−0
- src/Data/MultiKeyedMap.hs +17/−12
- src/Yarn/Lock/Parse.hs +3/−2
- src/Yarn/Lock/Types.hs +2/−1
- tests/TestMultiKeyedMap.hs +4/−11
- tests/TestParse.hs +3/−1
- yarn-lock.cabal +3/−3
CHANGELOG.md view
@@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.4.0] - 2017-10-07++### Changed+- MKMap functions `fromList` and `toList` only take non-empty key lists+ ## [0.3.4] - 2017-10-04 ### Fixed
src/Data/MultiKeyedMap.hs view
@@ -27,9 +27,11 @@ import qualified Data.Map.Strict as M import Data.Monoid (All(..))-import qualified Data.List as L+import Data.Semigroup ((<>))+import Data.Foldable (foldl')+import qualified Data.List.NonEmpty as NE import Data.Proxy (Proxy(..))-import qualified Data.Tuple as T+import qualified Data.Tuple as Tuple import qualified Text.Show as Show -- TODO: add time behaviour of functions to docstrings@@ -107,18 +109,22 @@ -- | Build a map from a list of key\/value pairs. fromList :: forall ik k v. (Ord k, Ord ik, Enum ik, Bounded ik) => (Proxy ik) -- ^ type of intermediate key- -> [([k], v)] -- ^ list of @(key, value)@+ -> [(NE.NonEmpty k, v)] -- ^ list of @(key, value)@ -> MKMap k v -- ^ new map -- TODO: it’s probably better to implement with M.fromList-fromList p = L.foldl' (\m (ks, v) -> newVal ks v m) (mkMKMap p)+fromList p = foldl' (\m (ks, v) -> newVal ks v m) (mkMKMap p) -- | Convert the map to a list of key\/value pairs.-toList :: MKMap k v -> [([k], v)]+toList :: MKMap k v -> [(NE.NonEmpty k, v)] toList MKMap{keyMap, valMap} =- map (fmap (valMap M.!) . T.swap) . M.assocs . aggregateIk $ keyMap- where aggregateIk = M.foldlWithKey- (\m k ik -> M.insertWith (++) ik [k] m) mempty+ map (fmap (valMap M.!) . Tuple.swap) . M.assocs . aggregateIk $ keyMap+ where+ aggregateIk :: forall k ik. (Ord ik, Enum ik)+ => M.Map k ik+ -> M.Map ik (NE.NonEmpty k)+ aggregateIk = M.foldlWithKey+ (\m k ik -> M.insertWith (<>) ik (pure k) m) mempty -- | “Unlink” keys that are pointing to the same value. --@@ -146,7 +152,7 @@ insert k v m@MKMap{keyMap, highestIk, valMap} = maybe ins upd $ M.lookup k keyMap where- ins = newVal [k] v m+ ins = newVal (pure k) v m upd ik = MKMap { keyMap, highestIk, valMap = M.insert ik v valMap } @@ -156,10 +162,9 @@ -- Insert every key into the keyMap, increase the intermediate counter, -- insert the value at new intermediate counter. -- Overwrites all already existing keys!-newVal :: (Ord k) => [k] -> v -> MKMap k v -> MKMap k v-newVal [] _ m = m+newVal :: (Ord k) => NE.NonEmpty k -> v -> MKMap k v -> MKMap k v newVal ks v MKMap{keyMap, highestIk, valMap} =- MKMap { keyMap = L.foldl' (\m k -> M.insert k next m) keyMap ks+ MKMap { keyMap = foldl' (\m k -> M.insert k next m) keyMap ks , highestIk = next , valMap = M.insert next v valMap } where next = succ highestIk
src/Yarn/Lock/Parse.hs view
@@ -22,6 +22,7 @@ import Protolude hiding (try) import qualified Data.Char as Ch+import qualified Data.List.NonEmpty as NE import qualified Data.Text as T import qualified Data.Map.Strict as M import Control.Monad (fail)@@ -87,11 +88,11 @@ -- @ -- align-text@^0.1.1, align-text@^0.1.3:\\n -- @-packageKeys :: Parser [YLT.PackageKey]+packageKeys :: Parser (NE.NonEmpty YLT.PackageKey) packageKeys = label "package keys" $ do firstEls <- many (try $ lexeme $ packageKey ":," <* char ',') lastEl <- packageKey ":" <* char ':'- pure $ firstEls ++ [lastEl]+ pure $ NE.fromList $ firstEls <> [lastEl] -- | A packageKey is @\<package-name\>\@\<semver\>@; --
src/Yarn/Lock/Types.hs view
@@ -9,6 +9,7 @@ import Protolude hiding (try) import qualified Data.MultiKeyedMap as MKM+import qualified Data.List.NonEmpty as NE -- | Yarn lockfile. --@@ -33,7 +34,7 @@ } deriving (Show, Eq, Ord) -- | Something with a list of 'PackageKey's pointing to it.-data Keyed a = Keyed [PackageKey] a+data Keyed a = Keyed (NE.NonEmpty PackageKey) a deriving (Show, Eq, Ord, Functor) -- | The actual npm package with dependencies and a way to download.
tests/TestMultiKeyedMap.hs view
@@ -3,6 +3,7 @@ import Protolude import qualified Data.List as List+import qualified Data.List.NonEmpty as NE import Test.Tasty (TestTree) import Test.Tasty.TH import Test.Tasty.QuickCheck@@ -12,31 +13,23 @@ emptyMkm :: (Ord k) => MKM.MKMap k v emptyMkm = MKM.mkMKMap (Proxy :: Proxy Int) -fromList :: [([Int], v)] -> MKM.MKMap Int v+fromList :: [((NE.NonEmpty Int), v)] -> MKM.MKMap Int v fromList = MKM.fromList (Proxy :: Proxy Int) prop_equality :: Property prop_equality =- forAll (resize 5 arbitrary :: Gen [([Int], Int)])- $ \map1 -> forAll (resize 2 arbitrary :: Gen [([Int], Int)])+ forAll (resize 5 arbitrary :: Gen [(NE.NonEmpty Int, Int)])+ $ \map1 -> forAll (resize 2 arbitrary :: Gen [(NE.NonEmpty Int, Int)]) $ \map2 ->- -- fromList drops empty keys, the right side would be different- keysNotEmpty map1 ==> keysNotEmpty map2 ==> -- equality of contents also applies to the MKM (map1 == map2) === (fromList map1 == fromList map2) -- force the contents to be the same, should always be equal- where- keysNotEmpty = all (\(ks, _) -> ks /= []) -- | inserting the same value is idempotent prop_insertIdempotent :: Int -> Int -> Property prop_insertIdempotent key val = do let insVal = MKM.insert key val (insVal emptyMkm) === (insVal (insVal emptyMkm))--prop_fromList_emptyKeyList :: Int -> ([Int], Int) -> Property-prop_fromList_emptyKeyList val el = do- fromList [([], val), el, ([], val)] === fromList [el] -- | inserting the same values in a different order -- results in the same map
tests/TestParse.hs view
@@ -3,6 +3,7 @@ import Protolude import qualified Data.Map as Map+import qualified Data.List.NonEmpty as NE import Test.Tasty (TestTree) import Test.Tasty.TH import Test.Tasty.HUnit@@ -99,7 +100,8 @@ let key = "foo@^1.3.4, bar@blafoo234, xnu@, @types/foo@@:\n" parseSuccess packageKeys key >>= \keys -> do- keys @?= [ PackageKey "foo" "^1.3.4"+ keys @?= NE.fromList+ [ PackageKey "foo" "^1.3.4" , PackageKey "bar" "blafoo234" -- yes, the version can be empty … , PackageKey "xnu" ""
yarn-lock.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack name: yarn-lock-version: 0.3.4+version: 0.4.0 synopsis: Represent and parse yarn.lock files description: Types and parser for the lock file format of the npm successor yarn. All modules should be imported qualified. category: Data@@ -28,7 +28,7 @@ src ghc-options: -Wall build-depends:- base >= 4.9 && < 4.10+ base == 4.9.* , containers , text , megaparsec == 5.*@@ -52,7 +52,7 @@ tests ghc-options: -Wall build-depends:- base >= 4.9 && < 4.10+ base == 4.9.* , containers , text , megaparsec == 5.*