diff --git a/modules/core/src/main/resources/artifact-migrations.conf b/modules/core/src/main/resources/artifact-migrations.conf index a2444547fc..8f0aa0415f 100644 --- a/modules/core/src/main/resources/artifact-migrations.conf +++ b/modules/core/src/main/resources/artifact-migrations.conf @@ -3,288 +3,240 @@ changes = [ groupIdBefore = com.eed3si9n groupIdAfter = com.github.sbt artifactIdAfter = sbt-unidoc - initialVersion = 0.5.0 }, { groupIdBefore = com.cavorite groupIdAfter = com.github.sbt artifactIdAfter = sbt-avro - initialVersion = 3.3.0 }, { groupIdBefore = com.geirsson groupIdAfter = com.github.sbt artifactIdAfter = sbt-ci-release - initialVersion = 1.5.9 }, { groupIdBefore = com.github.julien-truffaut groupIdAfter = dev.optics artifactIdAfter = monocle-core - initialVersion = 3.0.0 }, { groupIdBefore = com.github.julien-truffaut groupIdAfter = dev.optics artifactIdAfter = monocle-macro - initialVersion = 3.0.0 }, { groupIdBefore = com.github.julien-truffaut groupIdAfter = dev.optics artifactIdAfter = monocle-laws - initialVersion = 3.0.0 }, { groupIdBefore = com.github.julien-truffaut groupIdAfter = dev.optics artifactIdAfter = monocle-refined - initialVersion = 3.0.0 }, { groupIdBefore = com.pauldijou groupIdAfter = com.github.jwt-scala artifactIdAfter = jwt-argonaut - initialVersion = 6.0.0 }, { groupIdBefore = com.pauldijou groupIdAfter = com.github.jwt-scala artifactIdAfter = jwt-circe - initialVersion = 6.0.0 }, { groupIdBefore = com.pauldijou groupIdAfter = com.github.jwt-scala artifactIdAfter = jwt-core - initialVersion = 6.0.0 }, { groupIdBefore = com.pauldijou groupIdAfter = com.github.jwt-scala artifactIdAfter = jwt-json-common - initialVersion = 6.0.0 }, { groupIdBefore = com.pauldijou groupIdAfter = com.github.jwt-scala artifactIdAfter = jwt-json4s-common - initialVersion = 6.0.0 }, { groupIdBefore = com.pauldijou groupIdAfter = com.github.jwt-scala artifactIdAfter = jwt-json4s-jackson - initialVersion = 6.0.0 }, { groupIdBefore = com.pauldijou groupIdAfter = com.github.jwt-scala artifactIdAfter = jwt-json4s-native - initialVersion = 6.0.0 }, { groupIdBefore = com.pauldijou groupIdAfter = com.github.jwt-scala artifactIdAfter = jwt-play-json - initialVersion = 6.0.0 }, { groupIdBefore = com.pauldijou groupIdAfter = com.github.jwt-scala artifactIdAfter = jwt-play - initialVersion = 6.0.0 }, { groupIdBefore = com.pauldijou groupIdAfter = com.github.jwt-scala artifactIdAfter = jwt-spray-json - initialVersion = 6.0.0 }, { groupIdBefore = com.pauldijou groupIdAfter = com.github.jwt-scala artifactIdAfter = jwt-upickle - initialVersion = 6.0.0 }, { groupIdBefore = com.github.gseitz groupIdAfter = com.github.sbt artifactIdAfter = sbt-protobuf - initialVersion = 0.7.0 }, { groupIdBefore = com.github.gseitz groupIdAfter = com.github.sbt artifactIdAfter = sbt-release - initialVersion = 1.0.15 }, { groupIdBefore = com.twilio groupIdAfter = dev.guardrail artifactIdAfter = guardrail - initialVersion = 0.65.2 }, { groupIdBefore = com.twilio groupIdAfter = dev.guardrail artifactIdAfter = sbt-guardrail-core - initialVersion = 0.65.3 }, { groupIdBefore = com.twilio groupIdAfter = dev.guardrail artifactIdAfter = sbt-guardrail - initialVersion = 0.65.3 }, { groupIdBefore = com.typesafe.sbt groupIdAfter = com.github.sbt artifactIdAfter = sbt-native-packager - initialVersion = 1.9.0 }, { groupIdBefore = com.jsuereth groupIdAfter = com.github.sbt artifactIdAfter = sbt-pgp - initialVersion = 2.1.2 }, { groupIdBefore = com.geirsson groupIdAfter = org.scalameta artifactIdAfter = sbt-scalafmt - initialVersion = 2.0.0 }, { groupIdBefore = com.github.mpilquist groupIdAfter = org.typelevel artifactIdAfter = simulacrum - initialVersion = 1.0.0 }, { groupIdBefore = io.chrisdavenport groupIdAfter = org.typelevel artifactIdAfter = log4cats-core - initialVersion = 1.2.0 }, { groupIdBefore = io.chrisdavenport groupIdAfter = org.typelevel artifactIdAfter = log4cats-noop - initialVersion = 1.2.0 }, { groupIdBefore = io.chrisdavenport groupIdAfter = org.typelevel artifactIdAfter = log4cats-slf4j - initialVersion = 1.2.0 }, { groupIdBefore = io.chrisdavenport groupIdAfter = org.typelevel artifactIdAfter = log4cats-testing - initialVersion = 1.2.0 }, { groupIdBefore = net.ceedubs groupIdAfter = com.iheart artifactIdAfter = ficus - initialVersion = 1.3.4 }, { groupIdBefore = org.spire-math groupIdAfter = org.typelevel artifactIdAfter = kind-projector - initialVersion = 0.10.0 }, { groupIdAfter = org.scalatestplus artifactIdBefore = junit-4-12 artifactIdAfter = junit-4-13 - initialVersion = 3.2.3.0 }, { groupIdAfter = org.scalatestplus artifactIdBefore = mockito-3-3 artifactIdAfter = mockito-3-4 - initialVersion = 3.2.3.0 }, { groupIdAfter = org.scalatestplus artifactIdBefore = scalacheck-1-14 artifactIdAfter = scalacheck-1-15 - initialVersion = 3.2.2.0 }, { groupIdBefore = io.github.nafg groupIdAfter = io.github.nafg.slick-migration-api artifactIdAfter = slick-migration-api - initialVersion = 0.8.2 }, { groupIdBefore = io.github.nafg groupIdAfter = io.github.nafg.slick-migration-api artifactIdAfter = slick-migration-api-flyway - initialVersion = 0.8.1 }, { groupIdAfter = com.github.alexarchambault artifactIdBefore = scalacheck-shapeless_1.14 artifactIdAfter = scalacheck-shapeless_1.15 - initialVersion = 1.3.0 }, { groupIdAfter = com.github.alexarchambault artifactIdBefore = argonaut-shapeless_6.2 artifactIdAfter = argonaut-shapeless_6.3 - initialVersion = 1.3.0 }, { groupIdAfter = com.github.alexarchambault artifactIdBefore = argonaut-refined_6.2 artifactIdAfter = argonaut-refined_6.3 - initialVersion = 1.3.0 }, { groupIdBefore = com.kubukoz groupIdAfter = org.polyvariant artifactIdAfter = better-tostring - initialVersion = 0.3.8 }, { groupIdBefore = com.novocode groupIdAfter = com.github.sbt artifactIdAfter = junit-interface - initialVersion = 0.13.2 }, { groupIdBefore = com.xebia groupIdAfter = nl.wehkamp.cakemix artifactIdAfter = cakemix - initialVersion = 1.2.0 }, { groupIdBefore = io.chrisdavenport groupIdAfter = org.typelevel artifactIdAfter = cats-time - initialVersion = 0.5.0 }, { groupIdBefore = com.lightbend.sbt groupIdAfter = com.github.sbt artifactIdAfter = sbt-proguard - initialVersion = 0.5.0 }, { groupIdBefore = ky.korins groupIdAfter = pt.kcry artifactIdAfter = sha - initialVersion = 2.0.0 }, { groupIdBefore = ky.korins groupIdAfter = pt.kcry artifactIdAfter = blake3 - initialVersion = 3.0.0 } ] diff --git a/modules/core/src/main/scala/org/scalasteward/core/update/UpdateAlg.scala b/modules/core/src/main/scala/org/scalasteward/core/update/UpdateAlg.scala index 62c7c767ab..91c4d92abf 100644 --- a/modules/core/src/main/scala/org/scalasteward/core/update/UpdateAlg.scala +++ b/modules/core/src/main/scala/org/scalasteward/core/update/UpdateAlg.scala @@ -21,8 +21,10 @@ import cats.syntax.all._ import org.scalasteward.core.coursier.VersionsCache import org.scalasteward.core.data._ import org.scalasteward.core.repoconfig.RepoConfig -import org.scalasteward.core.update.artifact.ArtifactMigrationsFinder +import org.scalasteward.core.update.UpdateAlg.migratedDependency +import org.scalasteward.core.update.artifact.{ArtifactChange, ArtifactMigrationsFinder} import org.scalasteward.core.util.Nel + import scala.concurrent.duration.FiniteDuration final class UpdateAlg[F[_]](implicit @@ -36,13 +38,37 @@ final class UpdateAlg[F[_]](implicit maxAge: Option[FiniteDuration] ): F[Option[Update.Single]] = for { - versions <- versionsCache.getVersions(dependency, maxAge) - current = Version(dependency.value.version) - maybeNewerVersions = Nel.fromList(versions.filter(_ > current)) - maybeUpdate = maybeNewerVersions + existingVersions <- versionsCache.getVersions(dependency, maxAge) + maybeUpdate = maybeNewerVersions(dependency, existingVersions) .map(vs => Update.Single(CrossDependency(dependency.value), vs.map(_.value))) - .orElse(artifactMigrationsFinder.findUpdateWithRenamedArtifact(dependency.value)) - } yield maybeUpdate + maybeUpdateOrRename <- maybeUpdate match { + case Some(update) => F.pure(Some(update)) + case None => + artifactMigrationsFinder.findUpdateWithRenamedArtifact(dependency.value) match { + case Some(artifactChange) => verifyVersion(dependency, artifactChange, maxAge) + case None => F.pure(None) + } + } + } yield maybeUpdateOrRename + + private def verifyVersion( + dependency: Scope[Dependency], + artifactChange: ArtifactChange, + maxAge: Option[FiniteDuration] + ): F[Option[Update.Single]] = + versionsCache + .getVersions(migratedDependency(dependency, artifactChange), maxAge) + .map { existingVersions => + maybeNewerVersions(dependency, existingVersions) + .map(newerVersions => + Update.Single( + CrossDependency(dependency.value), + newerVersions.map(_.value), + Some(artifactChange.groupIdAfter), + Some(artifactChange.artifactIdAfter) + ) + ) + } def findUpdates( dependencies: List[Scope.Dependency], @@ -52,6 +78,14 @@ final class UpdateAlg[F[_]](implicit val updates = dependencies.traverseFilter(findUpdate(_, maxAge)) updates.flatMap(filterAlg.localFilterMany(repoConfig, _)) } + + private def maybeNewerVersions( + dependency: Scope[Dependency], + existingVersions: List[Version] + ): Option[Nel[Version]] = { + val current = Version(dependency.value.version) + Nel.fromList(existingVersions.filter(_ > current)) + } } object UpdateAlg { @@ -61,4 +95,24 @@ object UpdateAlg { update.currentVersion === dependency.version && update.artifactIds.contains_(dependency.artifactId) } + + def migratedDependency( + dependency: Scope[Dependency], + artifactChange: ArtifactChange + ): Scope[Dependency] = { + val oldArtifactId = dependency.value.artifactId + val newGroupId = artifactChange.groupIdAfter + val newArtifactId = ArtifactId( + artifactChange.artifactIdAfter, + oldArtifactId.maybeCrossName.map( + _.replace(oldArtifactId.name, artifactChange.artifactIdAfter) + ) + ) + dependency.copy(value = + dependency.value.copy( + groupId = newGroupId, + artifactId = newArtifactId + ) + ) + } } diff --git a/modules/core/src/main/scala/org/scalasteward/core/update/artifact/ArtifactChange.scala b/modules/core/src/main/scala/org/scalasteward/core/update/artifact/ArtifactChange.scala index 45799520b5..a4826edae6 100644 --- a/modules/core/src/main/scala/org/scalasteward/core/update/artifact/ArtifactChange.scala +++ b/modules/core/src/main/scala/org/scalasteward/core/update/artifact/ArtifactChange.scala @@ -24,8 +24,7 @@ final case class ArtifactChange( groupIdBefore: Option[GroupId], groupIdAfter: GroupId, artifactIdBefore: Option[String], - artifactIdAfter: String, - initialVersion: String + artifactIdAfter: String ) object ArtifactChange { diff --git a/modules/core/src/main/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsFinder.scala b/modules/core/src/main/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsFinder.scala index 3b6d44a607..15e0266c50 100644 --- a/modules/core/src/main/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsFinder.scala +++ b/modules/core/src/main/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsFinder.scala @@ -17,11 +17,10 @@ package org.scalasteward.core.update.artifact import cats.syntax.all._ -import org.scalasteward.core.data.{CrossDependency, Dependency, Update} -import org.scalasteward.core.util.Nel +import org.scalasteward.core.data.Dependency final class ArtifactMigrationsFinder(migrations: List[ArtifactChange]) { - def findUpdateWithRenamedArtifact(dependency: Dependency): Option[Update.Single] = + def findUpdateWithRenamedArtifact(dependency: Dependency): Option[ArtifactChange] = migrations .find { migration => (migration.groupIdBefore, migration.artifactIdBefore) match { @@ -37,12 +36,4 @@ final class ArtifactMigrationsFinder(migrations: List[ArtifactChange]) { case (None, None) => false } } - .map { migration => - Update.Single( - CrossDependency(dependency), - Nel.one(migration.initialVersion), - Some(migration.groupIdAfter), - Some(migration.artifactIdAfter) - ) - } } diff --git a/modules/core/src/test/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsFinderTest.scala b/modules/core/src/test/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsFinderTest.scala index 20b137f7b0..4b7bb07560 100644 --- a/modules/core/src/test/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsFinderTest.scala +++ b/modules/core/src/test/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsFinderTest.scala @@ -6,6 +6,8 @@ import org.scalasteward.core.TestSyntax._ import org.scalasteward.core.data.GroupId import org.scalasteward.core.mock.MockContext.context.updateAlg import org.scalasteward.core.mock.MockState +import org.scalasteward.core.update.UpdateAlg +import org.scalasteward.core.util.Nel class ArtifactMigrationsFinderTest extends FunSuite { @@ -15,8 +17,7 @@ class ArtifactMigrationsFinderTest extends FunSuite { groupIdBefore = Some(GroupId("org.spire-math")), groupIdAfter = GroupId("org.typelevel"), artifactIdBefore = None, - artifactIdAfter = "kind-projector", - initialVersion = "0.10.0" + artifactIdAfter = "kind-projector" ) ) ) @@ -27,8 +28,7 @@ class ArtifactMigrationsFinderTest extends FunSuite { groupIdBefore = None, groupIdAfter = GroupId("com.nodifferent"), artifactIdBefore = Some("artifact-before"), - artifactIdAfter = "artifact-after", - initialVersion = "0.10.0" + artifactIdAfter = "artifact-after" ) ) ) @@ -39,8 +39,7 @@ class ArtifactMigrationsFinderTest extends FunSuite { groupIdBefore = Some(GroupId("org.before")), groupIdAfter = GroupId("org.after"), artifactIdBefore = Some("artifact-before"), - artifactIdAfter = "artifact-after", - initialVersion = "0.10.0" + artifactIdAfter = "artifact-after" ) ) ) @@ -77,8 +76,12 @@ class ArtifactMigrationsFinderTest extends FunSuite { test("findUpdateWithRenamedArtifact: for groupId, returns Update.Single for updating groupId") { val original = "org.spire-math".g % ("kind-projector", "kind-projector_2.12").a % "0.9.0" val obtained = standardGroupMigrations.findUpdateWithRenamedArtifact(original) - val expected = (original %> "0.10.0").single - .copy(newerGroupId = Some("org.typelevel".g), newerArtifactId = Some("kind-projector")) + val expected = ArtifactChange( + Some("org.spire-math".g), + "org.typelevel".g, + None, + "kind-projector" + ) assertEquals(obtained, Some(expected)) } @@ -87,8 +90,12 @@ class ArtifactMigrationsFinderTest extends FunSuite { ) { val original = "com.nodifferent".g % ("artifact-before", "artifact-before_2.12").a % "0.9.0" val obtained = standardArtifactMigrations.findUpdateWithRenamedArtifact(original) - val expected = (original %> "0.10.0").single - .copy(newerGroupId = Some("com.nodifferent".g), newerArtifactId = Some("artifact-after")) + val expected = ArtifactChange( + None, + "com.nodifferent".g, + Some("artifact-before"), + "artifact-after" + ) assertEquals(obtained, Some(expected)) } @@ -98,15 +105,19 @@ class ArtifactMigrationsFinderTest extends FunSuite { ) { val original = "org.before".g % ("artifact-before", "artifact-before_2.12").a % "0.9.0" val obtained = standardBothMigrations.findUpdateWithRenamedArtifact(original) - val expected = (original %> "0.10.0").single - .copy(newerGroupId = Some("org.after".g), newerArtifactId = Some("artifact-after")) + val expected = ArtifactChange( + Some("org.before".g), + "org.after".g, + Some("artifact-before"), + "artifact-after" + ) assertEquals(obtained, Some(expected)) } test("findUpdate: newer groupId") { val dependency = "org.spire-math".g % ("kind-projector", "kind-projector_2.12").a % "0.9.10" val expected = ("org.spire-math".g % ("kind-projector", "kind-projector_2.12").a % "0.9.10" %> - "0.10.0").single + Nel.of("0.10.0", "0.10.1", "0.10.2", "0.10.3")).single .copy(newerGroupId = Some("org.typelevel".g), newerArtifactId = Some("kind-projector")) val obtained = updateAlg .findUpdate(dependency.withMavenCentral, None) @@ -114,4 +125,30 @@ class ArtifactMigrationsFinderTest extends FunSuite { .unsafeRunSync() assertEquals(obtained, Some(expected)) } + + test("migratedDependency: newer groupId") { + val dependency = "org.spire-math".g % ("kind-projector", "kind-projector_2.12").a % "0.9.10" + val artifactChange = ArtifactChange( + Some("org.spire-math".g), + "org.typelevel".g, + Some("kind-projector"), + "kind-projector" + ) + val expected = "org.typelevel".g % ("kind-projector", "kind-projector_2.12").a % "0.9.10" + val obtained = UpdateAlg.migratedDependency(dependency.withMavenCentral, artifactChange) + assertEquals(obtained, expected.withMavenCentral) + } + + test("migratedDependency: newer ArtifactId") { + val dependency = "org.spire-math".g % ("kind-projector", "kind-projector_2.12").a % "0.9.10" + val artifactChange = ArtifactChange( + Some("org.spire-math".g), + "org.spire-math".g, + Some("kind-projector"), + "new-projector" + ) + val expected = "org.spire-math".g % ("new-projector", "new-projector_2.12").a % "0.9.10" + val obtained = UpdateAlg.migratedDependency(dependency.withMavenCentral, artifactChange) + assertEquals(obtained, expected.withMavenCentral) + } } diff --git a/modules/core/src/test/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsLoaderTest.scala b/modules/core/src/test/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsLoaderTest.scala index 8430e348ac..546eaedc1b 100644 --- a/modules/core/src/test/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsLoaderTest.scala +++ b/modules/core/src/test/scala/org/scalasteward/core/update/artifact/ArtifactMigrationsLoaderTest.scala @@ -17,15 +17,13 @@ class ArtifactMigrationsLoaderTest extends FunSuite { | groupIdBefore = com.evilcorp | groupIdAfter = org.ice.cream | artifactIdAfter = yumyum - | initialVersion = 2.0.0 | } |]""".stripMargin val migration: ArtifactChange = ArtifactChange( groupIdBefore = Some(GroupId("com.evilcorp")), groupIdAfter = GroupId("org.ice.cream"), artifactIdBefore = None, - artifactIdAfter = "yumyum", - initialVersion = "2.0.0" + artifactIdAfter = "yumyum" ) test("loadAll: without extra file, without defaults") { @@ -80,7 +78,6 @@ class ArtifactMigrationsLoaderTest extends FunSuite { | { | groupIdAfter = org.ice.cream | artifactIdAfter = yumyum - | initialVersion = 2.0.0 | } |]""".stripMargin) val migrations = artifactMigrationsLoader