From 515106fedfa3f16080d1710c79985581d7e23dc4 Mon Sep 17 00:00:00 2001 From: Matyrobbrt <65940752+Matyrobbrt@users.noreply.github.com> Date: Wed, 10 Jul 2024 20:45:03 +0300 Subject: [PATCH] Parchment in NeoDev (#224) --- .../gradle/dsl/common/util/Constants.groovy | 2 +- .../extensions/NeoFormRuntimeExtension.java | 4 + .../extensions/DynamicProjectExtension.java | 170 +++++++++++++++--- .../RuntimeDevRuntimeDefinition.java | 11 +- .../extension/RuntimeDevRuntimeExtension.java | 92 +++++++++- .../RuntimeDevRuntimeSpecification.java | 19 +- .../tasks/OfficialMappingsJustParameters.java | 43 +++++ 7 files changed, 306 insertions(+), 35 deletions(-) create mode 100644 platform/src/main/java/net/neoforged/gradle/platform/tasks/OfficialMappingsJustParameters.java diff --git a/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/util/Constants.groovy b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/util/Constants.groovy index f4eb9322d..b038a1fff 100644 --- a/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/util/Constants.groovy +++ b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/util/Constants.groovy @@ -27,7 +27,7 @@ class Constants { public static final String DEFAULT_PARCHMENT_GROUP = "org.parchmentmc.data" public static final String DEFAULT_PARCHMENT_ARTIFACT_PREFIX = "parchment-" public static final String DEFAULT_PARCHMENT_MAVEN_URL = "https://maven.parchmentmc.org/" - public static final String JST_TOOL_ARTIFACT = "net.neoforged.jst:jst-cli-bundle:1.0.43" + public static final String JST_TOOL_ARTIFACT = "net.neoforged.jst:jst-cli-bundle:1.0.55" public static final String DEVLOGIN_TOOL_ARTIFACT = "net.covers1624:DevLogin:0.1.0.4" public static final String DEVLOGIN_MAIN_CLASS = "net.covers1624.devlogin.DevLogin" diff --git a/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/extensions/NeoFormRuntimeExtension.java b/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/extensions/NeoFormRuntimeExtension.java index ff66f36a3..57ed425af 100644 --- a/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/extensions/NeoFormRuntimeExtension.java +++ b/neoform/src/main/java/net/neoforged/gradle/neoform/runtime/extensions/NeoFormRuntimeExtension.java @@ -397,6 +397,10 @@ protected void bakeDefinition(NeoFormRuntimeDefinition definition) { } neoFormRuntimeTaskProvider = createExecute(spec, step, function); + + if (step.getType().equals("mergeMappings")) { + neoFormRuntimeTaskProvider.configure(tsk -> tsk.getOutputFileName().set("output.tsrg")); + } } Optional> finalAdaptedInput = adaptedInput; diff --git a/platform/src/main/java/net/neoforged/gradle/platform/extensions/DynamicProjectExtension.java b/platform/src/main/java/net/neoforged/gradle/platform/extensions/DynamicProjectExtension.java index 5ca329d83..47e9a7ec4 100644 --- a/platform/src/main/java/net/neoforged/gradle/platform/extensions/DynamicProjectExtension.java +++ b/platform/src/main/java/net/neoforged/gradle/platform/extensions/DynamicProjectExtension.java @@ -13,11 +13,13 @@ import net.neoforged.gradle.common.extensions.JarJarExtension; import net.neoforged.gradle.common.runtime.extensions.CommonRuntimeExtension; import net.neoforged.gradle.common.runtime.tasks.AccessTransformerFileGenerator; +import net.neoforged.gradle.common.runtime.tasks.DefaultExecute; import net.neoforged.gradle.common.runtime.tasks.DownloadAssets; import net.neoforged.gradle.common.tasks.JarJar; -import net.neoforged.gradle.common.tasks.WriteIMappingsFile; import net.neoforged.gradle.common.tasks.PotentiallySignJar; +import net.neoforged.gradle.common.tasks.WriteIMappingsFile; import net.neoforged.gradle.common.util.CacheableIMappingFile; +import net.neoforged.gradle.common.util.ToolUtilities; import net.neoforged.gradle.common.util.constants.RunsConstants; import net.neoforged.gradle.dsl.common.extensions.AccessTransformers; import net.neoforged.gradle.dsl.common.extensions.Mappings; @@ -26,7 +28,13 @@ import net.neoforged.gradle.dsl.common.runtime.naming.TaskBuildingContext; import net.neoforged.gradle.dsl.common.runtime.tasks.Runtime; import net.neoforged.gradle.dsl.common.tasks.WithOutput; -import net.neoforged.gradle.dsl.common.util.*; +import net.neoforged.gradle.dsl.common.util.Artifact; +import net.neoforged.gradle.dsl.common.util.CommonRuntimeUtils; +import net.neoforged.gradle.dsl.common.util.ConfigurationUtils; +import net.neoforged.gradle.dsl.common.util.Constants; +import net.neoforged.gradle.dsl.common.util.DistributionType; +import net.neoforged.gradle.dsl.common.util.GameArtifact; +import net.neoforged.gradle.dsl.common.util.NamingConstants; import net.neoforged.gradle.dsl.platform.model.InstallerProfile; import net.neoforged.gradle.dsl.platform.model.LauncherProfile; import net.neoforged.gradle.dsl.platform.model.Library; @@ -36,6 +44,7 @@ import net.neoforged.gradle.neoform.runtime.definition.NeoFormRuntimeDefinition; import net.neoforged.gradle.neoform.runtime.extensions.NeoFormRuntimeExtension; import net.neoforged.gradle.neoform.runtime.tasks.Download; +import net.neoforged.gradle.neoform.runtime.tasks.PackJar; import net.neoforged.gradle.neoform.runtime.tasks.UnpackZip; import net.neoforged.gradle.neoform.util.NeoFormRuntimeUtils; import net.neoforged.gradle.platform.PlatformDevProjectPlugin; @@ -45,8 +54,16 @@ import net.neoforged.gradle.platform.runtime.runtime.specification.RuntimeDevRuntimeSpecification; import net.neoforged.gradle.platform.runtime.runtime.tasks.GenerateBinaryPatches; import net.neoforged.gradle.platform.runtime.runtime.tasks.GenerateSourcePatches; -import net.neoforged.gradle.neoform.runtime.tasks.PackJar; -import net.neoforged.gradle.platform.tasks.*; +import net.neoforged.gradle.platform.tasks.BakePatches; +import net.neoforged.gradle.platform.tasks.CreateClasspathFiles; +import net.neoforged.gradle.platform.tasks.CreateLauncherJson; +import net.neoforged.gradle.platform.tasks.CreateLegacyInstaller; +import net.neoforged.gradle.platform.tasks.CreateLegacyInstallerJson; +import net.neoforged.gradle.platform.tasks.CreateUserdevJson; +import net.neoforged.gradle.platform.tasks.OfficialMappingsJustParameters; +import net.neoforged.gradle.platform.tasks.SetupProjectFromRuntime; +import net.neoforged.gradle.platform.tasks.StripBinPatchedClasses; +import net.neoforged.gradle.platform.tasks.TokenizedTask; import net.neoforged.gradle.platform.util.ArtifactPathsCollector; import net.neoforged.gradle.platform.util.SetupUtils; import net.neoforged.gradle.util.TransformerUtils; @@ -81,10 +98,18 @@ import java.nio.file.Files; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.Base64; +import java.util.Collection; +import java.util.EnumMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; +import static net.neoforged.gradle.dsl.common.util.Constants.DEFAULT_PARCHMENT_ARTIFACT_PREFIX; +import static net.neoforged.gradle.dsl.common.util.Constants.DEFAULT_PARCHMENT_GROUP; + public abstract class DynamicProjectExtension implements BaseDSLElement { private final Project project; @@ -146,8 +171,31 @@ public void neoform(final String neoFormVersion) { NeoFormRuntimeUtils.configureDefaultRuntimeSpecBuilder(project, builder); }); + + final var parchmentArtifact = getParchment().map(parch -> { + var split = parch.split("-"); + return DEFAULT_PARCHMENT_GROUP + + ":" + DEFAULT_PARCHMENT_ARTIFACT_PREFIX + split[0] + + ":" + split[1] + + "@zip"; + }); + + TaskProvider sourcesTask = runtimeDefinition.getSourceJarTask(); + if (parchmentArtifact.isPresent()) { + sourcesTask = RuntimeDevRuntimeExtension.applyParchment( + getProject(), + "applyParchment", + getProject().provider(() -> ToolUtilities.resolveTool(getProject(), parchmentArtifact.get())), + getProject().provider(() -> "p_"), + sourcesTask.flatMap(WithOutput::getOutput).map(RegularFile::getAsFile), + true, + runtimeDefinition.getSpecification(), + project.getLayout().getBuildDirectory().dir(String.format("neoForm/%s", neoFormVersion)).get().getAsFile(), + null + ); + } - configureSetupTasks(runtimeDefinition.getSourceJarTask().flatMap(WithOutput::getOutput), mainSource, runtimeDefinition.getMinecraftDependenciesConfiguration()); + configureSetupTasks(sourcesTask.flatMap(WithOutput::getOutput), mainSource, runtimeDefinition.getMinecraftDependenciesConfiguration()); } public void runtime(final String neoFormVersion) { @@ -173,12 +221,21 @@ public void runtime(final String neoFormVersion, Directory patches, Directory re // we need the actual version it was resolved to. Otherwise the NeoForm version used by installer & userdev could change over time. String neoformDependency = "net.neoforged:neoform:" + neoFormRuntimeDefinition.getSpecification().getVersion() + "@zip"; + final var parchmentArtifact = getParchment().map(parch -> { + var split = parch.split("-"); + return DEFAULT_PARCHMENT_GROUP + + ":" + DEFAULT_PARCHMENT_ARTIFACT_PREFIX + split[0] + + ":" + split[1] + + "@zip"; + }); + final RuntimeDevRuntimeExtension runtimeDevRuntimeExtension = project.getExtensions().getByType(RuntimeDevRuntimeExtension.class); final RuntimeDevRuntimeDefinition runtimeDefinition = runtimeDevRuntimeExtension.create(builder -> { builder.withNeoFormRuntime(neoFormRuntimeDefinition) .withPatchesDirectory(patches) .withRejectsDirectory(rejects) .withDistributionType(DistributionType.JOINED) + .withParchment(parchmentArtifact) .isUpdating(getIsUpdating()); }); @@ -219,7 +276,7 @@ public void runtime(final String neoFormVersion, Directory patches, Directory re final LauncherProfile launcherProfile = project.getExtensions().create(LauncherProfile.class, "launcherProfile", LauncherProfile.class); final InstallerProfile installerProfile = project.getExtensions().create("installerProfile", InstallerProfile.class); final UserdevProfile userdevProfile = project.getExtensions().create("userdevProfile", UserdevProfile.class, project.getObjects()); - + final TaskProvider setupTask = configureSetupTasks(runtimeDefinition.getSourceJarTask().flatMap(WithOutput::getOutput), mainSource, runtimeDefinition.getMinecraftDependenciesConfiguration()); setupTask.configure(task -> task.getShouldLockDirectories().set(false)); @@ -235,7 +292,7 @@ public void runtime(final String neoFormVersion, Directory patches, Directory re obfToMojMappingProviders.put(DistributionType.CLIENT, clientInverseMappings); obfToMojMappingProviders.put(DistributionType.SERVER, serverInverseMappings); obfToMojMappingProviders.put(DistributionType.JOINED, clientInverseMappings); - + final TaskProvider neoFormSources = runtimeDefinition.getJoinedNeoFormRuntimeDefinition().getSourceJarTask(); final TaskProvider packChanges = project.getTasks().register("packForgeChanges", PackJar.class, task -> { @@ -244,21 +301,39 @@ public void runtime(final String neoFormVersion, Directory patches, Directory re }); final TaskProvider createPatches = project.getTasks().register("createSourcePatches", GenerateSourcePatches.class, task -> { - task.getBase().set(neoFormSources.flatMap(WithOutput::getOutput)); + task.getBase().set(runtimeDefinition.getPatchBase().flatMap(WithOutput::getOutput)); task.getModified().set(packChanges.flatMap(WithOutput::getOutput)); - + CommonRuntimeExtension.configureCommonRuntimeTaskParameters(task, runtimeDefinition, workingDirectory); }); final TaskProvider unpackZip = project.getTasks().register("unpackSourcePatches", UnpackZip.class, task -> { task.getInput().from(project.zipTree(createPatches.flatMap(WithOutput::getOutput))); task.getUnpackingTarget().set(patches); + task.dependsOn(createPatches); CommonRuntimeExtension.configureCommonRuntimeTaskParameters(task, runtimeDefinition, workingDirectory); }); - - final TaskProvider compiledJarProvider = project.getTasks().named(mainSource.getJarTaskName(), Jar.class); - + + var mergeMappings = runtimeDefinition.getJoinedNeoFormRuntimeDefinition().getTask("mergeMappings"); + Provider compiledJarProvider; + if (parchmentArtifact.isPresent()) { + var officialWithParams = project.getTasks().register(CommonRuntimeUtils.buildTaskName(runtimeDefinition, "officialMappingsJustParameters"), OfficialMappingsJustParameters.class, tsk -> { + tsk.getInput().set(mergeMappings.flatMap(WithOutput::getOutput)); + tsk.dependsOn(mergeMappings); + + CommonRuntimeExtension.configureCommonRuntimeTaskParameters(tsk, runtimeDefinition, workingDirectory); + }); + compiledJarProvider = renameCompiledJar( + officialWithParams, + project.getTasks().named(mainSource.getJarTaskName(), Jar.class), + runtimeDefinition, + workingDirectory + ); + } else { + compiledJarProvider = project.getTasks().named(mainSource.getJarTaskName(), Jar.class).flatMap(Jar::getArchiveFile); + } + javaPluginExtension.withSourcesJar(); final TaskProvider sourcesJarProvider = project.getTasks().named(mainSource.getSourcesJarTaskName(), Jar.class); sourcesJarProvider.configure(task -> { @@ -266,13 +341,13 @@ public void runtime(final String neoFormVersion, Directory patches, Directory re task.exclude("com/**"); task.exclude("mcp/**"); }); - + final EnumMap> binaryPatchGenerators = new EnumMap<>(DistributionType.class); for (DistributionType distribution : DistributionType.values()) { final TaskProvider cleanProvider = cleanProviders.get(distribution); final TaskProvider generateBinaryPatchesTask = project.getTasks().register(distribution.createTaskName("generate", "BinaryPatches"), GenerateBinaryPatches.class, task -> { task.getClean().set(cleanProvider.flatMap(WithOutput::getOutput)); - task.getPatched().set(compiledJarProvider.flatMap(Jar::getArchiveFile)); + task.getPatched().set(compiledJarProvider); task.getDistributionType().set(distribution); task.getPatches().from(patches); task.getMappings().set(obfToMojMappingProviders.get(distribution).flatMap(WithOutput::getOutput)); @@ -346,7 +421,7 @@ public void runtime(final String neoFormVersion, Directory patches, Directory re final TaskProvider strippedJar = project.getTasks().register("stripBinaryPatchedClasses", StripBinPatchedClasses.class, task -> { task.getCompiled().set(project.getTasks().named(mainSource.getJarTaskName(), Jar.class).flatMap(Jar::getArchiveFile)); task.getClean().set(joinedCleanProvider.flatMap(WithOutput::getOutput)); - + CommonRuntimeExtension.configureCommonRuntimeTaskParameters(task, runtimeDefinition, workingDirectory); }); @@ -674,12 +749,36 @@ public void runtime(final String neoFormVersion, Directory patches, Directory re CommonRuntimeExtension.configureCommonRuntimeTaskParameters(task, runtimeDefinition, workingDirectory); }); - - final TaskProvider bakePatches = project.getTasks().register("bakePatches", BakePatches.class, task -> { - task.getInput().set(packPatches.flatMap(WithOutput::getOutput)); - - CommonRuntimeExtension.configureCommonRuntimeTaskParameters(task, runtimeDefinition, workingDirectory); - }); + + final TaskProvider bakePatches; + if (!parchmentArtifact.isPresent()) { + bakePatches = project.getTasks().register("bakePatches", BakePatches.class, task -> { + task.getInput().set(packPatches.flatMap(WithOutput::getOutput)); + + CommonRuntimeExtension.configureCommonRuntimeTaskParameters(task, runtimeDefinition, workingDirectory); + }); + } else { + final var sourceSetDir = SetupUtils.getSetupSourceTarget(project); + final var sourcesWithoutParchment = RuntimeDevRuntimeExtension.applyParchment( + project, + "reverseParchment", + mergeMappings.flatMap(WithOutput::getOutput).map(RegularFile::getAsFile), + project.provider(() -> ""), + project.provider(() -> sourceSetDir), + false, + runtimeDefinition.getSpecification(), + workingDirectory, + strippedJar + ); + sourcesWithoutParchment.configure(withOutput -> withOutput.getProgramArguments().add("--ignore-prefix=mcp/")); + bakePatches = project.getTasks().register("createRenamedSourcePatches", GenerateSourcePatches.class, task -> { + task.getBase().set(neoFormSources.flatMap(WithOutput::getOutput)); + task.getModified().set(sourcesWithoutParchment.flatMap(WithOutput::getOutput)); + task.getShouldCreateAutomaticHeader().set(false); + + CommonRuntimeExtension.configureCommonRuntimeTaskParameters(task, runtimeDefinition, workingDirectory); + }); + } final AccessTransformers accessTransformers = project.getExtensions().getByType(AccessTransformers.class); @@ -910,6 +1009,31 @@ private TaskProvider createFlippedMojMapProvider(final Tas }); } + private Provider renameCompiledJar(TaskProvider mappingsFile, + TaskProvider input, + final RuntimeDevRuntimeDefinition runtimeDefinition, + final File workingDirectory) { + var inputFile = input.flatMap(Jar::getArchiveFile); + return project.getTasks().register(CommonRuntimeUtils.buildTaskName(runtimeDefinition, "renameCompiledJar"), DefaultExecute.class, task -> { + task.getArguments().putRegularFile("mappings", mappingsFile.flatMap(WithOutput::getOutput)); + task.getArguments().putRegularFile("input", inputFile); + + task.getExecutingJar().set(ToolUtilities.resolveTool(project, Constants.FART)); + task.getProgramArguments().addAll("--names", "{mappings}"); + task.getProgramArguments().addAll("--input", "{input}"); + task.getProgramArguments().addAll("--output", "{output}"); + task.getProgramArguments().add("--disable-abstract-param"); + + project.getExtensions().getByType(SourceSetContainer.class).getByName("main").getCompileClasspath() + .forEach(f -> task.getProgramArguments().addAll("--lib", f.getAbsolutePath())); + + task.dependsOn(input); + task.dependsOn(mappingsFile); + + CommonRuntimeExtension.configureCommonRuntimeTaskParameters(task, runtimeDefinition, workingDirectory); + }).flatMap(WithOutput::getOutput); + } + private void configureUserdevRunType(final RunType runType, Configuration moduleOnlyConfiguration, Configuration gameLayerLibraryConfiguration, Configuration pluginLayerLibraryConfiguration, Configuration userdevCompileOnlyConfiguration, Project project) { runType.getMainClass().set("cpw.mods.bootstraplauncher.BootstrapLauncher"); @@ -946,4 +1070,6 @@ public DynamicProjectType getType() { @Inject public abstract ProviderFactory getProviderFactory(); + @DSLProperty + public abstract Property getParchment(); } diff --git a/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/definition/RuntimeDevRuntimeDefinition.java b/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/definition/RuntimeDevRuntimeDefinition.java index 0d83f5f62..c06398084 100644 --- a/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/definition/RuntimeDevRuntimeDefinition.java +++ b/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/definition/RuntimeDevRuntimeDefinition.java @@ -10,7 +10,6 @@ import net.neoforged.gradle.dsl.common.tasks.WithOutput; import net.neoforged.gradle.neoform.runtime.definition.NeoFormRuntimeDefinition; import net.neoforged.gradle.platform.runtime.runtime.specification.RuntimeDevRuntimeSpecification; -import org.gradle.api.artifacts.Dependency; import org.gradle.api.tasks.TaskProvider; import org.jetbrains.annotations.NotNull; @@ -22,10 +21,12 @@ //TODO: Create DSL for runtime public final class RuntimeDevRuntimeDefinition extends CommonRuntimeDefinition implements IDelegatingRuntimeDefinition { private final NeoFormRuntimeDefinition joinedNeoFormRuntimeDefinition; - - public RuntimeDevRuntimeDefinition(@NotNull RuntimeDevRuntimeSpecification specification, NeoFormRuntimeDefinition joinedNeoFormRuntimeDefinition, TaskProvider sourcesProvider) { + private final TaskProvider patchBase; + + public RuntimeDevRuntimeDefinition(@NotNull RuntimeDevRuntimeSpecification specification, NeoFormRuntimeDefinition joinedNeoFormRuntimeDefinition, TaskProvider sourcesProvider, TaskProvider patchBase) { super(specification, joinedNeoFormRuntimeDefinition.getTasks(), sourcesProvider, joinedNeoFormRuntimeDefinition.getRawJarTask(), joinedNeoFormRuntimeDefinition.getGameArtifactProvidingTasks(), joinedNeoFormRuntimeDefinition.getMinecraftDependenciesConfiguration(), joinedNeoFormRuntimeDefinition::configureAssociatedTask, joinedNeoFormRuntimeDefinition.getVersionJson()); this.joinedNeoFormRuntimeDefinition = joinedNeoFormRuntimeDefinition; + this.patchBase = patchBase; } public NeoFormRuntimeDefinition getJoinedNeoFormRuntimeDefinition() { @@ -64,6 +65,10 @@ protected Map buildRunInterpolationData(RunImpl run) { return interpolationData; } + public TaskProvider getPatchBase() { + return patchBase; + } + @Override public Definition getDelegate() { return joinedNeoFormRuntimeDefinition; diff --git a/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/extension/RuntimeDevRuntimeExtension.java b/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/extension/RuntimeDevRuntimeExtension.java index b36730686..c6c11132a 100644 --- a/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/extension/RuntimeDevRuntimeExtension.java +++ b/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/extension/RuntimeDevRuntimeExtension.java @@ -1,21 +1,32 @@ package net.neoforged.gradle.platform.runtime.runtime.extension; import io.codechicken.diffpatch.util.PatchMode; +import net.neoforged.gradle.common.runtime.definition.CommonRuntimeDefinition; import net.neoforged.gradle.common.runtime.extensions.CommonRuntimeExtension; -import net.neoforged.gradle.dsl.common.extensions.Mappings; -import net.neoforged.gradle.dsl.common.extensions.Minecraft; +import net.neoforged.gradle.common.runtime.specification.CommonRuntimeSpecification; +import net.neoforged.gradle.common.runtime.tasks.DefaultExecute; +import net.neoforged.gradle.common.util.ToolUtilities; +import net.neoforged.gradle.dsl.common.extensions.subsystems.Subsystems; import net.neoforged.gradle.dsl.common.tasks.ArtifactProvider; +import net.neoforged.gradle.dsl.common.tasks.WithOutput; +import net.neoforged.gradle.dsl.common.tasks.specifications.ExecuteSpecification; import net.neoforged.gradle.dsl.common.util.CommonRuntimeUtils; import net.neoforged.gradle.neoform.runtime.definition.NeoFormRuntimeDefinition; import net.neoforged.gradle.platform.runtime.runtime.definition.RuntimeDevRuntimeDefinition; import net.neoforged.gradle.platform.runtime.runtime.specification.RuntimeDevRuntimeSpecification; import net.neoforged.gradle.platform.runtime.runtime.tasks.ApplyPatches; import org.gradle.api.Project; +import org.gradle.api.file.RegularFile; +import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.SourceSetContainer; import org.gradle.api.tasks.TaskProvider; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.inject.Inject; import java.io.File; +import java.util.function.BiConsumer; +import java.util.function.Consumer; public abstract class RuntimeDevRuntimeExtension extends CommonRuntimeExtension { @@ -30,29 +41,96 @@ public RuntimeDevRuntimeExtension(Project project) { NeoFormRuntimeDefinition neoformRuntime = spec.getNeoFormRuntime(); + final TaskProvider patchBase; + if (spec.getParchmentArtifact() != null) { + patchBase = applyParchment( + spec.getProject(), + "applyParchment", + getProject().provider(() -> ToolUtilities.resolveTool(getProject(), spec.getParchmentArtifact())), + getProject().provider(() -> "p_"), + neoformRuntime.getSourceJarTask().flatMap(WithOutput::getOutput).map(RegularFile::getAsFile), + true, + spec, + workingDirectory, + null + ); + } else { + patchBase = neoformRuntime.getSourceJarTask(); + } + final TaskProvider patchApply = spec.getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(spec, "applyPatches"), ApplyPatches.class, task -> { - task.getBase().set(neoformRuntime.getSourceJarTask().flatMap(ArtifactProvider::getOutput)); + task.getBase().set(patchBase.flatMap(WithOutput::getOutput)); task.getPatches().set(spec.getPatchesDirectory()); task.getRejects().set(spec.getRejectsDirectory()); task.getPatchMode().set(spec.isUpdating() ? PatchMode.FUZZY : PatchMode.ACCESS); task.getShouldFailOnPatchFailure().set(!spec.isUpdating()); configureCommonRuntimeTaskParameters(task, "applyPatches", spec, workingDirectory); }); - + final TaskProvider sourcesProvider = spec.getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(spec, "sourceFromAppliedPatches"), ArtifactProvider.class, task -> { - task.getInputFiles().from(patchApply.flatMap(ApplyPatches::getOutput)); + task.getInputFiles().from(patchApply.flatMap(WithOutput::getOutput)); task.getOutput().set(new File(workingDirectory, "patched.jar")); }); return new RuntimeDevRuntimeDefinition( spec, neoformRuntime, - sourcesProvider - ); + sourcesProvider, + patchBase); } @Override protected RuntimeDevRuntimeSpecification.Builder createBuilder() { return RuntimeDevRuntimeSpecification.Builder.from(getProject()); } + + public static TaskProvider applyParchment(Project project, + String name, + Provider mappingsFile, + Provider conflictPrefix, + Provider input, + boolean inputFile, + CommonRuntimeSpecification spec, + File workingDirectory, + @Nullable TaskProvider extraClasspath) { + return project.getTasks().register(CommonRuntimeUtils.buildTaskName(spec, name), DefaultExecute.class, task -> { + File toolExecutable = ToolUtilities.resolveTool(project, project.getExtensions().getByType(Subsystems.class).getTools().getJST().get()); + + task.getArguments().putFile("mappings", mappingsFile); + if (inputFile) { + task.getArguments().putFile("input", input); + } else { + task.getArguments().putDirectoryFile("input", input); + } + + task.getExecutingJar().set(toolExecutable); + task.getProgramArguments().add("--enable-parchment"); + task.getProgramArguments().add("--no-parchment-javadoc"); + task.getProgramArguments().add("--parchment-mappings"); + task.getProgramArguments().add("{mappings}"); + task.getProgramArguments().add("--in-format=" + (inputFile ? "archive" : "folder")); + task.getProgramArguments().add("--out-format=archive"); + if (conflictPrefix.isPresent() && !conflictPrefix.get().isBlank()) { + task.getProgramArguments().add("--parchment-conflict-prefix=%s".formatted(conflictPrefix.get())); + } + final StringBuilder builder = new StringBuilder(); + project.getExtensions().getByType(SourceSetContainer.class).getByName("main").getCompileClasspath().forEach(f -> { + if (!builder.isEmpty()) { + builder.append(File.pathSeparator); + } + builder.append(f.getAbsolutePath()); + }); + if (extraClasspath != null) { + builder.append(File.pathSeparator).append(extraClasspath.get().getOutput().get().getAsFile().getAbsolutePath()); + task.dependsOn(extraClasspath); + } + task.getProgramArguments().add("--classpath=" + builder); + + task.getLogLevel().set(ExecuteSpecification.LogLevel.DISABLED); + task.getProgramArguments().add("{input}"); + task.getProgramArguments().add("{output}"); + + CommonRuntimeExtension.configureCommonRuntimeTaskParameters(task, name, spec, workingDirectory); + }); + } } diff --git a/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/specification/RuntimeDevRuntimeSpecification.java b/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/specification/RuntimeDevRuntimeSpecification.java index 9ef09b03a..cf1b2c7f0 100644 --- a/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/specification/RuntimeDevRuntimeSpecification.java +++ b/platform/src/main/java/net/neoforged/gradle/platform/runtime/runtime/specification/RuntimeDevRuntimeSpecification.java @@ -12,6 +12,7 @@ import org.gradle.api.file.Directory; import org.gradle.api.provider.Provider; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Objects; @@ -24,6 +25,7 @@ public final class RuntimeDevRuntimeSpecification extends CommonRuntimeSpecifica private final Directory patchesDirectory; private final Directory rejectsDirectory; private final boolean isUpdating; + private final String parchmentArtifact; public RuntimeDevRuntimeSpecification(NeoFormRuntimeDefinition neoFormRuntime, Multimap preTaskTypeAdapters, @@ -31,7 +33,8 @@ public RuntimeDevRuntimeSpecification(NeoFormRuntimeDefinition neoFormRuntime, Multimap> taskCustomizers, Directory patchesDirectory, Directory rejectsDirectory, - boolean isUpdating) { + boolean isUpdating, + String parchmentArtifact) { super(neoFormRuntime.getSpecification().getProject(), "platform", neoFormRuntime.getSpecification().getVersion(), @@ -44,6 +47,7 @@ public RuntimeDevRuntimeSpecification(NeoFormRuntimeDefinition neoFormRuntime, this.patchesDirectory = patchesDirectory; this.rejectsDirectory = rejectsDirectory; this.isUpdating = isUpdating; + this.parchmentArtifact = parchmentArtifact; } public NeoFormRuntimeDefinition getNeoFormRuntime() { @@ -72,6 +76,11 @@ public Directory getRejectsDirectory() { } return rejectsDirectory; } + + @Nullable + public String getParchmentArtifact() { + return parchmentArtifact; + } public boolean isUpdating() { return isUpdating; @@ -97,6 +106,7 @@ public static final class Builder extends CommonRuntimeSpecification.Builder patchesDirectory; private Provider rejectsDirectory; private Provider isUpdating; + private Provider parchment; private Builder(Project project) { super(project); @@ -155,6 +165,11 @@ public Builder isUpdating(final Boolean isUpdating) { return isUpdating(project.provider(() -> isUpdating)); } + public Builder withParchment(final Provider parchment) { + this.parchment = parchment; + return getThis(); + } + public @NotNull RuntimeDevRuntimeSpecification build() { if (neoFormRuntimeDefinition == null) { throw new IllegalStateException("Setting a neoFormRuntimeDefinition is required"); @@ -177,7 +192,7 @@ public Builder isUpdating(final Boolean isUpdating) { taskCustomizers, patchesDirectory.get(), rejectsDirectory.get(), - isUpdating.get()); + isUpdating.get(), parchment.getOrNull()); } } } diff --git a/platform/src/main/java/net/neoforged/gradle/platform/tasks/OfficialMappingsJustParameters.java b/platform/src/main/java/net/neoforged/gradle/platform/tasks/OfficialMappingsJustParameters.java new file mode 100644 index 000000000..5d7409121 --- /dev/null +++ b/platform/src/main/java/net/neoforged/gradle/platform/tasks/OfficialMappingsJustParameters.java @@ -0,0 +1,43 @@ +package net.neoforged.gradle.platform.tasks; + +import net.minecraftforge.srgutils.IMappingBuilder; +import net.minecraftforge.srgutils.IMappingFile; +import net.neoforged.gradle.common.runtime.tasks.DefaultRuntime; +import net.neoforged.gradle.dsl.common.tasks.WithOutput; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.tasks.CacheableTask; +import org.gradle.api.tasks.InputFile; +import org.gradle.api.tasks.PathSensitive; +import org.gradle.api.tasks.PathSensitivity; +import org.gradle.api.tasks.TaskAction; + +import javax.inject.Inject; +import java.io.IOException; + +@CacheableTask +public abstract class OfficialMappingsJustParameters extends DefaultRuntime implements WithOutput { + @Inject + public OfficialMappingsJustParameters() { + getOutputFileName().set("output.tsrg"); + } + + @InputFile + @PathSensitive(PathSensitivity.NONE) + public abstract RegularFileProperty getInput(); + + @TaskAction + void exec() throws IOException { + var source = IMappingFile.load(getInput().getAsFile().get()); + var builder = IMappingBuilder.create(); + source.getClasses().forEach(cls -> { + var c = builder.addClass(cls.getMapped(), cls.getMapped()); + cls.getMethods().forEach(mtd -> { + if (mtd.getParameters().isEmpty()) return; + + var m = c.method(mtd.getMappedDescriptor(), mtd.getMapped(), mtd.getMapped()); + mtd.getParameters().forEach(par -> m.parameter(par.getIndex(), par.getOriginal(), par.getMapped())); + }); + }); + builder.build().write(getOutput().get().getAsFile().toPath(), IMappingFile.Format.TSRG2); + } +}