refactor
This commit is contained in:
parent
ac5cff3668
commit
6c0155efb7
4 changed files with 77 additions and 51 deletions
|
@ -13,7 +13,6 @@ module Git.CatFile (
|
||||||
catObject
|
catObject
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import System.Cmd.Utils
|
|
||||||
import System.IO
|
import System.IO
|
||||||
import qualified Data.ByteString.Char8 as S
|
import qualified Data.ByteString.Char8 as S
|
||||||
import qualified Data.ByteString.Lazy.Char8 as L
|
import qualified Data.ByteString.Lazy.Char8 as L
|
||||||
|
@ -22,20 +21,18 @@ import Common
|
||||||
import Git
|
import Git
|
||||||
import Git.Sha
|
import Git.Sha
|
||||||
import Git.Command
|
import Git.Command
|
||||||
|
import qualified Utility.CoProcess as CoProcess
|
||||||
|
|
||||||
type CatFileHandle = (PipeHandle, Handle, Handle)
|
type CatFileHandle = CoProcess.CoProcessHandle
|
||||||
|
|
||||||
{- Starts git cat-file running in batch mode in a repo and returns a handle. -}
|
{- Starts git cat-file running in batch mode in a repo and returns a handle. -}
|
||||||
catFileStart :: Repo -> IO CatFileHandle
|
catFileStart :: Repo -> IO CatFileHandle
|
||||||
catFileStart repo = hPipeBoth "git" $ toCommand $
|
catFileStart repo = CoProcess.start "git" $ toCommand $
|
||||||
gitCommandLine [Param "cat-file", Param "--batch"] repo
|
gitCommandLine [Param "cat-file", Param "--batch"] repo
|
||||||
|
|
||||||
{- Stops git cat-file. -}
|
{- Stops git cat-file. -}
|
||||||
catFileStop :: CatFileHandle -> IO ()
|
catFileStop :: CatFileHandle -> IO ()
|
||||||
catFileStop (pid, from, to) = do
|
catFileStop = CoProcess.stop
|
||||||
hClose to
|
|
||||||
hClose from
|
|
||||||
forceSuccess pid
|
|
||||||
|
|
||||||
{- Reads a file from a specified branch. -}
|
{- Reads a file from a specified branch. -}
|
||||||
catFile :: CatFileHandle -> Branch -> FilePath -> IO L.ByteString
|
catFile :: CatFileHandle -> Branch -> FilePath -> IO L.ByteString
|
||||||
|
@ -44,23 +41,23 @@ catFile h branch file = catObject h $ Ref $ show branch ++ ":" ++ file
|
||||||
{- Uses a running git cat-file read the content of an object.
|
{- Uses a running git cat-file read the content of an object.
|
||||||
- Objects that do not exist will have "" returned. -}
|
- Objects that do not exist will have "" returned. -}
|
||||||
catObject :: CatFileHandle -> Ref -> IO L.ByteString
|
catObject :: CatFileHandle -> Ref -> IO L.ByteString
|
||||||
catObject (_, from, to) object = do
|
catObject h object = CoProcess.query h send receive
|
||||||
hPutStrLn to $ show object
|
where
|
||||||
hFlush to
|
send to = hPutStrLn to $ show object
|
||||||
|
receive from = do
|
||||||
header <- hGetLine from
|
header <- hGetLine from
|
||||||
case words header of
|
case words header of
|
||||||
[sha, objtype, size]
|
[sha, objtype, size]
|
||||||
| length sha == shaSize &&
|
| length sha == shaSize &&
|
||||||
validobjtype objtype -> handle size
|
validobjtype objtype ->
|
||||||
|
case reads size of
|
||||||
|
[(bytes, "")] -> readcontent bytes from
|
||||||
|
_ -> dne
|
||||||
| otherwise -> dne
|
| otherwise -> dne
|
||||||
_
|
_
|
||||||
| header == show object ++ " missing" -> dne
|
| header == show object ++ " missing" -> dne
|
||||||
| otherwise -> error $ "unknown response from git cat-file " ++ header
|
| otherwise -> error $ "unknown response from git cat-file " ++ header
|
||||||
where
|
readcontent bytes from = do
|
||||||
handle size = case reads size of
|
|
||||||
[(bytes, "")] -> readcontent bytes
|
|
||||||
_ -> dne
|
|
||||||
readcontent bytes = do
|
|
||||||
content <- S.hGet from bytes
|
content <- S.hGet from bytes
|
||||||
c <- hGetChar from
|
c <- hGetChar from
|
||||||
when (c /= '\n') $
|
when (c /= '\n') $
|
||||||
|
|
|
@ -11,8 +11,9 @@ import Common
|
||||||
import Git
|
import Git
|
||||||
import Git.Command
|
import Git.Command
|
||||||
import qualified Git.Version
|
import qualified Git.Version
|
||||||
|
import qualified Utility.CoProcess as CoProcess
|
||||||
|
|
||||||
type CheckAttrHandle = (PipeHandle, Handle, Handle, [Attr], String)
|
type CheckAttrHandle = (CoProcess.CoProcessHandle, [Attr], String)
|
||||||
|
|
||||||
type Attr = String
|
type Attr = String
|
||||||
|
|
||||||
|
@ -21,11 +22,10 @@ type Attr = String
|
||||||
checkAttrStart :: [Attr] -> Repo -> IO CheckAttrHandle
|
checkAttrStart :: [Attr] -> Repo -> IO CheckAttrHandle
|
||||||
checkAttrStart attrs repo = do
|
checkAttrStart attrs repo = do
|
||||||
cwd <- getCurrentDirectory
|
cwd <- getCurrentDirectory
|
||||||
(pid, from, to) <- hPipeBoth "git" $ toCommand $
|
h <- CoProcess.start "git" $ toCommand $
|
||||||
gitCommandLine params repo
|
gitCommandLine params repo
|
||||||
fileEncoding from
|
CoProcess.query h fileEncoding fileEncoding
|
||||||
fileEncoding to
|
return (h, attrs, cwd)
|
||||||
return (pid, from, to, attrs, cwd)
|
|
||||||
where
|
where
|
||||||
params =
|
params =
|
||||||
[ Param "check-attr"
|
[ Param "check-attr"
|
||||||
|
@ -35,24 +35,21 @@ checkAttrStart attrs repo = do
|
||||||
|
|
||||||
{- Stops git check-attr. -}
|
{- Stops git check-attr. -}
|
||||||
checkAttrStop :: CheckAttrHandle -> IO ()
|
checkAttrStop :: CheckAttrHandle -> IO ()
|
||||||
checkAttrStop (pid, from, to, _, _) = do
|
checkAttrStop (h, _, _) = CoProcess.stop h
|
||||||
hClose to
|
|
||||||
hClose from
|
|
||||||
forceSuccess pid
|
|
||||||
|
|
||||||
{- Gets an attribute of a file. -}
|
{- Gets an attribute of a file. -}
|
||||||
checkAttr :: CheckAttrHandle -> Attr -> FilePath -> IO String
|
checkAttr :: CheckAttrHandle -> Attr -> FilePath -> IO String
|
||||||
checkAttr (_, from, to, attrs, cwd) want file = do
|
checkAttr (h, attrs, cwd) want file = do
|
||||||
hPutStr to $ file' ++ "\0"
|
pairs <- CoProcess.query h send receive
|
||||||
hFlush to
|
|
||||||
pairs <- forM attrs $ \attr -> do
|
|
||||||
l <- hGetLine from
|
|
||||||
return (attr, attrvalue attr l)
|
|
||||||
let vals = map snd $ filter (\(attr, _) -> attr == want) pairs
|
let vals = map snd $ filter (\(attr, _) -> attr == want) pairs
|
||||||
case vals of
|
case vals of
|
||||||
[v] -> return v
|
[v] -> return v
|
||||||
_ -> error $ "unable to determine " ++ want ++ " attribute of " ++ file
|
_ -> error $ "unable to determine " ++ want ++ " attribute of " ++ file
|
||||||
where
|
where
|
||||||
|
send to = hPutStr to $ file' ++ "\0"
|
||||||
|
receive from = forM attrs $ \attr -> do
|
||||||
|
l <- hGetLine from
|
||||||
|
return (attr, attrvalue attr l)
|
||||||
{- Before git 1.7.7, git check-attr worked best with
|
{- Before git 1.7.7, git check-attr worked best with
|
||||||
- absolute filenames; using them worked around some bugs
|
- absolute filenames; using them worked around some bugs
|
||||||
- with relative filenames.
|
- with relative filenames.
|
||||||
|
|
|
@ -10,16 +10,16 @@ module Git.HashObject where
|
||||||
import Common
|
import Common
|
||||||
import Git
|
import Git
|
||||||
import Git.Command
|
import Git.Command
|
||||||
|
import qualified Utility.CoProcess as CoProcess
|
||||||
|
|
||||||
type HashObjectHandle = (PipeHandle, Handle, Handle)
|
type HashObjectHandle = CoProcess.CoProcessHandle
|
||||||
|
|
||||||
{- Starts git hash-object and returns a handle. -}
|
{- Starts git hash-object and returns a handle. -}
|
||||||
hashObjectStart :: Repo -> IO HashObjectHandle
|
hashObjectStart :: Repo -> IO HashObjectHandle
|
||||||
hashObjectStart repo = do
|
hashObjectStart repo = do
|
||||||
r@(_, _, toh) <- hPipeBoth "git" $
|
h <- CoProcess.start "git" $ toCommand $ gitCommandLine params repo
|
||||||
toCommand $ gitCommandLine params repo
|
CoProcess.query h fileEncoding (const $ return ())
|
||||||
fileEncoding toh
|
return h
|
||||||
return r
|
|
||||||
where
|
where
|
||||||
params =
|
params =
|
||||||
[ Param "hash-object"
|
[ Param "hash-object"
|
||||||
|
@ -29,14 +29,11 @@ hashObjectStart repo = do
|
||||||
|
|
||||||
{- Stops git hash-object. -}
|
{- Stops git hash-object. -}
|
||||||
hashObjectStop :: HashObjectHandle -> IO ()
|
hashObjectStop :: HashObjectHandle -> IO ()
|
||||||
hashObjectStop (pid, from, to) = do
|
hashObjectStop = CoProcess.stop
|
||||||
hClose to
|
|
||||||
hClose from
|
|
||||||
forceSuccess pid
|
|
||||||
|
|
||||||
{- Injects a file into git, returning the shas of the objects. -}
|
{- Injects a file into git, returning the shas of the objects. -}
|
||||||
hashFile :: HashObjectHandle -> FilePath -> IO Sha
|
hashFile :: HashObjectHandle -> FilePath -> IO Sha
|
||||||
hashFile (_, from, to) file = do
|
hashFile h file = CoProcess.query h send receive
|
||||||
hPutStrLn to file
|
where
|
||||||
hFlush to
|
send to = hPutStrLn to file
|
||||||
Ref <$> hGetLine from
|
receive from = Ref <$> hGetLine from
|
||||||
|
|
35
Utility/CoProcess.hs
Normal file
35
Utility/CoProcess.hs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{- Interface for running a shell command as a coprocess,
|
||||||
|
- sending it queries and getting back results.
|
||||||
|
-
|
||||||
|
- Copyright 2012 Joey Hess <joey@kitenet.net>
|
||||||
|
-
|
||||||
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Utility.CoProcess (
|
||||||
|
CoProcessHandle,
|
||||||
|
start,
|
||||||
|
stop,
|
||||||
|
query
|
||||||
|
) where
|
||||||
|
|
||||||
|
import System.Cmd.Utils
|
||||||
|
|
||||||
|
import Common
|
||||||
|
|
||||||
|
type CoProcessHandle = (PipeHandle, Handle, Handle)
|
||||||
|
|
||||||
|
start :: FilePath -> [String] -> IO CoProcessHandle
|
||||||
|
start command params = hPipeBoth command params
|
||||||
|
|
||||||
|
stop :: CoProcessHandle -> IO ()
|
||||||
|
stop (pid, from, to) = do
|
||||||
|
hClose to
|
||||||
|
hClose from
|
||||||
|
forceSuccess pid
|
||||||
|
|
||||||
|
query :: CoProcessHandle -> (Handle -> IO a) -> (Handle -> IO b) -> IO b
|
||||||
|
query (_, from, to) send receive = do
|
||||||
|
_ <- send to
|
||||||
|
hFlush to
|
||||||
|
receive from
|
Loading…
Add table
Add a link
Reference in a new issue