Skip to content

Commit

Permalink
Use stderr for Cabal's diagnostic messages instead of stdout
Browse files Browse the repository at this point in the history
  • Loading branch information
Rufflewind committed Sep 23, 2017
1 parent d53b6e0 commit 20d5790
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Cabal/Cabal.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ library
deepseq >= 1.3 && < 1.5,
filepath >= 1.3 && < 1.5,
pretty >= 1.1 && < 1.2,
process >= 1.1.0.1 && < 1.7,
process >= 1.2.1.0 && < 1.7,
time >= 1.4 && < 1.9

if flag(old-directory)
Expand Down
3 changes: 2 additions & 1 deletion Cabal/Distribution/Simple/Program/GHC.hs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,8 @@ ghcInvocation :: ConfiguredProgram -> Compiler -> Platform -> GhcOptions
-> ProgramInvocation
ghcInvocation prog comp platform opts =
(programInvocation prog (renderGhcOptions comp platform opts)) {
progInvokePathEnv = fromNubListR (ghcOptExtraPath opts)
progInvokePathEnv = fromNubListR (ghcOptExtraPath opts),
progInvokeOutAsErr = True
}

renderGhcOptions :: Compiler -> Platform -> GhcOptions -> [String]
Expand Down
21 changes: 14 additions & 7 deletions Cabal/Distribution/Simple/Program/Run.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import Distribution.Compat.Environment

import qualified Data.Map as Map
import System.FilePath
import System.IO ( stderr )
import System.Exit
( ExitCode(..), exitWith )

Expand All @@ -56,7 +57,8 @@ data ProgramInvocation = ProgramInvocation {
progInvokeCwd :: Maybe FilePath,
progInvokeInput :: Maybe String,
progInvokeInputEncoding :: IOEncoding,
progInvokeOutputEncoding :: IOEncoding
progInvokeOutputEncoding :: IOEncoding,
progInvokeOutAsErr :: Bool
}

data IOEncoding = IOEncodingText -- locale mode text
Expand All @@ -76,7 +78,8 @@ emptyProgramInvocation =
progInvokeCwd = Nothing,
progInvokeInput = Nothing,
progInvokeInputEncoding = IOEncodingText,
progInvokeOutputEncoding = IOEncodingText
progInvokeOutputEncoding = IOEncodingText,
progInvokeOutAsErr = False
}

simpleProgramInvocation :: FilePath -> [String] -> ProgramInvocation
Expand Down Expand Up @@ -116,16 +119,20 @@ runProgramInvocation verbosity
progInvokeEnv = envOverrides,
progInvokePathEnv = extraPath,
progInvokeCwd = mcwd,
progInvokeInput = Nothing
progInvokeInput = Nothing,
progInvokeOutAsErr = outAsErr
} = do
pathOverride <- getExtraPathEnv envOverrides extraPath
menv <- getEffectiveEnvironment (envOverrides ++ pathOverride)
exitCode <- rawSystemIOWithEnv verbosity
path args
mcwd menv
Nothing Nothing Nothing
exitCode <- rawSystemIOWithEnv_ False verbosity
path args
mcwd menv
Nothing childStdout Nothing
when (exitCode /= ExitSuccess) $
exitWith exitCode
where
childStdout | outAsErr = Just stderr
| otherwise = Nothing

runProgramInvocation verbosity
ProgramInvocation {
Expand Down
79 changes: 59 additions & 20 deletions Cabal/Distribution/Simple/Utils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ module Distribution.Simple.Utils (
rawSystemStdout,
rawSystemStdInOut,
rawSystemIOWithEnv,
rawSystemIOWithEnv_,
createProcessWithEnv,
createProcessWithEnv_,
maybeExit,
xargs,
findProgramLocation,
Expand Down Expand Up @@ -222,8 +224,8 @@ import System.FilePath
, splitExtension, splitExtensions, splitDirectories
, searchPathSeparator )
import System.IO
( Handle, hSetBinaryMode, hGetContents, stderr, stdout, hPutStr, hFlush
, hClose, hSetBuffering, BufferMode(..) )
( Handle, hSetBinaryMode, hGetContents, stderr, stdout, hPutStr, hPutStrLn
, hFlush, hClose, hSetBuffering, BufferMode(..) )
import System.IO.Error
import System.IO.Unsafe
( unsafeInterleaveIO )
Expand All @@ -236,8 +238,8 @@ import Numeric (showFFloat)
import qualified System.Process as Process
( CreateProcess(..), StdStream(..), proc)
import System.Process
( ProcessHandle, createProcess, rawSystem, runInteractiveProcess
, showCommandForUser, waitForProcess)
( ProcessHandle, createProcess, createProcess_, rawSystem
, runInteractiveProcess, showCommandForUser, waitForProcess)

import qualified Text.PrettyPrint as Disp

Expand Down Expand Up @@ -466,7 +468,8 @@ notice :: Verbosity -> String -> IO ()
notice verbosity msg = withFrozenCallStack $ do
when (verbosity >= normal) $ do
ts <- getPOSIXTime
hPutStr stdout . withMetadata ts NormalMark FlagTrace verbosity
hFlush stdout
hPutStr stderr . withMetadata ts NormalMark FlagTrace verbosity
. wrapTextVerbosity verbosity
$ msg

Expand All @@ -477,7 +480,8 @@ noticeNoWrap :: Verbosity -> String -> IO ()
noticeNoWrap verbosity msg = withFrozenCallStack $ do
when (verbosity >= normal) $ do
ts <- getPOSIXTime
hPutStr stdout . withMetadata ts NormalMark FlagTrace verbosity $ msg
hFlush stdout
hPutStr stderr . withMetadata ts NormalMark FlagTrace verbosity $ msg

-- | Pretty-print a 'Disp.Doc' status message at 'normal' verbosity
-- level. Use this if you need fancy formatting.
Expand All @@ -486,7 +490,8 @@ noticeDoc :: Verbosity -> Disp.Doc -> IO ()
noticeDoc verbosity msg = withFrozenCallStack $ do
when (verbosity >= normal) $ do
ts <- getPOSIXTime
hPutStr stdout . withMetadata ts NormalMark FlagTrace verbosity
hFlush stdout
hPutStr stderr . withMetadata ts NormalMark FlagTrace verbosity
. Disp.renderStyle defaultStyle $ msg

-- | Display a "setup status message". Prefer using setupMessage'
Expand All @@ -504,15 +509,17 @@ info :: Verbosity -> String -> IO ()
info verbosity msg = withFrozenCallStack $
when (verbosity >= verbose) $ do
ts <- getPOSIXTime
hPutStr stdout . withMetadata ts NeverMark FlagTrace verbosity
hFlush stdout
hPutStr stderr . withMetadata ts NeverMark FlagTrace verbosity
. wrapTextVerbosity verbosity
$ msg

infoNoWrap :: Verbosity -> String -> IO ()
infoNoWrap verbosity msg = withFrozenCallStack $
when (verbosity >= verbose) $ do
ts <- getPOSIXTime
hPutStr stdout . withMetadata ts NeverMark FlagTrace verbosity
hFlush stdout
hPutStr stderr . withMetadata ts NeverMark FlagTrace verbosity
$ msg

-- | Detailed internal debugging information
Expand All @@ -523,31 +530,34 @@ debug :: Verbosity -> String -> IO ()
debug verbosity msg = withFrozenCallStack $
when (verbosity >= deafening) $ do
ts <- getPOSIXTime
hPutStr stdout . withMetadata ts NeverMark FlagTrace verbosity
hFlush stdout
hPutStr stderr . withMetadata ts NeverMark FlagTrace verbosity
. wrapTextVerbosity verbosity
$ msg
-- ensure that we don't lose output if we segfault/infinite loop
hFlush stdout
hFlush stderr

-- | A variant of 'debug' that doesn't perform the automatic line
-- wrapping. Produces better output in some cases.
debugNoWrap :: Verbosity -> String -> IO ()
debugNoWrap verbosity msg = withFrozenCallStack $
when (verbosity >= deafening) $ do
ts <- getPOSIXTime
hPutStr stdout . withMetadata ts NeverMark FlagTrace verbosity
hFlush stdout
hPutStr stderr . withMetadata ts NeverMark FlagTrace verbosity
$ msg
-- ensure that we don't lose output if we segfault/infinite loop
hFlush stdout
hFlush stderr

-- | Perform an IO action, catching any IO exceptions and printing an error
-- if one occurs.
chattyTry :: String -- ^ a description of the action we were attempting
-> IO () -- ^ the action itself
-> IO ()
chattyTry desc action =
catchIO action $ \exception ->
putStrLn $ "Error while " ++ desc ++ ": " ++ show exception
catchIO action $ \exception -> do
hFlush stdout
hPutStrLn stderr $ "Error while " ++ desc ++ ": " ++ show exception

-- | Run an IO computation, returning @e@ if it raises a "file
-- does not exist" error.
Expand Down Expand Up @@ -764,9 +774,21 @@ rawSystemIOWithEnv :: Verbosity
-> Maybe Handle -- ^ stdout
-> Maybe Handle -- ^ stderr
-> IO ExitCode
rawSystemIOWithEnv verbosity path args mcwd menv inp out err = withFrozenCallStack $ do
(_,_,_,ph) <- createProcessWithEnv verbosity path args mcwd menv
(mbToStd inp) (mbToStd out) (mbToStd err)
rawSystemIOWithEnv = rawSystemIOWithEnv_ True

rawSystemIOWithEnv_ :: Bool -- ^ whether to close the provided handles
-> Verbosity
-> FilePath
-> [String]
-> Maybe FilePath -- ^ New working dir or inherit
-> Maybe [(String, String)] -- ^ New environment or inherit
-> Maybe Handle -- ^ stdin
-> Maybe Handle -- ^ stdout
-> Maybe Handle -- ^ stderr
-> IO ExitCode
rawSystemIOWithEnv_ close verbosity path args mcwd menv inp out err = withFrozenCallStack $ do
(_,_,_,ph) <- createProcessWithEnv_ close verbosity path args mcwd menv
(mbToStd inp) (mbToStd out) (mbToStd err)
exitcode <- waitForProcess ph
unless (exitcode == ExitSuccess) $ do
debug verbosity $ path ++ " returned " ++ show exitcode
Expand All @@ -787,10 +809,27 @@ createProcessWithEnv ::
-> IO (Maybe Handle, Maybe Handle, Maybe Handle,ProcessHandle)
-- ^ Any handles created for stdin, stdout, or stderr
-- with 'CreateProcess', and a handle to the process.
createProcessWithEnv verbosity path args mcwd menv inp out err = withFrozenCallStack $ do
createProcessWithEnv = createProcessWithEnv_ True

createProcessWithEnv_ ::
Bool -- ^ whether to close the provided handles
-> Verbosity
-> FilePath
-> [String]
-> Maybe FilePath -- ^ New working dir or inherit
-> Maybe [(String, String)] -- ^ New environment or inherit
-> Process.StdStream -- ^ stdin
-> Process.StdStream -- ^ stdout
-> Process.StdStream -- ^ stderr
-> IO (Maybe Handle, Maybe Handle, Maybe Handle,ProcessHandle)
-- ^ Any handles created for stdin, stdout, or stderr
-- with 'CreateProcess', and a handle to the process.
createProcessWithEnv_ close verbosity path args mcwd menv inp out err = withFrozenCallStack $ do
printRawCommandAndArgsAndEnv verbosity path args mcwd menv
hFlush stdout
(inp', out', err', ph) <- createProcess $
(inp', out', err', ph) <- (if close
then createProcess
else createProcess_ "createProcess_")
(Process.proc path args) {
Process.cwd = mcwd
, Process.env = menv
Expand Down
3 changes: 2 additions & 1 deletion Cabal/Distribution/Utils/LogProgress.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Distribution.Compat.Prelude
import Distribution.Utils.Progress
import Distribution.Verbosity
import Distribution.Simple.Utils
import System.IO ( stderr, hPutStrLn )
import Text.PrettyPrint

type CtxMsg = Doc
Expand Down Expand Up @@ -54,7 +55,7 @@ runLogProgress verbosity (LogProgress m) =
}
step_fn :: LogMsg -> NoCallStackIO a -> NoCallStackIO a
step_fn doc go = do
putStrLn (render doc)
hPutStrLn stderr (render doc)
go
fail_fn :: Doc -> NoCallStackIO a
fail_fn doc = do
Expand Down

0 comments on commit 20d5790

Please sign in to comment.