Skip to content

Fix --help/--wizard showing wrong subcommand help (#448)#559

Open
tjarvstrand wants to merge 1 commit intozio:masterfrom
tjarvstrand:subcommand-help
Open

Fix --help/--wizard showing wrong subcommand help (#448)#559
tjarvstrand wants to merge 1 commit intozio:masterfrom
tjarvstrand:subcommand-help

Conversation

@tjarvstrand
Copy link
Copy Markdown

No description provided.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a parsing edge case where invoking --help / --wizard at the root command level incorrectly displayed help/wizard output for a child subcommand when subcommands are present.

Changes:

  • Added regression tests covering root-level --help/-h and --wizard behavior when subcommands exist (issue #448).
  • Adjusted subcommand parsing so that the “final built-in option check” is disabled when probing child commands for help/wizard, preventing accidental selection of a child’s built-in help when no subcommand name is provided.
  • Tightened built-in option parsing to reject matches when non-option leftover args remain after built-in option validation.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
zio-cli/shared/src/test/scala/zio/cli/CommandSpec.scala Adds regression coverage ensuring root help/wizard prefers the parent command, while subcommand help still works.
zio-cli/shared/src/main/scala/zio/cli/Command.scala Fixes root --help/--wizard behavior by disabling final built-in checks while probing child commands, preventing incorrect child help selection.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +121 to +137
.flatMap { case (_, leftover, value) =>
if (leftover.nonEmpty)
ZIO.fail(
ValidationError(
ValidationErrorType.NoBuiltInMatch,
HelpDoc.p(s"No built-in option was matched")
)
)
else
ZIO
.fromOption(value)
.mapError(_ =>
ValidationError(
ValidationErrorType.NoBuiltInMatch,
HelpDoc.p(s"No built-in option was matched")
)
)
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In parseBuiltInArgs, the same ValidationError(NoBuiltInMatch, HelpDoc.p("No built-in option was matched")) is constructed in multiple branches. Consider extracting it into a local val and reusing it (and you can also drop the unnecessary s interpolator) to avoid duplication and reduce the chance of the branches drifting over time.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix this using a single match, like:

value match {
  case Some(value) if leftover.isEmpty => Exit.succeed(value)
  case _ => ZIO.fail(...)

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.

3 participants