From 69c09d0091f17901308e055b22ff7e51e8fe3f4e Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Fri, 14 Jun 2019 13:02:38 +0100 Subject: [PATCH] Tidy Main by extracting Program (#58) * [cli] ParseArgs now return an Option * [cli] Program extracted from Main --- .../scala/net/kemitix/s3thorp/cli/Main.scala | 33 ++++--------------- .../net/kemitix/s3thorp/cli/ParseArgs.scala | 14 +++----- .../net/kemitix/s3thorp/cli/Program.scala | 30 +++++++++++++++++ 3 files changed, 40 insertions(+), 37 deletions(-) create mode 100644 cli/src/main/scala/net/kemitix/s3thorp/cli/Program.scala diff --git a/cli/src/main/scala/net/kemitix/s3thorp/cli/Main.scala b/cli/src/main/scala/net/kemitix/s3thorp/cli/Main.scala index 39fe0ec..90b5349 100644 --- a/cli/src/main/scala/net/kemitix/s3thorp/cli/Main.scala +++ b/cli/src/main/scala/net/kemitix/s3thorp/cli/Main.scala @@ -1,13 +1,9 @@ package net.kemitix.s3thorp.cli -import java.io.File import java.nio.file.Paths import cats.effect.ExitCase.{Canceled, Completed, Error} import cats.effect.{ExitCode, IO, IOApp} -import net.kemitix.s3thorp.core.MD5HashGenerator.md5File -import net.kemitix.s3thorp.aws.lib.S3ClientBuilder -import net.kemitix.s3thorp.core.Sync import net.kemitix.s3thorp.domain.Config object Main extends IOApp { @@ -15,32 +11,15 @@ object Main extends IOApp { val defaultConfig: Config = Config(source = Paths.get(".").toFile) - def program(args: List[String]): IO[ExitCode] = - for { - config <- ParseArgs(args, defaultConfig) - logger = new Logger[IO](config.verbose) - info = (l: Int) => (m: String) => logger.info(l)(m) - _ <- logger.info(1)("S3Thorp - hashed sync for s3") - _ <- Sync.run[IO]( - config, - S3ClientBuilder.defaultClient, - hashGenerator(info), - info, - w => logger.warn(w)) - } yield ExitCode.Success - - private def hashGenerator(info: Int => String => IO[Unit]) = { - implicit val logInfo: Int => String => IO[Unit] = info - file: File => md5File[IO](file) - } - override def run(args: List[String]): IO[ExitCode] = { val logger = new Logger[IO](1) - program(args) + ParseArgs(args, defaultConfig) + .map(Program[IO]) + .getOrElse(IO(ExitCode.Error)) .guaranteeCase { - case Canceled => logger.warn("Interrupted") - case Error(e) => logger.error(e.getMessage) - case Completed => logger.info(1)("Done") + case Canceled => logger.warn("Interrupted") + case Error(e) => logger.error(e.getMessage) + case Completed => logger.info(1)("Done") } } diff --git a/cli/src/main/scala/net/kemitix/s3thorp/cli/ParseArgs.scala b/cli/src/main/scala/net/kemitix/s3thorp/cli/ParseArgs.scala index 77f7129..4448e3d 100644 --- a/cli/src/main/scala/net/kemitix/s3thorp/cli/ParseArgs.scala +++ b/cli/src/main/scala/net/kemitix/s3thorp/cli/ParseArgs.scala @@ -2,19 +2,16 @@ package net.kemitix.s3thorp.cli import java.nio.file.Paths -import cats.effect.IO -import net.kemitix.s3thorp._ import net.kemitix.s3thorp.domain.Filter.{Exclude, Include} import net.kemitix.s3thorp.domain.{Bucket, Config, RemoteKey} import scopt.OParser -import scopt.OParser.{builder, parse, sequence} object ParseArgs { val configParser: OParser[Unit, Config] = { - val parserBuilder = builder[Config] + val parserBuilder = OParser.builder[Config] import parserBuilder._ - sequence( + OParser.sequence( programName("s3thorp"), head("s3thorp"), opt[String]('s', "source") @@ -45,10 +42,7 @@ object ParseArgs { ) } - def apply(args: List[String], defaultConfig: Config): IO[Config] = - parse(configParser, args, defaultConfig) match { - case Some(config) => IO.pure(config) - case _ => IO.raiseError(new IllegalArgumentException) - } + def apply(args: List[String], defaultConfig: Config): Option[Config] = + OParser.parse(configParser, args, defaultConfig) } diff --git a/cli/src/main/scala/net/kemitix/s3thorp/cli/Program.scala b/cli/src/main/scala/net/kemitix/s3thorp/cli/Program.scala new file mode 100644 index 0000000..c6318a5 --- /dev/null +++ b/cli/src/main/scala/net/kemitix/s3thorp/cli/Program.scala @@ -0,0 +1,30 @@ +package net.kemitix.s3thorp.cli + +import java.io.File + +import cats.Monad +import cats.implicits._ +import cats.effect.ExitCode +import net.kemitix.s3thorp.aws.lib.S3ClientBuilder +import net.kemitix.s3thorp.core.MD5HashGenerator.md5File +import net.kemitix.s3thorp.core.{MD5HashGenerator, Sync} +import net.kemitix.s3thorp.domain.Config + +object Program { + + def apply[M[_]: Monad](config: Config): M[ExitCode] = { + val logger = new Logger[M](config.verbose) + val info = (l: Int) => (m: String) => logger.info(l) (m) + val warn = (w: String) => logger.warn(w) + for { + _ <- info(1)("S3Thorp - hashed sync for s3") + _ <- Sync.run[M](config, S3ClientBuilder.defaultClient, hashGenerator(info), info, warn) + } yield ExitCode.Success + } + + private def hashGenerator[M[_]: Monad](info: Int => String => M[Unit]) = { + implicit val logInfo: Int => String => M[Unit] = info + file: File => md5File[M](file) + } + +}