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
Send all diagnostic messages (including debug, info, notice) to stderr
instead of stdout.  Likewise, redirect GHC's stdout to stderr as GHC
sends progress output to stdout due to GHC Trac #3636.
  • Loading branch information
Rufflewind committed Sep 27, 2017
1 parent d53b6e0 commit 7dadaf8
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 27 deletions.
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
15 changes: 11 additions & 4 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
Nothing childStdout Nothing
when (exitCode /= ExitSuccess) $
exitWith exitCode
where
childStdout | outAsErr = Just stderr
| otherwise = Nothing

runProgramInvocation verbosity
ProgramInvocation {
Expand Down
36 changes: 22 additions & 14 deletions Cabal/Distribution/Simple/Utils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,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 Down Expand Up @@ -466,7 +466,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 +478,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 +488,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 +507,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 +528,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 @@ -754,7 +762,7 @@ rawSystemExitWithEnv verbosity path args env = withFrozenCallStack $ do
debug verbosity $ path ++ " returned " ++ show exitcode
exitWith exitcode

-- Closes the passed in handles before returning.
-- Closes the passed in handles before returning (excluding standard handles).
rawSystemIOWithEnv :: Verbosity
-> FilePath
-> [String]
Expand Down
2 changes: 1 addition & 1 deletion Cabal/Distribution/Utils/LogProgress.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ runLogProgress verbosity (LogProgress m) =
}
step_fn :: LogMsg -> NoCallStackIO a -> NoCallStackIO a
step_fn doc go = do
putStrLn (render doc)
notice verbosity (render doc)
go
fail_fn :: Doc -> NoCallStackIO a
fail_fn doc = do
Expand Down
8 changes: 4 additions & 4 deletions cabal-install/Distribution/Client/GenBounds.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import Distribution.Simple.Compiler
import Distribution.Simple.Program
( ProgramDb )
import Distribution.Simple.Utils
( tryFindPackageDesc )
( notice, tryFindPackageDesc, warn )
import Distribution.System
( Platform )
import Distribution.Text
Expand Down Expand Up @@ -116,13 +116,13 @@ genBounds verbosity packageDBs repoCtxt comp platform progdb mSandboxPkgInfo
let epd = finalizePD [] defaultComponentRequestedSpec
(const True) platform cinfo [] gpd
case epd of
Left _ -> putStrLn "finalizePD failed"
Left _ -> warn verbosity "finalizePD failed"
Right (pd,_) -> do
let needBounds = filter (not . hasUpperBound . depVersion) $
buildDepends pd

if (null needBounds)
then putStrLn
then notice verbosity
"Congratulations, all your dependencies have upper bounds!"
else go needBounds
where
Expand All @@ -131,7 +131,7 @@ genBounds verbosity packageDBs repoCtxt comp platform progdb mSandboxPkgInfo
verbosity packageDBs repoCtxt comp platform progdb
mSandboxPkgInfo globalFlags freezeFlags

putStrLn boundsNeededMsg
notice verbosity boundsNeededMsg

let isNeeded pkg = unPackageName (packageName pkg)
`elem` map depName needBounds
Expand Down
6 changes: 3 additions & 3 deletions cabal-install/Distribution/Client/Install.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ import System.Directory
import System.FilePath
( (</>), (<.>), equalFilePath, takeDirectory )
import System.IO
( openFile, IOMode(AppendMode), hClose )
( openFile, IOMode(AppendMode), hPutStr, hClose, stderr )
import System.IO.Error
( isDoesNotExistError, ioeGetFileName )

Expand Down Expand Up @@ -1206,11 +1206,11 @@ executeInstallPlan verbosity jobCtl keepGoing useLogFile plan0 installPkg =
Nothing -> return ()
Just (mkLogFileName, _) -> do
let logName = mkLogFileName pkgid uid
putStr $ "Build log ( " ++ logName ++ " ):\n"
hPutStr stderr $ "Build log ( " ++ logName ++ " ):\n"
printFile logName

printFile :: FilePath -> IO ()
printFile path = readFile path >>= putStr
printFile path = readFile path >>= hPutStr stderr

-- | Call an installer for an 'SourcePackage' but override the configure
-- flags with the ones given by the 'ReadyPackage'. In particular the
Expand Down

0 comments on commit 7dadaf8

Please sign in to comment.