Skip to content

Commit

Permalink
Various Task Improvements (Patch, Strip, Recompile) (#75)
Browse files Browse the repository at this point in the history
* Apply patches directly from the archive and not the unpacked NeoForm directory. End-Goal: Don't unpack NeoForm.

* Make strip use try-with-resources.

* Move doLast into the task action of RecompileSources.

* Disable Caching for ArtifactFromOutput, since all it does is copy a file, which is the same as the cache restore would do.
  • Loading branch information
shartte authored Dec 18, 2023
1 parent 818fd14 commit 1b8c085
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import org.apache.commons.io.FileUtils;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.*;
import org.gradle.work.DisableCachingByDefault;

@CacheableTask
@DisableCachingByDefault(because = "a simple file-copy is not worthwhile to cache")
public abstract class ArtifactFromOutput extends NeoGradleBase implements WithOutput {

public ArtifactFromOutput() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ private static void configureMcpRuntimeTaskWithDefaults(NeoFormRuntimeSpecificat

@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Nullable
private static TaskProvider<? extends WithOutput> createBuiltIn(final NeoFormRuntimeSpecification spec, NeoFormConfigConfigurationSpecV2 neoFormConfigV2, NeoFormConfigConfigurationSpecV1.Step step, final Map<String, TaskProvider<? extends WithOutput>> tasks, final Map<GameArtifact, TaskProvider<? extends WithOutput>> gameArtifactTaskProviders, final Optional<TaskProvider<? extends WithOutput>> adaptedInput) {
private static TaskProvider<? extends WithOutput> createBuiltIn(final NeoFormRuntimeSpecification spec,
NeoFormConfigConfigurationSpecV2 neoFormConfigV2,
NeoFormConfigConfigurationSpecV1.Step step,
final Map<String, TaskProvider<? extends WithOutput>> tasks,
final Map<GameArtifact, TaskProvider<? extends WithOutput>> gameArtifactTaskProviders,
final Optional<TaskProvider<? extends WithOutput>> adaptedInput) {
switch (step.getType()) {
case "decompile":
return createDecompile(spec, step, neoFormConfigV2);
Expand Down Expand Up @@ -123,7 +128,15 @@ private static TaskProvider<? extends WithOutput> createBuiltIn(final NeoFormRun
);
});
case "patch":
return spec.getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(spec, step.getName()), Patch.class, task -> task.getInput().fileProvider(NeoFormRuntimeUtils.getTaskInputFor(spec, tasks, step, task)));
return spec.getProject().getTasks().register(
CommonRuntimeUtils.buildTaskName(spec, step.getName()),
Patch.class,
task -> {
task.getInput().fileProvider(NeoFormRuntimeUtils.getTaskInputFor(spec, tasks, step, task));
task.getPatchArtifact().set(spec.getNeoFormArtifact());
task.getPatchDirectory().set(neoFormConfigV2.getData("patches", spec.getDistribution().getName()));
}
);
}
if (neoFormConfigV2.getSpec() >= 2) {
switch (step.getType()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import codechicken.diffpatch.cli.PatchOperation;
import codechicken.diffpatch.util.LoggingOutputStream;
import codechicken.diffpatch.util.PatchMode;
import codechicken.diffpatch.util.archiver.ArchiveFormat;
import net.neoforged.gradle.common.runtime.tasks.DefaultRuntime;
import org.gradle.api.file.DirectoryProperty;
import net.neoforged.gradle.dsl.common.util.Artifact;
import net.neoforged.gradle.dsl.common.util.ConfigurationUtils;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.logging.LogLevel;
import org.gradle.api.provider.Property;
Expand All @@ -20,7 +22,6 @@ public abstract class Patch extends DefaultRuntime {
public Patch() {
super();

getPatchDirectory().fileProvider(getRuntimeData().flatMap(data -> data.get("patches")));
getRejectsFile().fileProvider(getFileInOutputDirectory("rejects.zip"));
getIsVerbose().convention(false);
}
Expand All @@ -31,11 +32,14 @@ public void run() throws Exception {
final File output = ensureFileWorkspaceReady(getOutput());
final File rejects = getRejectsFile().get().getAsFile();

// Resolve the input artifact
File inputArtifact = ConfigurationUtils.getArtifactProvider(getProject(), getPatchArtifact().map(Artifact::getDescriptor)).get();

PatchOperation.Builder builder = PatchOperation.builder()
.logTo(new LoggingOutputStream(getLogger(), LogLevel.LIFECYCLE))
.basePath(input.toPath())
.patchesPath(getUnpackedMcpZipDirectory().get().getAsFile().toPath())
.patchesPrefix(getUnpackedMcpZipDirectory().get().getAsFile().toPath().relativize(getPatchDirectory().get().getAsFile().toPath()).toString())
.patchesPath(inputArtifact.toPath(), ArchiveFormat.ZIP)
.patchesPrefix(getPatchDirectory().get())
.outputPath(output.toPath())
.level(getIsVerbose().get() ? codechicken.diffpatch.util.LogLevel.ALL : codechicken.diffpatch.util.LogLevel.WARN)
.mode(PatchMode.OFFSET)
Expand All @@ -62,9 +66,11 @@ public void run() throws Exception {
@PathSensitive(PathSensitivity.NONE)
public abstract RegularFileProperty getInput();

@InputDirectory
@PathSensitive(PathSensitivity.NONE)
public abstract DirectoryProperty getPatchDirectory();
@Input
public abstract Property<Artifact> getPatchArtifact();

@Input
public abstract Property<String> getPatchDirectory();

@OutputFile
public abstract RegularFileProperty getRejectsFile();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import net.neoforged.gradle.dsl.common.runtime.tasks.RuntimeMultiArguments;
import net.neoforged.gradle.util.ZipBuildingFileTreeVisitor;
import net.neoforged.gradle.dsl.common.runtime.tasks.Runtime;
import org.gradle.api.Action;
import org.gradle.api.Task;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.logging.LogLevel;
Expand All @@ -25,10 +23,12 @@
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.PathSensitive;
import org.gradle.api.tasks.PathSensitivity;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.compile.JavaCompile;
import org.gradle.jvm.toolchain.JavaLanguageVersion;
import org.gradle.jvm.toolchain.JavaToolchainService;
import org.gradle.jvm.toolchain.internal.CurrentJvmToolchainSpec;
import org.gradle.work.InputChanges;

import java.io.File;
import java.io.FileOutputStream;
Expand All @@ -45,7 +45,7 @@ public abstract class RecompileSourceJar extends JavaCompile implements Runtime

public RecompileSourceJar() {
super();

arguments = getObjectFactory().newInstance(RuntimeArgumentsImpl.class, getProviderFactory());
multiArguments = getObjectFactory().newInstance(RuntimeMultiArgumentsImpl.class, getProviderFactory());

Expand Down Expand Up @@ -97,32 +97,30 @@ public RecompileSourceJar() {
getOptions().setFork(true);
getOptions().setIncremental(true);
getOptions().getIncrementalAfterFailure().set(true);
getInputJar().finalizeValueOnRead();
}

//Leave this as an anon class, so that gradle is aware of this. Lambdas can not be used during task tree analysis.
//noinspection Convert2Lambda
doLast(new Action<Task>() {
@Override
public void execute(Task doLast) {
try {
final File outputJar = RecompileSourceJar.this.ensureFileWorkspaceReady(RecompileSourceJar.this.getOutput());
final FileOutputStream fileOutputStream = new FileOutputStream(outputJar);
final ZipOutputStream outputZipStream = new ZipOutputStream(fileOutputStream);
final ZipBuildingFileTreeVisitor zipBuildingFileTreeVisitor = new ZipBuildingFileTreeVisitor(outputZipStream);
//Add the compiled output.
RecompileSourceJar.this.getDestinationDirectory().getAsFileTree().visit(zipBuildingFileTreeVisitor);
//Add the original resources.
RecompileSourceJar.this.getArchiveOperations().zipTree(RecompileSourceJar.this.getInputJar()).matching(filter -> filter.exclude("**/*.java")).visit(zipBuildingFileTreeVisitor);
outputZipStream.close();
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException("Failed to create recompiled output jar", e);
}
@Override
@TaskAction
protected void compile(InputChanges inputs) {
super.compile(inputs);

if (getState().getDidWork()) {
final File outputJar = ensureFileWorkspaceReady(getOutput());
try (FileOutputStream fileOutputStream = new FileOutputStream(outputJar);
ZipOutputStream outputZipStream = new ZipOutputStream(fileOutputStream)) {
ZipBuildingFileTreeVisitor zipBuildingFileTreeVisitor = new ZipBuildingFileTreeVisitor(outputZipStream);
//Add the compiled output.
getDestinationDirectory().getAsFileTree().visit(zipBuildingFileTreeVisitor);
//Add the original resources.
getArchiveOperations().zipTree(getInputJar()).matching(filter -> filter.exclude("**/*.java")).visit(zipBuildingFileTreeVisitor);
} catch (IOException e) {
throw new RuntimeException("Failed to create recompiled output jar", e);
}
});

getInputJar().finalizeValueOnRead();
}
}


@Override
public RuntimeArguments getArguments() {
return arguments;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,21 @@ protected void run() throws Throwable {
}

private void strip(File input, File output, boolean whitelist) throws IOException {
JarInputStream is = new JarInputStream(new FileInputStream(input));
JarOutputStream os = new JarOutputStream(new FileOutputStream(output));

// Ignore any entry that's not allowed
JarEntry entry;
while ((entry = is.getNextJarEntry()) != null) {
if (!isEntryValid(entry, whitelist)) continue;
os.putNextEntry(entry);
IOUtils.copyLarge(is, os);
os.closeEntry();
try (JarInputStream is = new JarInputStream(new FileInputStream(input));
FileOutputStream fout = new FileOutputStream(output);
JarOutputStream os = new JarOutputStream(fout)) {

// Ignore any entry that's not allowed
JarEntry entry;
while ((entry = is.getNextJarEntry()) != null) {
if (!isEntryValid(entry, whitelist)) {
continue;
}
os.putNextEntry(entry);
IOUtils.copyLarge(is, os);
os.closeEntry();
}
}

os.close();
is.close();
}

private boolean isEntryValid(JarEntry entry, boolean whitelist) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public UserDevRuntimeExtension(Project project) {

builder.withPreTaskAdapter("decompile", atAndSASAdapter);

builder.withPostTaskAdapter("patch", createPatchAdapter(userDevConfigurationSpec.getSourcePatchesDirectory().get(), unpackedForgeDirectory));
builder.withPostTaskAdapter("patch", createPatchAdapter(userDevDependency, userDevConfigurationSpec.getSourcePatchesDirectory().get()));

builder.withTaskCustomizer("inject", InjectZipContent.class, task -> configureNeoforgeInjects(
task,
Expand Down Expand Up @@ -155,10 +155,13 @@ private TaskTreeAdapter createAccessTransformerAdapter(final String accessTransf
};
}

private TaskTreeAdapter createPatchAdapter(final String patchDirectory, final File unpackForgeUserDevDirectory) {
private TaskTreeAdapter createPatchAdapter(Dependency userDevDependency, String patchDirectory) {
return (definition, previousTasksOutput, runtimeWorkspace, gameArtifacts, mappingVersionData, dependentTaskConfigurationHandler) -> definition.getSpecification().getProject().getTasks().register(CommonRuntimeUtils.buildTaskName(definition.getSpecification(), "patchUserDev"), Patch.class, task -> {
Artifact userDevArtifact = Artifact.from(userDevDependency);

task.getInput().set(previousTasksOutput.flatMap(WithOutput::getOutput));
task.getPatchDirectory().fileProvider(definition.getSpecification().getProject().provider(() -> new File(unpackForgeUserDevDirectory, patchDirectory)));
task.getPatchArtifact().set(userDevArtifact);
task.getPatchDirectory().set(patchDirectory);
});
}

Expand Down

0 comments on commit 1b8c085

Please sign in to comment.