{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE OverloadedStrings #-} module Path.CheckInstall where import Control.Monad (unless) import Control.Monad.Extra (anyM, (&&^)) import Control.Monad.IO.Class import Control.Monad.Logger import Data.Foldable (forM_) import Data.Text (Text) import qualified Data.Text as T import qualified System.Directory as D import qualified System.FilePath as FP -- | Checks if the installed executable will be available on the user's -- PATH. This doesn't use @envSearchPath menv@ because it includes paths -- only visible when running in the stack environment. warnInstallSearchPathIssues :: (MonadIO m, MonadLogger m) => FilePath -> [Text] -> m () warnInstallSearchPathIssues destDir installed = do searchPath <- liftIO FP.getSearchPath destDirIsInPATH <- liftIO $ anyM (\dir -> D.doesDirectoryExist dir &&^ fmap (FP.equalFilePath destDir) (D.canonicalizePath dir)) searchPath if destDirIsInPATH then forM_ installed $ \exe -> do mexePath <- (liftIO . D.findExecutable . T.unpack) exe case mexePath of Just exePath -> do exeDir <- (liftIO . fmap FP.takeDirectory . D.canonicalizePath) exePath unless (exeDir `FP.equalFilePath` destDir) $ do $logWarn "" $logWarn $ T.concat [ "WARNING: The \"" , exe , "\" executable found on the PATH environment variable is " , T.pack exePath , ", and not the version that was just installed." ] $logWarn $ T.concat [ "This means that \"" , exe , "\" calls on the command line will not use this version." ] Nothing -> do $logWarn "" $logWarn $ T.concat [ "WARNING: Installation path " , T.pack destDir , " is on the PATH but the \"" , exe , "\" executable that was just installed could not be found on the PATH." ] else do $logWarn "" $logWarn $ T.concat [ "WARNING: Installation path " , T.pack destDir , " not found on the PATH environment variable" ]