Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,41 +1,96 @@
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
import org.gradle.api.initialization.Settings
import java.net.URI

gradle.beforeSettings(Action<Settings> {
val gradlePluginProxy = providers.gradleProperty("gradlePluginProxy").orNull
val mavenRepositoryProxy = providers.gradleProperty("mavenRepositoryProxy").orNull
val mavenCentralUrls = setOf(
"https://repo.maven.apache.org/maven2",
"https://repo1.maven.org/maven2",
)
// Marks the proxy repository this script injects, so the deduplication below can tell it apart
// from a redirected mavenCentral() the nested build declared itself.
val injectedProxyName = "ddSmokeTestMavenRepositoryProxy"

fun RepositoryHandler.redirectMavenCentral() {
val proxy = mavenRepositoryProxy?.takeIf { it.isNotBlank() } ?: return
withType(MavenArtifactRepository::class.java).configureEach {
// A repository declared without a URL has a null one until Gradle validates it; leave it be
// so the nested build reports that itself instead of failing inside this init script.
val repositoryUrl = url?.toString()?.trimEnd('/')
if (repositoryUrl != null && repositoryUrl in mavenCentralUrls) {
url = URI(proxy)
isAllowInsecureProtocol = true
}
}
}

fun RepositoryHandler.removeDuplicateMavenProxy() {
val proxyUrl = mavenRepositoryProxy?.takeIf { it.isNotBlank() }?.trimEnd('/') ?: return
val proxies = withType(MavenArtifactRepository::class.java)
.filter { it.url?.toString()?.trimEnd('/') == proxyUrl }
// Keep the injected repository: it is the only one known to be unrestricted, since a declared
// mavenCentral() may carry content filters that redirectMavenCentral() does not lift.
if (proxies.none { it.name == injectedProxyName }) {
return
}
proxies.filter { it.name != injectedProxyName }.forEach { remove(it) }
}

buildscript.repositories.redirectMavenCentral()
pluginManagement.repositories.redirectMavenCentral()
dependencyResolutionManagement.repositories.redirectMavenCentral()

pluginManagement {
repositories {
mavenLocal()
gradlePluginProxy?.takeIf { it.isNotBlank() }?.let { proxy ->
maven {
url = java.net.URI(proxy)
url = URI(proxy)
isAllowInsecureProtocol = true
}
}
mavenRepositoryProxy?.takeIf { it.isNotBlank() }?.let { proxy ->
maven {
url = java.net.URI(proxy)
name = injectedProxyName
url = URI(proxy)
isAllowInsecureProtocol = true
}
}
gradlePluginPortal()
mavenCentral()
if (mavenRepositoryProxy.isNullOrBlank()) {
mavenCentral()
}
}
}

gradle.settingsEvaluated(Action<Settings> {
pluginManagement.repositories.removeDuplicateMavenProxy()
})

gradle.beforeProject(Action<Project> {
repositories.redirectMavenCentral()
buildscript.repositories.redirectMavenCentral()
repositories {
mavenLocal()
mavenRepositoryProxy?.takeIf { it.isNotBlank() }?.let { proxy ->
Comment thread
AlexeyKuznetsov-DD marked this conversation as resolved.
maven {
url = java.net.URI(proxy)
name = injectedProxyName
url = URI(proxy)
isAllowInsecureProtocol = true
}
}
mavenCentral()
if (mavenRepositoryProxy.isNullOrBlank()) {
Comment thread
AlexeyKuznetsov-DD marked this conversation as resolved.
mavenCentral()
}
}
})

gradle.afterProject(Action<Project> {
repositories.removeDuplicateMavenProxy()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ class SmokeTestAppEndToEndTest {
}

@Test
fun `local proxy property prepends Maven proxy repositories exactly once`() {
fun `Maven proxy replaces Maven Central in nested repositories`() {
writeOuterSettings()
val proxyRepository = projectDir.resolve("proxy-maven-repo").toFile()
val projectRepository = projectDir.resolve("project-maven-repo").toFile()
Expand All @@ -279,10 +279,37 @@ class SmokeTestAppEndToEndTest {
sysProperty = "resolved.repositories.path",
),
)
writeInnerSettings()
writeInnerSettings(
"""
pluginManagement {
repositories {
mavenCentral()
}
}

gradle.settingsEvaluated {
val outputDir = java.io.File(providers.gradleProperty("appBuildDir").get())
outputDir.mkdirs()
outputDir.resolve("plugin-repositories.txt").writeText(
pluginManagement.repositories
.withType(org.gradle.api.artifacts.repositories.MavenArtifactRepository::class.java)
.joinToString(System.lineSeparator()) { "repository=" + it.url }
)
}

gradle.projectsLoaded {
gradle.rootProject.repositories.mavenCentral {
content {
includeGroup("com.unrelated")
}
}
}
""".trimIndent(),
)
writeInnerBuild(
"""
repositories {
mavenCentral()
maven {
url = uri("${projectRepository.toURI()}")
}
Expand All @@ -301,8 +328,12 @@ class SmokeTestAppEndToEndTest {
val artifacts = configurations.compileClasspath.get()
.sortedBy { it.name }
.map { it.name + "=" + it.readText() }
val repositoryUrls = repositories
.withType(org.gradle.api.artifacts.repositories.MavenArtifactRepository::class.java)
.map { "repository=" + it.url }
resolved.get().asFile.writeText(
(listOf("init-script-count=" + gradle.startParameter.initScripts.size) + artifacts)
(listOf("init-script-count=" + gradle.startParameter.initScripts.size) +
repositoryUrls + artifacts)
.joinToString(System.lineSeparator())
)
}
Expand All @@ -319,11 +350,31 @@ class SmokeTestAppEndToEndTest {
assertThat(result.task(":resolveRepositories")?.outcome).isEqualTo(TaskOutcome.SUCCESS)
val resolvedFile = applicationOutput("resolved-repositories.txt")
assertThat(resolvedFile).exists()
assertThat(resolvedFile.readLines()).containsExactly(
val resolvedLines = resolvedFile.readLines()
assertThat(resolvedLines).contains(
"init-script-count=1",
"repository=${proxyRepository.toURI()}",
"project-only-1.0.jar=project-only",
"shared-1.0.jar=proxy",
)
assertThat(resolvedLines).containsOnlyOnce(
"repository=${proxyRepository.toURI()}",
)
assertThat(resolvedLines).doesNotContain(
"repository=https://repo.maven.apache.org/maven2/",
)
val pluginRepositoriesFile = applicationOutput("plugin-repositories.txt")
assertThat(pluginRepositoriesFile).exists()
val pluginRepositoryLines = pluginRepositoriesFile.readLines()
assertThat(pluginRepositoryLines).contains(
"repository=${proxyRepository.toURI()}",
)
assertThat(pluginRepositoryLines).containsOnlyOnce(
"repository=${proxyRepository.toURI()}",
)
assertThat(pluginRepositoryLines).doesNotContain(
"repository=https://repo.maven.apache.org/maven2/",
)
}

@Test
Expand Down Expand Up @@ -649,10 +700,11 @@ class SmokeTestAppEndToEndTest {
"fake-mvnw"
}

private fun writeInnerSettings() {
private fun writeInnerSettings(additionalContent: String = "") {
File(applicationDir, "settings.gradle.kts").writeText(
"""
rootProject.name = "smoke-test-app-fixture-application"
$additionalContent
""".trimIndent(),
)
}
Expand Down