hsinstall-3.0: src/app/HSInstall/Build.hs
module HSInstall.Build
( BuildTool
, PackageName (..)
, clean
, determineBuildTool
, installBinaries
, makeCabal
, warnAboutCabalMultiExe
)
where
import Data.List.NonEmpty qualified as NE
import System.Directory (getDirectoryContents)
import System.Process (callProcess)
import System.Log.Logger
import HSInstall.Except (justDoIt)
import HSInstall.Log (n)
import HSInstall.Opts (BuildMode (AppImage, Dist), ExeFile (..), ExeFiles (..))
import HSInstall.System.Process (CmdArgs, readProcessWithLogging)
newtype PackageName = PackageName String
data BuildTool = Cabal | Stack
instance Show BuildTool where
show Cabal = "cabal"
show Stack = "stack"
determineBuildTool :: IO BuildTool
determineBuildTool = do
dirContents <- getDirectoryContents "."
pure $ if "stack.yaml" `elem` dirContents
then Stack
else Cabal
clean :: BuildTool -> IO ()
clean Cabal = readProcessWithLogging "Clean specified" ("cabal", ["v2-clean"])
clean Stack = readProcessWithLogging "Clean specified" ("stack", ["clean"])
modeToStackArg :: BuildMode -> PackageName -> [String]
modeToStackArg (AppImage _ _ (ExeFile exeFp)) (PackageName pName) =
[ pName <> ":" <> exeFp ]
modeToStackArg (Dist _ _ AllExes) _ = []
modeToStackArg (Dist _ _ (SpecificExes ne)) (PackageName pName) =
NE.toList . NE.map (\(ExeFile n') -> pName <> ":" <> n') $ ne
mkInstallArgs :: BuildTool -> BuildMode -> PackageName -> FilePath -> CmdArgs
mkInstallArgs Cabal mode packageName binDir =
( "cabal"
, [ "v2-install"
, "--install-method=copy"
, "--overwrite-policy=always"
, "--installdir=" <> binDir
]
<> modeToStackArg mode packageName
)
mkInstallArgs Stack mode packageName binDir =
( "stack"
, [ "install"
, "--local-bin-path=" <> binDir
]
<> modeToStackArg mode packageName
)
installBinaries :: BuildTool -> BuildMode -> PackageName -> FilePath -> IO ()
installBinaries buildTool mode packageName binDir =
readProcessWithLogging "Installing binaries"
$ mkInstallArgs buildTool mode packageName binDir
makeCabal :: BuildTool -> IO ()
makeCabal Cabal = justDoIt $ callProcess "hpack" []
makeCabal Stack = justDoIt $ callProcess "stack" ["query"]
warnAboutCabalMultiExe :: BuildMode -> BuildTool -> IO ()
warnAboutCabalMultiExe (Dist _ _ (SpecificExes _)) Cabal =
warningM n "cabal will currently only install all binaries, I believe it's a bug"
warnAboutCabalMultiExe _ _ = pure ()