Repository: scala-steward-org/scala-steward (scala)

Issue:
Grouped PR description includes updates ignored via `// scala-steward:off`
We have a shared `.scala-steward.conf` that defines PR groupings. Because it's shared, we've opted to use the comment syntax to ignore dependency upgrades when the ignore is repo-specific (the `// scala-steward:off` style).

This is going well, the grouped PRs are created and the ignored dependencies are being ignored as expected. The only issue is that the grouped PR description still includes the version bumps that we've ignored and which aren't actually updated in the PR.

Pull request description:
Attempt to fix https://github.com/scala-steward-org/scala-steward/issues/3138

Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/forge/data/NewPullRequestData.scala b/modules/core/src/main/scala/org/scalasteward/core/forge/data/NewPullRequestData.scala
index e82c74f57c..727ba8cf3d 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/forge/data/NewPullRequestData.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/forge/data/NewPullRequestData.scala
@@ -54,15 +54,16 @@ object NewPullRequestData {
   ): String = {
     val migrations = edits.collect { case scalafixEdit: ScalafixEdit => scalafixEdit }
     val appliedMigrations = migrationNote(migrations)
-    val oldVersionDetails = oldVersionNote(filesWithOldVersion, update)
+    val updateWithEdits = filterUpdateWithEditAttempts(update, edits)
+    val oldVersionDetails = oldVersionNote(filesWithOldVersion, updateWithEdits)
     val details = List(
       appliedMigrations,
       oldVersionDetails,
-      adjustFutureUpdates(update).some,
+      adjustFutureUpdates(updateWithEdits).some,
       configParsingError.map(configParsingErrorDetails)
     ).flatten
 
-    val updatesText = update.on(
+    val updatesText = updateWithEdits.on(
       update = u => {
         val artifacts = artifactsWithOptionalUrl(u, artifactIdToUrl)
 
@@ -91,7 +92,7 @@ object NewPullRequestData {
       }
     )
 
-    val skipVersionMessage = update.on(
+    val skipVersionMessage = updateWithEdits.on(
       _ => "If you'd like to skip this version, you can just close this PR. ",
       _ => ""
     )
@@ -120,7 +121,7 @@ object NewPullRequestData {
     val metadataJson =
       Json
         .obj(
-          "Update" -> update.asJson,
+          "Update" -> updateWithEdits.asJson,
           "Labels" -> Json.fromValues(labels.map(_.asJson))
         )
         .toString
@@ -135,6 +136,21 @@ object NewPullRequestData {
     else plainBody
   }
 
+  private def filterUpdateWithEditAttempts(update: Update, edits: List[EditAttempt]): Update =
+    update match {
+      case single: Update.Single => single
+      case grouped: Update.Grouped =>
+        grouped.copy(updates = grouped.updates.filter { update =>
+          edits
+            .collect { case EditAttempt.UpdateEdit(update, _) =>
+              update.groupAndMainArtifactId
+            }
+            .exists { case (groupId, artifactId) =>
+              update.groupId == groupId && update.mainArtifactId == artifactId
+            }
+        })
+    }
+
   def renderUpdateInfoUrls(updateInfoUrls: List[UpdateInfoUrl]): Option[String] =
     Option.when(updateInfoUrls.nonEmpty) {
       updateInfoUrls


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/forge/data/NewPullRequestDataTest.scala b/modules/core/src/test/scala/org/scalasteward/core/forge/data/NewPullRequestDataTest.scala
index 5bd5ed12d3..f4754a6475 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/forge/data/NewPullRequestDataTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/forge/data/NewPullRequestDataTest.scala
@@ -193,10 +193,20 @@ class NewPullRequestDataTest extends FunSuite {
     val update1 = ("ch.qos.logback".g % "logback-classic".a % "1.2.0" %> "1.2.3").single
     val update2 = ("com.example".g % "foo".a % "1.0.0" %> "2.0.0").single
     val update = Update.Grouped("my-group", Some("The PR title"), List(update1, update2))
+    val edits = List(
+      UpdateEdit(
+        update = ("ch.qos.logback".g % "logback-classic".a % "1.2.0" %> "1.2.3").single,
+        commit = Commit(dummySha1)
+      ),
+      UpdateEdit(
+        update = ("com.example".g % "foo".a % "1.0.0" %> "2.0.0").single,
+        commit = Commit(dummySha1)
+      )
+    )
 
     val body = bodyFor(
       update = update,
-      edits = List.empty,
+      edits = edits,
       artifactIdToUrl = Map.empty,
       artifactIdToUpdateInfoUrls = Map.empty,
       filesWithOldVersion = List.empty,
@@ -398,6 +408,107 @@ class NewPullRequestDataTest extends FunSuite {
     assertEquals(body, expected)
   }
 
+  test("bodyFor() grouped update when edits does not contain an update (scala-steward:off case)") {
+    val update1 = ("ch.qos.logback".g % "logback-classic".a % "1.2.0" %> "1.2.3").single
+    val update2 = ("com.example".g % "foo".a % "1.0.0" %> "2.0.0").single
+    val update = Update.Grouped("my-group", Some("The PR title"), List(update1, update2))
+    val edits = List(
+      UpdateEdit(
+        update = ("ch.qos.logback".g % "logback-classic".a % "1.2.0" %> "1.2.3").single,
+        commit = Commit(dummySha1)
+      )
+    )
+
+    val body = bodyFor(
+      update = update,
+      edits = edits,
+      artifactIdToUrl = Map.empty,
+      artifactIdToUpdateInfoUrls = Map.empty,
+      filesWithOldVersion = List.empty,
+      configParsingError = None,
+      labels = List("library-update"),
+      maximumPullRequestLength = 65536
+    )
+    val expected =
+      s"""|## About this PR
+          |Updates:
+          |
+          |* 📦 ch.qos.logback:logback-classic from `1.2.0` to `1.2.3`
+          |
+          |## Usage
+          |✅ **Please merge!**
+          |
+          |I'll automatically update this PR to resolve conflicts as long as you don't change it yourself.
+          |
+          |If you have any feedback, just mention me in the comments below.
+          |
+          |Configure Scala Steward for your repository with a [`.scala-steward.conf`](https://github.com/scala-steward-org/scala-steward/blob/${org.scalasteward.core.BuildInfo.gitHeadCommit}/docs/repo-specific-configuration.md) file.
+          |
+          |_Have a fantastic day writing Scala!_
+          |
+          |<details>
+          |<summary>⚙ Adjust future updates</summary>
+          |
+          |Add these to your `.scala-steward.conf` file to ignore future updates of these dependencies:
+          |```
+          |updates.ignore = [
+          |  { groupId = "ch.qos.logback", artifactId = "logback-classic" }
+          |]
+          |```
+          |Or, add these to slow down future updates of these dependencies:
+          |```
+          |dependencyOverrides = [
+          |  {
+          |    pullRequests = { frequency = "30 days" },
+          |    dependency = { groupId = "ch.qos.logback", artifactId = "logback-classic" }
+          |  }
+          |]
+          |```
+          |</details>
+          |
+          |<sup>
+          |labels: library-update
+          |</sup>
+          |
+          |<!-- scala-steward = {
+          |  "Update" : {
+          |    "Grouped" : {
+          |      "name" : "my-group",
+          |      "title" : "The PR title",
+          |      "updates" : [
+          |        {
+          |          "ForArtifactId" : {
+          |            "crossDependency" : [
+          |              {
+          |                "groupId" : "ch.qos.logback",
+          |                "artifactId" : {
+          |                  "name" : "logback-classic",
+          |                  "maybeCrossName" : null
+          |                },
+          |                "version" : "1.2.0",
+          |                "sbtVersion" : null,
+          |                "scalaVersion" : null,
+          |                "configurations" : null
+          |              }
+          |            ],
+          |            "newerVersions" : [
+          |              "1.2.3"
+          |            ],
+          |            "newerGroupId" : null,
+          |            "newerArtifactId" : null
+          |          }
+          |        }
+          |      ]
+          |    }
+          |  },
+          |  "Labels" : [
+          |    "library-update"
+          |  ]
+          |} -->""".stripMargin
+
+    assertEquals(body, expected)
+  }
+
   test("fromTo") {
     val obtained = fromTo(("com.example".g % "foo".a % "1.2.0" %> "1.2.3").single)
     assertEquals(obtained, "from `1.2.0` to `1.2.3`")
@@ -837,6 +948,16 @@ class NewPullRequestDataTest extends FunSuite {
     val update1 = ("ch.qos.logback".g % "logback-classic".a % "1.2.0" %> "1.2.3").single
     val update2 = ("com.example".g % "foo".a % "1.0.0" %> "2.0.0").single
     val update = Update.Grouped("my-group", None, List(update1, update2))
+    val edits = List(
+      UpdateEdit(
+        update = ("ch.qos.logback".g % "logback-classic".a % "1.2.0" %> "1.2.3").single,
+        commit = Commit(dummySha1)
+      ),
+      UpdateEdit(
+        update = ("com.example".g % "foo".a % "1.0.0" %> "2.0.0").single,
+        commit = Commit(dummySha1)
+      )
+    )
 
     val data = UpdateData(
       repoData = RepoData(
@@ -851,8 +972,9 @@ class NewPullRequestDataTest extends FunSuite {
       updateBranch = Branch("update/logback-classic-1.2.3")
     )
     val obtained = from(
-      data,
-      "scala-steward:update/logback-classic-1.2.3",
+      data = data,
+      branchName = "scala-steward:update/logback-classic-1.2.3",
+      edits = edits,
       addLabels = true,
       labels = labelsFor(data.update)
     )