Repository: scala-steward-org/scala-steward
Pull request #1755 (2020-11-20 13:41:00)

Mill: extract artifact names with and without binary suffix
This handles dependencies like org.scalatest:scalatest_2.12
and org.scalatest:scalatest_2.13 as one dependency
(org.scalatest:scalatest) with different cross artifactIds.


Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/buildtool/mill/parser.scala b/modules/core/src/main/scala/org/scalasteward/core/buildtool/mill/parser.scala
index 7b13236a..b2e9518d 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/buildtool/mill/parser.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/buildtool/mill/parser.scala
@@ -18,7 +18,7 @@ package org.scalasteward.core.buildtool.mill
 
 import cats.syntax.all._
 import io.circe.{Decoder, DecodingFailure}
-import org.scalasteward.core.data.{ArtifactId, Dependency, GroupId, Resolver}
+import org.scalasteward.core.data.{Dependency, Resolver}
 
 object parser {
   sealed trait ParseError extends RuntimeException {
@@ -66,19 +66,11 @@ object MillModule {
     }
   }
 
-  val dependencyDecoder: Decoder[Dependency] = Decoder.instance { c =>
-    for {
-      groupId <- c.downField("groupId").as[GroupId]
-      artifactId <- c.downField("artifactId").as[String].map(aid => ArtifactId(aid, None))
-      version <- c.downField("version").as[String]
-    } yield Dependency(groupId, artifactId, version)
-  }
-
   implicit val decoder: Decoder[MillModule] = Decoder.instance(c =>
     for {
       name <- c.downField("name").as[String]
       resolvers <- c.downField("repositories").as(Decoder.decodeList(resolverDecoder))
-      dependencies <- c.downField("dependencies").as(Decoder.decodeList(dependencyDecoder))
+      dependencies <- c.downField("dependencies").as[List[Dependency]]
     } yield MillModule(name, resolvers, dependencies)
   )
 }
diff --git a/modules/mill-plugin/src/main/scala/org/scalasteward/mill/plugin/StewardPlugin.scala b/modules/mill-plugin/src/main/scala/org/scalasteward/mill/plugin/StewardPlugin.scala
index 75c799bb..912d94fa 100644
--- a/modules/mill-plugin/src/main/scala/org/scalasteward/mill/plugin/StewardPlugin.scala
+++ b/modules/mill-plugin/src/main/scala/org/scalasteward/mill/plugin/StewardPlugin.scala
@@ -69,25 +69,38 @@ object StewardPlugin extends ExternalModule {
 
   lazy val millDiscover: Discover[StewardPlugin.this.type] = Discover[this.type]
 
+  case class ArtifactId(
+      name: String,
+      maybeCrossName: Option[String]
+  ) {
+    def toJson =
+      Obj(
+        "name" -> Str(name),
+        "maybeCrossName" -> maybeCrossName.map(Str).getOrElse(Null)
+      )
+  }
+
   case class Dependency(
       groupId: String,
-      artifactId: String,
+      artifactId: ArtifactId,
       version: String
   ) {
     def toJson =
       Obj(
         "groupId" -> Str(groupId),
-        "artifactId" -> Str(artifactId),
+        "artifactId" -> artifactId.toJson,
         "version" -> Str(version)
       )
   }
 
   object Dependency {
     def fromDep(dep: Dep, modifiers: Option[(String, String, String)]) = {
-      val artifactId = modifiers match {
-        case Some((binary, full, platform)) => dep.artifactName(binary, full, platform)
-        case None                           => dep.dep.module.name.value
-      }
+      val artifactId = ArtifactId(
+        dep.dep.module.name.value,
+        modifiers.map { case (binary, full, platform) =>
+          dep.artifactName(binary, full, platform)
+        }
+      )
       Dependency(dep.dep.module.organization.value, artifactId, dep.dep.version)
     }
   }


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/buildtool/mill/MillDepParserTest.scala b/modules/core/src/test/scala/org/scalasteward/core/buildtool/mill/MillDepParserTest.scala
index ca0bc2e7..6512ada2 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/buildtool/mill/MillDepParserTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/buildtool/mill/MillDepParserTest.scala
@@ -7,17 +7,137 @@ import org.scalatest.matchers.should.Matchers
 class MillDepParserTest extends AnyFunSuite with Matchers {
   test("parse dependencies from https://github.com/lihaoyi/requests-scala") {
     val data =
-      """{"modules":[{"name":"requests[2.12.6]","repositories":[{"url":"https://repo1.maven.org/maven2","type":"maven","auth":null},{"url":"https://oss.sonatype.org/content/repositories/releases","type":"maven","auth":null}],"dependencies":[{"groupId":"com.lihaoyi","artifactId":"geny_2.12","version":"0.6.0"}]},{"name":"requests[2.12.6].test","repositories":[{"url":"https://repo1.maven.org/maven2","type":"maven","auth":null},{"url":"https://oss.sonatype.org/content/repositories/releases","type":"maven","auth":null}],"dependencies":[{"groupId":"com.lihaoyi","artifactId":"utest_2.12","version":"0.7.3"},{"groupId":"com.lihaoyi","artifactId":"ujson_2.12","version":"1.1.0"}]},{"name":"requests[2.13.0]","repositories":[{"url":"https://repo1.maven.org/maven2","type":"maven","auth":null},{"url":"https://oss.sonatype.org/content/repositories/releases","type":"maven","auth":null}],"dependencies":[{"groupId":"com.lihaoyi","artifactId":"geny_2.13","version":"0.6.0"}]},{"name":"requests[2.13.0].test","repositories":[{"url":"https://repo1.maven.org/maven2","type":"maven","auth":null},{"url":"https://oss.sonatype.org/content/repositories/releases","type":"maven","auth":null}],"dependencies":[{"groupId":"com.lihaoyi","artifactId":"utest_2.13","version":"0.7.3"},{"groupId":"com.lihaoyi","artifactId":"ujson_2.13","version":"1.1.0"}]}]}"""
+      """{
+        |  "modules": [
+        |    {
+        |      "name": "requests[2.12.6]",
+        |      "repositories": [
+        |        {
+        |          "url": "https://repo1.maven.org/maven2",
+        |          "type": "maven",
+        |          "auth": null
+        |        },
+        |        {
+        |          "url": "https://oss.sonatype.org/content/repositories/releases",
+        |          "type": "maven",
+        |          "auth": null
+        |        }
+        |      ],
+        |      "dependencies": [
+        |        {
+        |          "groupId": "com.lihaoyi",
+        |          "artifactId": {
+        |            "name": "geny",
+        |            "maybeCrossName": "geny_2.12"
+        |          },
+        |          "version": "0.6.0"
+        |        }
+        |      ]
+        |    },
+        |    {
+        |      "name": "requests[2.12.6].test",
+        |      "repositories": [
+        |        {
+        |          "url": "https://repo1.maven.org/maven2",
+        |          "type": "maven",
+        |          "auth": null
+        |        },
+        |        {
+        |          "url": "https://oss.sonatype.org/content/repositories/releases",
+        |          "type": "maven",
+        |          "auth": null
+        |        }
+        |      ],
+        |      "dependencies": [
+        |        {
+        |          "groupId": "com.lihaoyi",
+        |          "artifactId": {
+        |            "name": "utest",
+        |            "maybeCrossName": "utest_2.12"
+        |          },
+        |          "version": "0.7.3"
+        |        },
+        |        {
+        |          "groupId": "com.lihaoyi",
+        |          "artifactId": {
+        |            "name": "ujson",
+        |            "maybeCrossName": "ujson_2.12"
+        |          },
+        |          "version": "1.1.0"
+        |        }
+        |      ]
+        |    },
+        |    {
+        |      "name": "requests[2.13.0]",
+        |      "repositories": [
+        |        {
+        |          "url": "https://repo1.maven.org/maven2",
+        |          "type": "maven",
+        |          "auth": null
+        |        },
+        |        {
+        |          "url": "https://oss.sonatype.org/content/repositories/releases",
+        |          "type": "maven",
+        |          "auth": null
+        |        }
+        |      ],
+        |      "dependencies": [
+        |        {
+        |          "groupId": "com.lihaoyi",
+        |          "artifactId": {
+        |            "name": "geny",
+        |            "maybeCrossName": "geny_2.13"
+        |          },
+        |          "version": "0.6.0"
+        |        }
+        |      ]
+        |    },
+        |    {
+        |      "name": "requests[2.13.0].test",
+        |      "repositories": [
+        |        {
+        |          "url": "https://repo1.maven.org/maven2",
+        |          "type": "maven",
+        |          "auth": null
+        |        },
+        |        {
+        |          "url": "https://oss.sonatype.org/content/repositories/releases",
+        |          "type": "maven",
+        |          "auth": null
+        |        }
+        |      ],
+        |      "dependencies": [
+        |        {
+        |          "groupId": "com.lihaoyi",
+        |          "artifactId": {
+        |            "name": "utest",
+        |            "maybeCrossName": "utest_2.13"
+        |          },
+        |          "version": "0.7.3"
+        |        },
+        |        {
+        |          "groupId": "com.lihaoyi",
+        |          "artifactId": {
+        |            "name": "ujson",
+        |            "maybeCrossName": "ujson_2.13"
+        |          },
+        |          "version": "1.1.0"
+        |        }
+        |      ]
+        |    }
+        |  ]
+        |}
+        |""".stripMargin
     val result = parser.parseModules(data).fold(fail(_), identity)
 
     val dep12 = List(
-      Dependency(GroupId("com.lihaoyi"), ArtifactId(s"geny_2.12"), "0.6.0")
+      Dependency(GroupId("com.lihaoyi"), ArtifactId("geny", Some("geny_2.12")), "0.6.0")
     )
 
     assert(result.headOption.map(_.dependencies) === Some(dep12))
 
     val dep13 = List(
-      Dependency(GroupId("com.lihaoyi"), ArtifactId(s"geny_2.13"), "0.6.0")
+      Dependency(GroupId("com.lihaoyi"), ArtifactId("geny", Some("geny_2.13")), "0.6.0")
     )
 
     assert(result.find(_.name == "requests[2.13.0]").map(_.dependencies) === Some(dep13))