From a56c87c37b1be424cfd107f9f1a8efcee6d66ad5 Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Sat, 11 Nov 2023 19:20:57 +0100 Subject: [PATCH] Transform decompile step into a task that is customizable via specific settings. --- .../gradle/common/CommonProjectPlugin.java | 3 + .../subsystems/SubsystemsExtension.java | 21 ++++++ .../extensions/subsystems/Decompiler.groovy | 52 +++++++++++++++ .../extensions/subsystems/Subsystems.groovy | 21 ++++++ .../gradle/dsl/common/tasks/Execute.groovy | 2 - .../extensions/NeoFormRuntimeExtension.java | 64 +++++++++++++++++-- 6 files changed, 157 insertions(+), 6 deletions(-) create mode 100644 common/src/main/java/net/neoforged/gradle/common/extensions/subsystems/SubsystemsExtension.java create mode 100644 dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/extensions/subsystems/Decompiler.groovy create mode 100644 dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/extensions/subsystems/Subsystems.groovy diff --git a/common/src/main/java/net/neoforged/gradle/common/CommonProjectPlugin.java b/common/src/main/java/net/neoforged/gradle/common/CommonProjectPlugin.java index 943458c5b..23025af36 100644 --- a/common/src/main/java/net/neoforged/gradle/common/CommonProjectPlugin.java +++ b/common/src/main/java/net/neoforged/gradle/common/CommonProjectPlugin.java @@ -6,6 +6,7 @@ import net.neoforged.gradle.common.extensions.dependency.creation.ProjectBasedDependencyCreator; import net.neoforged.gradle.common.extensions.dependency.replacement.DependencyReplacementsExtension; import net.neoforged.gradle.common.extensions.repository.IvyDummyRepositoryExtension; +import net.neoforged.gradle.common.extensions.subsystems.SubsystemsExtension; import net.neoforged.gradle.common.runs.ide.IdeRunIntegrationManager; import net.neoforged.gradle.common.runs.run.RunImpl; import net.neoforged.gradle.common.runtime.definition.CommonRuntimeDefinition; @@ -20,6 +21,7 @@ import net.neoforged.gradle.dsl.common.extensions.*; import net.neoforged.gradle.dsl.common.extensions.dependency.replacement.DependencyReplacement; import net.neoforged.gradle.dsl.common.extensions.repository.Repository; +import net.neoforged.gradle.dsl.common.extensions.subsystems.Subsystems; import net.neoforged.gradle.dsl.common.runs.run.Run; import net.neoforged.gradle.dsl.common.runs.type.RunType; import net.neoforged.gradle.dsl.common.util.NamingConstants; @@ -72,6 +74,7 @@ public void apply(Project project) { extensionManager.registerExtension("minecraft", Minecraft.class, (p) -> p.getObjects().newInstance(MinecraftExtension.class, p)); extensionManager.registerExtension("mappings", Mappings.class, (p) -> p.getObjects().newInstance(MappingsExtension.class, p)); + extensionManager.registerExtension("subsystems", Subsystems.class, (p) -> p.getObjects().newInstance(SubsystemsExtension.class, p)); OfficialNamingChannelConfigurator.getInstance().configure(project); diff --git a/common/src/main/java/net/neoforged/gradle/common/extensions/subsystems/SubsystemsExtension.java b/common/src/main/java/net/neoforged/gradle/common/extensions/subsystems/SubsystemsExtension.java new file mode 100644 index 000000000..eb3d9fa92 --- /dev/null +++ b/common/src/main/java/net/neoforged/gradle/common/extensions/subsystems/SubsystemsExtension.java @@ -0,0 +1,21 @@ +package net.neoforged.gradle.common.extensions.subsystems; + +import net.minecraftforge.gdi.ConfigurableDSLElement; +import net.neoforged.gradle.dsl.common.extensions.subsystems.Subsystems; +import org.gradle.api.Project; + +import javax.inject.Inject; + +public abstract class SubsystemsExtension implements ConfigurableDSLElement, Subsystems { + private final Project project; + + @Inject + public SubsystemsExtension(Project project) { + this.project = project; + } + + @Override + public Project getProject() { + return project; + } +} diff --git a/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/extensions/subsystems/Decompiler.groovy b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/extensions/subsystems/Decompiler.groovy new file mode 100644 index 000000000..41f8c4a72 --- /dev/null +++ b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/extensions/subsystems/Decompiler.groovy @@ -0,0 +1,52 @@ +package net.neoforged.gradle.dsl.common.extensions.subsystems + +import groovy.transform.CompileStatic +import net.minecraftforge.gdi.ConfigurableDSLElement +import net.minecraftforge.gdi.annotations.DSLProperty +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional + +/** + * Allows configuration of the decompiler used by NeoGradle. + */ +@CompileStatic +interface Decompiler extends ConfigurableDSLElement { + + /** + * Allows the maximum memory provided to the decompiler to be overridden. Must be specified + * in the "123g" or "123m" form. + */ + @Input + @Optional + @DSLProperty + Property getMaxMemory(); + + /** + * Allows the maximum number of threads used by the decompiler to be constrained. By default, it will + * use all available threads. + */ + @Input + @Optional + @DSLProperty + Property getMaxThreads(); + + /** + * The log-level to use for the decompiler. Supported values: info, debug, warn, error. + * Defaults to info. + */ + @Input + @Optional + @DSLProperty + Property getLogLevel(); + + /** + * Allows additional JVM arguments to be added to the decompiler invocation. + */ + @Input + @Optional + @DSLProperty + ListProperty getJvmArgs(); + +} diff --git a/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/extensions/subsystems/Subsystems.groovy b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/extensions/subsystems/Subsystems.groovy new file mode 100644 index 000000000..eddf2078e --- /dev/null +++ b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/extensions/subsystems/Subsystems.groovy @@ -0,0 +1,21 @@ +package net.neoforged.gradle.dsl.common.extensions.subsystems + +import groovy.transform.CompileStatic +import net.minecraftforge.gdi.BaseDSLElement +import net.minecraftforge.gdi.annotations.DSLProperty +import org.gradle.api.tasks.Nested + +/** + * Allows configuration of various NeoGradle subsystems. + */ +@CompileStatic +interface Subsystems extends BaseDSLElement { + + /** + * @return Settings for the decompiler subsystem. + */ + @Nested + @DSLProperty + Decompiler getDecompiler(); + +} diff --git a/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/tasks/Execute.groovy b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/tasks/Execute.groovy index 01a62a840..59875cb41 100644 --- a/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/tasks/Execute.groovy +++ b/dsl/common/src/main/groovy/net/neoforged/gradle/dsl/common/tasks/Execute.groovy @@ -129,8 +129,6 @@ interface Execute extends WithWorkspace, WithOutput, WithJavaVersion, ExecuteSpe java.setWorkingDir(me.getOutputDirectory().get()) java.getMainClass().set(mainClass) java.setStandardOutput(log_out) - - java.setMaxHeapSize(String.format("%dm", Runtime.getRuntime().maxMemory().intdiv(1024 * 1024))) }).rethrowFailure().assertNormalExitValue() } } 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 ff754647b..7e84d99ba 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 @@ -3,6 +3,7 @@ import com.google.common.collect.Iterators; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import net.minecraftforge.gdi.ConfigurableDSLElement; import net.neoforged.gradle.common.runtime.extensions.CommonRuntimeExtension; import net.neoforged.gradle.common.runtime.tasks.Execute; import net.neoforged.gradle.common.runtime.tasks.ListLibraries; @@ -11,6 +12,8 @@ import net.neoforged.gradle.dsl.common.extensions.Mappings; import net.neoforged.gradle.dsl.common.extensions.Minecraft; import net.neoforged.gradle.dsl.common.extensions.MinecraftArtifactCache; +import net.neoforged.gradle.dsl.common.extensions.subsystems.Decompiler; +import net.neoforged.gradle.dsl.common.extensions.subsystems.Subsystems; import net.neoforged.gradle.dsl.common.runtime.naming.TaskBuildingContext; import net.neoforged.gradle.dsl.common.runtime.tasks.Runtime; import net.neoforged.gradle.dsl.common.runtime.tasks.RuntimeArguments; @@ -18,7 +21,11 @@ import net.neoforged.gradle.dsl.common.tasks.ArtifactProvider; import net.neoforged.gradle.dsl.common.tasks.WithOutput; import net.neoforged.gradle.dsl.common.tasks.specifications.OutputSpecification; -import net.neoforged.gradle.dsl.common.util.*; +import net.neoforged.gradle.dsl.common.util.CommonRuntimeUtils; +import net.neoforged.gradle.dsl.common.util.ConfigurationUtils; +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.neoform.configuration.NeoFormConfigConfigurationSpecV1; import net.neoforged.gradle.dsl.neoform.configuration.NeoFormConfigConfigurationSpecV2; import net.neoforged.gradle.neoform.runtime.definition.NeoFormRuntimeDefinition; @@ -43,11 +50,17 @@ import javax.annotation.Nullable; import java.io.File; import java.io.FileNotFoundException; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; @SuppressWarnings({"OptionalUsedAsFieldOrParameterType", "unused"}) // API Design -public abstract class NeoFormRuntimeExtension extends CommonRuntimeExtension { +public abstract class NeoFormRuntimeExtension extends CommonRuntimeExtension implements ConfigurableDSLElement { @javax.inject.Inject public NeoFormRuntimeExtension(Project project) { @@ -67,6 +80,8 @@ private static void configureMcpRuntimeTaskWithDefaults(NeoFormRuntimeSpecificat @Nullable private static TaskProvider createBuiltIn(final NeoFormRuntimeSpecification spec, NeoFormConfigConfigurationSpecV2 neoFormConfigV2, NeoFormConfigConfigurationSpecV1.Step step, final Map> tasks, final Map> gameArtifactTaskProviders, final Optional> adaptedInput) { switch (step.getType()) { + case "decompile": + return createDecompile(spec, step, neoFormConfigV2); case "downloadManifest": return gameArtifactTaskProviders.computeIfAbsent(GameArtifact.LAUNCHER_MANIFEST, a -> { throw new IllegalStateException("Launcher Manifest is required for this step, but was not provided"); @@ -117,7 +132,48 @@ private static TaskProvider createBuiltIn(final NeoFormRun return null; } - private static TaskProvider createExecute(final NeoFormRuntimeSpecification spec, final NeoFormConfigConfigurationSpecV1.Step step, final NeoFormConfigConfigurationSpecV1.Function function) { + @NotNull + private static TaskProvider createDecompile(NeoFormRuntimeSpecification spec, NeoFormConfigConfigurationSpecV1.Step step, NeoFormConfigConfigurationSpecV2 neoFormConfig) { + NeoFormConfigConfigurationSpecV1.Function function = neoFormConfig.getFunction(step.getType()); + if (function == null) { + throw new IllegalArgumentException(String.format("Invalid NeoForm Config, Unknown function step type: %s File: %s", step.getType(), neoFormConfig)); + } + + // Filter out decompiler arguments that aren't related to its output (log-level and thread-count) + List decompilerArgs = new ArrayList<>(function.getArgs()); + decompilerArgs.removeIf(arg -> arg.startsWith("-log=") || arg.startsWith("-thr=")); + + // Retrieve the default memory size from the JVM arguments configured in NeoForm + String defaultMaxMemory = "4g"; + List jvmArgs = new ArrayList<>(function.getJvmArgs()); + for (int i = jvmArgs.size() - 1; i >= 0; i--) { + if (jvmArgs.get(i).startsWith("-Xmx")) { + defaultMaxMemory = jvmArgs.get(i).substring("-Xmx".length()); + jvmArgs.remove(i); + } + } + + // Consider user-settings + Decompiler settings = spec.getProject().getExtensions().getByType(Subsystems.class).getDecompiler(); + String maxMemory = settings.getMaxMemory().getOrElse(defaultMaxMemory); + int maxThreads = settings.getMaxThreads().getOrElse(0); + String logLevel = settings.getLogLevel().getOrElse("INFO"); + + jvmArgs.addAll(settings.getJvmArgs().get()); + jvmArgs.add("-Xmx" + maxMemory); + if (maxThreads > 0) { + decompilerArgs.add(0, "-thr=" + maxThreads); + } + decompilerArgs.add(0, "-log=" + logLevel); + + return spec.getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(spec, step.getName()), Execute.class, task -> { + task.getExecutingJar().set(ToolUtilities.resolveTool(task.getProject(), function.getVersion())); + task.getJvmArguments().addAll(jvmArgs); + task.getProgramArguments().addAll(decompilerArgs); + }); + } + + private TaskProvider createExecute(final NeoFormRuntimeSpecification spec, final NeoFormConfigConfigurationSpecV1.Step step, final NeoFormConfigConfigurationSpecV1.Function function) { return spec.getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(spec, step.getName()), Execute.class, task -> { task.getExecutingJar().set(ToolUtilities.resolveTool(task.getProject(), function.getVersion())); task.getJvmArguments().addAll(function.getJvmArgs());