ghcup-0.2.5.0: lib/GHCup/Command/Whereis.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-|
Module : GHCup.Command.Whereis
Description : GHCup whereis
Copyright : (c) Julian Ospald, 2020
License : LGPL-3.0
Maintainer : hasufell@hasufell.de
Stability : experimental
Portability : portable
-}
module GHCup.Command.Whereis where
import GHCup.Errors
import GHCup.Legacy.Utils
import GHCup.Prelude
import GHCup.Query.DB
import GHCup.Query.GHCupDirs
import GHCup.System.Directory
import GHCup.Types
import GHCup.Types.Optics
import Control.Applicative
import Control.Monad
#if !MIN_VERSION_base(4,13,0)
import Control.Monad.Fail ( MonadFail )
#endif
import Control.Monad.Reader
import Data.Maybe
import Data.Variant.Excepts
import Data.Versions hiding ( patch )
import Prelude hiding ( abs, writeFile )
import System.Environment
import System.FilePath
import qualified Data.Text as T
---------------
--[ Whereis ]--
---------------
-- | Reports the binary location of a given tool:
--
-- * for GHC, this reports: @~\/.ghcup\/ghc\/\<ver\>\/bin\/ghc@
-- * for cabal, this reports @~\/.ghcup\/bin\/cabal-\<ver\>@
-- * for hls, this reports @~\/.ghcup\/bin\/haskell-language-server-wrapper-\<ver\>@
-- * for stack, this reports @~\/.ghcup\/bin\/stack-\<ver\>@
-- * for ghcup, this reports the location of the currently running executable
whereIsTool :: ( MonadReader env m
, HasDirs env
, HasLog env
, HasPlatformReq env
, MonadIOish m
)
=> Tool
-> TargetVersion
-> Excepts '[NotInstalled] m FilePath
whereIsTool tool ver@TargetVersion {..} = do
dirs <- lift getDirs
toolDir <- fromGHCupPath <$> lift (toolInstallDestination tool ver)
sSpec <- runE $ getSymlinkSpec tool ver
case sSpec of
(VRight (SymlinkSpec{..}:_)) ->
pure $ toolDir </> _slTarget
_ ->
case tool of
Tool "ghc" -> do
whenM (lift $ fmap not $ ghcInstalled ver)
$ throwE (NotInstalled ghc ver)
bdir <- fromGHCupPath <$> lift (ghcupGHCDir ver)
pure (bdir </> "bin" </> ghcBinaryName ver)
Tool "cabal" -> do
whenM (lift $ fmap not $ cabalInstalled _tvVersion)
$ throwE (NotInstalled cabal (TargetVersion Nothing _tvVersion))
pure (binDir dirs </> "cabal-" <> T.unpack (prettyVer _tvVersion) <> exeExt)
Tool "hls" -> do
whenM (lift $ fmap not $ hlsInstalled _tvVersion)
$ throwE (NotInstalled hls (TargetVersion Nothing _tvVersion))
ifM (lift $ isLegacyHLS _tvVersion)
(pure (binDir dirs </> "haskell-language-server-wrapper-" <> T.unpack (prettyVer _tvVersion) <> exeExt))
$ do
bdir <- fromGHCupPath <$> lift (ghcupHLSDir _tvVersion)
pure (bdir </> "bin" </> "haskell-language-server-wrapper" <> exeExt)
Tool "stack" -> do
whenM (lift $ fmap not $ stackInstalled _tvVersion)
$ throwE (NotInstalled stack (TargetVersion Nothing _tvVersion))
pure (binDir dirs </> "stack-" <> T.unpack (prettyVer _tvVersion) <> exeExt)
Tool "ghcup" -> do
currentRunningExecPath <- liftIO getExecutablePath
liftIO $ canonicalizePath currentRunningExecPath
_ -> throwE (NotInstalled tool ver)