From 06578d6a9627b5111027f2b7fc56c2d3180d3c92 Mon Sep 17 00:00:00 2001 From: Lorenzo Gabriele <lorenzolespaul@gmail.com> Date: Wed, 29 May 2024 11:52:18 +0200 Subject: [PATCH] Expose `command: Command` in `CommandIOApp` If you want to show the help when handling errors in the `IO` part of the app, you need to call `.showHelp` on the command instance. This is not possible with `CommandIOApp` since it doesn't expose the app but creates and uses it on the fly. This PR adds a `val command: Command[IO[ExitCode]]` to `CommandIOApp` so you can have similar errors to the errors printed by `validate` but when handling IO errors in the app with `.handleErrorWith` in the application logic --- .../decline/effect/CommandIOAppSpec.scala | 12 +++++++++++ .../decline/effect/CommandIOApp.scala | 20 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/effect/jvm/src/test/scala/com/monovore/decline/effect/CommandIOAppSpec.scala b/effect/jvm/src/test/scala/com/monovore/decline/effect/CommandIOAppSpec.scala index a392b287..918ab01b 100644 --- a/effect/jvm/src/test/scala/com/monovore/decline/effect/CommandIOAppSpec.scala +++ b/effect/jvm/src/test/scala/com/monovore/decline/effect/CommandIOAppSpec.scala @@ -24,6 +24,18 @@ class CommandIOAppSpec extends AnyFlatSpec with Matchers { runApp() shouldBe ExitCode.Error } + it should "expose command so showHelp can be called" in { + PureHelloWorld.command.showHelp shouldBe """Usage: pure-hello <to-greet> + | + |Pure Hello World with Decline + | + |Options and flags: + | --help + | Display this help text. + | --version, -v + | Print the version number and exit.""".stripMargin + } + private[this] def runApp(args: String*): ExitCode = PureHelloWorld.run(args.toList).unsafeRunSync()(IORuntime.global) diff --git a/effect/shared/src/main/scala/com/monovore/decline/effect/CommandIOApp.scala b/effect/shared/src/main/scala/com/monovore/decline/effect/CommandIOApp.scala index 26dfa8af..ebec921f 100644 --- a/effect/shared/src/main/scala/com/monovore/decline/effect/CommandIOApp.scala +++ b/effect/shared/src/main/scala/com/monovore/decline/effect/CommandIOApp.scala @@ -18,9 +18,17 @@ abstract class CommandIOApp( def main: Opts[IO[ExitCode]] + val command: Command[IO[ExitCode]] = + CommandIOApp.createCommand( + name = name, + header = header, + helpFlag = helpFlag, + version = Option(version).filter(_.nonEmpty), + main + ) + override final def run(args: List[String]): IO[ExitCode] = - CommandIOApp - .run[IO](name, header, helpFlag, Option(version).filter(_.nonEmpty))(main, args) + CommandIOApp.run[IO](command, args) } @@ -54,6 +62,14 @@ object CommandIOApp { else ExitCode.Success } + private[CommandIOApp] def createCommand( + name: String, + header: String, + helpFlag: Boolean, + version: Option[String], + opts: Opts[IO[ExitCode]] + ) = Command(name, header, helpFlag)(version.map(addVersionFlag(opts)).getOrElse(opts)) + private[CommandIOApp] def addVersionFlag[F[_]: Console: Functor]( opts: Opts[F[ExitCode]] )(version: String): Opts[F[ExitCode]] = {