Skip to content

Commit 371e226

Browse files
committed
Probe for the version of common tools
Print them to stderr when starting the server. Adds cli command `--probe-tools` for easier debugging.
1 parent 70a98dc commit 371e226

File tree

4 files changed

+80
-1
lines changed

4 files changed

+80
-1
lines changed

Diff for: exe/Arguments.hs

+7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import System.Environment
2626

2727
data Arguments
2828
= VersionMode PrintVersion
29+
| ProbeToolsMode
2930
| LspMode LspArguments
3031
deriving Show
3132

@@ -54,6 +55,7 @@ getArguments exeName = execParser opts
5455
where
5556
opts = info ((
5657
VersionMode <$> printVersionParser exeName
58+
<|> probeToolsParser exeName
5759
<|> LspMode <$> arguments)
5860
<**> helper)
5961
( fullDesc
@@ -68,6 +70,11 @@ printVersionParser exeName =
6870
flag' PrintNumericVersion
6971
(long "numeric-version" <> help ("Show numeric version of " ++ exeName))
7072

73+
probeToolsParser :: String -> Parser Arguments
74+
probeToolsParser exeName =
75+
flag' ProbeToolsMode
76+
(long "probe-tools" <> help ("Show " ++ exeName ++ " version and other tools of interest"))
77+
7178
arguments :: Parser LspArguments
7279
arguments = LspArguments
7380
<$> switch (long "lsp" <> help "Start talking to an LSP server")

Diff for: exe/Main.hs

+12
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import HIE.Bios.Cradle
4444
import qualified Language.Haskell.LSP.Core as LSP
4545
import Ide.Logger
4646
import Ide.Plugin
47+
import Ide.Version
4748
import Ide.Plugin.Config
4849
import Ide.Types (IdePlugins, ipMap)
4950
import Language.Haskell.LSP.Messages
@@ -133,6 +134,12 @@ main = do
133134

134135
hlsVer <- haskellLanguageServerVersion
135136
case args of
137+
ProbeToolsMode -> do
138+
programsOfInterest <- findProgramVersions
139+
putStrLn hlsVer
140+
putStrLn "Tool versions found on the $PATH"
141+
putStrLn $ showProgramVersionOfInterest programsOfInterest
142+
136143
VersionMode PrintVersion ->
137144
putStrLn hlsVer
138145

@@ -176,6 +183,7 @@ runLspMode lspArgs@LspArguments {..} = do
176183
hPutStrLn stderr $ " with plugins: " <> show (Map.keys $ ipMap idePlugins')
177184
hPutStrLn stderr $ " in directory: " <> dir
178185
hPutStrLn stderr "If you are seeing this in a terminal, you probably should have run ghcide WITHOUT the --lsp option!"
186+
179187
runLanguageServer options (pluginHandler plugins) getInitialConfig getConfigFromNotification $ \getLspId event vfs caps wProg wIndefProg _getConfig -> do
180188
t <- t
181189
hPutStrLn stderr $ "Started LSP server in " ++ showDuration t
@@ -199,6 +207,10 @@ runLspMode lspArgs@LspArguments {..} = do
199207

200208
putStrLn $ "(haskell-language-server)Ghcide setup tester in " ++ dir ++ "."
201209
putStrLn "Report bugs at https://github.com/haskell/haskell-language-server/issues"
210+
programsOfInterest <- findProgramVersions
211+
putStrLn ""
212+
putStrLn "Tool versions found on the $PATH"
213+
putStrLn $ showProgramVersionOfInterest programsOfInterest
202214

203215
putStrLn $ "\nStep 1/4: Finding files to test in " ++ dir
204216
files <- expandFiles (argFiles ++ ["." | null argFiles])

Diff for: exe/Wrapper.hs

+11-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ main = do
3030

3131
hlsVer <- haskellLanguageServerVersion
3232
case args of
33+
ProbeToolsMode -> do
34+
programsOfInterest <- findProgramVersions
35+
putStrLn hlsVer
36+
putStrLn "Tool versions found on the $PATH"
37+
putStrLn $ showProgramVersionOfInterest programsOfInterest
38+
3339
VersionMode PrintVersion ->
3440
putStrLn hlsVer
3541

@@ -60,7 +66,11 @@ launchHaskellLanguageServer LspArguments{..} = do
6066
hPutStrLn stderr $ "Arguments: " ++ show args
6167
hPutStrLn stderr $ "Cradle directory: " ++ cradleRootDir cradle
6268
hPutStrLn stderr $ "Cradle type: " ++ show (actionName (cradleOptsProg cradle))
63-
69+
programsOfInterest <- findProgramVersions
70+
hPutStrLn stderr ""
71+
hPutStrLn stderr "Tool versions found on the $PATH"
72+
hPutStrLn stderr $ showProgramVersionOfInterest programsOfInterest
73+
hPutStrLn stderr ""
6474
-- Get the ghc version -- this might fail!
6575
hPutStrLn stderr $ "Consulting the cradle to get project GHC version..."
6676
ghcVersion <- getRuntimeGhcVersion' cradle

Diff for: src/Ide/Version.hs

+50
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
{-# LANGUAGE RecordWildCards #-}
2+
{-# LANGUAGE LambdaCase #-}
13
{-# LANGUAGE CPP #-}
24
{-# LANGUAGE TemplateHaskell #-}
35
{-# LANGUAGE OverloadedStrings #-}
@@ -9,6 +11,11 @@ import Development.GitRev (gitCommitCount)
911
import Options.Applicative.Simple (simpleVersion)
1012
import qualified Paths_haskell_language_server as Meta
1113
import System.Info
14+
import Data.Version
15+
import Data.Maybe (listToMaybe)
16+
import System.Process
17+
import System.Exit
18+
import Text.ParserCombinators.ReadP
1219

1320
hlsVersion :: String
1421
hlsVersion =
@@ -24,3 +31,46 @@ hlsVersion =
2431
]
2532
where
2633
hlsGhcDisplayVersion = compilerName ++ "-" ++ VERSION_ghc
34+
35+
data ProgramsOfInterest = ProgramsOfInterest
36+
{ cabalVersion :: Maybe Version
37+
, stackVersion :: Maybe Version
38+
, ghcVersion :: Maybe Version
39+
}
40+
41+
showProgramVersionOfInterest :: ProgramsOfInterest -> String
42+
showProgramVersionOfInterest ProgramsOfInterest {..} =
43+
unlines
44+
[ concat ["cabal:\t\t", showVersionWithDefault cabalVersion]
45+
, concat ["stack:\t\t", showVersionWithDefault stackVersion]
46+
, concat ["ghc:\t\t", showVersionWithDefault ghcVersion]
47+
]
48+
where
49+
showVersionWithDefault :: Maybe Version -> String
50+
showVersionWithDefault = maybe ("Not found") showVersion
51+
52+
findProgramVersions :: IO ProgramsOfInterest
53+
findProgramVersions = ProgramsOfInterest
54+
<$> findVersionOf "cabal"
55+
<*> findVersionOf "stack"
56+
<*> findVersionOf "ghc"
57+
58+
-- | Find the version of the given program.
59+
-- Assumes the program accepts the cli argument "--numeric-version".
60+
-- If the invocation has a non-zero exit-code, we return 'Nothing'
61+
findVersionOf :: FilePath -> IO (Maybe Version)
62+
findVersionOf tool =
63+
readProcessWithExitCode tool ["--numeric-version"] "" >>= \case
64+
(ExitSuccess, sout, _) -> pure $ consumeParser myVersionParser sout
65+
_ -> pure $ Nothing
66+
67+
where
68+
myVersionParser = do
69+
skipSpaces
70+
version <- parseVersion
71+
skipSpaces
72+
pure version
73+
74+
consumeParser :: ReadP a -> String -> Maybe a
75+
consumeParser p input = listToMaybe $ map fst . filter (null . snd) $ readP_to_S p input
76+

0 commit comments

Comments
 (0)