glualint-1.26.0: app/GLuaFixer/Effects/Cli.hs
{-# 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