Skip to content

Instantly share code, notes, and snippets.

@mpkocher
Last active July 2, 2022 23:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mpkocher/e7b23d082a9ce9cba6e5ec3337658e76 to your computer and use it in GitHub Desktop.
Save mpkocher/e7b23d082a9ce9cba6e5ec3337658e76 to your computer and use it in GitHub Desktop.
ZIO 1.x + Decline Example for creating CLI tools and running them with scala-cli.
//> using platform "jvm"
//> using scala "2.13.8"
//> using lib "dev.zio::zio:1.0.14"
//> using lib "com.monovore::decline:2.2.0"
//> using mainClass "DeclinedApp"
// Runnable using `scala-cli run Declined.scala -- --user Ralph --alpha 3.14`
import zio.{ExitCode, ZEnv, ZIO, Task, RIO, IO, UIO, URIO}
import zio.console._
import com.monovore.decline._
import cats.implicits._
object DeclinedApp extends zio.App {
val VERSION = "0.1.0"
val versionOpt: Opts[RIO[Console, Unit]] = Opts
.flag(
"version",
"Show version and Exit",
"v",
visibility = Visibility.Partial
)
.orFalse
.map(_ => putStrLn(VERSION))
val nameOpt = Opts.option[String]("user", help = "User name", "u")
val alphaOpt = Opts
.option[Double]("alpha", help = "Alpha Filtering", "a")
.withDefault(1.23)
val forceOpt: Opts[Boolean] =
Opts.flag("fail", help = "Manually trigger a failure").orFalse
val mainOpt: Opts[RIO[Console, Unit]] =
(nameOpt, alphaOpt, forceOpt).mapN[RIO[Console, Unit]] {
(name, alpha, force) =>
if (force)
ZIO.fail(
new Exception(s"Manually FAIL triggered by $name! alpha=$alpha")
)
else putStrLn(s"Hello $name. Running with alpha=$alpha")
}
val command: Command[RIO[Console, Unit]] = Command[RIO[Console, Unit]](
name = "declined",
header = "Testing decline+zio"
)(versionOpt orElse mainOpt)
def effect(arg: List[String]): ZIO[Console, Throwable, Unit] = {
command.parse(arg) match {
case Left(help) => // a bit odd that --help returns here
if (help.errors.isEmpty) putStrLn(help.show)
else IO.fail(new Exception(s"${help.errors.reduceLeft(_ + "\n" + _)}"))
case Right(value) => value.map(_ => ())
}
}
override def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] =
effect(args).map(_ => ExitCode.success).catchAll { ex =>
for {
_ <- putStrLnErr(s"Error ${ex}").orDie
} yield ExitCode.failure
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment