Skip to content

Commit

Permalink
Switch to custom neodev plugin based on moddev
Browse files Browse the repository at this point in the history
  • Loading branch information
Technici4n authored and shartte committed Oct 24, 2024
1 parent fc455e6 commit a706b07
Show file tree
Hide file tree
Showing 34 changed files with 2,389 additions and 292 deletions.
19 changes: 11 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import java.util.regex.Pattern
plugins {
id 'net.neoforged.gradleutils' version '3.0.0'
id 'com.diffplug.spotless' version '6.22.0' apply false
id 'net.neoforged.licenser' version '0.7.2'
id 'net.neoforged.licenser' version '0.7.5'
id 'neoforge.formatting-conventions'
id 'neoforge.versioning'
}
Expand All @@ -23,19 +23,22 @@ System.out.println("NeoForge version ${project.version}")
allprojects {
version rootProject.version
group 'net.neoforged'
repositories {
mavenLocal()
}
}

subprojects {
apply plugin: 'java'

java.toolchain.languageVersion.set(JavaLanguageVersion.of(project.java_version))
}

repositories {
mavenCentral()
// Remove src/ sources from the root project. They are used in the neoforge subproject.
sourceSets {
main {
java {
srcDirs = []
}
resources {
srcDirs = []
}
}
}

// Put licenser here otherwise it tries to license all source sets including decompiled MC sources
Expand Down
23 changes: 23 additions & 0 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
plugins {
id 'java-gradle-plugin'
id 'groovy-gradle-plugin'
}

repositories {
gradlePluginPortal()
mavenCentral()
maven {
name = "NeoForged"
url = "https://maven.neoforged.net/releases"
content {
includeGroup "codechicken"
includeGroup "net.neoforged"
}
}
}

dependencies {
// buildSrc is an includedbuild of the parent directory (gradle.parent)
// ../settings.gradle sets the moddevgradle_plugin_version accordingly
implementation "net.neoforged:moddev-gradle:${gradle.parent.ext.moddevgradle_plugin_version}"

implementation "com.google.code.gson:gson:${project.gson_version}"
implementation "io.codechicken:DiffPatch:${project.diffpatch_version}"
}
3 changes: 3 additions & 0 deletions buildSrc/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

gson_version=2.11.0
diffpatch_version=2.0.0.35
Empty file added buildSrc/settings.gradle
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package net.neoforged.neodev;

import net.neoforged.moddevgradle.internal.utils.FileUtils;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.JavaExec;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;

import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;

abstract class ApplyAccessTransformer extends JavaExec {
@InputFile
public abstract RegularFileProperty getInputJar();

@InputFile
public abstract RegularFileProperty getAccessTransformer();

@OutputFile
public abstract RegularFileProperty getOutputJar();

// Used to give JST more information about the classes.
@Classpath
public abstract ConfigurableFileCollection getLibraries();

@Internal
public abstract RegularFileProperty getLibrariesFile();

@Inject
public ApplyAccessTransformer() {}

@Override
@TaskAction
public void exec() {
try {
FileUtils.writeLinesSafe(
getLibrariesFile().getAsFile().get().toPath(),
getLibraries().getFiles().stream().map(File::getAbsolutePath).toList(),
StandardCharsets.UTF_8);
} catch (IOException exception) {
throw new UncheckedIOException("Failed to write libraries for JST.", exception);
}

args(
"--enable-accesstransformers",
"--access-transformer", getAccessTransformer().getAsFile().get().getAbsolutePath(),
"--libraries-list", getLibrariesFile().getAsFile().get().getAbsolutePath(),
getInputJar().getAsFile().get().getAbsolutePath(),
getOutputJar().getAsFile().get().getAbsolutePath());

super.exec();
}
}
74 changes: 74 additions & 0 deletions buildSrc/src/main/java/net/neoforged/neodev/ApplyPatches.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package net.neoforged.neodev;

import io.codechicken.diffpatch.cli.PatchOperation;
import io.codechicken.diffpatch.util.Input.MultiInput;
import io.codechicken.diffpatch.util.Output.MultiOutput;
import io.codechicken.diffpatch.util.PatchMode;
import org.gradle.api.DefaultTask;
import org.gradle.api.Project;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.PathSensitive;
import org.gradle.api.tasks.PathSensitivity;
import org.gradle.api.tasks.TaskAction;
import org.gradle.work.DisableCachingByDefault;

import javax.inject.Inject;
import java.io.IOException;

@DisableCachingByDefault(because = "Not worth caching")
abstract class ApplyPatches extends DefaultTask {
@InputFile
public abstract RegularFileProperty getOriginalJar();

@InputDirectory
@PathSensitive(PathSensitivity.NONE)
public abstract DirectoryProperty getPatchesFolder();

@OutputFile
public abstract RegularFileProperty getPatchedJar();

@OutputDirectory
public abstract DirectoryProperty getRejectsFolder();

@Input
protected abstract Property<Boolean> getIsUpdating();

@Inject
public ApplyPatches(Project project) {
getIsUpdating().set(project.getProviders().gradleProperty("updating").map(Boolean::parseBoolean).orElse(false));
}

@TaskAction
public void applyPatches() throws IOException {
var isUpdating = getIsUpdating().get();

var builder = PatchOperation.builder()
.logTo(getLogger()::lifecycle)
.baseInput(MultiInput.detectedArchive(getOriginalJar().get().getAsFile().toPath()))
.patchesInput(MultiInput.folder(getPatchesFolder().get().getAsFile().toPath()))
.patchedOutput(MultiOutput.detectedArchive(getPatchedJar().get().getAsFile().toPath()))
.rejectsOutput(MultiOutput.folder(getRejectsFolder().get().getAsFile().toPath()))
.mode(isUpdating ? PatchMode.FUZZY : PatchMode.ACCESS)
.aPrefix("a/")
.bPrefix("b/")
.level(isUpdating ? io.codechicken.diffpatch.util.LogLevel.ALL : io.codechicken.diffpatch.util.LogLevel.WARN)
.minFuzz(0.9f); // The 0.5 default in DiffPatch is too low.

var result = builder.build().operate();

int exit = result.exit;
if (exit != 0 && exit != 1) {
throw new RuntimeException("DiffPatch failed with exit code: " + exit);
}
if (exit != 0 && !isUpdating) {
throw new RuntimeException("Patches failed to apply.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package net.neoforged.neodev;

import net.neoforged.nfrtgradle.CreateMinecraftArtifacts;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.OutputFile;

import javax.inject.Inject;

abstract class CreateCleanArtifacts extends CreateMinecraftArtifacts {
@OutputFile
abstract RegularFileProperty getCleanClientJar();

@OutputFile
abstract RegularFileProperty getRawServerJar();

@OutputFile
abstract RegularFileProperty getCleanServerJar();

@OutputFile
abstract RegularFileProperty getCleanJoinedJar();

@OutputFile
abstract RegularFileProperty getMergedMappings();

@Inject
public CreateCleanArtifacts() {
getAdditionalResults().put("node.stripClient.output.output", getCleanClientJar().getAsFile());
getAdditionalResults().put("node.downloadServer.output.output", getRawServerJar().getAsFile());
getAdditionalResults().put("node.stripServer.output.output", getCleanServerJar().getAsFile());
getAdditionalResults().put("node.rename.output.output", getCleanJoinedJar().getAsFile());
getAdditionalResults().put("node.mergeMappings.output.output", getMergedMappings().getAsFile());

// TODO: does anyone care about this? they should be contained in the client mappings
//"--write-result", "node.downloadServerMappings.output.output:" + getServerMappings().get().getAsFile().getAbsolutePath()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package net.neoforged.neodev;

import org.gradle.api.GradleException;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.JavaExec;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputFile;

import javax.inject.Inject;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

abstract class GenerateBinaryPatches extends JavaExec {
@Inject
public GenerateBinaryPatches() {}

/**
* The jar file containing classes in the base state.
*/
@InputFile
abstract RegularFileProperty getCleanJar();

/**
* The jar file containing classes in the desired target state.
*/
@InputFile
abstract RegularFileProperty getPatchedJar();

@InputFile
abstract RegularFileProperty getMappings();

/**
* This directory of patch files for the Java sources is used as a hint to only diff class files that
* supposedly have changed. If it is not set, the tool will diff every .class file instead.
*/
@InputDirectory
@Optional
abstract DirectoryProperty getSourcePatchesFolder();

/**
* The location where the LZMA compressed binary patches are written to.
*/
@OutputFile
abstract RegularFileProperty getOutputFile();

@Override
public void exec() {
args("--clean", getCleanJar().get().getAsFile().getAbsolutePath());
args("--dirty", getPatchedJar().get().getAsFile().getAbsolutePath());
args("--srg", getMappings().get().getAsFile().getAbsolutePath());
if (getSourcePatchesFolder().isPresent()) {
args("--patches", getSourcePatchesFolder().get().getAsFile().getAbsolutePath());
}
args("--output", getOutputFile().get().getAsFile().getAbsolutePath());

var logFile = new File(getTemporaryDir(), "console.log");
try (var out = new BufferedOutputStream(new FileOutputStream(logFile))) {
getLogger().info("Logging binpatcher console output to {}", logFile.getAbsolutePath());
setStandardOutput(out);
super.exec();
} catch (IOException e) {
throw new GradleException("Failed to create binary patches.", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package net.neoforged.neodev;

import io.codechicken.diffpatch.cli.CliOperation;
import io.codechicken.diffpatch.cli.DiffOperation;
import io.codechicken.diffpatch.util.Input.MultiInput;
import io.codechicken.diffpatch.util.Output.MultiOutput;
import org.gradle.api.DefaultTask;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputFile;
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;

abstract class GenerateSourcePatches extends DefaultTask {
@InputFile
public abstract RegularFileProperty getOriginalJar();

@InputDirectory
@PathSensitive(PathSensitivity.RELATIVE)
public abstract DirectoryProperty getModifiedSources();

@OutputFile
public abstract RegularFileProperty getPatchesJar();

@Inject
public GenerateSourcePatches() {}

@TaskAction
public void generateSourcePatches() throws IOException {
var builder = DiffOperation.builder()
.logTo(getLogger()::lifecycle)
.baseInput(MultiInput.detectedArchive(getOriginalJar().get().getAsFile().toPath()))
.changedInput(MultiInput.folder(getModifiedSources().get().getAsFile().toPath()))
.patchesOutput(MultiOutput.detectedArchive(getPatchesJar().get().getAsFile().toPath()))
.autoHeader(true)
.level(io.codechicken.diffpatch.util.LogLevel.WARN)
.summary(false)
.aPrefix("a/")
.bPrefix("b/")
.lineEnding("\n");

CliOperation.Result<DiffOperation.DiffSummary> result = builder.build().operate();

int exit = result.exit;
if (exit != 0 && exit != 1) {
throw new RuntimeException("DiffPatch failed with exit code: " + exit);
}
}
}
23 changes: 23 additions & 0 deletions buildSrc/src/main/java/net/neoforged/neodev/NeoDevBasePlugin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package net.neoforged.neodev;

import net.neoforged.minecraftdependencies.MinecraftDependenciesPlugin;
import net.neoforged.nfrtgradle.CreateMinecraftArtifacts;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.tasks.Sync;

public class NeoDevBasePlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
// These plugins allow us to declare dependencies on Minecraft libraries needed to compile the official sources
project.getPlugins().apply(MinecraftDependenciesPlugin.class);

var createSources = NeoDevPlugin.configureMinecraftDecompilation(project);

project.getTasks().register("setup", Sync.class, task -> {
task.setDescription("Replaces the contents of the base project sources with the unpatched, decompiled Minecraft source code.");
task.from(project.zipTree(createSources.flatMap(CreateMinecraftArtifacts::getSourcesArtifact)));
task.into(project.file("src/main/java/"));
});
}
}
Loading

0 comments on commit a706b07

Please sign in to comment.