ByteString Ref continued
Attoparsec parser for diff-tree. Changed fromRef back to producing a String, to avoid needing to convert every use of it. However, this does mean I'm going to miss some opportunities where fromRef is used and the result converted back to a ByteString. Would be worth revisiting that at some point maybe.
This commit is contained in:
parent
279991604d
commit
d5d8259937
12 changed files with 77 additions and 52 deletions
|
@ -1,6 +1,6 @@
|
|||
{- git diff-tree interface
|
||||
-
|
||||
- Copyright 2012 Joey Hess <id@joeyh.name>
|
||||
- Copyright 2012-2020 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- Licensed under the GNU AGPL version 3 or higher.
|
||||
-}
|
||||
|
@ -18,6 +18,9 @@ module Git.DiffTree (
|
|||
) where
|
||||
|
||||
import Numeric
|
||||
import qualified Data.ByteString.Lazy as L
|
||||
import qualified Data.Attoparsec.ByteString.Lazy as A
|
||||
import qualified Data.Attoparsec.ByteString.Char8 as A8
|
||||
|
||||
import Common
|
||||
import Git
|
||||
|
@ -27,6 +30,7 @@ import Git.FilePath
|
|||
import Git.DiffTreeItem
|
||||
import qualified Git.Filename
|
||||
import qualified Git.Ref
|
||||
import Utility.Attoparsec
|
||||
|
||||
{- Checks if the DiffTreeItem modifies a file with a given name
|
||||
- or under a directory by that name. -}
|
||||
|
@ -89,7 +93,7 @@ commitDiff ref = getdiff (Param "show")
|
|||
getdiff :: CommandParam -> [CommandParam] -> Repo -> IO ([DiffTreeItem], IO Bool)
|
||||
getdiff command params repo = do
|
||||
(diff, cleanup) <- pipeNullSplit ps repo
|
||||
return (parseDiffRaw (map decodeBL diff), cleanup)
|
||||
return (parseDiffRaw diff, cleanup)
|
||||
where
|
||||
ps =
|
||||
command :
|
||||
|
@ -100,26 +104,28 @@ getdiff command params repo = do
|
|||
params
|
||||
|
||||
{- Parses --raw output used by diff-tree and git-log. -}
|
||||
parseDiffRaw :: [String] -> [DiffTreeItem]
|
||||
parseDiffRaw :: [L.ByteString] -> [DiffTreeItem]
|
||||
parseDiffRaw l = go l
|
||||
where
|
||||
go [] = []
|
||||
go (info:f:rest) = mk info f : go rest
|
||||
go (s:[]) = error $ "diff-tree parse error near \"" ++ s ++ "\""
|
||||
go (info:f:rest) = case A.parse (parserDiffRaw (L.toStrict f)) info of
|
||||
A.Done _ r -> r : go rest
|
||||
A.Fail _ _ err -> error $ "diff-tree parse error: " ++ err
|
||||
go (s:[]) = error $ "diff-tree parse error near \"" ++ decodeBL' s ++ "\""
|
||||
|
||||
mk info f = DiffTreeItem
|
||||
{ srcmode = readmode srcm
|
||||
, dstmode = readmode dstm
|
||||
, srcsha = fromMaybe (error "bad srcsha") $ extractSha ssha
|
||||
, dstsha = fromMaybe (error "bad dstsha") $ extractSha dsha
|
||||
, status = s
|
||||
, file = asTopFilePath $ fromInternalGitPath $ Git.Filename.decode $ toRawFilePath f
|
||||
}
|
||||
where
|
||||
readmode = fst . Prelude.head . readOct
|
||||
|
||||
-- info = :<srcmode> SP <dstmode> SP <srcsha> SP <dstsha> SP <status>
|
||||
(srcm, past_srcm) = splitAt 7 $ drop 1 info
|
||||
(dstm, past_dstm) = splitAt 7 past_srcm
|
||||
(ssha, past_ssha) = separate (== ' ') past_dstm
|
||||
(dsha, s) = separate (== ' ') past_ssha
|
||||
-- :<srcmode> SP <dstmode> SP <srcsha> SP <dstsha> SP <status>
|
||||
parserDiffRaw :: RawFilePath -> A.Parser DiffTreeItem
|
||||
parserDiffRaw f = DiffTreeItem
|
||||
<$ A8.char ':'
|
||||
<*> octal
|
||||
<* A8.char ' '
|
||||
<*> octal
|
||||
<* A8.char ' '
|
||||
<*> (maybe (fail "bad srcsha") return . extractSha =<< nextword)
|
||||
<* A8.char ' '
|
||||
<*> (maybe (fail "bad dstsha") return . extractSha =<< nextword)
|
||||
<* A8.char ' '
|
||||
<*> A.takeByteString
|
||||
<*> pure (asTopFilePath $ fromInternalGitPath $ Git.Filename.decode f)
|
||||
where
|
||||
nextword = A8.takeTill (== ' ')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue