From fa9d40047a6e851943bbb3ace22911f7418b3bfa Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Fri, 2 Jan 2026 15:44:03 +0100 Subject: [PATCH 1/2] Add NmcpAggregationExtension.allowDuplicateProjectNames --- nmcp/api/nmcp.api | 1 + .../main/kotlin/nmcp/NmcpAggregationExtension.kt | 11 +++++++++++ .../internal/DefaultNmcpAggregationExtension.kt | 14 +++++++++----- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/nmcp/api/nmcp.api b/nmcp/api/nmcp.api index 51b6f43..c9c7012 100644 --- a/nmcp/api/nmcp.api +++ b/nmcp/api/nmcp.api @@ -19,6 +19,7 @@ public abstract class nmcp/LocalRepositoryOptions { public abstract interface class nmcp/NmcpAggregationExtension { public abstract fun centralPortal (Lorg/gradle/api/Action;)V public abstract fun getAllFiles ()Lorg/gradle/api/file/FileCollection; + public abstract fun getAllowDuplicateProjectNames ()Lorg/gradle/api/provider/Property; public abstract fun getAllowEmptyAggregation ()Lorg/gradle/api/provider/Property; public abstract fun localRepository (Lorg/gradle/api/Action;)V public abstract fun publishAllProjectsProbablyBreakingProjectIsolation ()V diff --git a/nmcp/src/main/kotlin/nmcp/NmcpAggregationExtension.kt b/nmcp/src/main/kotlin/nmcp/NmcpAggregationExtension.kt index dd62364..a667ec5 100644 --- a/nmcp/src/main/kotlin/nmcp/NmcpAggregationExtension.kt +++ b/nmcp/src/main/kotlin/nmcp/NmcpAggregationExtension.kt @@ -44,4 +44,15 @@ interface NmcpAggregationExtension { * Set this to true to allow empty aggregations. */ val allowEmptyAggregation: Property + + /** + * By default, Nmcp errors if there are duplicate project names because + * it confuses the dependency resolution algorithm. + * + * If you have duplicate project names that do not contribute publishing, + * set this to true to allow them. + * + * See https://github.com/gradle/gradle/issues/36167 for more details. + */ + val allowDuplicateProjectNames: Property } diff --git a/nmcp/src/main/kotlin/nmcp/internal/DefaultNmcpAggregationExtension.kt b/nmcp/src/main/kotlin/nmcp/internal/DefaultNmcpAggregationExtension.kt index eabbb67..45701c1 100644 --- a/nmcp/src/main/kotlin/nmcp/internal/DefaultNmcpAggregationExtension.kt +++ b/nmcp/src/main/kotlin/nmcp/internal/DefaultNmcpAggregationExtension.kt @@ -52,12 +52,14 @@ internal abstract class DefaultNmcpAggregationExtension(private val project: Pro project.afterEvaluate { val allNames = mutableSetOf() - project.allprojects { - check (!allNames.contains(it.name.lowercase())) { - "Nmcp: duplicate project name: '${it.name}'. This is usually resolved by setting your root project name in your settings.gradle[.kts] file: `rootProject.name = \"\${someUniqueName}\". " + - "See https://github.com/gradle/gradle/issues/36167 for more details" + if(!allowDuplicateProjectNames.orElse(false).get()) { + project.allprojects { + check(!allNames.contains(it.name.lowercase())) { + "Nmcp: duplicate project name: '${it.name}'. This is usually resolved by setting your root project name in your settings.gradle[.kts] file: `rootProject.name = \"\${someUniqueName}\". " + + "See https://github.com/gradle/gradle/issues/36167 for more details" + } + allNames.add(it.name.lowercase()) } - allNames.add(it.name.lowercase()) } if (!allowEmptyAggregation.orElse(false).get()) { @@ -99,6 +101,8 @@ internal abstract class DefaultNmcpAggregationExtension(private val project: Pro } abstract override val allowEmptyAggregation: Property + + abstract override val allowDuplicateProjectNames: Property } private fun isCompatible(artifactResult: ArtifactResult): Boolean { From ec169656b6e84a267f6d91e7f42c095966572aef Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Fri, 2 Jan 2026 15:59:47 +0100 Subject: [PATCH 2/2] better error message --- gradle.properties | 5 +++++ .../nmcp/internal/DefaultNmcpAggregationExtension.kt | 8 ++++++-- nmcp/src/test/kotlin/MainTest.kt | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index d7a34a5..18e6ed8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,6 @@ org.gradle.jvmargs=-Xmx2g + +org.gradle.configuration-cache.parallel=true +org.gradle.unsafe.isolated-projects=true +org.gradle.configuration-cache=true +ksp.project.isolation.enabled=true diff --git a/nmcp/src/main/kotlin/nmcp/internal/DefaultNmcpAggregationExtension.kt b/nmcp/src/main/kotlin/nmcp/internal/DefaultNmcpAggregationExtension.kt index 45701c1..b0e927f 100644 --- a/nmcp/src/main/kotlin/nmcp/internal/DefaultNmcpAggregationExtension.kt +++ b/nmcp/src/main/kotlin/nmcp/internal/DefaultNmcpAggregationExtension.kt @@ -55,8 +55,12 @@ internal abstract class DefaultNmcpAggregationExtension(private val project: Pro if(!allowDuplicateProjectNames.orElse(false).get()) { project.allprojects { check(!allNames.contains(it.name.lowercase())) { - "Nmcp: duplicate project name: '${it.name}'. This is usually resolved by setting your root project name in your settings.gradle[.kts] file: `rootProject.name = \"\${someUniqueName}\". " + - "See https://github.com/gradle/gradle/issues/36167 for more details" + """ + Nmcp: some projects have the same name: '${'$'}{it.name}'. This creates issues when resolving the aggregation. + You can usually resolve this error by renaming your projects (including possibly your root project). + Or you can disable this check by calling `allowDuplicateProjectNames.set(true)`. + See https://github.com/gradle/gradle/issues/36167 for more details. + """.trimIndent() } allNames.add(it.name.lowercase()) } diff --git a/nmcp/src/test/kotlin/MainTest.kt b/nmcp/src/test/kotlin/MainTest.kt index e71d04e..2996ac4 100644 --- a/nmcp/src/test/kotlin/MainTest.kt +++ b/nmcp/src/test/kotlin/MainTest.kt @@ -18,7 +18,7 @@ class MainTest { .withArguments("nmcpZipAggregation") .buildAndFail() - assert(result.output.contains("duplicate project name")) + assert(result.output.contains("some projects have the same name")) } @Test