summaryrefslogtreecommitdiff
path: root/Git/Command.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Git/Command.hs')
-rw-r--r--Git/Command.hs70
1 files changed, 39 insertions, 31 deletions
diff --git a/Git/Command.hs b/Git/Command.hs
index eb20af2..894f6ae 100644
--- a/Git/Command.hs
+++ b/Git/Command.hs
@@ -1,6 +1,6 @@
{- running git commands
-
- - Copyright 2010-2013 Joey Hess <id@joeyh.name>
+ - Copyright 2010-2020 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
@@ -39,19 +39,23 @@ runBool params repo = assertLocal repo $
run :: [CommandParam] -> Repo -> IO ()
run params repo = assertLocal repo $
unlessM (runBool params repo) $
- error $ "git " ++ show params ++ " failed"
+ giveup $ "git " ++ show params ++ " failed"
{- Runs git and forces it to be quiet, throwing an error if it fails. -}
runQuiet :: [CommandParam] -> Repo -> IO ()
-runQuiet params repo = withQuietOutput createProcessSuccess $
- (proc "git" $ toCommand $ gitCommandLine (params) repo)
- { env = gitEnv repo }
+runQuiet params repo = withNullHandle $ \nullh ->
+ let p = (proc "git" $ toCommand $ gitCommandLine (params) repo)
+ { env = gitEnv repo
+ , std_out = UseHandle nullh
+ , std_err = UseHandle nullh
+ }
+ in withCreateProcess p $ \_ _ _ -> forceSuccessProcess p
{- Runs a git command and returns its output, lazily.
-
- Also returns an action that should be used when the output is all
- read, that will wait on the command, and
- - return True if it succeeded. Failure to wait will result in zombies.
+ - return True if it succeeded.
-}
pipeReadLazy :: [CommandParam] -> Repo -> IO (L.ByteString, IO Bool)
pipeReadLazy params repo = assertLocal repo $ do
@@ -66,33 +70,47 @@ pipeReadLazy params repo = assertLocal repo $ do
- Nonzero exit status is ignored.
-}
pipeReadStrict :: [CommandParam] -> Repo -> IO S.ByteString
-pipeReadStrict = pipeReadStrict' S.hGetContents
-
-{- The reader action must be strict. -}
-pipeReadStrict' :: (Handle -> IO a) -> [CommandParam] -> Repo -> IO a
-pipeReadStrict' reader params repo = assertLocal repo $
- withHandle StdoutHandle (createProcessChecked ignoreFailureProcess) p $ \h -> do
- output <- reader h
- hClose h
- return output
+pipeReadStrict = pipeReadStrict' id
+
+pipeReadStrict' :: (CreateProcess -> CreateProcess) -> [CommandParam] -> Repo -> IO S.ByteString
+pipeReadStrict' fp params repo = assertLocal repo $ withCreateProcess p go
where
- p = gitCreateProcess params repo
+ p = fp (gitCreateProcess params repo) { std_out = CreatePipe }
+
+ go _ (Just outh) _ pid = do
+ output <- S.hGetContents outh
+ hClose outh
+ void $ waitForProcess pid
+ return output
+ go _ _ _ _ = error "internal"
{- Runs a git command, feeding it an input, and returning its output,
- which is expected to be fairly small, since it's all read into memory
- strictly. -}
-pipeWriteRead :: [CommandParam] -> Maybe (Handle -> IO ()) -> Repo -> IO String
+pipeWriteRead :: [CommandParam] -> Maybe (Handle -> IO ()) -> Repo -> IO S.ByteString
pipeWriteRead params writer repo = assertLocal repo $
writeReadProcessEnv "git" (toCommand $ gitCommandLine params repo)
- (gitEnv repo) writer (Just adjusthandle)
+ (gitEnv repo) writer'
where
+ writer' = case writer of
+ Nothing -> Nothing
+ Just a -> Just $ \h -> do
+ adjusthandle h
+ a h
adjusthandle h = hSetNewlineMode h noNewlineTranslation
{- Runs a git command, feeding it input on a handle with an action. -}
pipeWrite :: [CommandParam] -> Repo -> (Handle -> IO ()) -> IO ()
-pipeWrite params repo = assertLocal repo $
- withHandle StdinHandle createProcessSuccess $
- gitCreateProcess params repo
+pipeWrite params repo feeder = assertLocal repo $
+ let p = (gitCreateProcess params repo)
+ { std_in = CreatePipe }
+ in withCreateProcess p (go p)
+ where
+ go p (Just hin) _ _ pid = do
+ feeder hin
+ hClose hin
+ forceSuccessProcess p pid
+ go _ _ _ _ _ = error "internal"
{- Reads null terminated output of a git command (as enabled by the -z
- parameter), and splits it. -}
@@ -114,16 +132,6 @@ pipeNullSplitStrict params repo = do
s <- pipeReadStrict params repo
return $ filter (not . S.null) $ S.split 0 s
-pipeNullSplitZombie :: [CommandParam] -> Repo -> IO [L.ByteString]
-pipeNullSplitZombie params repo = leaveZombie <$> pipeNullSplit params repo
-
-pipeNullSplitZombie' :: [CommandParam] -> Repo -> IO [S.ByteString]
-pipeNullSplitZombie' params repo = leaveZombie <$> pipeNullSplit' params repo
-
-{- Doesn't run the cleanup action. A zombie results. -}
-leaveZombie :: (a, IO Bool) -> a
-leaveZombie = fst
-
{- Runs a git command as a coprocess. -}
gitCoProcessStart :: Bool -> [CommandParam] -> Repo -> IO CoProcess.CoProcessHandle
gitCoProcessStart restartable params repo = CoProcess.start numrestarts "git"