packages feed

svndump 0.2.0 → 0.3.0

raw patch · 5 files changed

+128/−116 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Subversion.Dump: Entry :: FieldMap -> FieldMap -> ByteString -> Entry
- Subversion.Dump: data Entry
- Subversion.Dump: entryBody :: Entry -> ByteString
- Subversion.Dump: entryProps :: Entry -> FieldMap
- Subversion.Dump: entryTags :: Entry -> FieldMap
- Subversion.Dump: instance Show Entry
- Subversion.Dump: parseEntry :: Parser Entry
- Subversion.Dump: parseHeader :: Parser ByteString
- Subversion.Dump: readSvnDumpRaw :: ByteString -> Result [Entry]
- Subversion.Dump: type FieldMap = [(ByteString, ByteString)]
+ Subversion.Dump.Raw: Entry :: FieldMap -> FieldMap -> ByteString -> Entry
+ Subversion.Dump.Raw: data Entry
+ Subversion.Dump.Raw: entryBody :: Entry -> ByteString
+ Subversion.Dump.Raw: entryProps :: Entry -> FieldMap
+ Subversion.Dump.Raw: entryTags :: Entry -> FieldMap
+ Subversion.Dump.Raw: instance Show Entry
+ Subversion.Dump.Raw: readInt :: ByteString -> Int
+ Subversion.Dump.Raw: readSvnDumpRaw :: ByteString -> [Entry]
+ Subversion.Dump.Raw: type FieldMap = [(ByteString, ByteString)]
- Subversion.Dump: readSvnDump :: ByteString -> Either String [Revision]
+ Subversion.Dump: readSvnDump :: ByteString -> [Revision]

Files

src/Subversion/Dump.hs view
@@ -8,21 +8,10 @@        , OpAction(..)        , Operation(..) -       , FieldMap-       , Entry(..)-        , readSvnDump-       , readSvnDumpRaw--       , parseHeader-       , parseEntry        ) where  import           Control.Applicative hiding (many)-import           Control.Monad-import qualified Data.Attoparsec.Char8 as AC-import           Data.Attoparsec.Combinator-import           Data.Attoparsec.Lazy as AL import           Data.ByteString as B hiding (map) import qualified Data.ByteString.Char8 as BC hiding (map) import qualified Data.ByteString.Lazy as BL hiding (map)@@ -30,9 +19,9 @@ import           Data.Text (Text) import qualified Data.Text.Encoding as E import           Data.Maybe-import           Data.Word (Word8)-import           System.FilePath +import           Subversion.Dump.Raw+ import           Prelude hiding (getContents)  default (ByteString)@@ -99,12 +88,8 @@ -- | Reads a dump file from a ByteString in the IO monad into a list of --   Revision values.  This is the "cooked" parallel of 'readSvnDumpRaw'. -readSvnDump :: BL.ByteString -> Either String [Revision]-readSvnDump io = do-  case readSvnDumpRaw io of-    Fail _ _ y    -> Left y-    Done _ result -> Right $ map processRevs (L.groupBy sameRev result)-+readSvnDump :: BL.ByteString -> [Revision]+readSvnDump dump = map processRevs $ L.groupBy sameRev $ readSvnDumpRaw dump   where sameRev _ y     = isNothing $                           L.lookup "Revision-number" (entryTags y)         getField f n x  = L.lookup n (f x)@@ -147,85 +132,8 @@           "change"  -> Change           "replace" -> Replace           _      -> error "Unexpected"--type FieldMap = [(ByteString, ByteString)] -data Entry = Entry { entryTags  :: FieldMap-                   , entryProps :: FieldMap-                   , entryBody  :: ByteString }-           deriving Show--readSvnDumpRaw :: BL.ByteString -> Result [Entry]-readSvnDumpRaw dump = parse parseSvnDump dump---- These are the Parsec parsers for the various parts of the input file.--space :: Parser Word8-space = satisfy (== 32)--newline :: Parser Word8-newline = satisfy (== 10)--parseTag :: Parser (ByteString, ByteString)-parseTag =-  (,) <$> takeWhile1 fieldChar <* string ": " -- :-      <*> takeWhile1 (/= 10) <* newline-  where fieldChar w =   (w >= 65 && w <= 90)  -- A-Z-                      || (w >= 97 && w <= 121) -- a-z-                      || (w >= 48 && w <= 57)  -- 0-9-                      || w == 45            -- --                      || w == 95            -- _--parseIndicator :: Parser (Word8, Int)-parseIndicator = (,) <$> satisfy (oneOf 75 86) <* space -- K or V-                     <*> AC.decimal <* newline-  where oneOf x y w = w == x || w == y--parseSpecValue :: Parser ByteString-parseSpecValue = do-  (_, len) <- parseIndicator-  AL.take len <* newline--parseProperty :: Parser (ByteString, ByteString)-parseProperty = (,) <$> parseSpecValue -- K-                    <*> parseSpecValue -- V--readInt :: ByteString -> Int-readInt bs = B.foldl' addup 0 bs-  where addup acc x = acc * 10 + (fromIntegral x - 48) -- '0'--parseEntry :: Parser Entry-parseEntry = do-  fields <- many1 parseTag <* newline--  props  <- case L.lookup "Prop-content-length" fields of-              Nothing -> return []-              Just _  -> manyTill parseProperty (try (string "PROPS-END\n"))--  body   <- case L.lookup "Text-content-length" fields of-              Nothing  -> return B.empty-              Just len -> AL.take (readInt len)--  _ <- AL.takeWhile (== 10)--  return Entry { entryTags  = fields-               , entryProps = props-               , entryBody  = body }--parseHeader :: Parser ByteString-parseHeader = do-  _ <- string "SVN-fs-dump-format-version: 2\n\n"-       <?> "Dump file starts without a recognizable tag"-  string "UUID: " *> takeWhile1 uuidMember-    <* newline <* newline-  where-    -- Accept any hexadecimal character, or '-'-    uuidMember w = w == 45 || (w >= 48 && w <= 57) || (w >= 97 && w <= 102)--parseSvnDump :: Parser [Entry]-parseSvnDump = parseHeader >> many1 parseEntry- parseDate :: ByteString -> RevDate parseDate = E.decodeUtf8 --- SvnDump.hs ends here+-- Dump.hs ends here
+ src/Subversion/Dump/Raw.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE OverloadedStrings #-}++module Subversion.Dump.Raw+       ( FieldMap+       , Entry(..)++       , readInt+       , readSvnDumpRaw+       ) where++import           Control.Applicative hiding (many)+import           Control.Monad+import qualified Data.Attoparsec.Char8 as AC+import           Data.Attoparsec.Combinator+import           Data.Attoparsec.Lazy as AL+import           Data.ByteString as B hiding (map)+import qualified Data.ByteString.Lazy as BL hiding (map)+import qualified Data.List as L+import           Data.Maybe+import           Data.Word (Word8)++import           Prelude hiding (getContents)++default (ByteString)++type FieldMap = [(ByteString, ByteString)]++data Entry = Entry { entryTags  :: FieldMap+                   , entryProps :: FieldMap+                   , entryBody  :: ByteString }+           deriving Show++readSvnDumpRaw :: BL.ByteString -> [Entry]+readSvnDumpRaw dump =+  case parse parseHeader dump of+    Fail _ _ _      -> error "Stream is not a Subversion dump file"+    Done contents _ -> parseDumpFile contents++parseDumpFile :: BL.ByteString -> [Entry]+parseDumpFile contents = do+  case parse parseEntry contents of+    Fail _ _ _ -> []+    Done contents' entry -> do+      entry : parseDumpFile contents'++-- These are the Parsec parsers for the various parts of the input file.++space :: Parser Word8+space = satisfy (== 32)++newline :: Parser Word8+newline = satisfy (== 10)++parseTag :: Parser (ByteString, ByteString)+parseTag =+  (,) <$> takeWhile1 fieldChar <* string ": " -- :+      <*> takeWhile1 (/= 10) <* newline+  where fieldChar w =   (w >= 65 && w <= 90)  -- A-Z+                      || (w >= 97 && w <= 121) -- a-z+                      || (w >= 48 && w <= 57)  -- 0-9+                      || w == 45            -- -+                      || w == 95            -- _++parseIndicator :: Parser (Word8, Int)+parseIndicator = (,) <$> satisfy (oneOf 75 86) <* space -- K or V+                     <*> AC.decimal <* newline+  where oneOf x y w = w == x || w == y++parseSpecValue :: Parser ByteString+parseSpecValue = do+  (_, len) <- parseIndicator+  AL.take len <* newline++parseProperty :: Parser (ByteString, ByteString)+parseProperty = (,) <$> parseSpecValue -- K+                    <*> parseSpecValue -- V++readInt :: ByteString -> Int+readInt bs = B.foldl' addup 0 bs+  where addup acc x = acc * 10 + (fromIntegral x - 48) -- '0'++parseEntry :: Parser Entry+parseEntry = do+  fields <- many1 parseTag <* newline++  props  <- case L.lookup "Prop-content-length" fields of+              Nothing -> return []+              Just _  -> manyTill parseProperty (try (string "PROPS-END\n"))++  body   <- case L.lookup "Text-content-length" fields of+              Nothing  -> return B.empty+              Just len -> AL.take (readInt len)++  _ <- AL.takeWhile (== 10)++  return Entry { entryTags  = fields+               , entryProps = props+               , entryBody  = body }++parseHeader :: Parser ByteString+parseHeader = do+  _ <- string "SVN-fs-dump-format-version: 2\n\n"+       <?> "Dump file starts without a recognizable tag"+  string "UUID: " *> takeWhile1 uuidMember+    <* newline <* newline+  where+    -- Accept any hexadecimal character, or '-'+    uuidMember w = w == 45 || (w >= 48 && w <= 57) || (w >= 97 && w <= 102)++-- SvnDump.hs ends here
svndump.cabal view
@@ -1,6 +1,6 @@ name:          svndump category:      Subversion-version:       0.2.0+version:       0.3.0 license:       BSD3 cabal-version: >= 1.8 license-file:  LICENSE@@ -40,6 +40,7 @@   exposed-modules:     Subversion     Subversion.Dump+    Subversion.Dump.Raw    ghc-options: -Wall -fwarn-tabs -O2   hs-source-dirs: src
test/test-cooked.hs view
@@ -8,13 +8,10 @@ main :: IO () main = do   file <- B.readFile "data/cunit.dump.gz"-  case readSvnDump (GZip.decompress file) of-    Left _   -> exitFailure-    Right xs -> do-      let len = length xs-      putStrLn $ show len ++ " cooked entries found, expecting 157"-      if len == 157-        then exitSuccess-        else exitFailure+  let len = length $ readSvnDump (GZip.decompress file)+  putStrLn $ show len ++ " cooked entries found, expecting 157"+  if len == 157+    then exitSuccess+    else exitFailure  -- test-cooked.hs ends here
test/test-raw.hs view
@@ -1,21 +1,17 @@ module Main where  import qualified Codec.Compression.GZip as GZip-import           Data.Attoparsec.Lazy import qualified Data.ByteString.Lazy as B-import           Subversion.Dump+import           Subversion.Dump.Raw import           System.Exit  main :: IO () main = do   file <- B.readFile "data/cunit.dump.gz"-  case readSvnDumpRaw (GZip.decompress file) of-    Fail _ _ _ -> exitFailure-    Done _ xs  -> do-      let len = length xs-      putStrLn $ show len ++ " raw entries found, expecting 1950"-      if len == 1950-        then exitSuccess-        else exitFailure+  let len = length $ readSvnDumpRaw (GZip.decompress file)+  putStrLn $ show len ++ " raw entries found, expecting 1950"+  if len == 1950+    then exitSuccess+    else exitFailure  -- test-raw.hs ends here