Skip to content

Commit 6b29d09

Browse files
committed
no longer silence stderr
Instead, send all ghcide output through the logger and keep stderr open for fatals
1 parent 1ce6cc9 commit 6b29d09

File tree

4 files changed

+37
-53
lines changed

4 files changed

+37
-53
lines changed

ghcide/session-loader/Development/IDE/Session.hs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ data SessionLoadingOptions = SessionLoadingOptions
102102
-- or 'Nothing' to respect the cradle setting
103103
, getCacheDirs :: String -> [String] -> IO CacheDirs
104104
-- | Return the GHC lib dir to use for the 'unsafeGlobalDynFlags'
105-
, getInitialGhcLibDir :: FilePath -> IO (Maybe LibDir)
105+
, getInitialGhcLibDir :: Logger -> FilePath -> IO (Maybe LibDir)
106106
, fakeUid :: UnitId
107107
-- ^ unit id used to tag the internal component built by ghcide
108108
-- To reuse external interface files the unit ids must match,
@@ -140,11 +140,11 @@ loadWithImplicitCradle mHieYaml rootDir = do
140140
Just yaml -> HieBios.loadCradle yaml
141141
Nothing -> loadImplicitHieCradle $ addTrailingPathSeparator rootDir
142142

143-
getInitialGhcLibDirDefault :: FilePath -> IO (Maybe LibDir)
144-
getInitialGhcLibDirDefault rootDir = do
143+
getInitialGhcLibDirDefault :: Logger -> FilePath -> IO (Maybe LibDir)
144+
getInitialGhcLibDirDefault logger rootDir = do
145145
hieYaml <- findCradle def rootDir
146146
cradle <- loadCradle def hieYaml rootDir
147-
hPutStrLn stderr $ "setInitialDynFlags cradle: " ++ show cradle
147+
logDebug logger $ T.pack $ "setInitialDynFlags cradle: " ++ show cradle
148148
libDirRes <- getRuntimeGhcLibDir cradle
149149
case libDirRes of
150150
CradleSuccess libdir -> pure $ Just $ LibDir libdir
@@ -156,9 +156,9 @@ getInitialGhcLibDirDefault rootDir = do
156156
pure Nothing
157157

158158
-- | Sets `unsafeGlobalDynFlags` on using the hie-bios cradle and returns the GHC libdir
159-
setInitialDynFlags :: FilePath -> SessionLoadingOptions -> IO (Maybe LibDir)
160-
setInitialDynFlags rootDir SessionLoadingOptions{..} = do
161-
libdir <- getInitialGhcLibDir rootDir
159+
setInitialDynFlags :: Logger -> FilePath -> SessionLoadingOptions -> IO (Maybe LibDir)
160+
setInitialDynFlags logger rootDir SessionLoadingOptions{..} = do
161+
libdir <- getInitialGhcLibDir logger rootDir
162162
dynFlags <- mapM dynFlagsForPrinting libdir
163163
mapM_ setUnsafeGlobalDynFlags dynFlags
164164
pure libdir
@@ -167,8 +167,8 @@ setInitialDynFlags rootDir SessionLoadingOptions{..} = do
167167
-- writing. Actions are picked off one by one from the `HieWriterChan` and executed in serial
168168
-- by a worker thread using a dedicated database connection.
169169
-- This is done in order to serialize writes to the database, or else SQLite becomes unhappy
170-
runWithDb :: FilePath -> (HieDb -> IndexQueue -> IO ()) -> IO ()
171-
runWithDb fp k = do
170+
runWithDb :: Logger -> FilePath -> (HieDb -> IndexQueue -> IO ()) -> IO ()
171+
runWithDb logger fp k = do
172172
-- Delete the database if it has an incompatible schema version
173173
withHieDb fp (const $ pure ())
174174
`Safe.catch` \IncompatibleSchemaVersion{} -> removeFile fp
@@ -186,9 +186,9 @@ runWithDb fp k = do
186186
k <- atomically $ readTQueue chan
187187
k db
188188
`Safe.catch` \e@SQLError{} -> do
189-
hPutStrLn stderr $ "SQLite error in worker, ignoring: " ++ show e
189+
logDebug logger $ T.pack $ "SQLite error in worker, ignoring: " ++ show e
190190
`Safe.catchAny` \e -> do
191-
hPutStrLn stderr $ "Uncaught error in database worker, ignoring: " ++ show e
191+
logDebug logger $ T.pack $ "Uncaught error in database worker, ignoring: " ++ show e
192192

193193

194194
getHieDbLoc :: FilePath -> IO FilePath
@@ -361,7 +361,7 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do
361361
res <- loadDLL hscEnv "libm.so.6"
362362
case res of
363363
Nothing -> pure ()
364-
Just err -> hPutStrLn stderr $
364+
Just err -> logDebug logger $ T.pack $
365365
"Error dynamically loading libm.so.6:\n" <> err
366366

367367
-- Make a map from unit-id to DynFlags, this is used when trying to
@@ -425,7 +425,7 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do
425425
let progMsg = "Setting up " <> T.pack (takeBaseName (cradleRootDir cradle))
426426
<> " (for " <> T.pack lfp <> ")"
427427
eopts <- mRunLspTCallback lspEnv (withIndefiniteProgress progMsg NotCancellable) $
428-
cradleToOptsAndLibDir cradle cfp
428+
cradleToOptsAndLibDir logger cradle cfp
429429

430430
logDebug logger $ T.pack ("Session loading result: " <> show eopts)
431431
case eopts of
@@ -495,11 +495,11 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do
495495
-- This then builds dependencies or whatever based on the cradle, gets the
496496
-- GHC options/dynflags needed for the session and the GHC library directory
497497

498-
cradleToOptsAndLibDir :: Show a => Cradle a -> FilePath
498+
cradleToOptsAndLibDir :: Show a => Logger -> Cradle a -> FilePath
499499
-> IO (Either [CradleError] (ComponentOptions, FilePath))
500-
cradleToOptsAndLibDir cradle file = do
500+
cradleToOptsAndLibDir logger cradle file = do
501501
-- Start off by getting the session options
502-
hPutStrLn stderr $ "Output from setting up the cradle " <> show cradle
502+
logDebug logger $ T.pack $ "Output from setting up the cradle " <> show cradle
503503
cradleRes <- HieBios.getCompilerOptions file cradle
504504
case cradleRes of
505505
CradleSuccess r -> do

ghcide/src/Development/IDE/LSP/LanguageServer.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ runLanguageServer options inH outH getHieDbLoc defaultConfig onConfigurationChan
141141
T.pack $ "Fatal error in server thread: " <> show e
142142
exitClientMsg
143143
handleServerException _ = pure ()
144-
_ <- flip forkFinally handleServerException $ runWithDb dbLoc $ \hiedb hieChan -> do
144+
logger = ideLogger ide
145+
_ <- flip forkFinally handleServerException $ runWithDb logger dbLoc $ \hiedb hieChan -> do
145146
putMVar dbMVar (hiedb,hieChan)
146147
forever $ do
147148
msg <- readChan clientMsgChan

ghcide/src/Development/IDE/Main.hs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ import Development.IDE.Session (SessionLoadingOptions,
6363
setInitialDynFlags)
6464
import Development.IDE.Types.Location (NormalizedUri,
6565
toNormalizedFilePath')
66-
import Development.IDE.Types.Logger (Logger (Logger))
66+
import Development.IDE.Types.Logger (Logger (Logger),
67+
logDebug, logInfo)
6768
import Development.IDE.Types.Options (IdeGhcSession,
6869
IdeOptions (optCheckParents, optCheckProject, optReportProgress, optRunSubset),
6970
IdeTesting (IdeTesting),
@@ -251,20 +252,20 @@ defaultMain Arguments{..} = do
251252
LT.putStrLn $ decodeUtf8 $ A.encodePretty $ pluginsToDefaultConfig argsHlsPlugins
252253
LSP -> withNumCapabilities (maybe (numProcessors `div` 2) fromIntegral argsThreads) $ do
253254
t <- offsetTime
254-
hPutStrLn stderr "Starting LSP server..."
255-
hPutStrLn stderr "If you are seeing this in a terminal, you probably should have run WITHOUT the --lsp option!"
255+
logInfo logger "Starting LSP server..."
256+
logInfo logger "If you are seeing this in a terminal, you probably should have run WITHOUT the --lsp option!"
256257
runLanguageServer options inH outH argsGetHieDbLoc argsDefaultHlsConfig argsOnConfigChange (pluginHandlers plugins) $ \env vfs rootPath hiedb hieChan -> do
257258
traverse_ IO.setCurrentDirectory rootPath
258259
t <- t
259-
hPutStrLn stderr $ "Started LSP server in " ++ showDuration t
260+
logInfo logger $ T.pack $ "Started LSP server in " ++ showDuration t
260261

261262
dir <- maybe IO.getCurrentDirectory return rootPath
262263

263264
-- We want to set the global DynFlags right now, so that we can use
264265
-- `unsafeGlobalDynFlags` even before the project is configured
265266
_mlibdir <-
266-
setInitialDynFlags dir argsSessionLoadingOptions
267-
`catchAny` (\e -> (hPutStrLn stderr $ "setInitialDynFlags: " ++ displayException e) >> pure Nothing)
267+
setInitialDynFlags logger dir argsSessionLoadingOptions
268+
`catchAny` (\e -> (logDebug logger $ T.pack $ "setInitialDynFlags: " ++ displayException e) >> pure Nothing)
268269

269270

270271
sessionLoader <- loadSessionWithOptions argsSessionLoadingOptions dir
@@ -273,7 +274,7 @@ defaultMain Arguments{..} = do
273274

274275
-- disable runSubset if the client doesn't support watched files
275276
runSubset <- (optRunSubset def_options &&) <$> LSP.runLspT env isWatchSupported
276-
hPutStrLn stderr $ "runSubset: " <> show runSubset
277+
logDebug logger $ T.pack $ "runSubset: " <> show runSubset
277278

278279
let options = def_options
279280
{ optReportProgress = clientSupportsProgress caps
@@ -299,7 +300,7 @@ defaultMain Arguments{..} = do
299300
Check argFiles -> do
300301
dir <- IO.getCurrentDirectory
301302
dbLoc <- getHieDbLoc dir
302-
runWithDb dbLoc $ \hiedb hieChan -> do
303+
runWithDb logger dbLoc $ \hiedb hieChan -> do
303304
-- GHC produces messages with UTF8 in them, so make sure the terminal doesn't error
304305
hSetEncoding stdout utf8
305306
hSetEncoding stderr utf8
@@ -363,14 +364,14 @@ defaultMain Arguments{..} = do
363364
Db dir opts cmd -> do
364365
dbLoc <- getHieDbLoc dir
365366
hPutStrLn stderr $ "Using hiedb at: " ++ dbLoc
366-
mlibdir <- setInitialDynFlags dir def
367+
mlibdir <- setInitialDynFlags logger dir def
367368
case mlibdir of
368369
Nothing -> exitWith $ ExitFailure 1
369370
Just libdir -> HieDb.runCommand libdir opts{HieDb.database = dbLoc} cmd
370371

371372
Custom projectRoot (IdeCommand c) -> do
372373
dbLoc <- getHieDbLoc projectRoot
373-
runWithDb dbLoc $ \hiedb hieChan -> do
374+
runWithDb logger dbLoc $ \hiedb hieChan -> do
374375
vfs <- makeVFSHandle
375376
sessionLoader <- loadSessionWithOptions argsSessionLoadingOptions "."
376377
let def_options = argsIdeOptions argsDefaultHlsConfig sessionLoader

hls-test-utils/src/Test/Hls.hs

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,14 @@ import Ide.Plugin.Config (Config, formattingProvider)
5353
import Ide.PluginUtils (idePluginsToPluginDesc, pluginDescToIdePlugins)
5454
import Ide.Types
5555
import Language.LSP.Test
56-
import Language.LSP.Types hiding
57-
(SemanticTokenAbsolute (length, line),
58-
SemanticTokenRelative (length),
59-
SemanticTokensEdit (_start))
60-
import Language.LSP.Types.Capabilities (ClientCapabilities)
61-
import System.Directory (getCurrentDirectory,
62-
setCurrentDirectory)
63-
import System.Environment.Blank (getEnvDefault)
56+
import Language.LSP.Types hiding
57+
(SemanticTokenAbsolute (length, line),
58+
SemanticTokenRelative (length),
59+
SemanticTokensEdit (_start))
60+
import Language.LSP.Types.Capabilities (ClientCapabilities)
61+
import System.Directory (getCurrentDirectory,
62+
setCurrentDirectory)
6463
import System.FilePath
65-
import System.IO.Extra
6664
import System.IO.Unsafe (unsafePerformIO)
6765
import System.Process.Extra (createPipe)
6866
import System.Time.Extra
@@ -133,22 +131,6 @@ runSessionWithServerFormatter plugin formatter =
133131
def
134132
fullCaps
135133

136-
-- | Run an action, with stderr silenced
137-
silenceStderr :: IO a -> IO a
138-
silenceStderr action = do
139-
showStderr <- getEnvDefault "LSP_TEST_LOG_STDERR" "0"
140-
case showStderr of
141-
"0" -> withTempFile $ \temp ->
142-
bracket (openFile temp ReadWriteMode) hClose $ \h -> do
143-
old <- hDuplicate stderr
144-
buf <- hGetBuffering stderr
145-
h `hDuplicateTo'` stderr
146-
action `finally` do
147-
old `hDuplicateTo'` stderr
148-
hSetBuffering stderr buf
149-
hClose old
150-
_ -> action
151-
152134
-- | Restore cwd after running an action
153135
keepCurrentDirectory :: IO a -> IO a
154136
keepCurrentDirectory = bracket getCurrentDirectory setCurrentDirectory . const
@@ -171,7 +153,7 @@ runSessionWithServer' ::
171153
FilePath ->
172154
Session a ->
173155
IO a
174-
runSessionWithServer' plugin conf sconf caps root s = withLock lock $ keepCurrentDirectory $ silenceStderr $ do
156+
runSessionWithServer' plugin conf sconf caps root s = withLock lock $ keepCurrentDirectory $ do
175157
(inR, inW) <- createPipe
176158
(outR, outW) <- createPipe
177159
server <-

0 commit comments

Comments
 (0)