Skip to content

Commit a67787c

Browse files
committed
Reorder Maven Central repository to precede managed repositories
1 parent db57c0a commit a67787c

2 files changed

Lines changed: 164 additions & 1 deletion

File tree

src/main/java/net/neoforged/moddevgradle/internal/RepositoriesPlugin.java

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package net.neoforged.moddevgradle.internal;
22

33
import java.net.URI;
4+
import java.util.Locale;
5+
import java.util.Set;
46
import net.neoforged.moddevgradle.internal.generated.MojangRepositoryFilter;
57
import org.gradle.api.GradleException;
68
import org.gradle.api.Plugin;
79
import org.gradle.api.Project;
810
import org.gradle.api.artifacts.dsl.RepositoryHandler;
11+
import org.gradle.api.artifacts.repositories.ArtifactRepository;
912
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
1013
import org.gradle.api.initialization.Settings;
1114
import org.gradle.api.invocation.Gradle;
@@ -20,12 +23,20 @@
2023
* </ul>
2124
*/
2225
public class RepositoriesPlugin implements Plugin<PluginAware> {
26+
private static final String NEOFORGED_RELEASES_NAME = "NeoForged Releases";
27+
28+
private static final Set<String> MAVEN_CENTRAL_URLS = Set.of(
29+
normalizeRepositoryUrl(URI.create("https://repo.maven.apache.org/maven2/")),
30+
normalizeRepositoryUrl(URI.create("https://repo1.maven.org/maven2/")));
31+
2332
@Override
2433
public void apply(PluginAware target) {
2534
if (target instanceof Project project) {
2635
applyRepositories(project.getRepositories());
36+
project.afterEvaluate(p -> moveMavenCentralBeforeManagedRepositories(p.getRepositories()));
2737
} else if (target instanceof Settings settings) {
2838
applyRepositories(settings.getDependencyResolutionManagement().getRepositories());
39+
settings.getGradle().settingsEvaluated(s -> moveMavenCentralBeforeManagedRepositories(settings.getDependencyResolutionManagement().getRepositories()));
2940
settings.getGradle().getPlugins().apply(getClass()); // Add a marker to Gradle
3041
} else if (target instanceof Gradle gradle) {
3142
// Do nothing
@@ -54,7 +65,7 @@ private void applyRepositories(RepositoryHandler repositories) {
5465
sortFirst(repositories, mojangMetaMaven);
5566

5667
repositories.maven(repo -> {
57-
repo.setName("NeoForged Releases");
68+
repo.setName(NEOFORGED_RELEASES_NAME);
5869
repo.setUrl(URI.create("https://maven.neoforged.net/releases/"));
5970
});
6071
}
@@ -63,4 +74,38 @@ private static void sortFirst(RepositoryHandler repositories, MavenArtifactRepos
6374
repositories.remove(repo);
6475
repositories.add(0, repo);
6576
}
77+
78+
private static void moveMavenCentralBeforeManagedRepositories(RepositoryHandler repositories) {
79+
MavenArtifactRepository mavenCentral = repositories.stream()
80+
.filter(MavenArtifactRepository.class::isInstance)
81+
.map(MavenArtifactRepository.class::cast)
82+
.filter(RepositoriesPlugin::isMavenCentral)
83+
.findFirst()
84+
.orElse(null);
85+
86+
if (mavenCentral == null) {
87+
return;
88+
}
89+
90+
repositories.remove(mavenCentral);
91+
92+
int insertIndex = repositories.size();
93+
for (int i = 0; i < repositories.size(); i++) {
94+
ArtifactRepository repository = repositories.get(i);
95+
if (NEOFORGED_RELEASES_NAME.equals(repository.getName())) {
96+
insertIndex = i;
97+
break;
98+
}
99+
}
100+
101+
repositories.add(insertIndex, mavenCentral);
102+
}
103+
104+
private static boolean isMavenCentral(MavenArtifactRepository repository) {
105+
return MAVEN_CENTRAL_URLS.contains(normalizeRepositoryUrl(repository.getUrl()));
106+
}
107+
108+
private static String normalizeRepositoryUrl(URI uri) {
109+
return uri.toString().replaceAll("/+$", "").toLowerCase(Locale.ROOT);
110+
}
66111
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package net.neoforged.moddevgradle.functional;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.io.IOException;
6+
import java.util.List;
7+
import java.util.regex.Pattern;
8+
import org.gradle.testkit.runner.BuildResult;
9+
import org.gradle.testkit.runner.GradleRunner;
10+
import org.junit.jupiter.api.Test;
11+
12+
public class RepositoriesPluginFunctionalTest extends AbstractFunctionalTest {
13+
private static final Pattern REPOSITORY_ORDER_PATTERN = Pattern.compile("REPOSITORY_ORDER=(.+)");
14+
private static final List<String> MANAGED_REPOSITORIES = List.of("NeoForged Releases");
15+
16+
@Test
17+
void placesMavenCentralBeforeManagedRepositories() throws IOException {
18+
writeFile(settingsFile, "rootProject.name = 'repository-order-test'");
19+
writeGroovyBuildScript("""
20+
plugins {
21+
id "net.neoforged.moddev.repositories"
22+
}
23+
24+
repositories {
25+
mavenCentral()
26+
}
27+
28+
tasks.register("printRepositoryOrder") {
29+
doLast {
30+
println("REPOSITORY_ORDER=" + repositories.collect {
31+
def urlPart = it.hasProperty("url") ? it.url.toString() : ""
32+
return it.name + "@" + urlPart
33+
}.join("|"))
34+
}
35+
}
36+
""");
37+
38+
BuildResult result = GradleRunner.create()
39+
.withPluginClasspath()
40+
.withProjectDir(testProjectDir)
41+
.withArguments("printRepositoryOrder")
42+
.build();
43+
44+
List<String> repositoryNames = extractRepositoryOrder(result);
45+
assertMavenCentralBeforeManagedRepositories(repositoryNames);
46+
}
47+
48+
@Test
49+
void placesMavenCentralBeforeManagedRepositoriesInSettings() throws IOException {
50+
writeGroovySettingsScript("""
51+
plugins {
52+
id "net.neoforged.moddev.repositories"
53+
}
54+
55+
rootProject.name = "repository-order-settings-test"
56+
57+
dependencyResolutionManagement {
58+
repositories {
59+
mavenCentral()
60+
}
61+
}
62+
63+
gradle.settingsEvaluated {
64+
println("REPOSITORY_ORDER=" + dependencyResolutionManagement.repositories.collect {
65+
def urlPart = it.hasProperty("url") ? it.url.toString() : ""
66+
return it.name + "@" + urlPart
67+
}.join("|"))
68+
}
69+
""");
70+
writeGroovyBuildScript("");
71+
72+
BuildResult result = GradleRunner.create()
73+
.withPluginClasspath()
74+
.withProjectDir(testProjectDir)
75+
.withArguments("help")
76+
.build();
77+
78+
List<String> repositoryNames = extractRepositoryOrder(result);
79+
assertMavenCentralBeforeManagedRepositories(repositoryNames);
80+
}
81+
82+
private static List<String> extractRepositoryOrder(BuildResult result) {
83+
var matcher = REPOSITORY_ORDER_PATTERN.matcher(result.getOutput());
84+
assertThat(matcher.find())
85+
.as("Expected repository order marker in Gradle output")
86+
.isTrue();
87+
return List.of(matcher.group(1).split("\\|"));
88+
}
89+
90+
private static void assertMavenCentralBeforeManagedRepositories(List<String> repositoryNames) {
91+
int mavenCentralIndex = -1;
92+
for (int i = 0; i < repositoryNames.size(); i++) {
93+
String repository = repositoryNames.get(i);
94+
if (repository.contains("repo.maven.apache.org/maven2") || repository.contains("repo1.maven.org/maven2")) {
95+
mavenCentralIndex = i;
96+
break;
97+
}
98+
}
99+
int firstManagedIndex = repositoryNames.size();
100+
for (String managedRepository : MANAGED_REPOSITORIES) {
101+
for (int i = 0; i < repositoryNames.size(); i++) {
102+
if (repositoryNames.get(i).startsWith(managedRepository + "@") && i < firstManagedIndex) {
103+
firstManagedIndex = i;
104+
}
105+
}
106+
}
107+
108+
assertThat(mavenCentralIndex)
109+
.as("Expected mavenCentral repository to exist. Actual order: %s", repositoryNames)
110+
.isGreaterThanOrEqualTo(0);
111+
assertThat(firstManagedIndex)
112+
.as("Expected at least one managed repository to exist. Actual order: %s", repositoryNames)
113+
.isLessThan(repositoryNames.size());
114+
assertThat(mavenCentralIndex)
115+
.as("Expected mavenCentral before managed repositories. Actual order: %s", repositoryNames)
116+
.isLessThan(firstManagedIndex);
117+
}
118+
}

0 commit comments

Comments
 (0)