cabal-clean-0.2.20230609: src/DiscoverGHCs.hs
-- | Discover installed GHCs.
module DiscoverGHCs where
import Control.Exception
( evaluate )
import System.FilePath
( getSearchPath, stripExtension, takeFileName )
import System.FilePath.Find
( find, anyPerms, depth, fileName, (<=?), (~~?), (&&?) )
import System.IO.Silently
( hSilence )
import Util
import Options
import Types
-- | Discover executables ghc-VERSION on the PATH.
discoverGHCs :: Options -> IO [CompilerVersion]
discoverGHCs opts = do
-- Get PATH.
path <- getSearchPath
chatLines opts $ "PATH:" : map ("- " ++) path
-- Look for ghc-* executables on PATH.
ghcs <- hSilence [stderr] $ do -- Silence warnings about broken symlinks produced by @find@.
evaluate =<< do -- Needed under Windows, otherwise warnings are raised too lazily
-- and not caught by @hSilence@.
concat <$> mapM (find recursionP filterP) path
chatLines opts $ "GHCs on PATH:" : map ("- " ++) ghcs
-- Parse results into @[CompilerVersion]@.
let versions = sort $ mapMaybe (parseCompilerString . stripExe . takeFileName) ghcs
chatLines opts $ "Installed GHCs:" :
map (("- " ++) . printNumericVersion . toNumericVersion) versions
return versions
where
-- Never recurse into subdirectories.
recursionP = depth <=? 0
-- Find executables named @ghc-[0-9]*@.
filterP = fileName ~~? "ghc-[0-9]*" &&? anyPerms 0111
-- Remove a potential "exe" extension.
stripExe file = fromMaybe file $ stripExtension "exe" file