Skip to content

Commit e5f4ad5

Browse files
authored
Merge branch '1.21.x' into reactionable-testing
2 parents 6fb0b05 + b7942bb commit e5f4ad5

File tree

614 files changed

+8263
-9355
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

614 files changed

+8263
-9355
lines changed

.github/workflows/build-prs.yml

+1-16
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,7 @@ jobs:
2020
runs-on: ubuntu-latest
2121
steps:
2222
- name: Checkout repository
23-
uses: actions/checkout@v4
24-
with:
25-
fetch-depth: 1000
26-
fetch-tags: true
27-
28-
# GradleUtils will append the branch name to the version,
29-
# but for that we need a properly checked out branch
30-
- name: Create branch for commit (PR)
31-
if: ${{ github.event_name == 'pull_request' }}
32-
run:
33-
git switch -C pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.ref }}
34-
35-
- name: Create branch for commit
36-
if: ${{ github.event_name != 'pull_request' }}
37-
run:
38-
git switch -C ${{ github.ref_name }}
23+
uses: neoforged/actions/checkout@main
3924

4025
- name: Setup JDK 21
4126
uses: neoforged/actions/setup-java@main

.github/workflows/check-local-changes.yml

+1-10
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,7 @@ jobs:
1313
runs-on: ubuntu-latest
1414
steps:
1515
- name: Checkout repository
16-
uses: actions/checkout@v4
17-
with:
18-
fetch-depth: 1000
19-
fetch-tags: true
20-
21-
# GradleUtils will append the branch name to the version,
22-
# but for that we need a properly checked out branch
23-
- name: Create branch for commit
24-
run:
25-
git switch -C pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.ref }}
16+
uses: neoforged/actions/checkout@main
2617

2718
- name: Setup JDK 21
2819
uses: neoforged/actions/setup-java@main

.github/workflows/test-prs.yml

+1-10
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,7 @@ jobs:
1717
runs-on: ubuntu-latest
1818
steps:
1919
- name: Checkout repository
20-
uses: actions/checkout@v4
21-
with:
22-
fetch-depth: 1000
23-
fetch-tags: true
24-
25-
# GradleUtils will append the branch name to the version,
26-
# but for that we need a properly checked out branch
27-
- name: Create branch for commit
28-
run:
29-
git switch -C pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.ref }}
20+
uses: neoforged/actions/checkout@main
3021

3122
- name: Setup JDK 21
3223
uses: neoforged/actions/setup-java@main

build.gradle

+23-17
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,22 @@ immaculate {
7272
return fileContents
7373
}
7474

75-
def interfaceChange = Pattern.compile('^[-+].*(implements|(interface.*extends)).*\$', Pattern.UNIX_LINES | Pattern.MULTILINE)
76-
custom 'noInterfaceRemoval', { String fileContents ->
77-
def interfaceChanges = fileContents.findAll(interfaceChange)
75+
def interfaceChange = Pattern.compile('[-+].*(implements|(interface.*extends))(.*)\\{')
76+
custom 'noInterfaceModifications', { String fileContents ->
77+
def interfaceChanges = fileContents.lines().filter { it.matches(interfaceChange) }.toList()
7878
if (interfaceChanges.isEmpty()) return fileContents
79-
String removalChange = ""
79+
String oldInterfaces = ""
80+
// we expect interface additions/removals in pairs of - and then +
8081
interfaceChanges.each { String change ->
82+
final match = change =~ interfaceChange
83+
match.find()
84+
final values = match.group(3).trim()
8185
if (change.startsWith('-')) {
82-
//Skip the - and the ending brace
83-
int implementsIndex = change.indexOf("implements")
84-
if (implementsIndex == -1) implementsIndex = change.indexOf("extends")
85-
//It should never still be -1 based on our initial matching regex, but if it does fail so we can figure out why
86-
if (implementsIndex == -1) implementsIndex = 1
87-
removalChange = change.substring(implementsIndex, change.length() - 1).trim()
88-
} else if (!removalChange.isEmpty() && !change.contains(removalChange)) {
89-
throw new GradleException("Removal of interfaces via patches is not allowed!")
90-
} else {
91-
removalChange = ""
86+
oldInterfaces = values
87+
} else if (oldInterfaces != values) {
88+
throw new GradleException("Modification of interfaces via patches is not allowed!")
9289
}
9390
}
94-
if (!removalChange.isEmpty()) {
95-
throw new GradleException("Removal of interfaces via patches is not allowed!")
96-
}
9791
return fileContents
9892
}
9993

@@ -148,6 +142,18 @@ immaculate {
148142
return sb.toString()
149143
}
150144

145+
// Disallow explicit not null in patches, it's always implied.
146+
custom 'noNotNull', { String fileContents ->
147+
fileContents.eachLine {
148+
if (!it.startsWith("+")) return
149+
if (it.contains('@NotNull') || it.contains('@Nonnull')
150+
|| it.contains('@org.jetbrains.annotations.NotNull')
151+
|| it.contains('@javax.annotation.Nonnull')) {
152+
throw new GradleException('@NotNull and @Nonnull are disallowed.')
153+
}
154+
}
155+
}
156+
151157
//Replace any FQN versions of javax.annotation.Nullable with the jetbrains variant
152158
custom 'jetbrainsNullablePatches', { String fileContents ->
153159
fileContents.replace('@javax.annotation.Nullable', '@org.jetbrains.annotations.Nullable')

buildSrc/build.gradle

+12-1
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,25 @@ repositories {
1414
includeGroup "net.neoforged"
1515
}
1616
}
17+
maven {
18+
name = "MojangMeta"
19+
url = "https://maven.neoforged.net/mojang-meta"
20+
content {
21+
includeModule("net.neoforged", "minecraft-dependencies")
22+
}
23+
}
1724
}
1825

1926
dependencies {
2027
// buildSrc is an includedbuild of the parent directory (gradle.parent)
2128
// ../settings.gradle sets these version properties accordingly
2229
implementation "net.neoforged:moddev-gradle:${gradle.parent.ext.moddevgradle_plugin_version}"
2330

24-
implementation "com.google.code.gson:gson:${gradle.parent.ext.gson_version}"
31+
implementation(platform("net.neoforged:minecraft-dependencies:${gradle.parent.ext.minecraft_version}") {
32+
exclude group: 'org.ow2.asm' // The platform requests a strictly lower version of ASM and we bump it
33+
})
34+
35+
implementation "com.google.code.gson:gson"
2536
implementation "io.codechicken:DiffPatch:${gradle.parent.ext.diffpatch_version}"
2637

2738
implementation "org.ow2.asm:asm:${gradle.parent.ext.asm_version}"

buildSrc/src/main/java/net/neoforged/neodev/GenerateSourcePatches.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import org.gradle.api.file.RegularFileProperty;
1010
import org.gradle.api.tasks.InputDirectory;
1111
import org.gradle.api.tasks.InputFile;
12+
import org.gradle.api.tasks.Optional;
13+
import org.gradle.api.tasks.OutputDirectory;
1214
import org.gradle.api.tasks.OutputFile;
1315
import org.gradle.api.tasks.PathSensitive;
1416
import org.gradle.api.tasks.PathSensitivity;
@@ -25,9 +27,14 @@ abstract class GenerateSourcePatches extends DefaultTask {
2527
@PathSensitive(PathSensitivity.RELATIVE)
2628
public abstract DirectoryProperty getModifiedSources();
2729

30+
@Optional
2831
@OutputFile
2932
public abstract RegularFileProperty getPatchesJar();
3033

34+
@Optional
35+
@OutputDirectory
36+
public abstract DirectoryProperty getPatchesFolder();
37+
3138
@Inject
3239
public GenerateSourcePatches() {}
3340

@@ -37,7 +44,7 @@ public void generateSourcePatches() throws IOException {
3744
.logTo(getLogger()::lifecycle)
3845
.baseInput(MultiInput.detectedArchive(getOriginalJar().get().getAsFile().toPath()))
3946
.changedInput(MultiInput.folder(getModifiedSources().get().getAsFile().toPath()))
40-
.patchesOutput(MultiOutput.detectedArchive(getPatchesJar().get().getAsFile().toPath()))
47+
.patchesOutput(getPatchesJar().isPresent() ? MultiOutput.detectedArchive(getPatchesJar().get().getAsFile().toPath()) : MultiOutput.folder(getPatchesFolder().getAsFile().get().toPath()))
4148
.autoHeader(true)
4249
.level(io.codechicken.diffpatch.util.LogLevel.WARN)
4350
.summary(false)

buildSrc/src/main/java/net/neoforged/neodev/NeoDevConfigurations.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ private NeoDevConfigurations(Project project) {
138138

139139
// Libraries & module libraries & MC dependencies need to be available when compiling in NeoDev,
140140
// and on the runtime classpath too for IDE debugging support.
141-
configurations.getByName("implementation").extendsFrom(libraries, moduleLibraries, neoFormDependencies);
141+
configurations.getByName("api").extendsFrom(libraries, moduleLibraries, neoFormDependencies);
142142

143143
// runtimeClasspath is our reference for all MC dependency versions.
144144
// Make sure that any classpath we resolve is consistent with it.

buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java

+63-39
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.io.File;
3838
import java.net.URI;
3939
import java.util.ArrayList;
40+
import java.util.Collections;
4041
import java.util.List;
4142
import java.util.Map;
4243
import java.util.function.Consumer;
@@ -100,24 +101,39 @@ public void apply(Project project) {
100101
);
101102
var applyAt = configureAccessTransformer(
102103
project,
103-
configurations,
104104
createSourceArtifacts,
105105
neoDevBuildDir,
106106
atFiles);
107107

108108
applyAt.configure(task -> task.mustRunAfter(genAtsTask));
109109

110-
// 3. Apply patches to the source jar from 2.
110+
// 3. Apply interface injections after the ATs
111+
// this jar is only used for the patches in the repo
112+
var applyInterfaceInjection = project.getTasks().register("applyInterfaceInjection", TransformSources.class, task -> {
113+
task.getInputJar().set(applyAt.flatMap(TransformSources::getOutputJar));
114+
task.getInterfaceInjectionData().from(project.getRootProject().file("src/main/resources/META-INF/injected-interfaces.json"));
115+
task.getOutputJar().set(neoDevBuildDir.map(dir -> dir.file("artifacts/interface-injected-sources.jar")));
116+
});
117+
118+
tasks.withType(TransformSources.class, task -> {
119+
task.setGroup(INTERNAL_GROUP);
120+
task.classpath(configurations.getExecutableTool(Tools.JST));
121+
122+
task.getLibraries().from(configurations.neoFormClasspath);
123+
task.getLibrariesFile().set(neoDevBuildDir.map(dir -> dir.file("minecraft-libraries-for-" + task.getName() + ".txt")));
124+
});
125+
126+
// 4. Apply patches to the source jar from 3.
111127
var patchesFolder = project.getRootProject().file("patches");
112128
var applyPatches = tasks.register("applyPatches", ApplyPatches.class, task -> {
113129
task.setGroup(INTERNAL_GROUP);
114-
task.getOriginalJar().set(applyAt.flatMap(ApplyAccessTransformer::getOutputJar));
130+
task.getOriginalJar().set(applyInterfaceInjection.flatMap(TransformSources::getOutputJar));
115131
task.getPatchesFolder().set(patchesFolder);
116132
task.getPatchedJar().set(neoDevBuildDir.map(dir -> dir.file("artifacts/patched-sources.jar")));
117133
task.getRejectsFolder().set(project.getRootProject().file("rejects"));
118134
});
119135

120-
// 4. Unpack jar from 3.
136+
// 5. Unpack jar from 4.
121137
var mcSourcesPath = project.file("src/main/java");
122138
tasks.register("setup", Sync.class, task -> {
123139
task.setGroup(GROUP);
@@ -185,14 +201,22 @@ public void apply(Project project) {
185201
* OTHER TASKS
186202
*/
187203

188-
// Generate source patches into a patch archive.
204+
// Generate source patches into a patch archive, based on the jar with injected interfaces.
189205
var genSourcePatches = tasks.register("generateSourcePatches", GenerateSourcePatches.class, task -> {
190206
task.setGroup(INTERNAL_GROUP);
191-
task.getOriginalJar().set(applyAt.flatMap(ApplyAccessTransformer::getOutputJar));
207+
task.getOriginalJar().set(applyInterfaceInjection.flatMap(TransformSources::getOutputJar));
192208
task.getModifiedSources().set(project.file("src/main/java"));
193209
task.getPatchesJar().set(neoDevBuildDir.map(dir -> dir.file("source-patches.zip")));
194210
});
195211

212+
// Generate source patches that are based on the production environment (without separate interface injection)
213+
var genProductionPatches = tasks.register("generateProductionSourcePatches", GenerateSourcePatches.class, task -> {
214+
task.setGroup(INTERNAL_GROUP);
215+
task.getOriginalJar().set(applyAt.flatMap(TransformSources::getOutputJar));
216+
task.getModifiedSources().set(project.file("src/main/java"));
217+
task.getPatchesFolder().set(neoDevBuildDir.map(dir -> dir.dir("production-source-patches")));
218+
});
219+
196220
// Update the patch/ folder with the current patches.
197221
tasks.register("genPatches", Sync.class, task -> {
198222
task.setGroup(GROUP);
@@ -245,9 +269,10 @@ public void apply(Project project) {
245269
configurations,
246270
createCleanArtifacts,
247271
neoDevBuildDir,
248-
patchesFolder
272+
genProductionPatches.flatMap(GenerateSourcePatches::getPatchesFolder)
249273
);
250274

275+
var installerRepositoryUrls = getInstallerRepositoryUrls(project);
251276
// Launcher profile = the version.json file used by the Minecraft launcher.
252277
var createLauncherProfile = tasks.register("createLauncherProfile", CreateLauncherProfile.class, task -> {
253278
task.setGroup(INTERNAL_GROUP);
@@ -256,17 +281,7 @@ public void apply(Project project) {
256281
task.getNeoForgeVersion().set(neoForgeVersion);
257282
task.getRawNeoFormVersion().set(rawNeoFormVersion);
258283
task.setLibraries(configurations.launcherProfileClasspath);
259-
task.getRepositoryURLs().set(project.provider(() -> {
260-
List<URI> repos = new ArrayList<>();
261-
for (var repo : project.getRepositories().withType(MavenArtifactRepository.class)) {
262-
var uri = repo.getUrl();
263-
if (!uri.toString().endsWith("/")) {
264-
uri = URI.create(uri + "/");
265-
}
266-
repos.add(uri);
267-
}
268-
return repos;
269-
}));
284+
task.getRepositoryURLs().set(installerRepositoryUrls);
270285
// ${version_name}.jar will be filled out by the launcher. It corresponds to the raw SRG Minecraft client jar.
271286
task.getIgnoreList().addAll("client-extra", "${version_name}.jar");
272287
task.setModules(configurations.modulePath);
@@ -285,17 +300,7 @@ public void apply(Project project) {
285300
task.addLibraries(configurations.launcherProfileClasspath);
286301
// We need the NeoForm zip for the SRG mappings.
287302
task.addLibraries(configurations.neoFormDataOnly);
288-
task.getRepositoryURLs().set(project.provider(() -> {
289-
List<URI> repos = new ArrayList<>();
290-
for (var repo : project.getRepositories().withType(MavenArtifactRepository.class)) {
291-
var uri = repo.getUrl();
292-
if (!uri.toString().endsWith("/")) {
293-
uri = URI.create(uri + "/");
294-
}
295-
repos.add(uri);
296-
}
297-
return repos;
298-
}));
303+
task.getRepositoryURLs().set(installerRepositoryUrls);
299304
task.getUniversalJar().set(universalJar.flatMap(AbstractArchiveTask::getArchiveFile));
300305
task.getInstallerProfile().set(neoDevBuildDir.map(dir -> dir.file("installer-profile.json")));
301306

@@ -411,7 +416,7 @@ public void apply(Project project) {
411416
task.from(binaryPatchOutputs.binaryPatchesForMerged(), spec -> {
412417
spec.rename(s -> "joined.lzma");
413418
});
414-
task.from(project.zipTree(genSourcePatches.flatMap(GenerateSourcePatches::getPatchesJar)), spec -> {
419+
task.from(project.fileTree(genProductionPatches.flatMap(GenerateSourcePatches::getPatchesFolder)), spec -> {
415420
spec.into("patches/");
416421
});
417422
});
@@ -444,32 +449,51 @@ public void apply(Project project) {
444449
setupProductionServerTest(project, installerJar);
445450
}
446451

447-
private static TaskProvider<ApplyAccessTransformer> configureAccessTransformer(
452+
/**
453+
* Get the list of Maven repositories that may contain artifacts for the installer.
454+
*/
455+
private static Provider<List<URI>> getInstallerRepositoryUrls(Project project) {
456+
return project.provider(() -> {
457+
List<URI> repos = new ArrayList<>();
458+
var projectRepos = project.getRepositories();
459+
if (!projectRepos.isEmpty()) {
460+
for (var repo : projectRepos.withType(MavenArtifactRepository.class)) {
461+
repos.add(repo.getUrl());
462+
}
463+
} else {
464+
// If no project repos are defined, use the repository list we exposed in settings.gradle via an extension
465+
// See the end of settings.gradle for details
466+
Collections.addAll(repos, (URI[]) project.getGradle().getExtensions().getByName("repositoryBaseUrls"));
467+
}
468+
469+
// Ensure all base urls end with a slash
470+
repos.replaceAll(uri -> uri.toString().endsWith("/") ? uri : URI.create(uri + "/"));
471+
472+
return repos;
473+
});
474+
}
475+
476+
private static TaskProvider<TransformSources> configureAccessTransformer(
448477
Project project,
449-
NeoDevConfigurations configurations,
450478
TaskProvider<CreateMinecraftArtifacts> createSourceArtifacts,
451479
Provider<Directory> neoDevBuildDir,
452480
List<File> atFiles) {
453481

454482
// Pass -PvalidateAccessTransformers to validate ATs.
455483
var validateAts = project.getProviders().gradleProperty("validateAccessTransformers").map(p -> true).orElse(false);
456-
return project.getTasks().register("applyAccessTransformer", ApplyAccessTransformer.class, task -> {
457-
task.setGroup(INTERNAL_GROUP);
458-
task.classpath(configurations.getExecutableTool(Tools.JST));
484+
return project.getTasks().register("applyAccessTransformer", TransformSources.class, task -> {
459485
task.getInputJar().set(createSourceArtifacts.flatMap(CreateMinecraftArtifacts::getSourcesArtifact));
460486
task.getAccessTransformers().from(atFiles);
461-
task.getValidate().set(validateAts);
487+
task.getValidateAccessTransformers().set(validateAts);
462488
task.getOutputJar().set(neoDevBuildDir.map(dir -> dir.file("artifacts/access-transformed-sources.jar")));
463-
task.getLibraries().from(configurations.neoFormClasspath);
464-
task.getLibrariesFile().set(neoDevBuildDir.map(dir -> dir.file("minecraft-libraries-for-jst.txt")));
465489
});
466490
}
467491

468492
private static BinaryPatchOutputs configureBinaryPatchCreation(Project project,
469493
NeoDevConfigurations configurations,
470494
TaskProvider<CreateCleanArtifacts> createCleanArtifacts,
471495
Provider<Directory> neoDevBuildDir,
472-
File sourcesPatchesFolder) {
496+
Provider<Directory> sourcesPatchesFolder) {
473497
var tasks = project.getTasks();
474498

475499
var artConfig = configurations.getExecutableTool(Tools.AUTO_RENAMING_TOOL);

0 commit comments

Comments
 (0)