mirror of https://github.com/FabricMC/yarn.git
Move filament into the yarn repo. (#3296)
This will make further developments a lot easier.
This commit is contained in:
parent
18a44f9955
commit
1f985580c7
|
@ -1,2 +1,7 @@
|
|||
[*.{gradle,mapping,unpick}]
|
||||
indent_style = tab
|
||||
|
||||
[*.java]
|
||||
indent_style = tab
|
||||
ij_continuation_indent_size = 8
|
||||
ij_java_imports_layout = $*,|,java.**,|,javax.**,|,*,|,net.fabricmc.**
|
||||
|
|
|
@ -5,7 +5,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
java: [17-jdk, 18-jdk]
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
container:
|
||||
image: openjdk:${{ matrix.java }}
|
||||
options: --user root
|
||||
|
@ -20,3 +20,13 @@ jobs:
|
|||
with:
|
||||
name: Artifacts
|
||||
path: build/libs/
|
||||
|
||||
test-build-logic:
|
||||
runs-on: ubuntu-22.04
|
||||
container:
|
||||
image: openjdk:18-jdk
|
||||
options: --user root
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
- run: ./gradlew :filament:build
|
||||
|
|
|
@ -4,7 +4,7 @@ concurrency: ci-${{ github.ref }}
|
|||
jobs:
|
||||
publish:
|
||||
if: ${{ github.repository_owner == 'FabricMC' }}
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
container:
|
||||
image: openjdk:18-jdk
|
||||
options: --user root
|
||||
|
|
|
@ -7,7 +7,7 @@ on:
|
|||
jobs:
|
||||
update:
|
||||
if: ${{ github.event.label.name == 'update-base' }}
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: FabricMC/fabric-action-scripts@v1
|
||||
with:
|
||||
|
|
|
@ -24,7 +24,7 @@ plugins {
|
|||
id 'de.undercouch.download' version '4.1.2'
|
||||
id 'maven-publish'
|
||||
id "com.diffplug.spotless" version "6.4.2"
|
||||
id 'net.fabricmc.filament' version '0.3.0'
|
||||
id 'net.fabricmc.filament'
|
||||
}
|
||||
|
||||
def minecraft_version = "1.19.2"
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
plugins {
|
||||
id 'java-library'
|
||||
id 'java-gradle-plugin'
|
||||
id 'checkstyle'
|
||||
}
|
||||
|
||||
group = 'net.fabricmc'
|
||||
|
||||
def properties = new Properties()
|
||||
file('../gradle.properties').newInputStream().withCloseable {
|
||||
properties.load(it)
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name "Fabric Repository"
|
||||
url 'https://maven.fabricmc.net'
|
||||
}
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.ow2.asm:asm:${properties.asm_version}"
|
||||
implementation "org.ow2.asm:asm-tree:${properties.asm_version}"
|
||||
implementation "cuchaz:enigma:$properties.enigma_version"
|
||||
implementation "net.fabricmc.unpick:unpick:$properties.unpick_version"
|
||||
implementation "net.fabricmc.unpick:unpick-format-utils:$properties.unpick_version"
|
||||
implementation "net.fabricmc:tiny-mappings-parser:$properties.tiny_mappings_parser_version"
|
||||
|
||||
testImplementation platform("org.junit:junit-bom:$properties.junit_version")
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||
testImplementation "org.assertj:assertj-core:$properties.assertj_version"
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = "UTF-8"
|
||||
options.release = 17
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
configFile = file('checkstyle.xml')
|
||||
toolVersion = '10.3.3'
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
filament {
|
||||
id = 'net.fabricmc.filament'
|
||||
implementationClass = 'net.fabricmc.filament.FilamentGradlePlugin'
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
|
||||
<module name="Checker">
|
||||
<property name="charset" value="UTF-8"/>
|
||||
<property name="fileExtensions" value="java"/>
|
||||
<property name="localeLanguage" value="en"/>
|
||||
<property name="localeCountry" value="US"/>
|
||||
|
||||
<module name="NewlineAtEndOfFile"/>
|
||||
|
||||
<!-- disallow trailing whitespace -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="\s+$"/>
|
||||
<property name="message" value="trailing whitespace"/>
|
||||
</module>
|
||||
|
||||
<!-- note: RegexpMultiline shows nicer messages than Regexp, but has to be outside TreeWalker -->
|
||||
<!-- disallow multiple consecutive blank lines -->
|
||||
<module name="RegexpMultiline">
|
||||
<property name="format" value="\n[\t ]*\r?\n[\t ]*\r?\n"/>
|
||||
<property name="message" value="adjacent blank lines"/>
|
||||
</module>
|
||||
|
||||
<!-- disallow blank after { -->
|
||||
<module name="RegexpMultiline">
|
||||
<property name="format" value="\{[\t ]*\r?\n[\t ]*\r?\n"/>
|
||||
<property name="message" value="blank line after '{'"/>
|
||||
</module>
|
||||
|
||||
<!-- disallow blank before } -->
|
||||
<module name="RegexpMultiline">
|
||||
<property name="format" value="\n[\t ]*\r?\n[\t ]*\}"/>
|
||||
<property name="message" value="blank line before '}'"/>
|
||||
</module>
|
||||
|
||||
<!-- require blank before { in the same indentation level -->
|
||||
<module name="RegexpMultiline">
|
||||
<!-- the regex works as follows:
|
||||
It matches (=fails) for \n<indentation><something>\n<same indentation><control statement>[...]{\n
|
||||
while <something> is a single line comment, it'll look for a blank line one line earlier
|
||||
if <something> is a space, indicating a formatting error or ' */', it'll ignore the instance
|
||||
if <something> is a tab, indicating a continued line, it'll ignore the instance
|
||||
<control statement> is 'if', 'do', 'while', 'for', 'try' or nothing (instance initializer block)
|
||||
|
||||
- first \n: with positive lookbehind (?<=\n) to move the error marker to a more reasonable place
|
||||
- capture tabs for <indentation>, later referenced via \1
|
||||
- remaining preceding line as a non-comment (doesn't start with '/', '//', ' ' or '\t') or multiple lines where all but the first are a single line comment with the same indentation
|
||||
- new line
|
||||
- <indentation> as captured earlier
|
||||
- <control statement> as specified above
|
||||
- { before the next new line -->
|
||||
<property name="format" value="(?<=\n)([\t]+)(?:[^/\r\n \t][^\r\n]*|/[^/\r\n][^\r\n]*|[^/\r\n][^\r\n]*(\r?\n\1//[^\r\n]*)+)\r?\n\1(|(if|do|while|for|try)[^\r\n]+)\{[\t ]*\r?\n"/>
|
||||
<property name="message" value="missing blank line before block at same indentation level"/>
|
||||
</module>
|
||||
|
||||
<!-- require blank after } in the same indentation level -->
|
||||
<module name="RegexpMultiline">
|
||||
<!-- \n<indentation>}\n<same indentation><whatever unless newline, '}' or starting with cas(e) or def(ault)> -->
|
||||
<property name="format" value="(?<=\n)([\t]+)\}\r?\n\1(?:[^\r\n\}cd]|c[^\r\na]|ca[^\r\ns]|d[^\r\ne]|de[^\r\nf])"/>
|
||||
<property name="message" value="missing blank line after block at same indentation level"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<!-- Ensure all imports are ship shape -->
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="IllegalImport"/>
|
||||
<module name="RedundantImport"/>
|
||||
<module name="UnusedImports"/>
|
||||
|
||||
<module name="ImportOrder">
|
||||
<property name="groups" value="java,javax,*,net.minecraft,net.fabricmc"/>
|
||||
<property name="ordered" value="false"/><!-- the plugin orders alphabetically without considering separators.. -->
|
||||
<property name="separated" value="true"/>
|
||||
<property name="option" value="top"/>
|
||||
<property name="sortStaticImportsAlphabetically" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- Ensures braces are at the end of a line -->
|
||||
<module name="LeftCurly"/>
|
||||
<module name="RightCurly"/>
|
||||
|
||||
<!-- single line statements on one line, -->
|
||||
<module name="NeedBraces">
|
||||
<property name="tokens" value="LITERAL_IF,LITERAL_FOR,LITERAL_WHILE"/>
|
||||
<property name="allowSingleLineStatement" value="true"/>
|
||||
</module>
|
||||
<module name="NeedBraces">
|
||||
<property name="tokens" value="LITERAL_ELSE,LITERAL_DO"/>
|
||||
<property name="allowSingleLineStatement" value="false"/>
|
||||
</module>
|
||||
|
||||
<module name="EmptyLineSeparator">
|
||||
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
||||
<property name="allowMultipleEmptyLines" value="false"/>
|
||||
<!-- exclude METHOD_DEF and VARIABLE_DEF -->
|
||||
<property name="tokens" value="PACKAGE_DEF,IMPORT,STATIC_IMPORT,CLASS_DEF,INTERFACE_DEF,ENUM_DEF,STATIC_INIT,INSTANCE_INIT,CTOR_DEF"/>
|
||||
</module>
|
||||
|
||||
<module name="OperatorWrap"/>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="tokens" value="DOT,ELLIPSIS,AT"/>
|
||||
<property name="option" value="nl"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="tokens" value="COMMA,SEMI"/>
|
||||
<property name="option" value="eol"/>
|
||||
</module>
|
||||
|
||||
<module name="Indentation">
|
||||
<property name="basicOffset" value="8"/>
|
||||
<property name="caseIndent" value="0"/>
|
||||
<property name="throwsIndent" value="8"/>
|
||||
<property name="arrayInitIndent" value="8"/>
|
||||
<property name="lineWrappingIndentation" value="16"/>
|
||||
</module>
|
||||
|
||||
<module name="ParenPad"/>
|
||||
<module name="NoWhitespaceBefore"/>
|
||||
<module name="NoWhitespaceAfter">
|
||||
<!-- allow ARRAY_INIT -->
|
||||
<property name="tokens" value="AT,INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT,ARRAY_DECLARATOR,INDEX_OP"/>
|
||||
</module>
|
||||
<module name="WhitespaceAfter"/>
|
||||
<module name="WhitespaceAround">
|
||||
<!-- Allow PLUS, MINUS, MUL, DIV as they may be more readable without spaces in some cases -->
|
||||
<property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV_ASSIGN,DO_WHILE,EQUAL,GE,GT,LAMBDA,LAND,LCURLY,LE,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,LOR,LT,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS_ASSIGN,QUESTION,RCURLY,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND"/>
|
||||
</module>
|
||||
<module name="SingleSpaceSeparator"/>
|
||||
<module name="GenericWhitespace"/>
|
||||
<module name="CommentsIndentation"/>
|
||||
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<module name="DefaultComesLast">
|
||||
<property name="skipIfLastAndSharedWithCase" value="true"/>
|
||||
</module>
|
||||
<module name="SimplifyBooleanExpression"/>
|
||||
<module name="SimplifyBooleanReturn"/>
|
||||
<module name="StringLiteralEquality"/>
|
||||
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="RedundantModifier"/>
|
||||
|
||||
<module name="AnnotationLocation"/>
|
||||
<module name="MissingOverride"/>
|
||||
|
||||
<!-- By default this allows catch blocks with only comments -->
|
||||
<module name="EmptyCatchBlock"/>
|
||||
|
||||
<!-- Enforce tabs -->
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="^\t* ([^*]|\*[^ /])"/>
|
||||
<property name="message" value="non-tab indentation"/>
|
||||
</module>
|
||||
|
||||
<module name="OuterTypeFilename"/>
|
||||
|
||||
<!--<module name="InvalidJavadocPosition"/>-->
|
||||
<module name="JavadocParagraph"/>
|
||||
<module name="JavadocStyle"/>
|
||||
<module name="AtclauseOrder">
|
||||
<property name="tagOrder" value="@param,@return,@throws,@deprecated"/>
|
||||
</module>
|
||||
</module>
|
||||
</module>
|
|
@ -0,0 +1 @@
|
|||
rootProject.name = 'fabric-filament'
|
|
@ -0,0 +1,25 @@
|
|||
package net.fabricmc.filament;
|
||||
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
|
||||
import net.fabricmc.filament.task.CombineUnpickDefinitionsTask;
|
||||
import net.fabricmc.filament.task.GeneratePackageInfoMappingsTask;
|
||||
import net.fabricmc.filament.task.JavadocLintTask;
|
||||
import net.fabricmc.filament.task.RemapUnpickDefinitionsTask;
|
||||
|
||||
public final class FilamentGradlePlugin implements Plugin<Project> {
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
project.getTasks().register("generatePackageInfoMappings", GeneratePackageInfoMappingsTask.class);
|
||||
project.getTasks().register("javadocLint", JavadocLintTask.class);
|
||||
|
||||
var combineUnpickDefinitions = project.getTasks().register("combineUnpickDefinitions", CombineUnpickDefinitionsTask.class);
|
||||
project.getTasks().register("remapUnpickDefinitionsIntermediary", RemapUnpickDefinitionsTask.class, task -> {
|
||||
task.dependsOn(combineUnpickDefinitions);
|
||||
task.getInput().set(combineUnpickDefinitions.flatMap(CombineUnpickDefinitionsTask::getOutput));
|
||||
task.getSourceNamespace().set("named");
|
||||
task.getTargetNamespace().set("intermediary");
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package net.fabricmc.filament.task;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import daomephsta.unpick.constantmappers.datadriven.parser.v2.UnpickV2Reader;
|
||||
import daomephsta.unpick.constantmappers.datadriven.parser.v2.UnpickV2Writer;
|
||||
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.OutputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.workers.WorkAction;
|
||||
import org.gradle.workers.WorkParameters;
|
||||
import org.gradle.workers.WorkQueue;
|
||||
import org.gradle.workers.WorkerExecutor;
|
||||
|
||||
import net.fabricmc.filament.util.FileUtil;
|
||||
import net.fabricmc.filament.util.UnpickUtil;
|
||||
|
||||
public abstract class CombineUnpickDefinitionsTask extends DefaultTask {
|
||||
@InputDirectory
|
||||
public abstract DirectoryProperty getInput();
|
||||
|
||||
@OutputFile
|
||||
public abstract RegularFileProperty getOutput();
|
||||
|
||||
@Inject
|
||||
protected abstract WorkerExecutor getWorkerExecutor();
|
||||
|
||||
@TaskAction
|
||||
public void run() {
|
||||
WorkQueue workQueue = getWorkerExecutor().noIsolation();
|
||||
workQueue.submit(CombineAction.class, parameters -> {
|
||||
parameters.getInput().set(getInput());
|
||||
parameters.getOutput().set(getOutput());
|
||||
});
|
||||
}
|
||||
|
||||
public interface CombineParameters extends WorkParameters {
|
||||
@InputDirectory
|
||||
DirectoryProperty getInput();
|
||||
|
||||
@OutputFile
|
||||
RegularFileProperty getOutput();
|
||||
}
|
||||
|
||||
public abstract static class CombineAction implements WorkAction<CombineParameters> {
|
||||
@Inject
|
||||
public CombineAction() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
File output = getParameters().getOutput().getAsFile().get();
|
||||
FileUtil.deleteIfExists(output);
|
||||
|
||||
UnpickV2Writer writer = new UnpickV2Writer();
|
||||
|
||||
// Sort inputs to get reproducible outputs (also for testing)
|
||||
List<File> files = new ArrayList<>(getParameters().getInput().getAsFileTree().getFiles());
|
||||
files.sort(Comparator.comparing(File::getName));
|
||||
|
||||
for (File file : files) {
|
||||
if (!file.getName().endsWith(".unpick")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try (UnpickV2Reader reader = new UnpickV2Reader(new FileInputStream(file))) {
|
||||
reader.accept(writer);
|
||||
}
|
||||
}
|
||||
|
||||
FileUtil.write(output, UnpickUtil.getLfOutput(writer));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package net.fabricmc.filament.task;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
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.InputFile;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import net.fabricmc.filament.util.FileUtil;
|
||||
|
||||
public class GeneratePackageInfoMappingsTask extends DefaultTask {
|
||||
private final RegularFileProperty inputJar = getProject().getObjects().fileProperty();
|
||||
private final Property<String> packageName = getProject().getObjects().property(String.class);
|
||||
private final DirectoryProperty outputDir = getProject().getObjects().directoryProperty();
|
||||
|
||||
@InputFile
|
||||
public RegularFileProperty getInputJar() {
|
||||
return inputJar;
|
||||
}
|
||||
|
||||
@Input
|
||||
public Property<String> getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
@OutputDirectory
|
||||
public DirectoryProperty getOutputDir() {
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void run() throws IOException {
|
||||
getProject().getLogger().lifecycle("Scanning {} for package-info classes", inputJar.get().getAsFile());
|
||||
|
||||
FileUtil.deleteDirectory(outputDir.get().getAsFile());
|
||||
|
||||
try (ZipFile zipFile = new ZipFile(inputJar.get().getAsFile())) {
|
||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
|
||||
if (entry.getName().endsWith(".class")) {
|
||||
try (InputStream is = zipFile.getInputStream(entry)) {
|
||||
processEntry(entry.getName(), is);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processEntry(String name, InputStream inputStream) throws IOException {
|
||||
name = name.replace(".class", "");
|
||||
|
||||
if (name.contains("$")) {
|
||||
// Dont care about inner classes
|
||||
return;
|
||||
}
|
||||
|
||||
ClassReader classReader = new ClassReader(inputStream);
|
||||
ClassNode classNode = new ClassNode();
|
||||
classReader.accept(classNode, 0);
|
||||
|
||||
if (classNode.access != (Opcodes.ACC_ABSTRACT | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_INTERFACE)) {
|
||||
// We only care about abstract synthetic interfaces, hopefully this is specific enough
|
||||
return;
|
||||
}
|
||||
|
||||
if (classNode.methods.size() > 0 || classNode.fields.size() > 0 || classNode.interfaces.size() > 0) {
|
||||
// Nope cannot be a package-info
|
||||
return;
|
||||
}
|
||||
|
||||
generateMapping(name);
|
||||
}
|
||||
|
||||
private void generateMapping(String name) throws IOException {
|
||||
String inputName = name.substring(name.lastIndexOf("/") + 1);
|
||||
String className = "PackageInfo" + name.substring(name.lastIndexOf("_") + 1);
|
||||
String fullName = packageName.get() + className;
|
||||
File mappingsFile = new File(outputDir.get().getAsFile(), className + ".mapping");
|
||||
|
||||
mappingsFile.getParentFile().mkdirs();
|
||||
|
||||
try (PrintWriter writer = new PrintWriter(new FileWriter(mappingsFile))) {
|
||||
writer.printf("CLASS net/minecraft/%s %s", inputName, fullName);
|
||||
writer.print('\n'); // println is platform-dependent and may produce CRLF.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
package net.fabricmc.filament.task;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import cuchaz.enigma.ProgressListener;
|
||||
import cuchaz.enigma.translation.mapping.EntryMapping;
|
||||
import cuchaz.enigma.translation.mapping.serde.MappingParseException;
|
||||
import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader;
|
||||
import cuchaz.enigma.translation.mapping.tree.EntryTree;
|
||||
import cuchaz.enigma.translation.representation.entry.Entry;
|
||||
import cuchaz.enigma.translation.representation.entry.LocalVariableEntry;
|
||||
import cuchaz.enigma.translation.representation.entry.MethodEntry;
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.file.ConfigurableFileCollection;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.file.FileType;
|
||||
import org.gradle.api.logging.Logger;
|
||||
import org.gradle.api.logging.Logging;
|
||||
import org.gradle.api.tasks.InputDirectory;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.work.ChangeType;
|
||||
import org.gradle.work.FileChange;
|
||||
import org.gradle.work.Incremental;
|
||||
import org.gradle.work.InputChanges;
|
||||
import org.gradle.workers.WorkAction;
|
||||
import org.gradle.workers.WorkParameters;
|
||||
import org.gradle.workers.WorkQueue;
|
||||
import org.gradle.workers.WorkerExecutor;
|
||||
|
||||
import net.fabricmc.filament.util.FileUtil;
|
||||
|
||||
public abstract class JavadocLintTask extends DefaultTask {
|
||||
private static final Pattern PARAM_DOC_LINE = Pattern.compile("^@param\\s+[^<].*$");
|
||||
private final DirectoryProperty mappingDirectory = getProject().getObjects().directoryProperty();
|
||||
|
||||
@Incremental
|
||||
@InputDirectory
|
||||
public DirectoryProperty getMappingDirectory() {
|
||||
return mappingDirectory;
|
||||
}
|
||||
|
||||
public JavadocLintTask() {
|
||||
// Ignore outputs for up-to-date checks as there aren't any (so only inputs are checked)
|
||||
getOutputs().upToDateWhen(task -> true);
|
||||
}
|
||||
|
||||
@Inject
|
||||
protected abstract WorkerExecutor getWorkerExecutor();
|
||||
|
||||
@TaskAction
|
||||
public void run(InputChanges changes) {
|
||||
WorkQueue workQueue = getWorkerExecutor().noIsolation();
|
||||
|
||||
workQueue.submit(LintAction.class, parameters -> {
|
||||
for (FileChange change : changes.getFileChanges(mappingDirectory)) {
|
||||
if (change.getChangeType() != ChangeType.REMOVED && change.getFileType() == FileType.FILE) {
|
||||
parameters.getMappingFiles().from(change.getFile());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isRegularMethodParameter(String line) {
|
||||
return PARAM_DOC_LINE.matcher(line).matches();
|
||||
}
|
||||
|
||||
private static String getFirstWord(String str) {
|
||||
int i = str.indexOf(' ');
|
||||
return i != -1 ? str.substring(0, i) : str;
|
||||
}
|
||||
|
||||
private static String getFullName(EntryTree<EntryMapping> mappings, Entry<?> entry) {
|
||||
String name = mappings.get(entry).targetName();
|
||||
|
||||
if (entry instanceof MethodEntry method) {
|
||||
name += method.getDesc().toString();
|
||||
}
|
||||
|
||||
if (entry.getParent() != null) {
|
||||
name = getFullName(mappings, entry.getParent()) + '.' + name;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public interface LintParameters extends WorkParameters {
|
||||
ConfigurableFileCollection getMappingFiles();
|
||||
}
|
||||
|
||||
public abstract static class LintAction implements WorkAction<LintParameters> {
|
||||
private static final Logger LOGGER = Logging.getLogger(LintAction.class);
|
||||
|
||||
@Inject
|
||||
public LintAction() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
var files = FileUtil.toPaths(getParameters().getMappingFiles().getFiles()).toArray(new Path[0]);
|
||||
EntryTree<EntryMapping> mappings = EnigmaMappingsReader.readFiles(ProgressListener.none(), files);
|
||||
List<String> errors = new ArrayList<>();
|
||||
|
||||
mappings.getAllEntries().parallel().forEach(entry -> {
|
||||
EntryMapping mapping = mappings.get(entry);
|
||||
String javadoc = mapping.javadoc();
|
||||
|
||||
if (javadoc != null && !javadoc.isEmpty()) {
|
||||
List<String> localErrors = new ArrayList<>();
|
||||
|
||||
if (entry instanceof LocalVariableEntry && ((LocalVariableEntry) entry).isArgument()) {
|
||||
if (javadoc.endsWith(".")) {
|
||||
localErrors.add("parameter javadoc ends with '.'");
|
||||
}
|
||||
|
||||
if (Character.isUpperCase(javadoc.charAt(0))) {
|
||||
String word = getFirstWord(javadoc);
|
||||
|
||||
// ignore single-letter "words" (like X or Z)
|
||||
if (word.length() > 1) {
|
||||
localErrors.add("parameter javadoc starts with uppercase word '" + word + "'");
|
||||
}
|
||||
}
|
||||
} else if (entry instanceof MethodEntry) {
|
||||
if (javadoc.lines().anyMatch(JavadocLintTask::isRegularMethodParameter)) {
|
||||
localErrors.add("method javadoc contains parameter docs, which should be on the parameter itself");
|
||||
}
|
||||
}
|
||||
|
||||
// new rules can be added here in the future
|
||||
|
||||
if (!localErrors.isEmpty()) {
|
||||
String name = getFullName(mappings, entry);
|
||||
|
||||
for (String error : localErrors) {
|
||||
errors.add(name + ": " + error);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!errors.isEmpty()) {
|
||||
for (String error : errors) {
|
||||
LOGGER.error("lint: {}", error);
|
||||
}
|
||||
|
||||
throw new GradleException("Found " + errors.size() + " javadoc format errors! See the log for details.");
|
||||
}
|
||||
} catch (IOException | MappingParseException e) {
|
||||
throw new GradleException("Could not read and parse mappings", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
package net.fabricmc.filament.task;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import daomephsta.unpick.constantmappers.datadriven.parser.FieldKey;
|
||||
import daomephsta.unpick.constantmappers.datadriven.parser.MethodKey;
|
||||
import daomephsta.unpick.constantmappers.datadriven.parser.v2.UnpickV2Reader;
|
||||
import daomephsta.unpick.constantmappers.datadriven.parser.v2.UnpickV2Remapper;
|
||||
import daomephsta.unpick.constantmappers.datadriven.parser.v2.UnpickV2Writer;
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.OutputFile;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.workers.WorkAction;
|
||||
import org.gradle.workers.WorkParameters;
|
||||
import org.gradle.workers.WorkQueue;
|
||||
import org.gradle.workers.WorkerExecutor;
|
||||
|
||||
import net.fabricmc.filament.util.FileUtil;
|
||||
import net.fabricmc.filament.util.UnpickUtil;
|
||||
import net.fabricmc.mapping.tree.ClassDef;
|
||||
import net.fabricmc.mapping.tree.FieldDef;
|
||||
import net.fabricmc.mapping.tree.MethodDef;
|
||||
import net.fabricmc.mapping.tree.TinyMappingFactory;
|
||||
import net.fabricmc.mapping.tree.TinyTree;
|
||||
|
||||
public abstract class RemapUnpickDefinitionsTask extends DefaultTask {
|
||||
@InputFile
|
||||
public abstract RegularFileProperty getInput();
|
||||
|
||||
@InputFile
|
||||
public abstract RegularFileProperty getMappings();
|
||||
|
||||
@Input
|
||||
public abstract Property<String> getSourceNamespace();
|
||||
|
||||
@Input
|
||||
public abstract Property<String> getTargetNamespace();
|
||||
|
||||
@OutputFile
|
||||
public abstract RegularFileProperty getOutput();
|
||||
|
||||
@Inject
|
||||
protected abstract WorkerExecutor getWorkerExecutor();
|
||||
|
||||
@TaskAction
|
||||
public void run() {
|
||||
WorkQueue workQueue = getWorkerExecutor().noIsolation();
|
||||
workQueue.submit(RemapAction.class, parameters -> {
|
||||
parameters.getInput().set(getInput());
|
||||
parameters.getMappings().set(getMappings());
|
||||
parameters.getSourceNamespace().set(getSourceNamespace());
|
||||
parameters.getTargetNamespace().set(getTargetNamespace());
|
||||
parameters.getOutput().set(getOutput());
|
||||
});
|
||||
}
|
||||
|
||||
public interface RemapParameters extends WorkParameters {
|
||||
@InputFile
|
||||
RegularFileProperty getInput();
|
||||
|
||||
@InputFile
|
||||
RegularFileProperty getMappings();
|
||||
|
||||
@Input
|
||||
Property<String> getSourceNamespace();
|
||||
|
||||
@Input
|
||||
Property<String> getTargetNamespace();
|
||||
|
||||
@OutputFile
|
||||
RegularFileProperty getOutput();
|
||||
}
|
||||
|
||||
public abstract static class RemapAction implements WorkAction<RemapParameters> {
|
||||
@Inject
|
||||
public RemapAction() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
File output = getParameters().getOutput().getAsFile().get();
|
||||
FileUtil.deleteIfExists(output);
|
||||
|
||||
Map<String, String> classMappings = new HashMap<>();
|
||||
Map<MethodKey, String> methodMappings = new HashMap<>();
|
||||
Map<FieldKey, String> fieldMappings = new HashMap<>();
|
||||
String fromM = getParameters().getSourceNamespace().get();
|
||||
String toM = getParameters().getTargetNamespace().get();
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(getParameters().getMappings().getAsFile().get()))) {
|
||||
TinyTree tinyTree = TinyMappingFactory.loadWithDetection(reader);
|
||||
|
||||
for (ClassDef classDef : tinyTree.getClasses()) {
|
||||
classMappings.put(classDef.getName(fromM), classDef.getName(toM));
|
||||
|
||||
for (MethodDef methodDef : classDef.getMethods()) {
|
||||
methodMappings.put(
|
||||
new MethodKey(classDef.getName(fromM), methodDef.getName(fromM), methodDef.getDescriptor(fromM)),
|
||||
methodDef.getName(toM)
|
||||
);
|
||||
}
|
||||
|
||||
for (FieldDef fieldDef : classDef.getFields()) {
|
||||
fieldMappings.put(
|
||||
new FieldKey(classDef.getName(fromM), fieldDef.getName(fromM)),
|
||||
fieldDef.getName(toM)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try (UnpickV2Reader reader = new UnpickV2Reader(new FileInputStream(getParameters().getInput().getAsFile().get()))) {
|
||||
UnpickV2Writer writer = new UnpickV2Writer();
|
||||
reader.accept(new UnpickV2Remapper(classMappings, methodMappings, fieldMappings, writer));
|
||||
FileUtil.write(output, UnpickUtil.getLfOutput(writer));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package net.fabricmc.filament.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public final class FileUtil {
|
||||
private FileUtil() {
|
||||
}
|
||||
|
||||
public static Set<Path> toPaths(Iterable<File> files) {
|
||||
Set<Path> set = files instanceof Collection<File> c ? new HashSet<>(c.size()) : new HashSet<>();
|
||||
|
||||
for (File file : files) {
|
||||
set.add(file.toPath());
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
public static void deleteDirectory(File directory) throws IOException {
|
||||
for (File child : directory.listFiles()) {
|
||||
if (child.isDirectory()) {
|
||||
deleteDirectory(child);
|
||||
} else {
|
||||
if (!child.delete()) {
|
||||
throw new IOException("Could not delete file " + child.getName() + " in directory " + directory.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!directory.delete()) {
|
||||
throw new IOException("Could not delete directory " + directory.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteIfExists(File file) throws IOException {
|
||||
Files.deleteIfExists(file.toPath());
|
||||
}
|
||||
|
||||
public static void write(File file, String content) throws IOException {
|
||||
Files.writeString(file.toPath(), content, StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package net.fabricmc.filament.util;
|
||||
|
||||
import daomephsta.unpick.constantmappers.datadriven.parser.v2.UnpickV2Writer;
|
||||
|
||||
public final class UnpickUtil {
|
||||
private UnpickUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the output of the writer with all {@linkplain System#lineSeparator() system line separators}
|
||||
* replaced with {@code \n}.
|
||||
*
|
||||
* @param writer the writer
|
||||
* @return the output using LF as the line separator
|
||||
*/
|
||||
public static String getLfOutput(UnpickV2Writer writer) {
|
||||
return writer.getOutput().replace(System.lineSeparator(), "\n");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
The tests for Filament are mostly Gradle projects that are automatically tested using JUnit 5.
|
||||
|
||||
## Structure
|
||||
|
||||
### `/projects/sharedData`
|
||||
|
||||
Data files shared between tests. This includes large files like a build of Yarn mappings.
|
||||
|
||||
### `/projects/javadocLint`
|
||||
|
||||
Test project for the `javadocLint` task (`JavadocLintTask`).
|
||||
|
||||
### `/projects/unpickDef`
|
||||
|
||||
Test project for the `combineUnpickDefinitions` and `remapUnpickDefinitionsIntermediary` tasks
|
||||
(`CombineUnpickDefinitionsTask` and `RemapUnpickDefinitionsTask`).
|
|
@ -0,0 +1,60 @@
|
|||
package net.fabricmc.filament.test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import net.fabricmc.filament.util.FileUtil;
|
||||
|
||||
class FileUtilTest {
|
||||
@TempDir
|
||||
protected File directory;
|
||||
|
||||
@Test
|
||||
void deleteIfExists() throws IOException {
|
||||
File file = new File(directory, "some-file.txt");
|
||||
file.createNewFile();
|
||||
|
||||
FileUtil.deleteIfExists(file);
|
||||
assertThat(file).doesNotExist();
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteIfExistsMissing() throws IOException {
|
||||
File file = new File(directory, "missing-file.txt");
|
||||
|
||||
FileUtil.deleteIfExists(file);
|
||||
assertThat(file).doesNotExist();
|
||||
}
|
||||
|
||||
@Test
|
||||
void write() throws IOException {
|
||||
File file = new File(directory, "some-file.txt");
|
||||
|
||||
FileUtil.write(file, "Hello, world!");
|
||||
assertThat(file).hasContent("Hello, world!");
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteDirectory() throws IOException {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
File file = new File(directory, "file-" + i + ".txt");
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
File subdirectory = new File(directory, "subdirectory");
|
||||
subdirectory.mkdir();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
File file = new File(subdirectory, "file-" + i + ".txt");
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
FileUtil.deleteDirectory(directory);
|
||||
assertThat(directory).doesNotExist();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package net.fabricmc.filament.test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.gradle.testkit.runner.BuildResult;
|
||||
import org.gradle.testkit.runner.GradleRunner;
|
||||
import org.gradle.testkit.runner.TaskOutcome;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class JavadocLintTest extends ProjectTest {
|
||||
private BuildResult runGradleBuild(boolean shouldSucceed) {
|
||||
GradleRunner runner = GradleRunner.create()
|
||||
.withPluginClasspath()
|
||||
.withProjectDir(projectDirectory)
|
||||
.withArguments("javadocLint");
|
||||
|
||||
return shouldSucceed ? runner.build() : runner.buildAndFail();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void paramInMethod() {
|
||||
setupProject("javadocLint", "mappings/ParamInMethod.mapping");
|
||||
BuildResult result = runGradleBuild(false);
|
||||
|
||||
assertThat(result.task(":javadocLint").getOutcome()).isEqualTo(TaskOutcome.FAILED);
|
||||
assertThat(result.getOutput()).contains("method javadoc contains parameter docs");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void periodInParam() {
|
||||
setupProject("javadocLint", "mappings/ParamPeriod.mapping");
|
||||
BuildResult result = runGradleBuild(false);
|
||||
|
||||
assertThat(result.task(":javadocLint").getOutcome()).isEqualTo(TaskOutcome.FAILED);
|
||||
assertThat(result.getOutput()).contains("parameter javadoc ends with '.'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uppercaseParam() {
|
||||
setupProject("javadocLint", "mappings/UppercaseParam.mapping");
|
||||
BuildResult result = runGradleBuild(false);
|
||||
|
||||
assertThat(result.task(":javadocLint").getOutcome()).isEqualTo(TaskOutcome.FAILED);
|
||||
assertThat(result.getOutput()).contains("parameter javadoc starts with uppercase word 'The'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleErrors() {
|
||||
setupProject(
|
||||
"javadocLint",
|
||||
"mappings/ParamInMethod.mapping",
|
||||
"mappings/ParamPeriod.mapping",
|
||||
"mappings/UppercaseParam.mapping"
|
||||
);
|
||||
BuildResult result = runGradleBuild(false);
|
||||
|
||||
assertThat(result.task(":javadocLint").getOutcome()).isEqualTo(TaskOutcome.FAILED);
|
||||
assertThat(result.getOutput()).contains("Found 3 javadoc format errors");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successful() {
|
||||
setupProject("javadocLint", "mappings/Successful.mapping");
|
||||
BuildResult result = runGradleBuild(true);
|
||||
|
||||
assertThat(result.task(":javadocLint").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package net.fabricmc.filament.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
abstract class ProjectTest {
|
||||
@TempDir
|
||||
protected File projectDirectory;
|
||||
|
||||
protected final void setupProject(String name, String... extraFiles) {
|
||||
try {
|
||||
copyProjectFile(name, "build.gradle");
|
||||
copyProjectFile(name, "settings.gradle");
|
||||
|
||||
for (String file : extraFiles) {
|
||||
copyProjectFile(name, file);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Could not set up test for project " + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected final void copyYarnV2Data(String fileName) {
|
||||
try {
|
||||
copyProjectFile("sharedData", "yarn-mappings-v2.tiny", fileName);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Could not copy Yarn mapping data to " + fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected final InputStream getProjectFile(String projectName, String file) {
|
||||
return ProjectTest.class.getResourceAsStream("/projects/" + projectName + '/' + file);
|
||||
}
|
||||
|
||||
protected final String getProjectFileText(String projectName, String file) throws IOException {
|
||||
try (InputStream in = getProjectFile(projectName, file)) {
|
||||
return new String(in.readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyProjectFile(String projectName, String file) throws IOException {
|
||||
copyProjectFile(projectName, file, file);
|
||||
}
|
||||
|
||||
private void copyProjectFile(String projectName, String from, String to) throws IOException {
|
||||
try (InputStream in = getProjectFile(projectName, from)) {
|
||||
Path target = projectDirectory.toPath().resolve(to);
|
||||
Files.createDirectories(target.getParent());
|
||||
Files.copy(in, target);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package net.fabricmc.filament.test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.gradle.testkit.runner.BuildResult;
|
||||
import org.gradle.testkit.runner.GradleRunner;
|
||||
import org.gradle.testkit.runner.TaskOutcome;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class UnpickDefinitionsTest extends ProjectTest {
|
||||
@Test
|
||||
void remapUnpickDefinitionsIntermediary() throws IOException {
|
||||
setupProject(
|
||||
"unpickDef",
|
||||
"unpick-definitions/screen_handler_slot_ids.unpick",
|
||||
"unpick-definitions/set_block_state_flags.unpick"
|
||||
);
|
||||
copyYarnV2Data("yarn-mappings-v2.tiny");
|
||||
|
||||
BuildResult result = GradleRunner.create()
|
||||
.withPluginClasspath()
|
||||
.withProjectDir(projectDirectory)
|
||||
.withArguments("remapUnpickDefinitionsIntermediary")
|
||||
.build();
|
||||
|
||||
assertThat(result.task(":combineUnpickDefinitions").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(result.task(":remapUnpickDefinitionsIntermediary").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(new File(projectDirectory, "combined_definitions.unpick")).exists().hasContent(getProjectFileText("unpickDef", "expected_named.unpick"));
|
||||
assertThat(new File(projectDirectory, "intermediary_definitions.unpick")).exists().hasContent(getProjectFileText("unpickDef", "expected_intermediary.unpick"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
plugins {
|
||||
id 'net.fabricmc.filament'
|
||||
}
|
||||
|
||||
javadocLint {
|
||||
mappingDirectory = file('mappings')
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
CLASS a com/example/ParamInMethod
|
||||
METHOD a something (Ljava/lang/String;)V
|
||||
COMMENT @param name the name
|
||||
ARG 1 name
|
|
@ -0,0 +1,4 @@
|
|||
CLASS b com/example/ParamPeriod
|
||||
METHOD a something (Ljava/lang/String;)V
|
||||
ARG 1 name
|
||||
COMMENT the name.
|
|
@ -0,0 +1,6 @@
|
|||
CLASS d com/example/Successful
|
||||
METHOD a something (Ljava/lang/String;)V
|
||||
COMMENT This is a method that does something.
|
||||
COMMENT @param <T> an unused type
|
||||
ARG 1 name
|
||||
COMMENT the name
|
|
@ -0,0 +1,4 @@
|
|||
CLASS c com/example/UppercaseParam
|
||||
METHOD a something (Ljava/lang/String;)V
|
||||
ARG 1 name
|
||||
COMMENT The name
|
|
@ -0,0 +1,10 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "FabricMC"
|
||||
url = "https://maven.fabricmc.net"
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,13 @@
|
|||
plugins {
|
||||
id 'net.fabricmc.filament'
|
||||
}
|
||||
|
||||
combineUnpickDefinitions {
|
||||
input = file('unpick-definitions')
|
||||
output = file('combined_definitions.unpick')
|
||||
}
|
||||
|
||||
remapUnpickDefinitionsIntermediary {
|
||||
output = file('intermediary_definitions.unpick')
|
||||
mappings = file('yarn-mappings-v2.tiny')
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
v2
|
||||
constant screen_handler_slot_ids net/minecraft/class_1703 field_30730
|
||||
target_method net/minecraft/class_1703 method_30010 (IILnet/minecraft/class_1713;Lnet/minecraft/class_1657;)V
|
||||
param 0 screen_handler_slot_ids
|
||||
flag set_block_state_flags net/minecraft/class_2248 field_31036
|
||||
flag set_block_state_flags net/minecraft/class_2248 field_31027
|
||||
flag set_block_state_flags net/minecraft/class_2248 field_31028
|
||||
flag set_block_state_flags net/minecraft/class_2248 field_31029
|
||||
flag set_block_state_flags net/minecraft/class_2248 field_31030
|
||||
flag set_block_state_flags net/minecraft/class_2248 field_31031
|
||||
flag set_block_state_flags net/minecraft/class_2248 field_31032
|
||||
flag set_block_state_flags net/minecraft/class_2248 field_31033
|
||||
flag set_block_state_flags net/minecraft/class_2248 field_31034
|
||||
target_method net/minecraft/class_1945 method_8652 (Lnet/minecraft/class_2338;Lnet/minecraft/class_2680;I)Z
|
||||
param 2 set_block_state_flags
|
|
@ -0,0 +1,15 @@
|
|||
v2
|
||||
constant screen_handler_slot_ids net/minecraft/screen/ScreenHandler EMPTY_SPACE_SLOT_INDEX
|
||||
target_method net/minecraft/screen/ScreenHandler internalOnSlotClick (IILnet/minecraft/screen/slot/SlotActionType;Lnet/minecraft/entity/player/PlayerEntity;)V
|
||||
param 0 screen_handler_slot_ids
|
||||
flag set_block_state_flags net/minecraft/block/Block NOTIFY_ALL
|
||||
flag set_block_state_flags net/minecraft/block/Block NOTIFY_NEIGHBORS
|
||||
flag set_block_state_flags net/minecraft/block/Block NOTIFY_LISTENERS
|
||||
flag set_block_state_flags net/minecraft/block/Block NO_REDRAW
|
||||
flag set_block_state_flags net/minecraft/block/Block REDRAW_ON_MAIN_THREAD
|
||||
flag set_block_state_flags net/minecraft/block/Block FORCE_STATE
|
||||
flag set_block_state_flags net/minecraft/block/Block SKIP_DROPS
|
||||
flag set_block_state_flags net/minecraft/block/Block MOVED
|
||||
flag set_block_state_flags net/minecraft/block/Block SKIP_LIGHTING_UPDATES
|
||||
target_method net/minecraft/world/ModifiableWorld setBlockState (Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z
|
||||
param 2 set_block_state_flags
|
|
@ -0,0 +1,10 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "FabricMC"
|
||||
url = "https://maven.fabricmc.net"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
v2
|
||||
|
||||
constant screen_handler_slot_ids net/minecraft/screen/ScreenHandler EMPTY_SPACE_SLOT_INDEX
|
||||
|
||||
target_method net/minecraft/screen/ScreenHandler internalOnSlotClick (IILnet/minecraft/screen/slot/SlotActionType;Lnet/minecraft/entity/player/PlayerEntity;)V
|
||||
param 0 screen_handler_slot_ids
|
|
@ -0,0 +1,14 @@
|
|||
v2
|
||||
|
||||
flag set_block_state_flags net/minecraft/block/Block NOTIFY_ALL
|
||||
flag set_block_state_flags net/minecraft/block/Block NOTIFY_NEIGHBORS
|
||||
flag set_block_state_flags net/minecraft/block/Block NOTIFY_LISTENERS
|
||||
flag set_block_state_flags net/minecraft/block/Block NO_REDRAW
|
||||
flag set_block_state_flags net/minecraft/block/Block REDRAW_ON_MAIN_THREAD
|
||||
flag set_block_state_flags net/minecraft/block/Block FORCE_STATE
|
||||
flag set_block_state_flags net/minecraft/block/Block SKIP_DROPS
|
||||
flag set_block_state_flags net/minecraft/block/Block MOVED
|
||||
flag set_block_state_flags net/minecraft/block/Block SKIP_LIGHTING_UPDATES
|
||||
|
||||
target_method net/minecraft/world/ModifiableWorld setBlockState (Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z
|
||||
param 2 set_block_state_flags
|
|
@ -13,3 +13,8 @@ asm_version=9.3
|
|||
fabric_loader_version=0.13.3
|
||||
jetbrains_annotations_version=23.0.0
|
||||
mappingpoet_version=0.3.0
|
||||
|
||||
# Build logic
|
||||
tiny_mappings_parser_version=0.3.0+build.17
|
||||
junit_version=5.7.1
|
||||
assertj_version=3.19.0
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -14,4 +14,6 @@ if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) {
|
|||
throw new UnsupportedOperationException("Yarn's buildscript requires Java 17 or higher.")
|
||||
}
|
||||
|
||||
rootProject.name = "yarn"
|
||||
rootProject.name = "yarn"
|
||||
|
||||
includeBuild 'filament'
|
Loading…
Reference in New Issue