From 48e01498042cf5ff6a4503feea0ea157d6f92cbf Mon Sep 17 00:00:00 2001 From: Cat Core Date: Wed, 8 Nov 2023 17:49:56 +0100 Subject: [PATCH 01/10] :sparkles: Add loom's Interface Injection support for Fabric providers --- .../InterfaceInjectionMinecraftTransformer.kt | 84 ++++++++++++++++++ .../fabric/FabricLikeMinecraftTransformer.kt | 4 + .../fabric/FabricMinecraftTransformer.kt | 86 +++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/ii/InterfaceInjectionMinecraftTransformer.kt diff --git a/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/ii/InterfaceInjectionMinecraftTransformer.kt b/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/ii/InterfaceInjectionMinecraftTransformer.kt new file mode 100644 index 00000000..6790239c --- /dev/null +++ b/src/mapping/kotlin/xyz/wagyourtail/unimined/internal/mapping/ii/InterfaceInjectionMinecraftTransformer.kt @@ -0,0 +1,84 @@ +package xyz.wagyourtail.unimined.internal.mapping.ii + +import org.gradle.api.logging.Logger +import org.objectweb.asm.ClassReader +import org.objectweb.asm.ClassWriter +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.ClassNode +import xyz.wagyourtail.unimined.util.openZipFileSystem +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.StandardCopyOption +import java.nio.file.StandardOpenOption +import kotlin.io.path.inputStream + +object InterfaceInjectionMinecraftTransformer { + fun transform( + injections: Map>, + baseMinecraft: Path, + output: Path, + logger: Logger + ): Boolean { + if (injections.isNotEmpty()) { + Files.copy(baseMinecraft, output, StandardCopyOption.REPLACE_EXISTING) + output.openZipFileSystem(mapOf("mutable" to true)).use { fs -> + logger.debug("Transforming $output with ${injections.values.sumOf { it.size }} interface injections") + + for (target in injections.keys) { + try { + val targetClass = "/" + target.replace(".", "/") + ".class" + val targetPath = fs.getPath(targetClass) + logger.debug("Transforming $targetPath") + if (Files.exists(targetPath)) { + val reader = ClassReader(targetPath.inputStream()) + val writer = ClassWriter(0) + + val node = ClassNode(Opcodes.ASM9) + reader.accept(node, 0) + + if (node.interfaces == null) { + node.interfaces = arrayListOf(); + } + + for (injected in injections[target]!!) { + if (!node.interfaces.contains(injected)) node.interfaces.add(injected) + } + + if (node.signature != null) { + val resultingSignature = StringBuilder(node.signature) + + for (injected in injections[target]!!) { + val computedSignature = "L" + injected.replace(".", "/") + ";" + + if (!resultingSignature.contains(computedSignature)) resultingSignature.append(computedSignature) + } + + node.signature = resultingSignature.toString() + } + + node.accept(writer); + Files.write( + targetPath, + writer.toByteArray(), + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING + ) + } else { + logger.warn("Could not find class $targetClass in $output") + } + } catch (e: Exception) { + logger.warn( + "An error occurred while transforming $target with interface injection in $output", + e + ) + } + } + } + + + return true + } + + return false + } +} \ No newline at end of file diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt index 24382adb..1f0db242 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt @@ -415,4 +415,8 @@ abstract class FabricLikeMinecraftTransformer( // fabric provides its own asm, exclude asm-all from vanilla minecraftLibraries return !library.name.startsWith("org.ow2.asm:asm-all") } + + fun getModJsonPath(): File? { + return provider.sourceSet.resources.first { it.name.equals(modJsonName) } + } } \ No newline at end of file diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt index e96e25fc..c28880c0 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt @@ -2,12 +2,20 @@ package xyz.wagyourtail.unimined.internal.minecraft.patch.fabric import com.google.gson.JsonArray import com.google.gson.JsonObject +import com.google.gson.JsonParser import org.gradle.api.Project import org.gradle.api.artifacts.Dependency import xyz.wagyourtail.unimined.api.minecraft.EnvType import xyz.wagyourtail.unimined.api.runs.RunConfig import xyz.wagyourtail.unimined.api.unimined +import xyz.wagyourtail.unimined.internal.mapping.ii.InterfaceInjectionMinecraftTransformer import xyz.wagyourtail.unimined.internal.minecraft.MinecraftProvider +import xyz.wagyourtail.unimined.internal.minecraft.patch.MinecraftJar +import xyz.wagyourtail.unimined.util.getShortSha1 +import java.io.InputStreamReader +import java.nio.file.Files +import kotlin.io.path.createDirectories +import kotlin.io.path.exists abstract class FabricMinecraftTransformer( project: Project, @@ -60,4 +68,82 @@ abstract class FabricMinecraftTransformer( "-Dfabric.remapClasspathFile=${intermediaryClasspath}" ) } + + override fun afterRemap(baseMinecraft: MinecraftJar): MinecraftJar { + val baseMinecraft = super.afterRemap(baseMinecraft) + + val injections = hashMapOf>() + + this.collectInterfaceInjections(baseMinecraft, injections) + + return if (injections.isNotEmpty()) { + val output = MinecraftJar( + baseMinecraft, + parentPath = provider.localCache.resolve("fabric").createDirectories(), + awOrAt = "ii+${injections.hashCode()}" + ); + + if (!output.path.exists() || project.unimined.forceReload) { + if (InterfaceInjectionMinecraftTransformer.transform( + injections, + baseMinecraft.path, + output.path, + project.logger + ) + ) { + output + } else baseMinecraft + } else output + } else baseMinecraft + } + + private fun collectInterfaceInjections(baseMinecraft: MinecraftJar, injections: HashMap>) { + val modJsonPath = this.getModJsonPath() + + if (modJsonPath != null && modJsonPath.exists()) { + val json = JsonParser.parseReader(InputStreamReader(Files.newInputStream(modJsonPath.toPath()))).asJsonObject + + val custom = json.getAsJsonObject("custom") + + if (custom != null) { + val interfaces = custom.getAsJsonObject("loom:injected_interfaces") + + if (interfaces != null) { + injections.putAll(interfaces.entrySet() + .filterNotNull() + .filter { it.key != null && it.value != null && it.value.isJsonArray } + .map { + val element = it.value!! + + Pair(it.key!!, if (element.isJsonArray) { + element.asJsonArray.mapNotNull { name -> name.asString } + } else arrayListOf()) + } + .map { + var target = it.first + + val clazz = provider.mappings.mappingTree.getClass( + target, + provider.mappings.mappingTree.getNamespaceId(prodNamespace.name) + ) + + if (clazz != null) { + var newTarget = clazz.getName(provider.mappings.mappingTree.getNamespaceId(baseMinecraft.mappingNamespace.name)) + + if (newTarget == null) { + newTarget = clazz.getName(provider.mappings.mappingTree.getNamespaceId(baseMinecraft.fallbackNamespace.name)) + } + + if (newTarget != null) { + target = newTarget + } + } + + Pair(target, it.second) + } + ) + } + } + } + } } \ No newline at end of file From 19bfd2253c7aeb731291d6227afa9732e2b9dd86 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 18 Nov 2023 00:03:52 +0100 Subject: [PATCH 02/10] Add a test for Interface Injection --- .../FabricInterfaceInjectionTest.kt | 44 ++++ .../unimined/util/IntegrationTestUtils.kt | 15 +- .../Fabric-Interface-Injection/build.gradle | 88 +++++++ .../gradle.properties | 4 + .../gradle/wrapper/gradle-wrapper.properties | 6 + testing/Fabric-Interface-Injection/gradlew | 244 ++++++++++++++++++ .../Fabric-Interface-Injection/gradlew.bat | 92 +++++++ .../settings.gradle | 31 +++ .../com/example/fabric/ExampleInterface.java | 5 + .../com/example/fabric/ExampleModFabric.java | 13 + .../src/fabric/resources/fabric.mod.json | 42 +++ .../src/main/java/com/example/ExampleMod.java | 9 + .../java/com/example/mixin/ExampleMixin.java | 17 ++ .../src/main/resources/modid.mixins.json | 14 + 14 files changed, 623 insertions(+), 1 deletion(-) create mode 100644 src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt create mode 100644 testing/Fabric-Interface-Injection/build.gradle create mode 100644 testing/Fabric-Interface-Injection/gradle.properties create mode 100644 testing/Fabric-Interface-Injection/gradle/wrapper/gradle-wrapper.properties create mode 100755 testing/Fabric-Interface-Injection/gradlew create mode 100644 testing/Fabric-Interface-Injection/gradlew.bat create mode 100644 testing/Fabric-Interface-Injection/settings.gradle create mode 100644 testing/Fabric-Interface-Injection/src/fabric/java/com/example/fabric/ExampleInterface.java create mode 100644 testing/Fabric-Interface-Injection/src/fabric/java/com/example/fabric/ExampleModFabric.java create mode 100644 testing/Fabric-Interface-Injection/src/fabric/resources/fabric.mod.json create mode 100644 testing/Fabric-Interface-Injection/src/main/java/com/example/ExampleMod.java create mode 100644 testing/Fabric-Interface-Injection/src/main/java/com/example/mixin/ExampleMixin.java create mode 100644 testing/Fabric-Interface-Injection/src/main/resources/modid.mixins.json diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt new file mode 100644 index 00000000..3782a533 --- /dev/null +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt @@ -0,0 +1,44 @@ +package xyz.wagyourtail.unimined.test.integration + +import org.gradle.testkit.runner.TaskOutcome +import org.junit.jupiter.api.Test +import org.objectweb.asm.ClassReader +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.ClassNode +import xyz.wagyourtail.unimined.util.openZipFileSystem +import xyz.wagyourtail.unimined.util.runTestProject +import java.nio.file.Files +import kotlin.io.path.inputStream +import kotlin.test.* + +class FabricInterfaceInjectionTest { + @Test + fun test_fabric_interface_injection() { + val projectName = "Fabric-Interface-Injection" + val result = runTestProject(projectName) + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + + val fs = openZipFileSystem(projectName, ".gradle/unimined/local/fabric/fabric/minecraft-1.14.4-fabric-merged+fixed-mojmap+intermediary-ii+-1221611203.jar") + + assertNotNull(fs, "Couldn't find the interface injected jar!") + + fs.use { + val target = it.getPath("/net/minecraft/advancements/Advancement.class") + + assertNotNull(target, "Couldn't find the injected class in mc jar!") + assertTrue(Files.exists(target), "Couldn't find the injected class in mc jar!") + + val reader = ClassReader(target.inputStream()) + val node = ClassNode(Opcodes.ASM9) + reader.accept(node, 0) + + assertNotNull(node.interfaces, "Injected class doesn't have any interface!") + assertEquals(1, node.interfaces.size) + assertContains(node.interfaces, "com/example/fabric/ExampleInterface") + } + + fs.close() + } +} \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/util/IntegrationTestUtils.kt b/src/test/kotlin/xyz/wagyourtail/unimined/util/IntegrationTestUtils.kt index 22cc791b..c3588428 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/util/IntegrationTestUtils.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/util/IntegrationTestUtils.kt @@ -3,13 +3,26 @@ package xyz.wagyourtail.unimined.util import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.GradleRunner import java.io.File +import java.nio.file.FileSystem import java.nio.file.Path import java.nio.file.Paths import kotlin.io.path.exists import kotlin.io.path.writeText fun runTestProject(name: String): BuildResult { - return runGradle(Paths.get(".").resolve("testing").resolve(name)); + return runGradle(getTestProjectPath(name)); +} + +fun getTestProjectPath(name: String): Path { + return Paths.get(".").resolve("testing").resolve(name) +} + +fun openZipFileSystem(project: String, path: String): FileSystem? { + val fullPath = getTestProjectPath(project).resolve(path) + + if (!fullPath.exists()) return null + + return fullPath.openZipFileSystem(mapOf("mutable" to false)) } fun runGradle(dir: Path): BuildResult { diff --git a/testing/Fabric-Interface-Injection/build.gradle b/testing/Fabric-Interface-Injection/build.gradle new file mode 100644 index 00000000..4e1275f0 --- /dev/null +++ b/testing/Fabric-Interface-Injection/build.gradle @@ -0,0 +1,88 @@ +plugins { + id 'java' + id 'xyz.wagyourtail.unimined' // version '1.0.0' +} + +group 'com.example' +version '1.0-SNAPSHOT' + +base { + archivesName.set('UniminedExampleMod') +} + +// this is just here so we can test the outputs easier and clean between tests +unimined.useGlobalCache = false + +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + +sourceSets { + fabric { + compileClasspath += sourceSets.main.output + runtimeClasspath += sourceSets.main.output + } +} + +repositories { + mavenCentral() + maven { + name = "sponge" + url = "https://repo.spongepowered.org/maven" + } +} + +unimined.minecraft { + version project.minecraft_version + + mappings { + intermediary() + mojmap() + + devFallbackNamespace "intermediary" + } + + defaultRemapJar = false +} + +unimined.minecraft(sourceSets.fabric) { + version project.minecraft_version + + mappings { + mojmap() + } + + fabric { + loader project.fabric_version + } +} + +configurations { + mainImplementation + implementation { + extendsFrom fabricImplementation + } +} + +sourceSets { + main { + compileClasspath += configurations.mainImplementation + runtimeClasspath += configurations.mainImplementation + } +} + +dependencies { + // we need this in main where it isn't by default + mainImplementation "org.spongepowered:mixin:0.8.5-SNAPSHOT" +} + +jar { + enabled = false +} + +processFabricResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} \ No newline at end of file diff --git a/testing/Fabric-Interface-Injection/gradle.properties b/testing/Fabric-Interface-Injection/gradle.properties new file mode 100644 index 00000000..2a999ef3 --- /dev/null +++ b/testing/Fabric-Interface-Injection/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs = -Xmx2G + +minecraft_version = 1.14.4 +fabric_version = 0.14.24 \ No newline at end of file diff --git a/testing/Fabric-Interface-Injection/gradle/wrapper/gradle-wrapper.properties b/testing/Fabric-Interface-Injection/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..42defcc9 --- /dev/null +++ b/testing/Fabric-Interface-Injection/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/testing/Fabric-Interface-Injection/gradlew b/testing/Fabric-Interface-Injection/gradlew new file mode 100755 index 00000000..79a61d42 --- /dev/null +++ b/testing/Fabric-Interface-Injection/gradlew @@ -0,0 +1,244 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/testing/Fabric-Interface-Injection/gradlew.bat b/testing/Fabric-Interface-Injection/gradlew.bat new file mode 100644 index 00000000..93e3f59f --- /dev/null +++ b/testing/Fabric-Interface-Injection/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/testing/Fabric-Interface-Injection/settings.gradle b/testing/Fabric-Interface-Injection/settings.gradle new file mode 100644 index 00000000..dbfcacdf --- /dev/null +++ b/testing/Fabric-Interface-Injection/settings.gradle @@ -0,0 +1,31 @@ + +pluginManagement { + repositories { + mavenCentral() + maven { + url = "https://maven.neoforged.net/releases" + } + maven { + url = "https://maven.minecraftforge.net/" + } + maven { + url = "https://maven.fabricmc.net/" + } + maven { + url = "https://maven.wagyourtail.xyz/releases" + } + maven { + url = "https://maven.wagyourtail.xyz/snapshots" + } + gradlePluginPortal() { + content { + excludeGroup("org.apache.logging.log4j") + } + } + } +} + +// so we can use the unimined directly provided by the super project +includeBuild('../../') + +rootProject.name = 'Fabric-Interface-Injection' \ No newline at end of file diff --git a/testing/Fabric-Interface-Injection/src/fabric/java/com/example/fabric/ExampleInterface.java b/testing/Fabric-Interface-Injection/src/fabric/java/com/example/fabric/ExampleInterface.java new file mode 100644 index 00000000..086ab183 --- /dev/null +++ b/testing/Fabric-Interface-Injection/src/fabric/java/com/example/fabric/ExampleInterface.java @@ -0,0 +1,5 @@ +package com.example.fabric; + +public interface ExampleInterface { + String test(); +} \ No newline at end of file diff --git a/testing/Fabric-Interface-Injection/src/fabric/java/com/example/fabric/ExampleModFabric.java b/testing/Fabric-Interface-Injection/src/fabric/java/com/example/fabric/ExampleModFabric.java new file mode 100644 index 00000000..51bca524 --- /dev/null +++ b/testing/Fabric-Interface-Injection/src/fabric/java/com/example/fabric/ExampleModFabric.java @@ -0,0 +1,13 @@ +package com.example.fabric; + +import com.example.ExampleMod; +import net.fabricmc.api.ModInitializer; + +public class ExampleModFabric implements ModInitializer { + + @Override + public void onInitialize() { + ExampleMod.LOGGER.info("Hello from Fabric!"); + } + +} diff --git a/testing/Fabric-Interface-Injection/src/fabric/resources/fabric.mod.json b/testing/Fabric-Interface-Injection/src/fabric/resources/fabric.mod.json new file mode 100644 index 00000000..3a58e439 --- /dev/null +++ b/testing/Fabric-Interface-Injection/src/fabric/resources/fabric.mod.json @@ -0,0 +1,42 @@ +{ + "schemaVersion": 1, + "id": "modid", + "version": "${version}", + + "name": "Example Mod", + "description": "This is an example description! Tell everyone what your mod is about!", + "authors": [ + "Me!" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + + "license": "CC0-1.0", + "icon": "assets/modid/icon.png", + + "environment": "*", + "entrypoints": { + "main": [ + "com.example.fabric.ExampleModFabric" + ] + }, + "mixins": [ + "modid.mixins.json" + ], + + "depends": { + "fabricloader": ">=0.14.19", + "minecraft": "~1.16.5", + "java": ">=8" + }, + + "custom": { + "loom:injected_interfaces": { + "net/minecraft/class_161": [ + "com/example/fabric/ExampleInterface" + ] + } + } +} \ No newline at end of file diff --git a/testing/Fabric-Interface-Injection/src/main/java/com/example/ExampleMod.java b/testing/Fabric-Interface-Injection/src/main/java/com/example/ExampleMod.java new file mode 100644 index 00000000..ef3ef249 --- /dev/null +++ b/testing/Fabric-Interface-Injection/src/main/java/com/example/ExampleMod.java @@ -0,0 +1,9 @@ +package com.example; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class ExampleMod { + public static final Logger LOGGER = LogManager.getLogger("modid"); + +} diff --git a/testing/Fabric-Interface-Injection/src/main/java/com/example/mixin/ExampleMixin.java b/testing/Fabric-Interface-Injection/src/main/java/com/example/mixin/ExampleMixin.java new file mode 100644 index 00000000..428dc930 --- /dev/null +++ b/testing/Fabric-Interface-Injection/src/main/java/com/example/mixin/ExampleMixin.java @@ -0,0 +1,17 @@ +package com.example.mixin; + +import com.example.ExampleMod; +import net.minecraft.client.gui.screens.TitleScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public class ExampleMixin { + + @Inject(method = "init()V", at = @At("HEAD")) + private void init(CallbackInfo info) { + ExampleMod.LOGGER.info("This line is printed by an example mod mixin!"); + } +} diff --git a/testing/Fabric-Interface-Injection/src/main/resources/modid.mixins.json b/testing/Fabric-Interface-Injection/src/main/resources/modid.mixins.json new file mode 100644 index 00000000..a08e9c51 --- /dev/null +++ b/testing/Fabric-Interface-Injection/src/main/resources/modid.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "com.example.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + ], + "client": [ + "ExampleMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file From e261df3ee25bed1d46af5eafc5999f792ebb959d Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 18 Nov 2023 00:24:21 +0100 Subject: [PATCH 03/10] Log test build output when it fails --- .../test/integration/BabricModloaderB1_7_3Test.kt | 12 +++++++++--- .../test/integration/FabricInterfaceInjectionTest.kt | 12 +++++++++--- .../unimined/test/integration/Forge1_3_2Test.kt | 12 +++++++++--- .../unimined/test/integration/Forge1_6_4Test.kt | 12 +++++++++--- .../test/integration/ForgeFabric1_12_2Test.kt | 12 +++++++++--- .../test/integration/ForgeFabric1_14_4Test.kt | 12 +++++++++--- .../test/integration/ForgeFabric1_15_2Test.kt | 12 +++++++++--- .../test/integration/ForgeFabric1_16_5Test.kt | 12 +++++++++--- .../test/integration/ForgeFabric1_17_1Test.kt | 12 +++++++++--- .../unimined/test/integration/ForgeFabric1_20Test.kt | 12 +++++++++--- .../test/integration/ForgeFabric1_7_10Test.kt | 12 +++++++++--- .../test/integration/ForgeFabric1_8_9Test.kt | 12 +++++++++--- .../test/integration/ForgeModloader1_2_5Test.kt | 12 +++++++++--- .../test/integration/NeoForgedFabric1_20_1Test.kt | 12 +++++++++--- .../integration/NeoForgedForgeFabric1_20_2Test.kt | 12 +++++++++--- 15 files changed, 135 insertions(+), 45 deletions(-) diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/BabricModloaderB1_7_3Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/BabricModloaderB1_7_3Test.kt index 61ccb44f..62822b9a 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/BabricModloaderB1_7_3Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/BabricModloaderB1_7_3Test.kt @@ -8,8 +8,14 @@ class BabricModloaderB1_7_3Test { @Test fun test_babric_modloader_b1_7_3() { val result = runTestProject("b1.7.3-Babric-Modloader") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt index 3782a533..b3377cb7 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt @@ -16,9 +16,15 @@ class FabricInterfaceInjectionTest { fun test_fabric_interface_injection() { val projectName = "Fabric-Interface-Injection" val result = runTestProject(projectName) - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } val fs = openZipFileSystem(projectName, ".gradle/unimined/local/fabric/fabric/minecraft-1.14.4-fabric-merged+fixed-mojmap+intermediary-ii+-1221611203.jar") diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_3_2Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_3_2Test.kt index acab62d7..1d30c6b0 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_3_2Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_3_2Test.kt @@ -8,8 +8,14 @@ class Forge1_3_2Test { @Test fun test_forge_1_3_2() { val result = runTestProject("1.3.2-Forge") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_6_4Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_6_4Test.kt index 15b69f59..b6f9d90b 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_6_4Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_6_4Test.kt @@ -8,8 +8,14 @@ class Forge1_6_4Test { @Test fun test_forge_1_6_4() { val result = runTestProject("1.6.4-Forge") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_12_2Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_12_2Test.kt index 05d2f397..3cdf8a81 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_12_2Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_12_2Test.kt @@ -8,8 +8,14 @@ class ForgeFabric1_12_2Test { @Test fun test_forge_fabric_1_12_2() { val result = runTestProject("1.12.2-Forge-Fabric") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_14_4Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_14_4Test.kt index 38b9c72b..79a3538f 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_14_4Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_14_4Test.kt @@ -8,8 +8,14 @@ class ForgeFabric1_14_4Test { @Test fun test_forge_fabric_1_14_4() { val result = runTestProject("1.14.4-Forge-Fabric") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_15_2Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_15_2Test.kt index 50b4e5e4..feecd7e2 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_15_2Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_15_2Test.kt @@ -8,8 +8,14 @@ class ForgeFabric1_15_2Test { @Test fun test_forge_fabric_1_15_2() { val result = runTestProject("1.15.2-Forge-Fabric") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_16_5Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_16_5Test.kt index b348e013..6fc57f83 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_16_5Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_16_5Test.kt @@ -8,8 +8,14 @@ class ForgeFabric1_16_5Test { @Test fun test_forge_fabric_1_16_5() { val result = runTestProject("1.16.5-Forge-Fabric") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_17_1Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_17_1Test.kt index 0842033e..0d8f9e6d 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_17_1Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_17_1Test.kt @@ -8,8 +8,14 @@ class ForgeFabric1_17_1Test { @Test fun test_forge_fabric_1_17_1() { val result = runTestProject("1.17.1-Forge-Fabric") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_20Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_20Test.kt index cc2e5971..398940aa 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_20Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_20Test.kt @@ -10,8 +10,14 @@ class ForgeFabric1_20Test { @Disabled fun test_forge_fabric_1_20() { val result = runTestProject("1.20-Forge-Fabric") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_7_10Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_7_10Test.kt index c8c5058f..78465bab 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_7_10Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_7_10Test.kt @@ -8,8 +8,14 @@ class ForgeFabric1_7_10Test { @Test fun test_forge_fabric_1_7_10() { val result = runTestProject("1.7.10-Forge-Fabric") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_8_9Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_8_9Test.kt index 1907d8ba..a51fcdb9 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_8_9Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_8_9Test.kt @@ -8,8 +8,14 @@ class ForgeFabric1_8_9Test { @Test fun test_forge_fabric_1_8_9() { val result = runTestProject("1.8.9-Forge-Fabric") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeModloader1_2_5Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeModloader1_2_5Test.kt index 5fb65e22..dd64d856 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeModloader1_2_5Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeModloader1_2_5Test.kt @@ -8,8 +8,14 @@ class ForgeModloader1_2_5Test { @Test fun test_forge_modloader_1_2_5() { val result = runTestProject("1.2.5-Forge-Modloader") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedFabric1_20_1Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedFabric1_20_1Test.kt index edc7504b..72932023 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedFabric1_20_1Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedFabric1_20_1Test.kt @@ -8,8 +8,14 @@ class NeoForgedFabric1_20_1Test { @Test fun test_neoforged_fabric_1_20_1() { val result = runTestProject("1.20.1-NeoForged-Fabric") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedForgeFabric1_20_2Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedForgeFabric1_20_2Test.kt index aa0977a4..9b50d303 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedForgeFabric1_20_2Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedForgeFabric1_20_2Test.kt @@ -8,8 +8,14 @@ class NeoForgedForgeFabric1_20_2Test { @Test fun test_neoforged_fabric_1_20_2() { val result = runTestProject("1.20.2-NeoForged-Forge-Fabric") - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } } } \ No newline at end of file From 0b7371287c46c72d5290b2dea1f2515b0161326f Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 18 Nov 2023 00:35:22 +0100 Subject: [PATCH 04/10] Log more info during tests --- .github/workflows/test-push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-push.yml b/.github/workflows/test-push.yml index e34a19f1..11cb2e9c 100644 --- a/.github/workflows/test-push.yml +++ b/.github/workflows/test-push.yml @@ -56,7 +56,7 @@ jobs: steps: - uses: actions/checkout@v3 - - run: gradle test --tests ${{ matrix.test }} --stacktrace --warning-mode fail + - run: gradle test --tests ${{ matrix.test }} --stacktrace --info --warning-mode fail env: TEST_WARNING_MODE: fail id: test From dfa6e3f98269588a5872ff36c85690a8a2f29cbf Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 18 Nov 2023 00:43:33 +0100 Subject: [PATCH 05/10] Catch more test crashes --- .../integration/BabricModloaderB1_7_3Test.kt | 22 ++++++++++++------- .../FabricInterfaceInjectionTest.kt | 22 ++++++++++++------- .../test/integration/Forge1_3_2Test.kt | 22 ++++++++++++------- .../test/integration/Forge1_6_4Test.kt | 22 ++++++++++++------- .../test/integration/ForgeFabric1_12_2Test.kt | 22 ++++++++++++------- .../test/integration/ForgeFabric1_14_4Test.kt | 22 ++++++++++++------- .../test/integration/ForgeFabric1_15_2Test.kt | 22 ++++++++++++------- .../test/integration/ForgeFabric1_16_5Test.kt | 22 ++++++++++++------- .../test/integration/ForgeFabric1_17_1Test.kt | 22 ++++++++++++------- .../test/integration/ForgeFabric1_20Test.kt | 22 ++++++++++++------- .../test/integration/ForgeFabric1_7_10Test.kt | 22 ++++++++++++------- .../test/integration/ForgeFabric1_8_9Test.kt | 22 ++++++++++++------- .../integration/ForgeModloader1_2_5Test.kt | 22 ++++++++++++------- .../integration/NeoForgedFabric1_20_1Test.kt | 22 ++++++++++++------- .../NeoForgedForgeFabric1_20_2Test.kt | 22 ++++++++++++------- 15 files changed, 210 insertions(+), 120 deletions(-) diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/BabricModloaderB1_7_3Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/BabricModloaderB1_7_3Test.kt index 62822b9a..c7379fb3 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/BabricModloaderB1_7_3Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/BabricModloaderB1_7_3Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class BabricModloaderB1_7_3Test { @Test fun test_babric_modloader_b1_7_3() { - val result = runTestProject("b1.7.3-Babric-Modloader") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("b1.7.3-Babric-Modloader") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt index b3377cb7..a4fa07c9 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt @@ -1,6 +1,7 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import org.objectweb.asm.ClassReader import org.objectweb.asm.Opcodes @@ -15,15 +16,20 @@ class FabricInterfaceInjectionTest { @Test fun test_fabric_interface_injection() { val projectName = "Fabric-Interface-Injection" - val result = runTestProject(projectName) - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject(projectName) + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } val fs = openZipFileSystem(projectName, ".gradle/unimined/local/fabric/fabric/minecraft-1.14.4-fabric-merged+fixed-mojmap+intermediary-ii+-1221611203.jar") diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_3_2Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_3_2Test.kt index 1d30c6b0..d2b5b3fb 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_3_2Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_3_2Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class Forge1_3_2Test { @Test fun test_forge_1_3_2() { - val result = runTestProject("1.3.2-Forge") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.3.2-Forge") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_6_4Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_6_4Test.kt index b6f9d90b..09a8fd14 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_6_4Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/Forge1_6_4Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class Forge1_6_4Test { @Test fun test_forge_1_6_4() { - val result = runTestProject("1.6.4-Forge") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.6.4-Forge") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_12_2Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_12_2Test.kt index 3cdf8a81..25e61ee4 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_12_2Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_12_2Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class ForgeFabric1_12_2Test { @Test fun test_forge_fabric_1_12_2() { - val result = runTestProject("1.12.2-Forge-Fabric") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.12.2-Forge-Fabric") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_14_4Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_14_4Test.kt index 79a3538f..6bdfe2a2 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_14_4Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_14_4Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class ForgeFabric1_14_4Test { @Test fun test_forge_fabric_1_14_4() { - val result = runTestProject("1.14.4-Forge-Fabric") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.14.4-Forge-Fabric") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_15_2Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_15_2Test.kt index feecd7e2..514c7816 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_15_2Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_15_2Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class ForgeFabric1_15_2Test { @Test fun test_forge_fabric_1_15_2() { - val result = runTestProject("1.15.2-Forge-Fabric") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.15.2-Forge-Fabric") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_16_5Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_16_5Test.kt index 6fc57f83..4af6ff2f 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_16_5Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_16_5Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class ForgeFabric1_16_5Test { @Test fun test_forge_fabric_1_16_5() { - val result = runTestProject("1.16.5-Forge-Fabric") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.16.5-Forge-Fabric") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_17_1Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_17_1Test.kt index 0d8f9e6d..2668fb47 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_17_1Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_17_1Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class ForgeFabric1_17_1Test { @Test fun test_forge_fabric_1_17_1() { - val result = runTestProject("1.17.1-Forge-Fabric") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.17.1-Forge-Fabric") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_20Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_20Test.kt index 398940aa..db0bca78 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_20Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_20Test.kt @@ -1,6 +1,7 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject @@ -9,15 +10,20 @@ class ForgeFabric1_20Test { @Test @Disabled fun test_forge_fabric_1_20() { - val result = runTestProject("1.20-Forge-Fabric") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.20-Forge-Fabric") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_7_10Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_7_10Test.kt index 78465bab..b9b80a9f 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_7_10Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_7_10Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class ForgeFabric1_7_10Test { @Test fun test_forge_fabric_1_7_10() { - val result = runTestProject("1.7.10-Forge-Fabric") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.7.10-Forge-Fabric") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_8_9Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_8_9Test.kt index a51fcdb9..2d625984 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_8_9Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeFabric1_8_9Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class ForgeFabric1_8_9Test { @Test fun test_forge_fabric_1_8_9() { - val result = runTestProject("1.8.9-Forge-Fabric") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.8.9-Forge-Fabric") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeModloader1_2_5Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeModloader1_2_5Test.kt index dd64d856..672e54b0 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeModloader1_2_5Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/ForgeModloader1_2_5Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class ForgeModloader1_2_5Test { @Test fun test_forge_modloader_1_2_5() { - val result = runTestProject("1.2.5-Forge-Modloader") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.2.5-Forge-Modloader") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedFabric1_20_1Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedFabric1_20_1Test.kt index 72932023..4e3b6f82 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedFabric1_20_1Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedFabric1_20_1Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class NeoForgedFabric1_20_1Test { @Test fun test_neoforged_fabric_1_20_1() { - val result = runTestProject("1.20.1-NeoForged-Fabric") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.20.1-NeoForged-Fabric") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedForgeFabric1_20_2Test.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedForgeFabric1_20_2Test.kt index 9b50d303..c44ec183 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedForgeFabric1_20_2Test.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/NeoForgedForgeFabric1_20_2Test.kt @@ -1,21 +1,27 @@ package xyz.wagyourtail.unimined.test.integration import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure import org.junit.jupiter.api.Test import xyz.wagyourtail.unimined.util.runTestProject class NeoForgedForgeFabric1_20_2Test { @Test fun test_neoforged_fabric_1_20_2() { - val result = runTestProject("1.20.2-NeoForged-Forge-Fabric") - try { - result.task(":build")?.outcome?.let { - if (it != TaskOutcome.SUCCESS) throw Exception("build failed") - } ?: throw Exception("build failed") - } catch (e: Exception) { - println(result.output) - throw Exception(e) + val result = runTestProject("1.20.2-NeoForged-Forge-Fabric") + + try { + result.task(":build")?.outcome?.let { + if (it != TaskOutcome.SUCCESS) throw Exception("build failed") + } ?: throw Exception("build failed") + } catch (e: Exception) { + println(result.output) + throw Exception(e) + } + } catch (e: UnexpectedBuildFailure) { + println(e) + throw Exception("build failed", e) } } } \ No newline at end of file From 62caf5d328762ce41c822cf007919df1b1728700 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 18 Nov 2023 19:05:06 +0100 Subject: [PATCH 06/10] Add neoforged maven to forge to fix accesstransformer --- .../minecraft/patch/forge/MinecraftForgeMinecraftTransformer.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/MinecraftForgeMinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/MinecraftForgeMinecraftTransformer.kt index ad2d3ca3..64195cf3 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/MinecraftForgeMinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/forge/MinecraftForgeMinecraftTransformer.kt @@ -23,6 +23,7 @@ class MinecraftForgeMinecraftTransformer(project: Project, provider: MinecraftPr override fun addMavens() { project.unimined.minecraftForgeMaven() + project.unimined.neoForgedMaven() } override fun loader(dep: Any, action: Dependency.() -> Unit) { From 1b9ab331583bc2fe51e5c5df34f503409e5cff22 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 18 Nov 2023 19:23:57 +0100 Subject: [PATCH 07/10] Show more info about tests on windows too --- .github/workflows/test-push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-push.yml b/.github/workflows/test-push.yml index 11cb2e9c..f694bfc9 100644 --- a/.github/workflows/test-push.yml +++ b/.github/workflows/test-push.yml @@ -90,7 +90,7 @@ jobs: with: java-version: ${{ matrix.java }} distribution: 'temurin' - - run: ./gradlew test --tests ${{ matrix.test }} --stacktrace --warning-mode fail + - run: ./gradlew test --tests ${{ matrix.test }} --stacktrace --info --warning-mode fail env: TEST_WARNING_MODE: fail id: test From 7a4b7b110d8f3cc7d85d1d1bcef7c04dcf652ecd Mon Sep 17 00:00:00 2001 From: Cat Core Date: Sat, 18 Nov 2023 22:22:27 +0100 Subject: [PATCH 08/10] Retain old suffix in interface injected jar name --- .../minecraft/patch/fabric/FabricMinecraftTransformer.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt index c28880c0..c7619519 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt @@ -77,10 +77,12 @@ abstract class FabricMinecraftTransformer( this.collectInterfaceInjections(baseMinecraft, injections) return if (injections.isNotEmpty()) { + val oldSuffix = if (baseMinecraft.awOrAt != null) baseMinecraft.awOrAt + "+" else "" + val output = MinecraftJar( baseMinecraft, parentPath = provider.localCache.resolve("fabric").createDirectories(), - awOrAt = "ii+${injections.hashCode()}" + awOrAt = "${oldSuffix}ii+${injections.hashCode()}" ); if (!output.path.exists() || project.unimined.forceReload) { From 15a199b7cc9aa2ac452eac7baf9d5694949287c9 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Wed, 22 Nov 2023 11:45:32 +0100 Subject: [PATCH 09/10] :sparkles: Add quilt support to Interface Injection, switch to short sha --- .../xyz/wagyourtail/unimined/util/Utils.kt | 11 +++ .../fabric/FabricLikeMinecraftTransformer.kt | 70 ++++++++++++++++++- .../fabric/FabricMinecraftTransformer.kt | 66 +---------------- .../patch/fabric/QuiltMinecraftTransformer.kt | 32 +++++++++ 4 files changed, 114 insertions(+), 65 deletions(-) diff --git a/src/api/kotlin/xyz/wagyourtail/unimined/util/Utils.kt b/src/api/kotlin/xyz/wagyourtail/unimined/util/Utils.kt index 32baadaa..35f2780c 100644 --- a/src/api/kotlin/xyz/wagyourtail/unimined/util/Utils.kt +++ b/src/api/kotlin/xyz/wagyourtail/unimined/util/Utils.kt @@ -18,6 +18,7 @@ import java.security.MessageDigest import java.util.* import java.util.zip.ZipInputStream import java.util.zip.ZipOutputStream +import kotlin.collections.HashMap import kotlin.io.path.* import kotlin.reflect.KClass import kotlin.reflect.KProperty1 @@ -118,6 +119,16 @@ fun Path.getShortSha1(): String = getSha1().substring(0, 7) fun File.getShortSha1() = toPath().getShortSha1() +fun HashMap.getSha1(): String { + val digestSha1 = MessageDigest.getInstance("SHA-1") + digestSha1.update(toString().toByteArray()) + val hashBytes = digestSha1.digest() + return hashBytes.joinToString("") { String.format("%02x", it)} +} + +fun HashMap.getShortSha1(): String = getSha1().substring(0, 7) + + //fun runJarInSubprocess( // jar: Path, diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt index 1f0db242..e4b553df 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricLikeMinecraftTransformer.kt @@ -16,6 +16,7 @@ import xyz.wagyourtail.unimined.api.task.RemapJarTask import xyz.wagyourtail.unimined.api.unimined import xyz.wagyourtail.unimined.internal.mapping.at.AccessTransformerMinecraftTransformer import xyz.wagyourtail.unimined.internal.mapping.aw.AccessWidenerMinecraftTransformer +import xyz.wagyourtail.unimined.internal.mapping.ii.InterfaceInjectionMinecraftTransformer import xyz.wagyourtail.unimined.internal.mapping.task.ExportMappingsTaskImpl import xyz.wagyourtail.unimined.internal.minecraft.MinecraftProvider import xyz.wagyourtail.unimined.internal.minecraft.patch.AbstractMinecraftTransformer @@ -211,7 +212,9 @@ abstract class FabricLikeMinecraftTransformer( provider.minecraftLibraries.dependencies.add(dep) } - override fun afterRemap(baseMinecraft: MinecraftJar): MinecraftJar = + override fun afterRemap(baseMinecraft: MinecraftJar): MinecraftJar = applyInterfaceInjection(applyAccessWideners(baseMinecraft)) + + private fun applyAccessWideners(baseMinecraft: MinecraftJar): MinecraftJar = if (accessWidener != null) { val output = MinecraftJar( baseMinecraft, @@ -237,6 +240,71 @@ abstract class FabricLikeMinecraftTransformer( } } else baseMinecraft + private fun applyInterfaceInjection(baseMinecraft: MinecraftJar): MinecraftJar { + val injections = hashMapOf>() + + this.collectInterfaceInjections(baseMinecraft, injections) + + return if (injections.isNotEmpty()) { + val oldSuffix = if (baseMinecraft.awOrAt != null) baseMinecraft.awOrAt + "+" else "" + + val output = MinecraftJar( + baseMinecraft, + parentPath = provider.localCache.resolve("fabric").createDirectories(), + awOrAt = "${oldSuffix}ii+${injections.getShortSha1()}" + ) + + if (!output.path.exists() || project.unimined.forceReload) { + if (InterfaceInjectionMinecraftTransformer.transform( + injections, + baseMinecraft.path, + output.path, + project.logger + ) + ) { + output + } else baseMinecraft + } else output + } else baseMinecraft + } + + abstract fun collectInterfaceInjections(baseMinecraft: MinecraftJar, injections: HashMap>) + fun collectInterfaceInjections(baseMinecraft: MinecraftJar, injections: HashMap>, interfaces: JsonObject) { + injections.putAll(interfaces.entrySet() + .filterNotNull() + .filter { it.key != null && it.value != null && it.value.isJsonArray } + .map { + val element = it.value!! + + Pair(it.key!!, if (element.isJsonArray) { + element.asJsonArray.mapNotNull { name -> name.asString } + } else arrayListOf()) + } + .map { + var target = it.first + + val clazz = provider.mappings.mappingTree.getClass( + target, + provider.mappings.mappingTree.getNamespaceId(prodNamespace.name) + ) + + if (clazz != null) { + var newTarget = clazz.getName(provider.mappings.mappingTree.getNamespaceId(baseMinecraft.mappingNamespace.name)) + + if (newTarget == null) { + newTarget = clazz.getName(provider.mappings.mappingTree.getNamespaceId(baseMinecraft.fallbackNamespace.name)) + } + + if (newTarget != null) { + target = newTarget + } + } + + Pair(target, it.second) + } + ) + } + val intermediaryClasspath: Path = provider.localCache.resolve("remapClasspath.txt".withSourceSet(provider.sourceSet)) override fun afterEvaluate() { diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt index c7619519..a8b46bc3 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/FabricMinecraftTransformer.kt @@ -69,37 +69,7 @@ abstract class FabricMinecraftTransformer( ) } - override fun afterRemap(baseMinecraft: MinecraftJar): MinecraftJar { - val baseMinecraft = super.afterRemap(baseMinecraft) - - val injections = hashMapOf>() - - this.collectInterfaceInjections(baseMinecraft, injections) - - return if (injections.isNotEmpty()) { - val oldSuffix = if (baseMinecraft.awOrAt != null) baseMinecraft.awOrAt + "+" else "" - - val output = MinecraftJar( - baseMinecraft, - parentPath = provider.localCache.resolve("fabric").createDirectories(), - awOrAt = "${oldSuffix}ii+${injections.hashCode()}" - ); - - if (!output.path.exists() || project.unimined.forceReload) { - if (InterfaceInjectionMinecraftTransformer.transform( - injections, - baseMinecraft.path, - output.path, - project.logger - ) - ) { - output - } else baseMinecraft - } else output - } else baseMinecraft - } - - private fun collectInterfaceInjections(baseMinecraft: MinecraftJar, injections: HashMap>) { + override fun collectInterfaceInjections(baseMinecraft: MinecraftJar, injections: HashMap>) { val modJsonPath = this.getModJsonPath() if (modJsonPath != null && modJsonPath.exists()) { @@ -111,39 +81,7 @@ abstract class FabricMinecraftTransformer( val interfaces = custom.getAsJsonObject("loom:injected_interfaces") if (interfaces != null) { - injections.putAll(interfaces.entrySet() - .filterNotNull() - .filter { it.key != null && it.value != null && it.value.isJsonArray } - .map { - val element = it.value!! - - Pair(it.key!!, if (element.isJsonArray) { - element.asJsonArray.mapNotNull { name -> name.asString } - } else arrayListOf()) - } - .map { - var target = it.first - - val clazz = provider.mappings.mappingTree.getClass( - target, - provider.mappings.mappingTree.getNamespaceId(prodNamespace.name) - ) - - if (clazz != null) { - var newTarget = clazz.getName(provider.mappings.mappingTree.getNamespaceId(baseMinecraft.mappingNamespace.name)) - - if (newTarget == null) { - newTarget = clazz.getName(provider.mappings.mappingTree.getNamespaceId(baseMinecraft.fallbackNamespace.name)) - } - - if (newTarget != null) { - target = newTarget - } - } - - Pair(target, it.second) - } - ) + collectInterfaceInjections(baseMinecraft, injections, interfaces) } } } diff --git a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/QuiltMinecraftTransformer.kt b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/QuiltMinecraftTransformer.kt index 809b7e9d..095fe9e6 100644 --- a/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/QuiltMinecraftTransformer.kt +++ b/src/minecraft/kotlin/xyz/wagyourtail/unimined/internal/minecraft/patch/fabric/QuiltMinecraftTransformer.kt @@ -2,12 +2,16 @@ package xyz.wagyourtail.unimined.internal.minecraft.patch.fabric import com.google.gson.JsonArray import com.google.gson.JsonObject +import com.google.gson.JsonParser import org.gradle.api.Project import org.gradle.api.artifacts.Dependency import xyz.wagyourtail.unimined.api.minecraft.EnvType import xyz.wagyourtail.unimined.api.runs.RunConfig import xyz.wagyourtail.unimined.api.unimined import xyz.wagyourtail.unimined.internal.minecraft.MinecraftProvider +import xyz.wagyourtail.unimined.internal.minecraft.patch.MinecraftJar +import java.io.InputStreamReader +import java.nio.file.Files class QuiltMinecraftTransformer( project: Project, @@ -29,6 +33,34 @@ class QuiltMinecraftTransformer( } } + override fun collectInterfaceInjections(baseMinecraft: MinecraftJar, injections: HashMap>) { + val modJsonPath = this.getModJsonPath() + + if (modJsonPath != null && modJsonPath.exists()) { + val json = JsonParser.parseReader(InputStreamReader(Files.newInputStream(modJsonPath.toPath()))).asJsonObject + + val custom = json.getAsJsonObject("custom") + + if (custom != null) { + val quiltLoom = custom.getAsJsonObject("quilt_loom") + + if (quiltLoom != null) { + val interfaces = quiltLoom.getAsJsonObject("injected_interfaces") + + if (interfaces != null) collectInterfaceInjections(baseMinecraft, injections, interfaces) + } + } + + val quiltLoom = json.getAsJsonObject("quilt_loom") + + if (quiltLoom != null) { + val interfaces = quiltLoom.getAsJsonObject("injected_interfaces") + + if (interfaces != null) collectInterfaceInjections(baseMinecraft, injections, interfaces) + } + } + } + override fun loader(dep: Any, action: Dependency.() -> Unit) { fabric.dependencies.add( (if (dep is String && !dep.contains(":")) { From ab3c718bde75441851ffade386a2172144f96ac6 Mon Sep 17 00:00:00 2001 From: Cat Core Date: Wed, 22 Nov 2023 11:55:06 +0100 Subject: [PATCH 10/10] Udpate test --- .../unimined/test/integration/FabricInterfaceInjectionTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt index a4fa07c9..13b8a7b9 100644 --- a/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt +++ b/src/test/kotlin/xyz/wagyourtail/unimined/test/integration/FabricInterfaceInjectionTest.kt @@ -32,7 +32,7 @@ class FabricInterfaceInjectionTest { throw Exception("build failed", e) } - val fs = openZipFileSystem(projectName, ".gradle/unimined/local/fabric/fabric/minecraft-1.14.4-fabric-merged+fixed-mojmap+intermediary-ii+-1221611203.jar") + val fs = openZipFileSystem(projectName, ".gradle/unimined/local/fabric/fabric/minecraft-1.14.4-fabric-merged+fixed-mojmap+intermediary-ii+49c3b85.jar") assertNotNull(fs, "Couldn't find the interface injected jar!")