Skip to content

Fix duplicate gradlePluginPortal() in settings.gradle.kts#7230

Merged
pstreef merged 5 commits intomainfrom
pstreef/fix-kts-plugin-repo-dup
Apr 1, 2026
Merged

Fix duplicate gradlePluginPortal() in settings.gradle.kts#7230
pstreef merged 5 commits intomainfrom
pstreef/fix-kts-plugin-repo-dup

Conversation

@pstreef
Copy link
Copy Markdown
Contributor

@pstreef pstreef commented Apr 1, 2026

Problem

AddSettingsPluginRepository adds a duplicate gradlePluginPortal() entry in settings.gradle.kts when the existing method invocations have incorrect type attribution (e.g. declaring type resolved to kotlin.Unit instead of RepositoryHandler). The MethodMatcher takes the strict path with a non-null but wrong type and fails to match, so FindRepository misses the existing entry.

Note: This is a defensive workaround. The root cause is that GradleParser drops default Gradle API stubs when an explicit classpath is provided — see #7232 for the fix. This workaround is safe to keep even after the parser is fixed, as the name-based check is redundant (not conflicting) when types are correct.

Solution

Two changes:

  1. Name-based fallback in addRepoToRepositoriesBlock — before inserting a new repository, check if one with the same method name already exists in the repositories { } block using unwrapMethodCall. This catches duplicates regardless of type attribution quality.

  2. Guard in addPluginManagementRepos — when the name-based check prevents modification inside repositories { }, the returned list has referential equality with the input, which the existing code interprets as "no pluginManagement found" and inserts a whole new block. Added a scan for existing pluginManagement calls before the insert-new-block fallback.

pstreef added 2 commits April 1, 2026 12:40
…g type attribution

When method types have an incorrect declaring type (as happens on the
platform with KTS-parsed settings.gradle.kts), FindRepository's
MethodMatcher fails to detect existing repositories, causing
AddSettingsPluginRepository to add duplicates.

Reproduces moderneinc/customer-requests#2120
…ect type attribution

On the Moderne platform, KTS-parsed settings.gradle.kts files may have
incorrect type attribution on method invocations (e.g. wrong declaring
type instead of RepositoryHandler). This causes FindRepository's
MethodMatcher to fail the strict matching path, missing existing
repository entries and leading AddSettingsPluginRepository to add
duplicates.

Added two defensive checks:
1. In addRepoToRepositoriesBlock: name-based check if the repository
   already exists in the repositories block before adding
2. In addPluginManagementRepos: detect when pluginManagement exists but
   no change was needed, to avoid inserting a duplicate block

Fixes moderneinc/customer-requests#2120
@github-project-automation github-project-automation bot moved this to In Progress in OpenRewrite Apr 1, 2026
@pstreef pstreef marked this pull request as ready for review April 1, 2026 11:46
@timtebeek timtebeek requested review from Jenson3210 and MBoegers and removed request for Jenson3210 April 1, 2026 12:06
@github-project-automation github-project-automation bot moved this from In Progress to Ready to Review in OpenRewrite Apr 1, 2026
@pstreef pstreef merged commit 18e5bb7 into main Apr 1, 2026
1 check passed
@pstreef pstreef deleted the pstreef/fix-kts-plugin-repo-dup branch April 1, 2026 13:09
@github-project-automation github-project-automation bot moved this from Ready to Review to Done in OpenRewrite Apr 1, 2026
}

// Name-based fallback for when MethodMatcher fails due to incorrect type attribution (e.g. rewrite-kotlin)
private boolean repoAlreadyExists(J.MethodInvocation repos, String repoName) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that this fails for any non first party named repository. As an example, multiple maven {} are allowed and this would improperly match on those only allowing for there to be one.

I think the root cause issue here is improper matching in FindRepository which allows us to get this far. If we need to we do have the repositories available as elements in the GradleProject marker that we could utilize as well for match selection much like we do for FindGradleProject.

pstreef added a commit that referenced this pull request Apr 2, 2026
The name-based fallback added in #7230 incorrectly blocks adding a
second `maven {}` or `ivy {}` repository with a different URL, since
it only checks the method name. Gate the check on `url == null` so it
only applies to uniquely-named repositories like `gradlePluginPortal`,
`mavenCentral`, `mavenLocal`, and `google`.
pstreef added a commit that referenced this pull request Apr 2, 2026
The name-based fallback added in #7230 incorrectly blocks adding a
second `maven {}` or `ivy {}` repository with a different URL, since
it only checks the method name. Gate the check on `url == null` so it
only applies to uniquely-named repositories like `gradlePluginPortal`,
`mavenCentral`, `mavenLocal`, and `google`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants