Repository: scala-steward-org/scala-steward
Pull request #3372 (2024-06-03 08:38:12)

`scala-cli`: `using dep` and `using test.dep` directives support
Fixes https://github.com/scala-steward-org/scala-steward/issues/3371.

I tested these changes on the same `scala-cli`-based repository I was having issues with and the correct PRs got created.


Patch:
diff --git a/README.md b/README.md
index e0d5816a..a71c69bb 100644
--- a/README.md
+++ b/README.md
@@ -140,6 +140,7 @@ Thanks goes to these wonderful people for contributing to Scala Steward:
 * [miguelpuyol](https://github.com/miguelpuyol)
 * [nafg](https://github.com/nafg)
 * [Nabil Abdel-Hafeez](https://github.com/987Nabil)
+* [Nicola Di Pol](https://github.com/horothesun)
 * [Ondra Pelech](https://github.com/sideeffffect)
 * [Pavel Shapkin](https://github.com/psttf)
 * [Philippus Baalman](https://github.com/Philippus)
diff --git a/modules/core/src/main/scala/org/scalasteward/core/edit/update/Selector.scala b/modules/core/src/main/scala/org/scalasteward/core/edit/update/Selector.scala
index 5800617a..7d0390fd 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/edit/update/Selector.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/edit/update/Selector.scala
@@ -70,9 +70,13 @@ object Selector {
     versionPositions
       .collect { case p: DependencyDef => p }
       .filter {
-        case p: MillDependency => scalaCliUsingLib.matcher(p.before).matches() || !p.isCommented
-        case p: SbtDependency  => !p.isCommented && !p.before.toLowerCase.contains("previous")
-        case _                 => true
+        case p: MillDependency =>
+          scalaCliUsingLib.matcher(p.before).matches() ||
+          scalaCliUsingDep.matcher(p.before).matches() ||
+          scalaCliUsingTestDep.matcher(p.before).matches() ||
+          !p.isCommented
+        case p: SbtDependency => !p.isCommented && !p.before.toLowerCase.contains("previous")
+        case _                => true
       }
       .filter { p =>
         val artifactIdNames = Set(p.artifactId, p.artifactId.takeWhile(_ =!= '_'))
@@ -81,9 +85,15 @@ object Selector {
         }
       }
 
-  private def scalaCliUsingLib: Pattern =
+  private val scalaCliUsingLib: Pattern =
     Pattern.compile("""//>\s+using\s+lib\s+""")
 
+  private val scalaCliUsingDep: Pattern =
+    Pattern.compile("""//>\s+using\s+dep\s+""")
+
+  private val scalaCliUsingTestDep: Pattern =
+    Pattern.compile("""//>\s+using\s+test\.dep\s+""")
+
   private def scalaValInDependencyDefPositions(
       versionPositions: List[VersionPosition],
       modulePositions: List[ModulePosition]


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala
index fd806bd2..60c017e7 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala
@@ -134,4 +134,155 @@ class EditAlgTest extends FunSuite {
       case Log(_) => false
     })
   }
+
+  test("applyUpdate for scala-cli using lib") {
+    val repo = Repo("edit-alg", "test-4")
+    val data = RepoData(repo, dummyRepoCache, RepoConfig.empty)
+    val repoDir = workspaceAlg.repoDir(repo).unsafeRunSync()
+    val mainSc = repoDir / "main.sc"
+    val update = ("org.typelevel".g % "cats-effect".a % "3.5.2" %> "3.5.4").single
+
+    val state = MockState.empty
+      .copy(execCommands = true)
+      .initGitRepo(
+        repoDir,
+        mainSc ->
+          """
+            |//> using scala "3.4.2"
+            |//> using jvm "temurin:21"
+            |//> using lib "org.typelevel::cats-effect:3.5.2"
+            |println("Hello!")
+            |""".stripMargin
+      )
+      .flatMap(editAlg.applyUpdate(data, update).runS)
+      .unsafeRunSync()
+
+    val expected = MockState.empty.copy(
+      execCommands = true,
+      trace = Vector(
+        Cmd.gitGrep(repoDir, update.currentVersion.value),
+        Cmd("read", mainSc.pathAsString),
+        Cmd.gitGrep(repoDir, update.groupId.value),
+        Cmd("read", mainSc.pathAsString),
+        Cmd("read", mainSc.pathAsString),
+        Cmd("write", mainSc.pathAsString),
+        Cmd.gitStatus(repoDir),
+        Cmd.gitCommit(repoDir, "Update cats-effect to 3.5.4"),
+        Cmd.gitLatestSha1(repoDir)
+      ),
+      files = Map(
+        mainSc ->
+          """
+            |//> using scala "3.4.2"
+            |//> using jvm "temurin:21"
+            |//> using lib "org.typelevel::cats-effect:3.5.4"
+            |println("Hello!")
+            |""".stripMargin
+      )
+    )
+
+    assertEquals(state, expected)
+  }
+
+  test("applyUpdate for scala-cli using dep") {
+    val repo = Repo("edit-alg", "test-5")
+    val data = RepoData(repo, dummyRepoCache, RepoConfig.empty)
+    val repoDir = workspaceAlg.repoDir(repo).unsafeRunSync()
+    val mainSc = repoDir / "main.sc"
+    val update = ("org.typelevel".g % "cats-effect".a % "3.5.2" %> "3.5.4").single
+
+    val state = MockState.empty
+      .copy(execCommands = true)
+      .initGitRepo(
+        repoDir,
+        mainSc ->
+          """
+            |//> using scala "3.4.2"
+            |//> using jvm "temurin:21"
+            |//> using dep "org.typelevel::cats-effect:3.5.2"
+            |//> using test.dep "org.scalameta::munit:1.0.0"
+            |println("Hello!")
+            |""".stripMargin
+      )
+      .flatMap(editAlg.applyUpdate(data, update).runS)
+      .unsafeRunSync()
+
+    val expected = MockState.empty.copy(
+      execCommands = true,
+      trace = Vector(
+        Cmd.gitGrep(repoDir, update.currentVersion.value),
+        Cmd("read", mainSc.pathAsString),
+        Cmd.gitGrep(repoDir, update.groupId.value),
+        Cmd("read", mainSc.pathAsString),
+        Cmd("read", mainSc.pathAsString),
+        Cmd("write", mainSc.pathAsString),
+        Cmd.gitStatus(repoDir),
+        Cmd.gitCommit(repoDir, "Update cats-effect to 3.5.4"),
+        Cmd.gitLatestSha1(repoDir)
+      ),
+      files = Map(
+        mainSc ->
+          """
+            |//> using scala "3.4.2"
+            |//> using jvm "temurin:21"
+            |//> using dep "org.typelevel::cats-effect:3.5.4"
+            |//> using test.dep "org.scalameta::munit:1.0.0"
+            |println("Hello!")
+            |""".stripMargin
+      )
+    )
+
+    assertEquals(state, expected)
+  }
+
+  test("applyUpdate for scala-cli using test.dep") {
+    val repo = Repo("edit-alg", "test-6")
+    val data = RepoData(repo, dummyRepoCache, RepoConfig.empty)
+    val repoDir = workspaceAlg.repoDir(repo).unsafeRunSync()
+    val mainSc = repoDir / "main.sc"
+    val update = ("org.scalameta".g % "munit".a % "0.7.29" %> "1.0.0").single
+
+    val state = MockState.empty
+      .copy(execCommands = true)
+      .initGitRepo(
+        repoDir,
+        mainSc ->
+          """
+            |//> using scala "3.4.2"
+            |//> using jvm "temurin:21"
+            |//> using dep "org.typelevel::cats-effect:3.5.4"
+            |//> using test.dep "org.scalameta::munit:0.7.29"
+            |println("Hello!")
+            |""".stripMargin
+      )
+      .flatMap(editAlg.applyUpdate(data, update).runS)
+      .unsafeRunSync()
+
+    val expected = MockState.empty.copy(
+      execCommands = true,
+      trace = Vector(
+        Cmd.gitGrep(repoDir, update.currentVersion.value),
+        Cmd("read", mainSc.pathAsString),
+        Cmd.gitGrep(repoDir, update.groupId.value),
+        Cmd("read", mainSc.pathAsString),
+        Cmd("read", mainSc.pathAsString),
+        Cmd("write", mainSc.pathAsString),
+        Cmd.gitStatus(repoDir),
+        Cmd.gitCommit(repoDir, "Update munit to 1.0.0"),
+        Cmd.gitLatestSha1(repoDir)
+      ),
+      files = Map(
+        mainSc ->
+          """
+            |//> using scala "3.4.2"
+            |//> using jvm "temurin:21"
+            |//> using dep "org.typelevel::cats-effect:3.5.4"
+            |//> using test.dep "org.scalameta::munit:1.0.0"
+            |println("Hello!")
+            |""".stripMargin
+      )
+    )
+
+    assertEquals(state, expected)
+  }
 }