Skip to content

Commit

Permalink
Streamline Inject Tasks for Neoforge in Userdev (#71)
Browse files Browse the repository at this point in the history
* Add the ability to the runtime builder to customize individual tasks in addition to manipulating the task tree.

* Enhance the InjectCode task to handle multiple injection source simultaneously, each with their own filters.
Use that new task to merge the injections from NeoForm and NeoForge userdev into a single task.
  • Loading branch information
shartte authored Dec 12, 2023
1 parent 0882c21 commit 7c32053
Show file tree
Hide file tree
Showing 18 changed files with 694 additions and 210 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
import net.neoforged.gradle.dsl.common.runtime.extensions.CommonRuntimes;
import net.neoforged.gradle.dsl.common.runtime.spec.Specification;
import net.neoforged.gradle.dsl.common.runtime.tasks.Runtime;
import net.neoforged.gradle.dsl.common.runtime.tasks.tree.TaskCustomizer;
import net.neoforged.gradle.dsl.common.tasks.WithOutput;
import net.neoforged.gradle.dsl.common.util.CacheableMinecraftVersion;
import net.neoforged.gradle.dsl.common.util.CommonRuntimeUtils;
import net.neoforged.gradle.dsl.common.util.DistributionType;
import net.neoforged.gradle.dsl.common.util.GameArtifact;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.Directory;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.TaskProvider;
Expand Down Expand Up @@ -52,6 +53,10 @@ public static void configureCommonRuntimeTaskParameters(Runtime runtimeTask, Map
runtimeTask.getRuntimeDirectory().set(runtimeDirectory);
runtimeTask.getRuntimeName().set(spec.getVersionedName());
runtimeTask.getJavaVersion().convention(spec.getProject().getExtensions().getByType(JavaPluginExtension.class).getToolchain().getLanguageVersion());

for (TaskCustomizer<? extends Task> taskCustomizer : spec.getTaskCustomizers().get(step)) {
taskCustomizer.apply(runtimeTask);
}
}

public static void configureCommonRuntimeTaskParameters(Runtime mcpRuntimeTask, Map<String, File> dataFiles, Map<String, File> dataDirectories, String step, DistributionType distributionType, String minecraftVersion, Project project, File runtimeDirectory) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
import net.neoforged.gradle.common.runtime.definition.CommonRuntimeDefinition;
import net.neoforged.gradle.common.runtime.extensions.CommonRuntimeExtension;
import net.neoforged.gradle.dsl.common.runtime.spec.Specification;
import net.neoforged.gradle.dsl.common.runtime.tasks.tree.TaskCustomizer;
import net.neoforged.gradle.dsl.common.runtime.tasks.tree.TaskTreeAdapter;
import net.neoforged.gradle.dsl.common.util.DistributionType;
import org.apache.commons.lang3.StringUtils;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.provider.Provider;
import org.jetbrains.annotations.NotNull;

import java.util.Map;
import java.util.function.Consumer;

/**
* Defines a runtime specification.
Expand All @@ -25,14 +28,23 @@ public abstract class CommonRuntimeSpecification implements Specification {
@NotNull private final DistributionType distribution;
@NotNull private final Multimap<String, TaskTreeAdapter> preTaskTypeAdapters;
@NotNull private final Multimap<String, TaskTreeAdapter> postTypeAdapters;
@NotNull private final Multimap<String, TaskCustomizer<? extends Task>> taskCustomizers;
@NotNull private final CommonRuntimeExtension<?,?,?> runtimeExtension;
protected CommonRuntimeSpecification(Project project, @NotNull String name, @NotNull String version, DistributionType distribution, Multimap<String, TaskTreeAdapter> preTaskTypeAdapters, Multimap<String, TaskTreeAdapter> postTypeAdapters, @NotNull Class<? extends CommonRuntimeExtension<?, ?, ?>> runtimeExtensionClass) {
protected CommonRuntimeSpecification(Project project,
@NotNull String name,
@NotNull String version,
DistributionType distribution,
Multimap<String, TaskTreeAdapter> preTaskTypeAdapters,
Multimap<String, TaskTreeAdapter> postTypeAdapters,
Multimap<String, TaskCustomizer<? extends Task>> taskCustomizers,
@NotNull Class<? extends CommonRuntimeExtension<?, ?, ?>> runtimeExtensionClass) {
this.project = project;
this.name = name;
this.version = version;
this.distribution = distribution;
this.preTaskTypeAdapters = ImmutableMultimap.copyOf(preTaskTypeAdapters);
this.postTypeAdapters = ImmutableMultimap.copyOf(postTypeAdapters);
this.taskCustomizers = ImmutableMultimap.copyOf(taskCustomizers);
this.runtimeExtension = project.getExtensions().getByType(runtimeExtensionClass);
}

Expand Down Expand Up @@ -92,6 +104,12 @@ public Multimap<String, TaskTreeAdapter> getPostTypeAdapters() {
return postTypeAdapters;
}

@NotNull
@Override
public Multimap<String, TaskCustomizer<? extends Task>> getTaskCustomizers() {
return taskCustomizers;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand All @@ -103,6 +121,7 @@ public boolean equals(Object o) {
if (!getIdentifier().equals(that.getIdentifier())) return false;
if (getDistribution() != that.getDistribution()) return false;
if (!getPreTaskTypeAdapters().equals(that.getPreTaskTypeAdapters())) return false;
if (!getTaskCustomizers().equals(that.getTaskCustomizers())) return false;
return getPostTypeAdapters().equals(that.getPostTypeAdapters());
}

Expand All @@ -113,6 +132,7 @@ public int hashCode() {
result = 31 * result + getDistribution().hashCode();
result = 31 * result + getPreTaskTypeAdapters().hashCode();
result = 31 * result + getPostTypeAdapters().hashCode();
result = 31 * result + getTaskCustomizers().hashCode();
return result;
}

Expand All @@ -124,6 +144,7 @@ public String toString() {
", distribution=" + distribution +
", preTaskTypeAdapters=" + preTaskTypeAdapters +
", postTypeAdapters=" + postTypeAdapters +
", taskCustomizers=" + taskCustomizers +
'}';
}

Expand All @@ -140,6 +161,7 @@ public abstract static class Builder<S extends CommonRuntimeSpecification, B ext
protected boolean hasConfiguredDistributionType = false;
protected final Multimap<String, TaskTreeAdapter> preTaskAdapters = LinkedListMultimap.create();
protected final Multimap<String, TaskTreeAdapter> postTaskAdapters = LinkedListMultimap.create();
protected final Multimap<String, TaskCustomizer<? extends Task>> taskCustomizers = LinkedListMultimap.create();

/**
* Creates a new builder.
Expand Down Expand Up @@ -202,6 +224,14 @@ public final B withPostTaskAdapter(final String taskTypeName, final TaskTreeAdap
return getThis();
}


@Override
@NotNull
public final <T extends Task> B withTaskCustomizer(final String taskTypeName, Class<T> taskType, Consumer<T> customizer) {
this.taskCustomizers.put(taskTypeName, new TaskCustomizer<>(taskType, customizer));
return getThis();
}

/**
* Builds the specification.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ package net.neoforged.gradle.dsl.common.runtime.spec

import com.google.common.collect.Multimap
import groovy.transform.CompileStatic
import net.neoforged.gradle.dsl.common.runtime.tasks.tree.TaskCustomizer
import net.neoforged.gradle.dsl.common.util.DistributionType
import net.neoforged.gradle.dsl.common.runtime.tasks.tree.TaskTreeAdapter
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.provider.Provider
import org.jetbrains.annotations.NotNull

import java.util.function.Consumer

@CompileStatic
interface Specification {
/**
Expand Down Expand Up @@ -77,6 +81,11 @@ interface Specification {
*/
@NotNull Multimap<String, TaskTreeAdapter> getPostTypeAdapters();

/**
* The customizers that are allowed to change the configuration of Neoform tasks.
*/
@NotNull Multimap<String, TaskCustomizer<? extends Task>> getTaskCustomizers();

/**
* Determines the specifications minecraft version.
*
Expand Down Expand Up @@ -126,5 +135,15 @@ interface Specification {
* @return The builder instance.
*/
B withPostTaskAdapter(String taskTypeName, TaskTreeAdapter adapter);

/**
* Adds a task customizer to the specification which is about to be build.
*
* @param taskTypeName The name of the task type or specification step to which the customization should be applied.
* @param taskType The expected Gradle task type of the task.
* @param customizer The function to apply to the task via {@link Task#configure}.
* @return The builder instance.
*/
<T extends Task> B withTaskCustomizer(final String taskTypeName, Class<T> taskType, Consumer<T> customizer);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package net.neoforged.gradle.dsl.common.runtime.tasks.tree;

import net.neoforged.gradle.dsl.common.runtime.tasks.Runtime;
import org.gradle.api.Task;

import java.util.function.Consumer;

/**
* Encapsulates a task customizer that changes the configuration of a Gradle Task encapsulating a Neoform step.
*/
public final class TaskCustomizer<T extends Task> {
private final Class<T> taskClass;
private final Consumer<T> taskCustomizer;

public TaskCustomizer(Class<T> taskClass, Consumer<T> taskCustomizer) {
this.taskClass = taskClass;
this.taskCustomizer = taskCustomizer;
}

/**
* @return The expected task type. This will be validated to avoid unchecked casts.
*/
public Class<T> getTaskClass() {
return taskClass;
}

/**
* @return The function that will be applied to the task using {@link Task#configure}.
*/
public Consumer<T> getTaskCustomizer() {
return taskCustomizer;
}

public void apply(Runtime task) {
if (!taskClass.isInstance(task)) {
throw new IllegalArgumentException("Customization for step " + task.getStepName()
+ " requires task type " + taskClass + " but actual task is " + task.getClass());
}
taskCustomizer.accept(taskClass.cast(task));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.Dependency
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer

Expand Down Expand Up @@ -49,6 +51,17 @@ class ConfigurationUtils {
return configuration
}

/**
* Creates a provider that will resolve a temporary configuration containing the given dependency.
*/
static Provider<File> getArtifactProvider(Project project, Provider<? extends Object> dependencyNotationProvider) {
return dependencyNotationProvider.flatMap(dependencyNotation -> {
Configuration configuration = temporaryConfiguration(project, project.getDependencies().create(dependencyNotation));
configuration.transitive = false;
return configuration.getElements().map(files -> files.iterator().next().getAsFile());
});
}

static List<Configuration> findReplacementConfigurations(final Project project, final Configuration configuration) {
final Set<Configuration> resultContainer = new HashSet<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import net.neoforged.gradle.dsl.neoform.configuration.NeoFormConfigConfigurationSpecV2;
import net.neoforged.gradle.neoform.runtime.definition.NeoFormRuntimeDefinition;
import net.neoforged.gradle.neoform.runtime.specification.NeoFormRuntimeSpecification;
import net.neoforged.gradle.neoform.runtime.tasks.InjectCode;
import net.neoforged.gradle.neoform.runtime.tasks.InjectZipContent;
import net.neoforged.gradle.neoform.runtime.tasks.Patch;
import net.neoforged.gradle.neoform.runtime.tasks.RecompileSourceJar;
import net.neoforged.gradle.neoform.runtime.tasks.StripJar;
Expand Down Expand Up @@ -107,13 +107,18 @@ private static TaskProvider<? extends WithOutput> createBuiltIn(final NeoFormRun
task.getDownloadedVersionJsonFile().fileProvider(NeoFormRuntimeUtils.getTaskInputFor(spec, tasks, step, "downloadJson", adaptedInput, task));
});
case "inject":
return spec.getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(spec, step.getName()), InjectCode.class, task -> {
return spec.getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(spec, step.getName()), InjectZipContent.class, task -> {
task.getInjectionSource().fileProvider(NeoFormRuntimeUtils.getTaskInputFor(spec, tasks, step, task));
if (spec.getDistribution().equals(DistributionType.SERVER)) {
task.getInclusionFilter().add("**/server/**");
} else if (spec.getDistribution().equals(DistributionType.CLIENT)) {
task.getInclusionFilter().add("**/client/**");
}
task.injectDirectory(
task.getRuntimeData().flatMap(data -> data.get("inject")),
filter -> {
if (spec.getDistribution().equals(DistributionType.SERVER)) {
filter.include("**/server/**");
} else if (spec.getDistribution().equals(DistributionType.CLIENT)) {
filter.include("**/client/**");
}
}
);
});
case "patch":
return spec.getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(spec, step.getName()), Patch.class, task -> task.getInput().fileProvider(NeoFormRuntimeUtils.getTaskInputFor(spec, tasks, step, task)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@

import com.google.common.collect.Multimap;
import net.neoforged.gradle.common.runtime.specification.CommonRuntimeSpecification;
import net.neoforged.gradle.dsl.common.runtime.tasks.tree.TaskCustomizer;
import net.neoforged.gradle.dsl.common.util.ConfigurationUtils;
import net.neoforged.gradle.dsl.common.extensions.MinecraftArtifactCache;
import net.neoforged.gradle.dsl.common.runtime.tasks.tree.TaskTreeAdapter;
import net.neoforged.gradle.dsl.common.util.Artifact;
import net.neoforged.gradle.dsl.common.util.DistributionType;
import net.neoforged.gradle.dsl.neoform.runtime.specification.NeoFormSpecification;
import net.neoforged.gradle.neoform.runtime.extensions.NeoFormRuntimeExtension;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ResolvedArtifact;
import org.gradle.api.file.FileCollection;
import org.gradle.api.provider.Provider;

import java.util.Objects;
import java.util.Optional;

/**
* Defines a specification for an MCP runtime.
Expand All @@ -25,8 +24,15 @@ public class NeoFormRuntimeSpecification extends CommonRuntimeSpecification impl
private final Artifact neoFormArtifact;
private final FileCollection additionalRecompileDependencies;

public NeoFormRuntimeSpecification(Project project, String version, Artifact neoFormArtifact, DistributionType side, Multimap<String, TaskTreeAdapter> preTaskTypeAdapters, Multimap<String, TaskTreeAdapter> postTypeAdapters, FileCollection additionalRecompileDependencies) {
super(project, "neoForm", version, side, preTaskTypeAdapters, postTypeAdapters, NeoFormRuntimeExtension.class);
public NeoFormRuntimeSpecification(Project project,
String version,
Artifact neoFormArtifact,
DistributionType side,
Multimap<String, TaskTreeAdapter> preTaskTypeAdapters,
Multimap<String, TaskTreeAdapter> postTypeAdapters,
Multimap<String, TaskCustomizer<? extends Task>> taskCustomizers,
FileCollection additionalRecompileDependencies) {
super(project, "neoForm", version, side, preTaskTypeAdapters, postTypeAdapters, taskCustomizers, NeoFormRuntimeExtension.class);
this.neoFormArtifact = neoFormArtifact;
this.additionalRecompileDependencies = additionalRecompileDependencies;
}
Expand Down Expand Up @@ -168,7 +174,16 @@ public NeoFormRuntimeSpecification build() {
final Provider<Artifact> resolvedArtifact = neoFormArtifact.map(a -> resolveNeoFormVersion(project, a));
final Provider<String> resolvedVersion = resolvedArtifact.map(Artifact::getVersion).map(v -> v.equals("+") ? "" : v);

return new NeoFormRuntimeSpecification(project, resolvedVersion.get(), resolvedArtifact.get(), distributionType.get(), preTaskAdapters, postTaskAdapters, additionalDependencies);
return new NeoFormRuntimeSpecification(
project,
resolvedVersion.get(),
resolvedArtifact.get(),
distributionType.get(),
preTaskAdapters,
postTaskAdapters,
taskCustomizers,
additionalDependencies
);
}

private static Artifact resolveNeoFormVersion(final Project project, final Artifact current) {
Expand Down
Loading

0 comments on commit 7c32053

Please sign in to comment.