Skip to content

Convert Wasp CLI argument handling to optparse-applicative#4240

Draft
cprecioso wants to merge 6 commits into
mainfrom
cprecioso/cli-optparse-applicative
Draft

Convert Wasp CLI argument handling to optparse-applicative#4240
cprecioso wants to merge 6 commits into
mainfrom
cprecioso/cli-optparse-applicative

Conversation

@cprecioso

Copy link
Copy Markdown
Member

Description

Replaces the hand-written case args of dispatcher and the inconsistent per-command argument parsing (some optparse-applicative, some manual string matching) with a single optparse-applicative parser tree in the new Wasp.Cli.Parser module, so command dispatch, validation, and --help all derive from one source of truth. Each command handler now takes a typed args record instead of [String], the obsolete Wasp.Cli.Util.Parser helper is removed, and Command.Call.Call is reduced to just what telemetry needs. The hand-maintained usage strings in Main.hs are gone (help is now auto-generated), while the top-level help footer keeps the EXAMPLES section and color-coded community links. No change to user-facing CLI behavior; auto-generated help text formatting differs slightly.

Type of change

  • 🔧 Just code/docs improvement
  • 🐞 Bug fix
  • 🚀 New/improved feature
  • 💥 Breaking change

Checklist

  • I tested my change in a Wasp app to verify that it works as intended.

  • 🧪 Tests and apps:

    • I added unit tests for my change.
    • (if you fixed a bug) I added a regression test for the bug I fixed.
    • (if you added/updated a feature) I added/updated e2e tests in examples/kitchen-sink/e2e-tests.
    • (if you added/updated a feature) I updated the starter templates in waspc/data/Cli/templates, as needed.
    • (if you added/updated a feature) I updated the example apps in examples/, as needed.
      • (if you updated examples/tutorials) I updated the tutorial in the docs (and vice versa).
  • 📜 Documentation:

    • (if you added/updated a feature) I added/updated the documentation in web/docs/.
  • 🆕 Changelog: (if change is more than just code/docs improvement)

    • I updated waspc/ChangeLog.md with a user-friendly description of the change.
    • (if you did a breaking change) I added a step to the current migration guide in web/docs/migration-guides/.
    • I bumped the version in waspc/waspc.cabal to reflect the changes I introduced.

🤖 Generated with Claude Code

Replace the hand-written `case args of` dispatcher and ad-hoc per-command
parsing with a single optparse-applicative parser tree (`Wasp.Cli.Parser`).
Command dispatch, validation, and `--help` now derive from one source of
truth; the manual usage strings in `Main.hs` are gone. Each command takes a
typed args record instead of `[String]`, and `Command.Call.Call` is reduced
to what telemetry needs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cprecioso cprecioso self-assigned this Jun 1, 2026
@cprecioso cprecioso had a problem deploying to railway-deploy-test June 1, 2026 12:00 — with GitHub Actions Failure
@cprecioso cprecioso temporarily deployed to fly-deploy-test June 1, 2026 12:00 — with GitHub Actions Inactive
@pkg-pr-new

pkg-pr-new Bot commented Jun 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

@wasp.sh/wasp-cli

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/wasp-cli@4240

@wasp.sh/wasp-cli-darwin-arm64-unknown

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/wasp-cli-darwin-arm64-unknown@4240

@wasp.sh/wasp-cli-darwin-x64-unknown

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/wasp-cli-darwin-x64-unknown@4240

@wasp.sh/wasp-cli-linux-x64-glibc

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/wasp-cli-linux-x64-glibc@4240

@wasp.sh/wasp-cli-linux-x64-musl

npx https://pkg.pr.new/wasp-lang/wasp/@wasp.sh/wasp-cli-linux-x64-musl@4240

commit: 69f601e

cprecioso and others added 2 commits June 2, 2026 14:02
Invert the CLI parsing so each command module exports a
`parserInfo :: ParserInfo (IO ())` mapping its arguments directly to the
action to execute (runCommand/runWaspLS wrapped with telemetry). This drops
the central Action ADT and actionToCall: Wasp.Cli.Parser is now just a
registry of command names, and Main only parses, runs the node check, sets
env vars, and executes the returned action.

Telemetry moves into each command via Telemetry.runWithTelemetry, so a
command reports its own Call (e.g. deploy passes its args, build reports
Build) instead of Main mapping it back. printVersion moves to a new
Wasp.Cli.Command.Version module. Drop the now-unused async (exe) and
optparse-applicative/waspc (test) build-depends.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cprecioso cprecioso temporarily deployed to fly-deploy-test June 2, 2026 13:29 — with GitHub Actions Inactive
@cprecioso cprecioso had a problem deploying to railway-deploy-test June 2, 2026 13:29 — with GitHub Actions Failure
Each command's parserInfo repeated the same shape: wrap in Opt.info with a
progDesc, pick the runCommand runner, and report telemetry, plus the same
Opt/Call/Telemetry/runCommand imports. Introduce Wasp.Cli.Command.Definition
with combinators (command, commandWithArgs, commandGroup,
commandWithSubcommands, leaf/leafWithArgs, runWaspCommand/runWaspCommandAs/
runWaspIO, subcommandsParser) so each command becomes a declarative one-liner
and the boilerplate imports disappear.

Deploy stays a custom Opt.info (forwardOptions + arg-aware telemetry) and
Telemetry.parserInfo stays manual (Definition imports Telemetry, so using it
there would cycle). The registry is now a [(name, parserInfo)] list fed to
subcommandsParser. Behaviour (dispatch, telemetry, help text) is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cprecioso and others added 2 commits June 3, 2026 15:59
The build-start "no env vars" error embeds the parser's help text. That
rendering helper was inlined in BuildStart.Config; move it to a common util
(Wasp.Cli.Util.Parser.renderParserHelp) alongside the other Wasp.Cli.Util.*
argument helpers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NewAiArgs, StartDbArgs, and WaspLSArgs existed only to ferry parsed values
into a single handler that immediately destructured them. Generalize the
Definition combinators (commandWithArgs takes Opt.Parser (Command b),
leafWithArgs takes Opt.Parser (IO ())) so a handler can be applied directly to
its argument parsers, then drop those three records and their named parsers:
runNewAi/start now take curried args, and waspls folds its thin runWaspLS
wrapper into parserInfo.

NewProjectArgs and BuildStartArgs stay (consumed as records in
ProjectDescription/Config), as does the TestArgs dispatch ADT.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cprecioso cprecioso temporarily deployed to fly-deploy-test June 3, 2026 14:16 — with GitHub Actions Inactive
@cprecioso cprecioso had a problem deploying to railway-deploy-test June 3, 2026 14:16 — with GitHub Actions Failure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant