refactor command line parsing

This commit is contained in:
Stefan Matting 2019-06-15 21:13:09 +02:00
parent 9b047987ae
commit 60cb5cb5c3

View file

@ -16,7 +16,6 @@ import Data.List.NonEmpty (NonEmpty(..))
import Control.Arrow ((>>>)) import Control.Arrow ((>>>))
data CommonOptions = data CommonOptions =
CommonOptions CommonOptions
{ files :: NonEmpty FilePath { files :: NonEmpty FilePath
@ -24,47 +23,13 @@ data CommonOptions =
} }
deriving (Show) deriving (Show)
newtype DockerComposeArgs = newtype DockerComposeArgs =
DockerComposeArgs { unDockerComposeArgs :: [Text] } DockerComposeArgs { unDockerComposeArgs :: [Text] }
data DockerComposeCmd =
Build
| Bundle
| Config
| Create
| Down
| Events
| Exec
| Help
| Images
| Kill
| Logs
| Pause
| Port
| Ps
| Pull
| Push
| Restart
| Rm
| Run
| Scale
| Start
| Stop
| Top
| Unpause
| Up
| Version
deriving (Show)
ensureConfigFile :: [FilePath] -> NonEmpty FilePath ensureConfigFile :: [FilePath] -> NonEmpty FilePath
ensureConfigFile [] = "./arion-compose.nix" :| [] ensureConfigFile [] = "./arion-compose.nix" :| []
ensureConfigFile (x:xs) = x :| xs ensureConfigFile (x:xs) = x :| xs
parseOptions :: Parser CommonOptions parseOptions :: Parser CommonOptions
parseOptions = do parseOptions = do
files <- files <-
@ -85,94 +50,68 @@ parseOptions = do
\and evaluating the configuration." ) \and evaluating the configuration." )
pure CommonOptions{..} pure CommonOptions{..}
parseCommand :: Parser (CommonOptions -> IO ()) parseCommand :: Parser (CommonOptions -> IO ())
parseCommand = parseCommand =
hsubparser hsubparser
( command "cat" (info (pure runCat) fullDesc) ( command "cat" (info (pure runCat) (progDesc "TODO: cat doc" <> fullDesc))
<> command "repl" (info (pure runRepl) fullDesc) <> command "repl" (info (pure runRepl) (progDesc "TODO: repl doc" <> fullDesc))
<> command "exec" (info (pure runExec) fullDesc) <> command "exec" (info (pure runExec) (progDesc "TODO: exec doc" <> fullDesc))
) )
<|> <|>
hsubparser hsubparser
( dcParser "build" Build "Build or rebuild services" ( commandDC runBuildAndDC "build" "Build or rebuild services"
<> dcParser "bundle" Bundle "Generate a Docker bundle from the Compose file" <> commandDC runBuildAndDC "bundle" "Generate a Docker bundle from the Compose file"
<> dcParser "config" Config "Validate and view the Compose file" <> commandDC runEvalAndDC "config" "Validate and view the Compose file"
<> dcParser "create" Create "Create services" <> commandDC runBuildAndDC "create" "Create services"
<> dcParser "down" Down "Stop and remove containers, networks, images, and volumes" <> commandDC runEvalAndDC "down" "Stop and remove containers, networks, images, and volumes"
<> dcParser "events" Events "Receive real time events from containers" <> commandDC runEvalAndDC "events" "Receive real time events from containers"
<> dcParser "exec" Exec "Execute a command in a running container" <> commandDC runEvalAndDC "exec" "Execute a command in a running container"
<> dcParser "help" Help "Get help on a command" <> commandDC runDC "help" "Get help on a command"
<> dcParser "images" Images "List images" <> commandDC runEvalAndDC "images" "List images"
<> dcParser "kill" Kill "Kill containers" <> commandDC runEvalAndDC "kill" "Kill containers"
<> dcParser "logs" Logs "View output from containers" <> commandDC runEvalAndDC "logs" "View output from containers"
<> dcParser "pause" Pause "Pause services" <> commandDC runEvalAndDC "pause" "Pause services"
<> dcParser "port" Port "Print the public port for a port binding" <> commandDC runEvalAndDC "port" "Print the public port for a port binding"
<> dcParser "ps" Ps "List containers" <> commandDC runEvalAndDC "ps" "List containers"
<> dcParser "pull" Pull "Pull service images" <> commandDC runBuildAndDC "pull" "Pull service images"
<> dcParser "push" Push "Push service images" <> commandDC runBuildAndDC "push" "Push service images"
<> dcParser "restart" Restart "Restart services" <> commandDC runBuildAndDC "restart" "Restart services"
<> dcParser "rm" Rm "Remove stopped containers" <> commandDC runEvalAndDC "rm" "Remove stopped containers"
<> dcParser "run" Run "Run a one-off command" <> commandDC runBuildAndDC "run" "Run a one-off command"
<> dcParser "scale" Scale "Set number of containers for a service" <> commandDC runBuildAndDC "scale" "Set number of containers for a service"
<> dcParser "start" Start "Start services" <> commandDC runBuildAndDC "start" "Start services"
<> dcParser "stop" Stop "services" <> commandDC runEvalAndDC "stop" "Stop services"
<> dcParser "top" Top "Display the running processes" <> commandDC runEvalAndDC "top" "Display the running processes"
<> dcParser "unpause" Unpause "Unpause services" <> commandDC runEvalAndDC "unpause" "Unpause services"
<> dcParser "up" Up "Create and start containers" <> commandDC runBuildAndDC "up" "Create and start containers"
<> dcParser "version" Version "Show the Docker-Compose version information" <> commandDC runDC "version" "Show the Docker-Compose version information"
<> metavar "DOCKER-COMPOSE-COMMAND" <> metavar "DOCKER-COMPOSE-COMMAND"
<> commandGroup "Docker Compose Commands:" <> commandGroup "Docker Compose Commands:"
) )
dcParser
:: Text
-> DockerComposeCmd
-> Text
-> Mod CommandFields (CommonOptions -> IO ())
dcParser cmdStr cmd help =
command
(T.unpack cmdStr)
(info
(runDockerCompose <$> pure cmd <*> parseDockerComposeArgs)
(progDesc (T.unpack help) <> fullDesc <> forwardOptions))
parseAll :: Parser (IO ()) parseAll :: Parser (IO ())
parseAll = parseAll =
flip ($) <$> parseOptions <*> parseCommand flip ($) <$> parseOptions <*> parseCommand
parseDockerComposeArgs :: Parser DockerComposeArgs parseDockerComposeArgs :: Parser DockerComposeArgs
parseDockerComposeArgs = parseDockerComposeArgs =
DockerComposeArgs <$> DockerComposeArgs <$>
many (argument (T.pack <$> str) (metavar "DOCKER-COMPOSE ARGS...")) many (argument (T.pack <$> str) (metavar "DOCKER-COMPOSE ARGS..."))
commandDC
:: (Text -> DockerComposeArgs -> CommonOptions -> IO ())
-> Text
-> Text
-> Mod CommandFields (CommonOptions -> IO ())
commandDC run cmdStr help =
command
(T.unpack cmdStr)
(info
(run cmdStr <$> parseDockerComposeArgs)
(progDesc (T.unpack help) <> fullDesc <> forwardOptions))
shouldEval :: DockerComposeCmd -> Bool --------------------------------------------------------------------------------
shouldEval Up = True
shouldEval Down = True
runDockerCompose :: DockerComposeCmd -> DockerComposeArgs -> CommonOptions -> IO ()
runDockerCompose cmd args opts = T.putStrLn (show cmd)
runCat :: CommonOptions -> IO ()
runCat (CommonOptions files pkgs) = do
T.putStrLn "Running cat ... TODO"
T.putStrLn (modulesNixExpr files)
runRepl :: CommonOptions -> IO ()
runRepl opts = T.putStrLn "Running repl ... TODO"
runExec :: CommonOptions -> IO ()
runExec opts = T.putStrLn "Running exec ... TODO"
modulesNixExpr :: NonEmpty FilePath -> Text modulesNixExpr :: NonEmpty FilePath -> Text
modulesNixExpr = modulesNixExpr =
@ -189,8 +128,38 @@ modulesNixExpr =
wrapList s = "[ " <> s <> " ]" wrapList s = "[ " <> s <> " ]"
--------------------------------------------------------------------------------
runDC :: Text -> DockerComposeArgs -> CommonOptions -> IO ()
runDC cmd (DockerComposeArgs args) opts =
T.putStrLn $ "TODO: docker-compose " <> cmd <> " " <> T.unwords args
runBuildAndDC :: Text -> DockerComposeArgs -> CommonOptions -> IO ()
runBuildAndDC cmd dopts opts = do
T.putStrLn "TODO: build"
runDC cmd dopts opts
runEvalAndDC :: Text -> DockerComposeArgs -> CommonOptions -> IO ()
runEvalAndDC cmd dopts opts = do
T.putStrLn "TODO: eval"
runDC cmd dopts opts
runCat :: CommonOptions -> IO ()
runCat (CommonOptions files pkgs) = do
T.putStrLn "Running cat ... TODO"
T.putStrLn (modulesNixExpr files)
runRepl :: CommonOptions -> IO ()
runRepl opts =
T.putStrLn "Running repl ... TODO"
runExec :: CommonOptions -> IO ()
runExec opts =
T.putStrLn "Running exec ... TODO"
main :: IO () main :: IO ()
main = main =
(join . execParser) (info (parseAll <**> helper) fullDesc) (join . execParser) (info (parseAll <**> helper) fullDesc)
where
execParser = customExecParser (prefs showHelpOnEmpty)