Repository: scala-steward-org/scala-steward
Pull request #1653 (2020-10-10 20:25:48)

Use File in Cli.Args
This uses `File` in `Cli.Args` so that we don't need `Sync` when converting
from `Args` to `Config`.

codecov[bot]: # [Codecov](https://codecov.io/gh/scala-steward-org/scala-steward/pull/1653?src=pr&el=h1) Report
> Merging [#1653](https://codecov.io/gh/scala-steward-org/scala-steward/pull/1653?src=pr&el=desc) into [master](https://codecov.io/gh/scala-steward-org/scala-steward/commit/f9b4d80975257044e04d7a1d064c3f05103df904?el=desc) will **increase** coverage by `0.03%`.
> The diff coverage is `10.71%`.

[![Impacted file tree graph](https://codecov.io/gh/scala-steward-org/scala-steward/pull/1653/graphs/tree.svg?width=650&height=150&src=pr&token=udzMsc1Dne)](https://codecov.io/gh/scala-steward-org/scala-steward/pull/1653?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1653      +/-   ##
==========================================
+ Coverage   71.68%   71.71%   +0.03%     
==========================================
  Files         114      114              
  Lines        1875     1877       +2     
  Branches       57       55       -2     
==========================================
+ Hits         1344     1346       +2     
  Misses        531      531              
```


| [Impacted Files](https://codecov.io/gh/scala-steward-org/scala-steward/pull/1653?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [...ala/org/scalasteward/core/application/Config.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/1653/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9hcHBsaWNhdGlvbi9Db25maWcuc2NhbGE=) | `0.00% <0.00%> (ø)` | |
| [...la/org/scalasteward/core/application/Context.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/1653/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9hcHBsaWNhdGlvbi9Db250ZXh0LnNjYWxh) | `0.00% <0.00%> (ø)` | |
| [.../scala/org/scalasteward/core/application/Cli.scala](https://codecov.io/gh/scala-steward-org/scala-steward/pull/1653/diff?src=pr&el=tree#diff-bW9kdWxlcy9jb3JlL3NyYy9tYWluL3NjYWxhL29yZy9zY2FsYXN0ZXdhcmQvY29yZS9hcHBsaWNhdGlvbi9DbGkuc2NhbGE=) | `96.15% <75.00%> (-3.85%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/scala-steward-org/scala-steward/pull/1653?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/scala-steward-org/scala-steward/pull/1653?src=pr&el=footer). Last update [f9b4d80...af4004d](https://codecov.io/gh/scala-steward-org/scala-steward/pull/1653?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/application/Cli.scala b/modules/core/src/main/scala/org/scalasteward/core/application/Cli.scala
index 7998c174..b79adbad 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/application/Cli.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/application/Cli.scala
@@ -16,6 +16,7 @@
 
 package org.scalasteward.core.application
 
+import better.files.File
 import caseapp._
 import caseapp.core.Error.MalformedValue
 import caseapp.core.argparser.{ArgParser, SimpleArgParser}
@@ -26,15 +27,15 @@ import scala.concurrent.duration._
 
 object Cli {
   final case class Args(
-      workspace: String,
-      reposFile: String,
-      defaultRepoConf: Option[String] = None,
+      workspace: File,
+      reposFile: File,
+      defaultRepoConf: Option[File] = None,
       gitAuthorName: String = "Scala Steward",
       gitAuthorEmail: String,
       vcsType: SupportedVCS = SupportedVCS.GitHub,
       vcsApiHost: Uri = uri"https://api.github.com",
       vcsLogin: String,
-      gitAskPass: String,
+      gitAskPass: File,
       signCommits: Boolean = false,
       whitelist: List[String] = Nil,
       readOnly: List[String] = Nil,
@@ -45,7 +46,7 @@ object Cli {
       processTimeout: FiniteDuration = 10.minutes,
       scalafixMigrations: List[Uri] = Nil,
       disableDefaultScalafixMigrations: Boolean = false,
-      groupMigrations: Option[String] = None,
+      groupMigrations: Option[File] = None,
       cacheTtl: FiniteDuration = 2.hours,
       cacheMissDelay: FiniteDuration = 0.milliseconds,
       bitbucketServerUseDefaultReviewers: Boolean = false,
@@ -86,9 +87,15 @@ object Cli {
       }
     }
 
+  implicit val fileArgParser: ArgParser[File] =
+    ArgParser[String].xmapError(
+      _.toString,
+      s => Either.catchNonFatal(File(s)).leftMap(t => MalformedValue("File", t.getMessage))
+    )
+
   implicit val finiteDurationArgParser: ArgParser[FiniteDuration] =
     ArgParser[String].xmapError(
-      _.toString(),
+      _.toString,
       s =>
         parseFiniteDuration(s).leftMap { throwable =>
           val error = s"The value is expected in the following format: <length><unit>. ($throwable)"
diff --git a/modules/core/src/main/scala/org/scalasteward/core/application/Config.scala b/modules/core/src/main/scala/org/scalasteward/core/application/Config.scala
index 98c2d942..1fb3237c 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/application/Config.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/application/Config.scala
@@ -92,31 +92,29 @@ object Config {
       disableDefaults: Boolean
   )
 
-  def create[F[_]](args: Cli.Args)(implicit F: Sync[F]): F[Config] =
-    F.delay {
-      Config(
-        workspace = args.workspace.toFile,
-        reposFile = args.reposFile.toFile,
-        defaultRepoConfigFile = args.defaultRepoConf.map(_.toFile),
-        gitAuthor = Author(args.gitAuthorName, args.gitAuthorEmail),
-        vcsType = args.vcsType,
-        vcsApiHost = args.vcsApiHost,
-        vcsLogin = args.vcsLogin,
-        gitAskPass = args.gitAskPass.toFile,
-        signCommits = args.signCommits,
-        whitelistedDirectories = args.whitelist,
-        readOnlyDirectories = args.readOnly,
-        disableSandbox = args.disableSandbox,
-        doNotFork = args.doNotFork,
-        ignoreOptsFiles = args.ignoreOptsFiles,
-        envVars = args.envVar,
-        processTimeout = args.processTimeout,
-        scalafix = Scalafix(args.scalafixMigrations, args.disableDefaultScalafixMigrations),
-        groupMigrations = args.groupMigrations.map(_.toFile),
-        cacheTtl = args.cacheTtl,
-        cacheMissDelay = args.cacheMissDelay,
-        bitbucketServerUseDefaultReviewers = args.bitbucketServerUseDefaultReviewers,
-        gitlabMergeWhenPipelineSucceeds = args.gitlabMergeWhenPipelineSucceeds
-      )
-    }
+  def from(args: Cli.Args): Config =
+    Config(
+      workspace = args.workspace,
+      reposFile = args.reposFile,
+      defaultRepoConfigFile = args.defaultRepoConf,
+      gitAuthor = Author(args.gitAuthorName, args.gitAuthorEmail),
+      vcsType = args.vcsType,
+      vcsApiHost = args.vcsApiHost,
+      vcsLogin = args.vcsLogin,
+      gitAskPass = args.gitAskPass,
+      signCommits = args.signCommits,
+      whitelistedDirectories = args.whitelist,
+      readOnlyDirectories = args.readOnly,
+      disableSandbox = args.disableSandbox,
+      doNotFork = args.doNotFork,
+      ignoreOptsFiles = args.ignoreOptsFiles,
+      envVars = args.envVar,
+      processTimeout = args.processTimeout,
+      scalafix = Scalafix(args.scalafixMigrations, args.disableDefaultScalafixMigrations),
+      groupMigrations = args.groupMigrations,
+      cacheTtl = args.cacheTtl,
+      cacheMissDelay = args.cacheMissDelay,
+      bitbucketServerUseDefaultReviewers = args.bitbucketServerUseDefaultReviewers,
+      gitlabMergeWhenPipelineSucceeds = args.gitlabMergeWhenPipelineSucceeds
+    )
 }
diff --git a/modules/core/src/main/scala/org/scalasteward/core/application/Context.scala b/modules/core/src/main/scala/org/scalasteward/core/application/Context.scala
index e9b3cc18..541887fc 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/application/Context.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/application/Context.scala
@@ -51,7 +51,7 @@ object Context {
       blocker <- Blocker[F]
       implicit0(logger: Logger[F]) <- Resource.liftF(Slf4jLogger.create[F])
       _ <- Resource.liftF(printBanner[F])
-      implicit0(config: Config) <- Resource.liftF(Config.create[F](args))
+      implicit0(config: Config) <- Resource.pure(Config.from(args))
       implicit0(client: Client[F]) <- AsyncHttpClient.resource[F]()
       implicit0(httpExistenceClient: HttpExistenceClient[F]) <- HttpExistenceClient.create[F]
       implicit0(user: AuthenticatedUser) <- Resource.liftF(config.vcsUser[F])


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/application/CliTest.scala b/modules/core/src/test/scala/org/scalasteward/core/application/CliTest.scala
index e67fc1dd..469263d2 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/application/CliTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/application/CliTest.scala
@@ -1,5 +1,6 @@
 package org.scalasteward.core.application
 
+import better.files.File
 import org.http4s.syntax.literals._
 import org.scalasteward.core.application.Cli.EnvVar
 import org.scalasteward.core.application.Cli.ParseResult._
@@ -27,14 +28,14 @@ class CliTest extends AnyFunSuite with Matchers with EitherValues {
       ).flatten
     ) shouldBe Success(
       Cli.Args(
-        workspace = "a",
-        reposFile = "b",
-        defaultRepoConf = Some("c"),
+        workspace = File("a"),
+        reposFile = File("b"),
+        defaultRepoConf = Some(File("c")),
         gitAuthorEmail = "d",
         vcsType = SupportedVCS.Gitlab,
         vcsApiHost = uri"http://example.com",
         vcsLogin = "e",
-        gitAskPass = "f",
+        gitAskPass = File("f"),
         ignoreOptsFiles = true,
         envVar = List(EnvVar("g", "h"), EnvVar("i", "j")),
         processTimeout = 30.minutes
@@ -53,11 +54,11 @@ class CliTest extends AnyFunSuite with Matchers with EitherValues {
       ).flatten
     ) shouldBe Success(
       Cli.Args(
-        workspace = "a",
-        reposFile = "b",
+        workspace = File("a"),
+        reposFile = File("b"),
         gitAuthorEmail = "d",
         vcsLogin = "e",
-        gitAskPass = "f"
+        gitAskPass = File("f")
       )
     )
   }
@@ -102,4 +103,8 @@ class CliTest extends AnyFunSuite with Matchers with EitherValues {
   test("finiteDurationArgParser: previous value") {
     Cli.finiteDurationArgParser(Some(10.seconds), "20seconds").isLeft shouldBe true
   }
+
+  test("fileArgParser: previous value") {
+    Cli.fileArgParser(Some(File("/tmp")), "/opt").isLeft shouldBe true
+  }
 }