diff --git a/Jenkinsfile b/Jenkinsfile index 422b309..094a0a7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -7,7 +7,7 @@ node { sh "rm -rf build/libs/" sh "chmod +x gradlew" - sh "./gradlew build --refresh-dependencies" + sh "./gradlew build -x test --refresh-dependencies" stage "Archive artifacts" diff --git a/build.gradle b/build.gradle index ffbb846..5e24070 100644 --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,7 @@ plugins { id 'java-gradle-plugin' id 'idea' id 'eclipse' + id 'groovy' } sourceCompatibility = 1.8 @@ -54,6 +55,9 @@ dependencies { // source code remapping implementation ('org.cadixdev:mercury:0.1.0.fabric-SNAPSHOT') + // Testing + testImplementation(gradleTestKit()) + testImplementation("org.spockframework:spock-core:1.3-groovy-2.5") } jar { @@ -95,7 +99,7 @@ publishing { version project.version from components["java"] - + artifact sourcesJar artifact javadocJar } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 29953ea..87b738c 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradlew b/gradlew index cccdd3d..af6708f 100755 --- a/gradlew +++ b/gradlew @@ -28,7 +28,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/gradlew.bat b/gradlew.bat index f955316..6d57edc 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @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= +set DEFAULT_JVM_OPTS="-Xmx64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/src/main/java/net/fabricmc/loom/AbstractPlugin.java b/src/main/java/net/fabricmc/loom/AbstractPlugin.java index 0b247c5..5ed2d86 100644 --- a/src/main/java/net/fabricmc/loom/AbstractPlugin.java +++ b/src/main/java/net/fabricmc/loom/AbstractPlugin.java @@ -31,7 +31,10 @@ import net.fabricmc.loom.providers.MinecraftProvider; import net.fabricmc.loom.task.RemapJarTask; import net.fabricmc.loom.task.RemapSourcesJarTask; import net.fabricmc.loom.util.*; -import org.gradle.api.*; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.UnknownTaskException; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; import org.gradle.api.artifacts.component.ModuleComponentIdentifier; @@ -61,6 +64,10 @@ import java.util.function.Predicate; public class AbstractPlugin implements Plugin { protected Project project; + public static boolean isRootProject(Project project) { + return project.getRootProject() == project; + } + private void extendsFrom(String a, String b) { project.getConfigurations().getByName(a).extendsFrom(project.getConfigurations().getByName(b)); } @@ -121,8 +128,8 @@ public class AbstractPlugin implements Plugin { extendsFrom(Constants.MINECRAFT_NAMED, Constants.MINECRAFT_DEPENDENCIES); extendsFrom(Constants.MINECRAFT_INTERMEDIARY, Constants.MINECRAFT_DEPENDENCIES); - extendsFrom("compile", Constants.MAPPINGS); - extendsFrom("annotationProcessor", Constants.MAPPINGS); + extendsFrom("compile", Constants.MAPPINGS); + extendsFrom("annotationProcessor", Constants.MAPPINGS); configureIDEs(); configureCompile(); @@ -133,7 +140,7 @@ public class AbstractPlugin implements Plugin { Set taskSet = entry.getValue(); for (Task task : taskSet) { if (task instanceof JavaCompile - && !(task.getName().contains("Test")) && !(task.getName().contains("test"))) { + && !(task.getName().contains("Test")) && !(task.getName().contains("test"))) { JavaCompile javaCompileTask = (JavaCompile) task; javaCompileTask.doFirst(task1 -> { project.getLogger().lifecycle(":setting java compiler args"); @@ -161,8 +168,8 @@ public class AbstractPlugin implements Plugin { * Permit to add a Maven repository to a target project * * @param target The garget project - * @param name The name of the repository - * @param url The URL of the repository + * @param name The name of the repository + * @param url The URL of the repository * @return An object containing the name and the URL of the repository that can be modified later */ public MavenArtifactRepository addMavenRepo(Project target, final String name, final String url) { @@ -293,7 +300,7 @@ public class AbstractPlugin implements Plugin { project1.getTasks().getByName("idea").finalizedBy(project1.getTasks().getByName("genIdeaWorkspace")); project1.getTasks().getByName("eclipse").finalizedBy(project1.getTasks().getByName("genEclipseRuns")); - if(extension.autoGenIDERuns && isRootProject(project1)){ + if (extension.autoGenIDERuns && isRootProject(project1)) { SetupIntelijRunConfigs.setup(project1); } @@ -302,15 +309,15 @@ public class AbstractPlugin implements Plugin { AbstractArchiveTask jarTask = (AbstractArchiveTask) project1.getTasks().getByName("jar"); RemapJarTask remapJarTask = (RemapJarTask) project1.getTasks().findByName("remapJar"); - if (remapJarTask.getInput() == null) { - remapJarTask.setOutput(jarTask.getArchivePath()); - jarTask.setClassifier("dev"); - remapJarTask.setInput(jarTask.getArchivePath()); + assert remapJarTask != null; + if (!remapJarTask.getInput().isPresent()) { + remapJarTask.getArchiveClassifier().set("remapped"); + remapJarTask.getInput().set(jarTask.getArchiveFile()); } - remapJarTask.setAddNestedDependencies(true); + remapJarTask.getAddNestedDependencies().set(true); - remapJarTask.doLast(task -> project1.getArtifacts().add("archives", remapJarTask.getOutput())); + remapJarTask.doLast(task -> project1.getArtifacts().add("archives", remapJarTask.getArchiveFile())); remapJarTask.dependsOn(project1.getTasks().getByName("jar")); project1.getTasks().getByName("build").dependsOn(remapJarTask); @@ -318,7 +325,7 @@ public class AbstractPlugin implements Plugin { for (Map.Entry> entry : taskMap.entrySet()) { Set taskSet = entry.getValue(); for (Task task : taskSet) { - if (task instanceof RemapJarTask && ((RemapJarTask) task).isAddNestedDependencies()) { + if (task instanceof RemapJarTask && ((RemapJarTask) task).getAddNestedDependencies().get()) { //Run all the sub project remap jars tasks before the root projects jar, this is to allow us to include projects NestedJars.getRequiredTasks(project1).forEach(task::dependsOn); } @@ -394,8 +401,4 @@ public class AbstractPlugin implements Plugin { } }); } - - public static boolean isRootProject(Project project){ - return project.getRootProject() == project; - } } diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index e401881..996aad1 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -26,7 +26,6 @@ package net.fabricmc.loom.task; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.providers.MappingsProvider; -import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.MixinRefmapHelper; import net.fabricmc.loom.util.NestedJars; import net.fabricmc.loom.util.TinyRemapperMappingsHelper; @@ -34,29 +33,36 @@ import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; import net.fabricmc.tinyremapper.TinyUtils; import org.gradle.api.Project; +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.jvm.tasks.Jar; import java.io.File; import java.io.FileNotFoundException; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.util.LinkedHashSet; +import java.util.Set; -public class RemapJarTask extends AbstractLoomTask { - private Object input; - private Object output; - private boolean addNestedDependencies; +public class RemapJarTask extends Jar { + private RegularFileProperty input; + private Property addNestedDependencies; + + public RemapJarTask() { + super(); + input = getProject().getObjects().fileProperty(); + addNestedDependencies = getProject().getObjects().property(Boolean.class); + } @TaskAction public void doTask() throws Throwable { Project project = getProject(); LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); - Path input = getInput().toPath(); - Path output = getOutput().toPath(); + Path input = this.getInput().getAsFile().get().toPath(); + Path output = this.getArchiveFile().get().getAsFile().toPath(); if (!Files.exists(input)) { throw new FileNotFoundException(input.toString()); @@ -67,9 +73,9 @@ public class RemapJarTask extends AbstractLoomTask { String fromM = "named"; String toM = "intermediary"; - Set classpathFiles = new LinkedHashSet<>(); - //noinspection CollectionAddAllCanBeReplacedWithConstructor - classpathFiles.addAll(project.getConfigurations().getByName("compileClasspath").getFiles()); + Set classpathFiles = new LinkedHashSet<>( + project.getConfigurations().getByName("compileClasspath").getFiles() + ); Path[] classpath = classpathFiles.stream().map(File::toPath).filter((p) -> !input.equals(p)).toArray(Path[]::new); File mixinMapFile = mappingsProvider.MAPPINGS_MIXIN_EXPORT; @@ -111,7 +117,7 @@ public class RemapJarTask extends AbstractLoomTask { project.getLogger().debug("Transformed mixin reference maps in output JAR!"); } - if (addNestedDependencies) { + if (getAddNestedDependencies().get()) { if (NestedJars.addNestedJars(project, output)) { project.getLogger().debug("Added nested jar paths to mod json"); } @@ -119,29 +125,25 @@ public class RemapJarTask extends AbstractLoomTask { extension.addUnmappedMod(input); - /** - * + /*try { + if (modJar.exists()) { + Files.move(modJar, modJarUnmappedCopy); + extension.addUnmappedMod(modJarUnmappedCopy); + } - try { - if (modJar.exists()) { - Files.move(modJar, modJarUnmappedCopy); - extension.addUnmappedMod(modJarUnmappedCopy); - } - - Files.move(modJarOutput, modJar); - } catch (IOException e) { - throw new RuntimeException(e); - } - */ + Files.move(modJarOutput, modJar); + } catch (IOException e) { + throw new RuntimeException(e); + }*/ } - //@formatter:off - // the null-check in getInput() is done to allow reconfiguration by AbstractPlugin - @InputFile public File getInput() { return input == null ? null : getProject().file(input); } - @OutputFile public File getOutput() { return getProject().file(output); } - @Input public boolean isAddNestedDependencies() { return addNestedDependencies; } - public void setAddNestedDependencies(boolean value) { this.addNestedDependencies = value; } - public void setInput(Object input) { this.input = input; } - public void setOutput(Object output) { this.output = output; } - //@formatter:on + @InputFile + public RegularFileProperty getInput() { + return input; + } + + @Input + public Property getAddNestedDependencies() { + return addNestedDependencies; + } } diff --git a/src/main/java/net/fabricmc/loom/util/MixinRefmapHelper.java b/src/main/java/net/fabricmc/loom/util/MixinRefmapHelper.java index f451f15..c644ab9 100644 --- a/src/main/java/net/fabricmc/loom/util/MixinRefmapHelper.java +++ b/src/main/java/net/fabricmc/loom/util/MixinRefmapHelper.java @@ -26,7 +26,6 @@ package net.fabricmc.loom.util; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.fabricmc.tinyremapper.TinyRemapper; import org.objectweb.asm.commons.Remapper; @@ -37,10 +36,8 @@ import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; -import java.lang.reflect.Field; import java.nio.file.Path; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.zip.ZipEntry; diff --git a/src/main/java/net/fabricmc/loom/util/NestedJars.java b/src/main/java/net/fabricmc/loom/util/NestedJars.java index fd6ecf7..3aa6ebb 100644 --- a/src/main/java/net/fabricmc/loom/util/NestedJars.java +++ b/src/main/java/net/fabricmc/loom/util/NestedJars.java @@ -28,8 +28,10 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonObject; + import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.task.RemapJarTask; + import org.apache.commons.io.FileUtils; import org.gradle.api.Project; import org.gradle.api.Task; @@ -47,7 +49,11 @@ import org.zeroturnaround.zip.transform.ZipEntryTransformerEntry; import java.io.File; import java.io.IOException; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Locale; +import java.util.Set; import java.util.zip.ZipEntry; public class NestedJars { @@ -101,7 +107,7 @@ public class NestedJars { for (Task task : remapJarTasks.isEmpty() ? jarTasks : remapJarTasks) { if (task instanceof RemapJarTask) { - fileList.add(((RemapJarTask) task).getOutput()); + fileList.add(((RemapJarTask) task).getArchiveFile().get().getAsFile()); } else if (task instanceof AbstractArchiveTask) { fileList.add(((AbstractArchiveTask) task).getArchivePath()); } diff --git a/src/test/groovy/net/fabricmc/loom/BuildUtils.groovy b/src/test/groovy/net/fabricmc/loom/BuildUtils.groovy new file mode 100644 index 0000000..8391fec --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/BuildUtils.groovy @@ -0,0 +1,213 @@ +package net.fabricmc.loom + +/** + * Created by Mitchell Skaggs on 6/12/2019. + */ +static String genBuildFile() { + """ +plugins { + id 'fabric-loom' + id 'maven-publish' +} +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + +archivesBaseName = project.archives_base_name +version = project.mod_version +group = project.maven_group + +minecraft { +} + +dependencies { + //to change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:\${project.minecraft_version}" + mappings "net.fabricmc:yarn:\${project.yarn_mappings}" + modCompile "net.fabricmc:fabric-loader:\${project.loader_version}" + + // Fabric API. This is technically optional, but you probably want it anyway. + modCompile "net.fabricmc.fabric-api:fabric-api:\${project.fabric_version}" + + // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. + // You may need to force-disable transitiveness on them. +} + +processResources { + inputs.property "version", project.version + + from(sourceSets.main.resources.srcDirs) { + include "fabric.mod.json" + expand "version": project.version + } + + from(sourceSets.main.resources.srcDirs) { + exclude "fabric.mod.json" + } +} + +// ensure that the encoding is set to UTF-8, no matter what the system default is +// this fixes some edge cases with special characters not displaying correctly +// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html +tasks.withType(JavaCompile) { + options.encoding = "UTF-8" +} + +// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task +// if it is present. +// If you remove this task, sources will not be generated. +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = "sources" + from sourceSets.main.allSource +} + +jar { + from "LICENSE" +} + +// configure the maven publication +publishing { + publications { + mavenJava(MavenPublication) { + // add all the jars that should be included when publishing to maven + artifact(jar) { + builtBy remapJar + } + artifact(sourcesJar) { + builtBy remapSourcesJar + } + } + } + + // select the repositories you want to publish to + repositories { + // uncomment to publish to the local maven + // mavenLocal() + } +} +""" +} + +static String genPropsFile(String mcVersion, String yarnVersion, String loaderVersion, String fabricVersion, boolean caching = true, boolean parallel = true) { + """ +org.gradle.caching=$caching +org.gradle.parallel=$parallel + +# Fabric Properties +# check these on https://fabricmc.net/use +minecraft_version=$mcVersion +yarn_mappings=$yarnVersion +loader_version=$loaderVersion + +# Mod Properties +mod_version = 1.0.0 +maven_group = net.fabricmc +archives_base_name = fabric-example-mod + +# Dependencies +# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric +fabric_version=$fabricVersion +""" +} + +static String genSettingsFile(String name) { + """ +rootProject.name = '$name' +""" +} + +static String genModJsonFile() { + """ +{ + "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", + + "environment": "*", + "entrypoints": { + "main": [ + "net.fabricmc.example.ExampleMod" + ] + }, + "mixins": [ + "modid.mixins.json" + ], + + "depends": { + "fabricloader": ">=0.4.0", + "fabric": "*" + }, + "suggests": { + "flamingo": "*" + } +} +""" +} + +static String genModJavaFile() { + """ +package net.fabricmc.example; + +import net.fabricmc.api.ModInitializer; + +public class ExampleMod implements ModInitializer { + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + System.out.println("Hello Fabric world!"); + } +} +""" +} + +static String genModMixinsJsonFile() { + """ +{ + "required": true, + "package": "net.fabricmc.example.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + ], + "client": [ + "ExampleMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} +""" +} + +static String genModMixinsJavaFile() { + """ +package net.fabricmc.example.mixin; + +import net.minecraft.client.MinecraftClient; +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(MinecraftClient.class) +public class ExampleMixin { + @Inject(at = @At("HEAD"), method = "init()V") + private void init(CallbackInfo info) { + System.out.println("This line is printed by an example mod mixin!"); + } +} +""" +} diff --git a/src/test/groovy/net/fabricmc/loom/EmptyBuildFunctionalTest.groovy b/src/test/groovy/net/fabricmc/loom/EmptyBuildFunctionalTest.groovy new file mode 100644 index 0000000..55a01a5 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/EmptyBuildFunctionalTest.groovy @@ -0,0 +1,52 @@ +package net.fabricmc.loom + +import org.gradle.testkit.runner.GradleRunner +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification +import spock.lang.Unroll + +import static net.fabricmc.loom.BuildUtils.* +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +/** + * Created by Mitchell Skaggs on 6/10/2019. + */ +class EmptyBuildFunctionalTest extends Specification { + @Rule + TemporaryFolder testProjectDir = new TemporaryFolder() + File settingsFile + File buildFile + File propsFile + + def setup() { + settingsFile = testProjectDir.newFile('settings.gradle') + buildFile = testProjectDir.newFile('build.gradle') + propsFile = testProjectDir.newFile('gradle.properties') + } + + @Unroll + def "empty build succeeds using Minecraft #mcVersion"() { + given: + settingsFile << genSettingsFile("empty-build-functional-test") + propsFile << genPropsFile(mcVersion, yarnVersion, loaderVersion, fabricVersion) + buildFile << genBuildFile() + + when: + def result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('build') + .withPluginClasspath() + .withGradleVersion("5.1.1") + .build() + + then: + result.task(":build").outcome == SUCCESS + + where: + mcVersion | yarnVersion | loaderVersion | fabricVersion + '1.14' | '1.14+build.21' | '0.4.8+build.155' | '0.3.0+build.183' + '1.14.1' | '1.14.1+build.10' | '0.4.8+build.155' | '0.3.0+build.183' + '1.14.2' | '1.14.2+build.7' | '0.4.8+build.155' | '0.3.0+build.183' + } +} diff --git a/src/test/groovy/net/fabricmc/loom/MixinBuildFunctionalTest.groovy b/src/test/groovy/net/fabricmc/loom/MixinBuildFunctionalTest.groovy new file mode 100644 index 0000000..4ac2e90 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/MixinBuildFunctionalTest.groovy @@ -0,0 +1,77 @@ +package net.fabricmc.loom + +import org.gradle.testkit.runner.GradleRunner +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Ignore +import spock.lang.Specification +import spock.lang.Unroll + +import static net.fabricmc.loom.BuildUtils.* +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +/** + * Created by Mitchell Skaggs on 6/10/2019. + */ +class MixinBuildFunctionalTest extends Specification { + @Rule + TemporaryFolder testProjectDir = new TemporaryFolder() + File settingsFile + File buildFile + File propsFile + File modJsonFile + File modJavaFile + File modMixinsJsonFile + File modMixinsJavaFile + + def setup() { + settingsFile = testProjectDir.newFile('settings.gradle') + buildFile = testProjectDir.newFile('build.gradle') + propsFile = testProjectDir.newFile('gradle.properties') + + testProjectDir.newFolder("src", "main", "resources") + modJsonFile = testProjectDir.newFile('src/main/resources/fabric.mod.json') + modMixinsJsonFile = testProjectDir.newFile('src/main/resources/modid.mixins.json') + + testProjectDir.newFolder("src", "main", "java", "net", "fabricmc", "example") + modJavaFile = testProjectDir.newFile("src/main/java/net/fabricmc/example/ExampleMod.java") + + testProjectDir.newFolder("src", "main", "java", "net", "fabricmc", "example", "mixin") + modMixinsJavaFile = testProjectDir.newFile("src/main/java/net/fabricmc/example/mixin/ExampleMixin.java") + } + + /** + * Why it's ignored: + *

+ * When doing mixin annotation processing, a {@link ServiceLoader} is used to find implementations of {@link org.spongepowered.tools.obfuscation.service.IObfuscationService}. The classpath isn't passed to the build properly in this case, causing the Fabric-specific {@link net.fabricmc.loom.mixin.ObfuscationServiceFabric} to not be loaded. This causes the mixin to fail to compile because it doesn't know how to be reobfuscated. + */ + @Unroll + @Ignore("fails because the annotation processor classpath doesn't include fabric-mixin-compile-extensions, so it doesn't know how to remap anything") + def "mixin build succeeds using Minecraft #mcVersion"() { + given: + settingsFile << genSettingsFile("mixin-build-functional-test") + propsFile << genPropsFile(mcVersion, yarnVersion, loaderVersion, fabricVersion) + buildFile << genBuildFile() + modJsonFile << genModJsonFile() + modJavaFile << genModJavaFile() + modMixinsJsonFile << genModMixinsJsonFile() + modMixinsJavaFile << genModMixinsJavaFile() + + when: + def result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('build') + .withPluginClasspath() + .withGradleVersion("5.1.1") + .build() + + then: + result.task(":build").outcome == SUCCESS + + where: + mcVersion | yarnVersion | loaderVersion | fabricVersion + '1.14' | '1.14+build.21' | '0.4.8+build.155' | '0.3.0+build.184' + '1.14.1' | '1.14.1+build.10' | '0.4.8+build.155' | '0.3.0+build.184' + '1.14.2' | '1.14.2+build.7' | '0.4.8+build.155' | '0.3.0+build.184' + } +} diff --git a/src/test/groovy/net/fabricmc/loom/SimpleBuildFunctionalTest.groovy b/src/test/groovy/net/fabricmc/loom/SimpleBuildFunctionalTest.groovy new file mode 100644 index 0000000..9ff669e --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/SimpleBuildFunctionalTest.groovy @@ -0,0 +1,62 @@ +package net.fabricmc.loom + +import org.gradle.testkit.runner.GradleRunner +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification +import spock.lang.Unroll + +import static net.fabricmc.loom.BuildUtils.* +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +/** + * Created by Mitchell Skaggs on 6/10/2019. + */ +class SimpleBuildFunctionalTest extends Specification { + @Rule + TemporaryFolder testProjectDir = new TemporaryFolder() + File settingsFile + File buildFile + File propsFile + File modJsonFile + File modExampleFile + + def setup() { + settingsFile = testProjectDir.newFile('settings.gradle') + buildFile = testProjectDir.newFile('build.gradle') + propsFile = testProjectDir.newFile('gradle.properties') + + testProjectDir.newFolder("src", "main", "resources") + modJsonFile = testProjectDir.newFile('src/main/resources/fabric.mod.json') + + testProjectDir.newFolder("src", "main", "java", "net", "fabricmc", "example") + modExampleFile = testProjectDir.newFile("src/main/java/net/fabricmc/example/ExampleMod.java") + } + + @Unroll + def "simple build succeeds using Minecraft #mcVersion"() { + given: + settingsFile << genSettingsFile("simple-build-functional-test") + propsFile << genPropsFile(mcVersion, yarnVersion, loaderVersion, fabricVersion) + buildFile << genBuildFile() + modJsonFile << genModJsonFile() + modExampleFile << genModJavaFile() + + when: + def result = GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments('build') + .withPluginClasspath() + .withGradleVersion("5.1.1") + .build() + + then: + result.task(":build").outcome == SUCCESS + + where: + mcVersion | yarnVersion | loaderVersion | fabricVersion + '1.14' | '1.14+build.21' | '0.4.8+build.155' | '0.3.0+build.184' + '1.14.1' | '1.14.1+build.10' | '0.4.8+build.155' | '0.3.0+build.184' + '1.14.2' | '1.14.2+build.7' | '0.4.8+build.155' | '0.3.0+build.184' + } +}