Skip to content

Commit

Permalink
help subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
pablf committed Feb 21, 2024
1 parent 8b82983 commit bf5c61c
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 17 deletions.
28 changes: 13 additions & 15 deletions zio-cli/shared/src/main/scala/zio/cli/Command.scala
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,9 @@ object Command {
args: List[String],
conf: CliConfig
): IO[ValidationError, CommandDirective[(A, B)]] = {
val helpDirectiveForChild = {
val safeTail = args match {
case Nil => Nil
case _ :: tail => tail
}
val helpDirectiveForChild =
child
.parse(safeTail, conf)
.parse(args.tail, conf)
.collect(ValidationError(ValidationErrorType.InvalidArgument, HelpDoc.empty)) {
case CommandDirective.BuiltIn(BuiltInOption.ShowHelp(synopsis, helpDoc)) =>
val parentName = names.headOption.getOrElse("")
Expand All @@ -310,22 +306,16 @@ object Command {
)
}
}
}

val helpDirectiveForParent =
ZIO.succeed(CommandDirective.builtIn(BuiltInOption.ShowHelp(synopsis, helpDoc)))

val wizardDirectiveForChild = {
val safeTail = args match {
case Nil => Nil
case _ :: tail => tail
}
val wizardDirectiveForChild =
child
.parse(safeTail, conf)
.parse(args.tail, conf)
.collect(ValidationError(ValidationErrorType.InvalidArgument, HelpDoc.empty)) {
case directive @ CommandDirective.BuiltIn(BuiltInOption.ShowWizard(_)) => directive
}
}

val wizardDirectiveForParent =
ZIO.succeed(CommandDirective.builtIn(BuiltInOption.ShowWizard(self)))
Expand Down Expand Up @@ -355,7 +345,15 @@ object Command {
)
case other: ValidationError => other
},
_.map((a, _))
_.map((a, _)).mapBuiltIn {
case BuiltInOption.ShowHelp(synopsis, helpDoc) =>
val parentName = names.headOption.getOrElse("")
BuiltInOption.ShowHelp(
UsageSynopsis.Named(List(parentName), None) + synopsis,
helpDoc
)
case builtIn => builtIn
}
)
case _ =>
helpDirectiveForParent
Expand Down
7 changes: 7 additions & 0 deletions zio-cli/shared/src/main/scala/zio/cli/CommandDirective.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ sealed trait CommandDirective[+A] { self =>
case x @ BuiltIn(_) => x
case UserDefined(leftover, value) => CommandDirective.UserDefined(leftover, f(value))
}

def mapBuiltIn(f: BuiltInOption => BuiltInOption): CommandDirective[A] =
self match {
case BuiltIn(x) => BuiltIn(f(x))
case x @ UserDefined(_, _) => x
}

}
object CommandDirective {
final case class BuiltIn(option: BuiltInOption) extends CommandDirective[Nothing]
Expand Down
2 changes: 1 addition & 1 deletion zio-cli/shared/src/main/scala/zio/cli/Options.scala
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ object Options extends OptionsPlatformSpecific {
}

/**
* `Options.validate` parses `args` for `options and returns an `Option[ValidationError]`, the leftover arguments and
* `Options.validate` parses `args` for options and returns an `Option[ValidationError]`, the leftover arguments and
* the constructed value of type `A`. The possible error inside `Option[ValidationError]` would only be triggered if
* there is an error when parsing the `Args` of a `Command`. This is because `ValidationErrors` are used to control
* the end of the args corresponding to options.
Expand Down
25 changes: 24 additions & 1 deletion zio-cli/shared/src/test/scala/zio/cli/CommandSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,13 @@ object CommandSpec extends ZIOSpecDefault {

val params8 = List("command", "-af", "asdgf", "--wizard")

val commandWithSubcommand = Command("test", Options.text("param")).subcommands(
Command("a")
.subcommands(
Command("b")
)
)

Vector(
test("trigger built-in options that are alone")(
assertZIO(command.parse(params1, CliConfig.default).map(directiveType _))(equalTo("help")) &&
Expand All @@ -319,7 +326,23 @@ object CommandSpec extends ZIOSpecDefault {
),
test("triggering wizard not alone")(
assertZIO(command.parse(params8, CliConfig.default).map(directiveType _))(equalTo("wizard"))
)
),
test("trigger child command's help if parent command is correct") {

def extractHelp(d: CommandDirective[String]): Option[(String, String)] = d match {
case CommandDirective.BuiltIn(BuiltInOption.ShowHelp(synopsis, doc)) =>
Some((synopsis.helpDoc.toPlaintext(), doc.toPlaintext()))
case _ => None
}

for {
help1 <- commandWithSubcommand
.parse(List("test", "--param", "text", "a", "--help"), CliConfig.default)
.map(extractHelp)
help2 <- commandWithSubcommand.parse(List("test", "a", "--help"), CliConfig.default).map(extractHelp)

} yield assertTrue(help1 == help2)
}
)
},
test("cmd opts -- args") {
Expand Down

0 comments on commit bf5c61c

Please sign in to comment.