From 9f078d5b30f044e4e77829dc95b39a4d0bd29c9f Mon Sep 17 00:00:00 2001 From: Albert Wang Date: Wed, 23 Sep 2026 19:49:37 +0000 Subject: [PATCH] Force remote metadata checks on Muzzle retries --- .../plugin/muzzle/MuzzleMavenRepoUtils.kt | 16 +++++- .../plugin/muzzle/MuzzleMavenRepoUtilsTest.kt | 49 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/datadog/gradle/plugin/muzzle/MuzzleMavenRepoUtils.kt b/buildSrc/src/main/kotlin/datadog/gradle/plugin/muzzle/MuzzleMavenRepoUtils.kt index c5bb333da6f..7a8858b1349 100644 --- a/buildSrc/src/main/kotlin/datadog/gradle/plugin/muzzle/MuzzleMavenRepoUtils.kt +++ b/buildSrc/src/main/kotlin/datadog/gradle/plugin/muzzle/MuzzleMavenRepoUtils.kt @@ -1,6 +1,8 @@ package datadog.gradle.plugin.muzzle import org.apache.maven.repository.internal.MavenRepositorySystemUtils +import org.eclipse.aether.DefaultRepositorySystemSession +import org.eclipse.aether.DefaultSessionData import org.eclipse.aether.RepositorySystem import org.eclipse.aether.RepositorySystemSession import org.eclipse.aether.artifact.Artifact @@ -8,6 +10,7 @@ import org.eclipse.aether.artifact.DefaultArtifact import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory import org.eclipse.aether.repository.LocalRepository import org.eclipse.aether.repository.RemoteRepository +import org.eclipse.aether.repository.RepositoryPolicy import org.eclipse.aether.resolution.VersionRangeRequest import org.eclipse.aether.resolution.VersionRangeResolutionException import org.eclipse.aether.resolution.VersionRangeResult @@ -158,9 +161,20 @@ internal object MuzzleMavenRepoUtils { val resultExceptions = mutableListOf>>() fun attemptResolve(): VersionRangeResult? { attemptCount++ + val resolutionSession = if (attemptCount == 1) { + session + } else { + // Aether caches failed update checks both in the local repository and in SessionData. + // Bypass both caches so each Muzzle retry performs a real remote request. + DefaultRepositorySystemSession(session).apply { + data = DefaultSessionData() + updatePolicy = RepositoryPolicy.UPDATE_POLICY_ALWAYS + setReadOnly() + } + } val result = try { failure = null - system.resolveVersionRange(session, rangeRequest) + system.resolveVersionRange(resolutionSession, rangeRequest) } catch (e: VersionRangeResolutionException) { failure = e e.result ?: return null diff --git a/buildSrc/src/test/kotlin/datadog/gradle/plugin/muzzle/MuzzleMavenRepoUtilsTest.kt b/buildSrc/src/test/kotlin/datadog/gradle/plugin/muzzle/MuzzleMavenRepoUtilsTest.kt index e6983e45b15..a2dff548dbc 100644 --- a/buildSrc/src/test/kotlin/datadog/gradle/plugin/muzzle/MuzzleMavenRepoUtilsTest.kt +++ b/buildSrc/src/test/kotlin/datadog/gradle/plugin/muzzle/MuzzleMavenRepoUtilsTest.kt @@ -2,6 +2,7 @@ package datadog.gradle.plugin.muzzle import datadog.gradle.plugin.MavenRepoFixture import org.eclipse.aether.RepositorySystem +import org.eclipse.aether.RepositorySystemSession import org.eclipse.aether.artifact.DefaultArtifact import org.eclipse.aether.repository.RemoteRepository import org.eclipse.aether.resolution.VersionRangeRequest @@ -90,6 +91,30 @@ class MuzzleMavenRepoUtilsTest { assertThat(attempts).hasValue(4) } + @Test + fun `resolveVersionRange retries remote metadata after a cached failure`() { + val fixture = MavenRepoFixture(File(tempDir, "initially-empty")) + val repo = RemoteRepository.Builder("initially-empty", "default", fixture.repoUrl).build() + val directive = MuzzleDirective().apply { + group = "com.example" + module = "mylib" + versions = "[1.0,)" + } + val attempts = AtomicInteger() + val publishingSystem = repositorySystemPublishingAfterFirstResolution(fixture, attempts) + + val result = MuzzleMavenRepoUtils.resolveVersionRange( + directive, + publishingSystem, + newSession(), + listOf(repo), + enableBackoffRetries = false + ) + + assertThat(result.versions.map { it.toString() }).containsExactly("1.0.0") + assertThat(attempts).hasValue(2) + } + @Test fun `resolveVersionRange throws IllegalStateException when resolution consistently fails`() { val emptyRepo = RemoteRepository.Builder("empty", "default", File(tempDir, "empty").apply { mkdirs() }.toURI().toString()).build() @@ -390,4 +415,28 @@ class MuzzleMavenRepoUtilsTest { } } as RepositorySystem + private fun repositorySystemPublishingAfterFirstResolution( + fixture: MavenRepoFixture, + attempts: AtomicInteger + ): RepositorySystem = + Proxy.newProxyInstance( + RepositorySystem::class.java.classLoader, + arrayOf(RepositorySystem::class.java) + ) { _, method, args -> + when (method.name) { + "resolveVersionRange" -> { + val result = system.resolveVersionRange( + args?.get(0) as RepositorySystemSession, + args[1] as VersionRangeRequest + ) + if (attempts.incrementAndGet() == 1) { + fixture.publishVersions("com.example", "mylib", listOf("1.0.0")) + } + result + } + "toString" -> "repositorySystemPublishingAfterFirstResolution" + else -> throw UnsupportedOperationException(method.name) + } + } as RepositorySystem + }