{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} module GLuaFixer.Effects.Cli where import Effectful (Dispatch (Static), DispatchOf, Eff, Effect, IOE, (:>)) import Effectful.Dispatch.Static (SideEffects (WithSideEffects), StaticRep, evalStaticRep, unsafeEff_) import qualified Effectful.Environment as Eff import GHC.IO.Exception (ExitCode (..)) import GLuaFixer.Cli (Options, legacyCliParser, runParse) import qualified Options.Applicative as Opt import qualified Options.Applicative.Help.Types as Opt -- | Effect for parsing the CLI arguments. data Cli :: Effect type instance DispatchOf Cli = Static WithSideEffects data instance StaticRep Cli = Cli -- | Run the Cli effect runCliIO :: IOE :> es => Eff (Cli : es) a -> Eff es a runCliIO = evalStaticRep Cli {- | The result of parsing the CLI arguments. Either successful, with Options describing the running parameters of glualint, or alternatively, show the help text and exit with the exit code -} data CliParseResult = ParseSuccessful Options | PrintHelpText ExitCode String -- | Parse the CLI options parseCliOptions :: (Eff.Environment :> es, Cli :> es) => Eff es CliParseResult parseCliOptions = do args <- Eff.getArgs case runParse args of Opt.Success options -> pure $ ParseSuccessful options Opt.CompletionInvoked completionResult -> do progName <- Eff.getProgName helpText <- execCompletion completionResult progName pure $ PrintHelpText ExitSuccess helpText Opt.Failure parserFailure -> do progName <- Eff.getProgName let (parserHelp, exitCode, terminalColumns) = Opt.execFailure parserFailure progName let printHelpText = PrintHelpText exitCode $ Opt.renderHelp terminalColumns parserHelp case exitCode of -- This means the help was activated. Print the help ExitSuccess -> pure printHelpText ExitFailure _ -> -- Attempt legacy CLI interface case legacyCliParser args of Just options -> pure $ ParseSuccessful options Nothing -> pure printHelpText -- | Calculate the autocomplete string execCompletion :: Cli :> es => Opt.CompletionResult -> String -> Eff es String execCompletion cmpletionResult progName = unsafeEff_ $ Opt.execCompletion cmpletionResult progName