bludigon-0.1.0.0: src/Bludigon/Main/CLI.hs
module Bludigon.Main.CLI (
launch
) where
import Control.DeepSeq
import Data.Version (showVersion)
import GHC.Generics
import System.Console.GetOpt
import System.Directory (XdgDirectory (..), createDirectoryIfMissing, doesFileExist, getXdgDirectory)
import System.Environment (getArgs, getProgName)
import System.Exit (ExitCode (..), exitFailure, exitSuccess)
import System.FilePath ((</>))
import System.Info (arch, compilerName, compilerVersion, os)
import System.Posix.Process (executeFile)
import System.Process (runProcess, waitForProcess)
import Paths_bludigon (version)
data Flag = Help
| Version
deriving (Eq, Generic, Ord, Read, Show)
instance NFData Flag
options :: [OptDescr Flag]
options = [ Option ['h'] ["help"] (NoArg Help) "Explain CLI usage"
, Option ['v'] ["version"] (NoArg Version) "Display version"
]
launch :: IO ()
launch = do
args <- getArgs
case getOpt Permute options args of
(optArgs, [], []) -> controlOptions optArgs
_ -> do printUsage
exitFailure
controlOptions :: [Flag] -> IO ()
controlOptions flags
| Help `elem` flags = do printUsage
exitSuccess
| otherwise = case flags of
[] -> build
[Version] -> do printVersion
exitSuccess
_ -> do printUsage
exitFailure
printUsage :: IO ()
printUsage = putStr $ usageInfo header options
where header = "Usage: bludigon [OPTIONS]"
printVersion :: IO ()
printVersion = putStrLn $ "bludigon-" <> showVersion version <> " compiled with " <> compiler
where compiler = compilerName <> "-" <> showVersion compilerVersion
getXdgDir :: XdgDirectory -> IO FilePath
getXdgDir = flip getXdgDirectory "bludigon"
build :: IO ()
build = do
configPath <- (</> configLeafname) <$> getXdgDir XdgConfig
configExists <- doesFileExist configPath
if configExists
then do progName <- getProgName
if progName == compiledConfigLeafname
then return ()
else do compile
cacheDir <- getXdgDir XdgCache
executeFile (cacheDir </> compiledConfigLeafname) False [] Nothing
else return ()
compile :: IO ()
compile = do
configDir <- getXdgDir XdgConfig
cacheDir <- getXdgDir XdgCache
createDirectoryIfMissing False cacheDir
status <- waitForProcess =<<
runProcess "ghc" [ "--make"
, configLeafname
, "-main-is", "main"
, "-v0"
, "-o", cacheDir </> compiledConfigLeafname
] (Just configDir) Nothing Nothing Nothing Nothing
case status of
ExitSuccess -> return ()
ExitFailure _ -> exitFailure
compiledConfigLeafname :: FilePath
compiledConfigLeafname = "bludigon-" <> arch <> "-" <> os
configLeafname :: FilePath
configLeafname = "bludigon.hs"