Command Line Subcommands in PureScript
Here’s the translation of the Go code to PureScript, along with explanations in Markdown format suitable for Hugo:
Our first example demonstrates how to create command-line subcommands in PureScript. Some command-line tools have multiple subcommands, each with its own set of flags. For example, git clone
and git push
are two different subcommands of the git
tool. In PureScript, we can use the optparse-applicative
library to easily define simple subcommands with their own flags.
module Main where
import Prelude
import Data.Either (Either(..))
import Effect (Effect)
import Effect.Console (log)
import Options.Applicative
data Command
= Foo { enable :: Boolean, name :: String }
| Bar { level :: Int }
fooCmd :: Parser Command
fooCmd = Foo <$> (FooOpts
<$> switch (long "enable" <> help "enable")
<*> strOption (long "name" <> metavar "NAME" <> help "name"))
barCmd :: Parser Command
barCmd = Bar <$> (BarOpts
<$> option auto (long "level" <> metavar "LEVEL" <> help "level"))
commandParser :: Parser Command
commandParser = subparser
( command "foo" (info fooCmd (progDesc "Foo subcommand"))
<> command "bar" (info barCmd (progDesc "Bar subcommand"))
)
main :: Effect Unit
main = do
cmd <- execParser $ info (commandParser <**> helper)
( fullDesc
<> progDesc "Command-line subcommands example"
<> header "subcommands - a test for subcommands" )
case cmd of
Foo { enable, name } -> do
log "subcommand 'foo'"
log $ " enable: " <> show enable
log $ " name: " <> name
Bar { level } -> do
log "subcommand 'bar'"
log $ " level: " <> show level
To run this program, you would typically compile it and then execute the resulting binary. Here are some example invocations:
First, invoke the foo subcommand:
$ spago run -- foo --enable --name=joe
subcommand 'foo'
enable: true
name: joe
Now try bar:
$ spago run -- bar --level 8
subcommand 'bar'
level: 8
But bar won’t accept foo’s flags:
$ spago run -- bar --enable
Invalid option `--enable'
Usage: subcommands bar --level LEVEL
Available options:
--level LEVEL level
-h,--help Show this help text
In this PureScript version, we use the optparse-applicative
library to define our subcommands and their respective flags. The Command
data type represents our subcommands, and we define separate parsers for each subcommand (fooCmd
and barCmd
).
The commandParser
combines these subcommand parsers, and main
uses execParser
to run the parser and handle the result.
This approach provides a type-safe way to handle command-line arguments and subcommands in PureScript, with helpful error messages and automatically generated help text.