relay external special remote stderr through progress suppression machinery (eep!)
It sounds worse than it is. ;) Some external special remotes may run commands that display progress on stderr. If git-annex is run with --quiet, this should filter out such displays while letting the errors through.
This commit is contained in:
parent
2343f99c85
commit
30aa902174
4 changed files with 44 additions and 28 deletions
|
@ -70,6 +70,12 @@ mkOutputHandler = OutputHandler
|
||||||
<$> commandProgressDisabled
|
<$> commandProgressDisabled
|
||||||
<*> mkStderrEmitter
|
<*> mkStderrEmitter
|
||||||
|
|
||||||
|
mkStderrRelayer :: Annex (Handle -> IO ())
|
||||||
|
mkStderrRelayer = do
|
||||||
|
quiet <- commandProgressDisabled
|
||||||
|
emitter <- mkStderrEmitter
|
||||||
|
return $ \h -> avoidProgress quiet h emitter
|
||||||
|
|
||||||
{- Generates an IO action that can be used to emit stderr.
|
{- Generates an IO action that can be used to emit stderr.
|
||||||
-
|
-
|
||||||
- When a progress meter is displayed, this takes care to avoid
|
- When a progress meter is displayed, this takes care to avoid
|
||||||
|
|
|
@ -17,6 +17,7 @@ import qualified Git
|
||||||
import Config
|
import Config
|
||||||
import Remote.Helper.Special
|
import Remote.Helper.Special
|
||||||
import Utility.Metered
|
import Utility.Metered
|
||||||
|
import Messages.Progress
|
||||||
import Logs.Transfer
|
import Logs.Transfer
|
||||||
import Logs.PreferredContent.Raw
|
import Logs.PreferredContent.Raw
|
||||||
import Logs.RemoteState
|
import Logs.RemoteState
|
||||||
|
@ -26,6 +27,7 @@ import Annex.UUID
|
||||||
import Creds
|
import Creds
|
||||||
|
|
||||||
import Control.Concurrent.STM
|
import Control.Concurrent.STM
|
||||||
|
import Control.Concurrent.Async
|
||||||
import System.Log.Logger (debugM)
|
import System.Log.Logger (debugM)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
|
||||||
|
@ -323,19 +325,26 @@ fromExternal lck external extractor a =
|
||||||
{- Starts an external remote process running, but does not handle checking
|
{- Starts an external remote process running, but does not handle checking
|
||||||
- VERSION, etc. -}
|
- VERSION, etc. -}
|
||||||
startExternal :: ExternalType -> Annex ExternalState
|
startExternal :: ExternalType -> Annex ExternalState
|
||||||
startExternal externaltype = liftIO $ do
|
startExternal externaltype = do
|
||||||
(Just hin, Just hout, _, pid) <- createProcess $ (proc cmd [])
|
errrelayer <- mkStderrRelayer
|
||||||
|
liftIO $ do
|
||||||
|
(Just hin, Just hout, Just herr, pid) <- createProcess $
|
||||||
|
(proc cmd [])
|
||||||
{ std_in = CreatePipe
|
{ std_in = CreatePipe
|
||||||
, std_out = CreatePipe
|
, std_out = CreatePipe
|
||||||
, std_err = Inherit
|
, std_err = CreatePipe
|
||||||
}
|
}
|
||||||
fileEncoding hin
|
fileEncoding hin
|
||||||
fileEncoding hout
|
fileEncoding hout
|
||||||
|
fileEncoding herr
|
||||||
|
stderrelay <- async $ errrelayer herr
|
||||||
checkearlytermination =<< getProcessExitCode pid
|
checkearlytermination =<< getProcessExitCode pid
|
||||||
return $ ExternalState
|
return $ ExternalState
|
||||||
{ externalSend = hin
|
{ externalSend = hin
|
||||||
, externalReceive = hout
|
, externalReceive = hout
|
||||||
, externalPid = pid
|
, externalShutdown = do
|
||||||
|
cancel stderrelay
|
||||||
|
void $ waitForProcess pid
|
||||||
, externalPrepared = Unprepared
|
, externalPrepared = Unprepared
|
||||||
}
|
}
|
||||||
where
|
where
|
||||||
|
@ -357,7 +366,7 @@ stopExternal external = liftIO $ stop =<< atomically (tryReadTMVar v)
|
||||||
void $ atomically $ tryTakeTMVar v
|
void $ atomically $ tryTakeTMVar v
|
||||||
hClose $ externalSend st
|
hClose $ externalSend st
|
||||||
hClose $ externalReceive st
|
hClose $ externalReceive st
|
||||||
void $ waitForProcess $ externalPid st
|
externalShutdown st
|
||||||
v = externalState external
|
v = externalState external
|
||||||
|
|
||||||
externalRemoteProgram :: ExternalType -> String
|
externalRemoteProgram :: ExternalType -> String
|
||||||
|
|
2
Remote/External/Types.hs
vendored
2
Remote/External/Types.hs
vendored
|
@ -70,7 +70,7 @@ type ExternalType = String
|
||||||
data ExternalState = ExternalState
|
data ExternalState = ExternalState
|
||||||
{ externalSend :: Handle
|
{ externalSend :: Handle
|
||||||
, externalReceive :: Handle
|
, externalReceive :: Handle
|
||||||
, externalPid :: ProcessHandle
|
, externalShutdown :: IO ()
|
||||||
, externalPrepared :: PrepareStatus
|
, externalPrepared :: PrepareStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,10 +197,6 @@ commandMeter progressparser oh meterupdate cmd params = catchBoolIO $
|
||||||
{- Runs a command, that may display one or more progress meters on
|
{- Runs a command, that may display one or more progress meters on
|
||||||
- either stdout or stderr, and prevents the meters from being displayed.
|
- either stdout or stderr, and prevents the meters from being displayed.
|
||||||
-
|
-
|
||||||
- To suppress progress output, while displaying other messages,
|
|
||||||
- filter out lines that contain \r (typically used to reset to the
|
|
||||||
- beginning of the line when updating a progress display).
|
|
||||||
-
|
|
||||||
- The other command output is handled as configured by the OutputHandler.
|
- The other command output is handled as configured by the OutputHandler.
|
||||||
-}
|
-}
|
||||||
demeterCommand :: OutputHandler -> FilePath -> [CommandParam] -> IO Bool
|
demeterCommand :: OutputHandler -> FilePath -> [CommandParam] -> IO Bool
|
||||||
|
@ -209,8 +205,8 @@ demeterCommand oh cmd params = demeterCommandEnv oh cmd params Nothing
|
||||||
demeterCommandEnv :: OutputHandler -> FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO Bool
|
demeterCommandEnv :: OutputHandler -> FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO Bool
|
||||||
demeterCommandEnv oh cmd params environ = catchBoolIO $
|
demeterCommandEnv oh cmd params environ = catchBoolIO $
|
||||||
withOEHandles createProcessSuccess p $ \(outh, errh) -> do
|
withOEHandles createProcessSuccess p $ \(outh, errh) -> do
|
||||||
ep <- async $ avoidprogress errh $ stderrHandler oh
|
ep <- async $ avoidProgress True errh $ stderrHandler oh
|
||||||
op <- async $ avoidprogress outh $ \l ->
|
op <- async $ avoidProgress True outh $ \l ->
|
||||||
unless (quietMode oh) $
|
unless (quietMode oh) $
|
||||||
putStrLn l
|
putStrLn l
|
||||||
wait ep
|
wait ep
|
||||||
|
@ -220,8 +216,13 @@ demeterCommandEnv oh cmd params environ = catchBoolIO $
|
||||||
p = (proc cmd (toCommand params))
|
p = (proc cmd (toCommand params))
|
||||||
{ env = environ }
|
{ env = environ }
|
||||||
|
|
||||||
avoidprogress h emitter = unlessM (hIsEOF h) $ do
|
{- To suppress progress output, while displaying other messages,
|
||||||
|
- filter out lines that contain \r (typically used to reset to the
|
||||||
|
- beginning of the line when updating a progress display).
|
||||||
|
-}
|
||||||
|
avoidProgress :: Bool -> Handle -> (String -> IO ()) -> IO ()
|
||||||
|
avoidProgress doavoid h emitter = unlessM (hIsEOF h) $ do
|
||||||
s <- hGetLine h
|
s <- hGetLine h
|
||||||
unless ('\r' `elem` s) $
|
unless (doavoid && '\r' `elem` s) $
|
||||||
emitter s
|
emitter s
|
||||||
avoidprogress h emitter
|
avoidProgress doavoid h emitter
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue