Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/5-internal/refactor-get-options
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Refactor getOptions
68 changes: 34 additions & 34 deletions libs/types-common/src/Util/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import Data.Yaml hiding (Parser)
import Imports
import Options.Applicative
import Options.Applicative.Types
import System.Exit (die)
import URI.ByteString
import Util.Options.Common

Expand Down Expand Up @@ -111,7 +110,14 @@ loadSecret (FilePathSecrets p) = do
then over _Left show . decodeEither' <$> BS.readFile path
else pure (Left "File doesn't exist")

-- | Get configuration options from the command line or configuration file.
--
-- This uses the provided optparse-applicative parser, if given. In all cases,
-- it prepends a `config-file` option to the parser that accepts a file name.
-- When that option is found, the config file is used to get the options,
-- instead of the command line.
getOptions ::
forall a.
FromJSON a =>
-- | Program description
String ->
Expand All @@ -120,46 +126,40 @@ getOptions ::
-- | Default config path, can be overridden with @--config-file@
FilePath ->
IO a
getOptions desc pars defaultPath = do
path <- parseConfigPath defaultPath mkDesc
file <- doesFileExist path
case (file, pars) of
-- Config exists, we can just take options from there
getOptions desc mp defaultPath = do
(path, mOpts) <-
execParser $
info
(optsOrConfigFile <**> helper)
(header desc <> fullDesc)
exists <- doesFileExist path
case (exists, mOpts) of
-- config file exists, take options from there
(True, _) -> do
configFile <- decodeFileEither path
case configFile of
decodeFileEither path >>= \case
Left e ->
fail $
show e
<> " while attempting to decode "
<> show path
<> path
Right o -> pure o
-- Config doesn't exist but at least we have a CLI options parser
(False, Just p) -> do
execParser (info (helper <*> p) mkDesc)
-- No config, no parser :(
(False, Nothing) -> do
die $ "Config file at " ++ path ++ " does not exist. \n"
where
mkDesc :: InfoMod b
mkDesc = header desc <> fullDesc

parseConfigPath :: FilePath -> InfoMod String -> IO String
parseConfigPath defaultPath desc = do
args <- getArgs
let result =
getParseResult $
execParserPure defaultPrefs (info (helper <*> pathParser) desc) args
pure $ fromMaybe defaultPath result
-- config doesn't exist, take options from command line
(False, Just opts) -> pure opts
-- no config, no parser, just fail
(False, Nothing) ->
fail $ "Config file at " <> path <> " does not exist."
where
pathParser :: Parser String
pathParser =
strOption $
long "config-file"
<> short 'c'
<> help "Config file to load"
<> showDefault
<> value defaultPath
optsOrConfigFile :: Parser (FilePath, Maybe a)
optsOrConfigFile =
(,)
<$> strOption
( long "config-file"
<> short 'c'
<> help "Config file to load"
<> showDefault
<> value defaultPath
)
<*> sequenceA mp

parseAWSEndpoint :: ReadM AWSEndpoint
parseAWSEndpoint = readerAsk >>= maybe (error "Could not parse AWS endpoint") pure . fromByteString . fromString
Expand Down