diff --git a/gradle/test.libs.versions.toml b/gradle/test.libs.versions.toml index ebccd40a..7688a0cd 100644 --- a/gradle/test.libs.versions.toml +++ b/gradle/test.libs.versions.toml @@ -7,8 +7,8 @@ java-debug = "0.53.1" mixin = "0.15.3+mixin.0.8.7" bouncycastle = "1.82" -gradle-nightly = "9.3.0-20251108020513+0000" -fabric-loader = "0.16.14" +gradle-nightly = "9.4.0-20251123003120+0000" +fabric-loader = "0.18.1" [libraries] spock = { module = "org.spockframework:spock-core", version.ref = "spock" } diff --git a/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java b/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java index b13b1285..04b78fb2 100644 --- a/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java +++ b/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java @@ -53,6 +53,7 @@ import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.JavaExec; import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.Optional; +import org.gradle.process.CommandLineArgumentProvider; import org.gradle.process.ExecOperations; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -117,13 +118,21 @@ public abstract class AbstractRunTask extends JavaExec { config.get().configName) ))); - getArgumentProviders().add(() -> config.get().programArgs); - getArgumentProviders().add(() -> { - if (getTracyCapture().isPresent()) { - return List.of("--tracy"); + getArgumentProviders().add(new CommandLineArgumentProvider() { + @Override + public Iterable asArguments() { + return config.get().programArgs; } + }); + getArgumentProviders().add(new CommandLineArgumentProvider() { + @Override + public Iterable asArguments() { + if (AbstractRunTask.this.getTracyCapture().isPresent()) { + return List.of("--tracy"); + } - return List.of(); + return List.of(); + } }); getMainClass().set(config.map(runConfig -> runConfig.mainClass)); getJvmArguments().addAll(getProject().provider(this::getGameJvmArgs)); diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/noRemap/SimpleDebofTest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/noRemap/SimpleDebofTest.groovy index 2f5ee992..76ec40e4 100644 --- a/src/test/groovy/net/fabricmc/loom/test/integration/noRemap/SimpleDebofTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/integration/noRemap/SimpleDebofTest.groovy @@ -42,6 +42,7 @@ class SimpleDebofTest extends Specification implements GradleProjectTestTrait { dependencies { minecraft 'com.mojang:minecraft:25w45a_unobfuscated' implementation "net.fabricmc:fabric-loader:0.17.3" + implementation "net.fabricmc.fabric-api:fabric-api:0.138.3+1.21.11_unobfuscated" } ''' def sourceFile = new File(gradle.projectDir, "src/main/java/example/Test.java") diff --git a/src/test/groovy/net/fabricmc/loom/test/integration/noRemap/UnobfFabricAPITest.groovy b/src/test/groovy/net/fabricmc/loom/test/integration/noRemap/UnobfFabricAPITest.groovy new file mode 100644 index 00000000..f3ffe717 --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/integration/noRemap/UnobfFabricAPITest.groovy @@ -0,0 +1,100 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2021-2023 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.integration.noRemap + +import java.util.concurrent.TimeUnit + +import spock.lang.Specification +import spock.lang.Timeout + +import net.fabricmc.loom.test.util.GradleProjectTestTrait +import net.fabricmc.loom.test.util.ServerRunner +import net.fabricmc.loom.util.ZipUtils + +import static net.fabricmc.loom.test.LoomTestConstants.PRE_RELEASE_GRADLE +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +@Timeout(value = 30, unit = TimeUnit.MINUTES) +class UnobfFabricAPITest extends Specification implements GradleProjectTestTrait { + def "build and run"() { + setup: + def gradle = gradleProject( + repo: "https://github.com/FabricMC/fabric.git", + commit: "36a5116592042c6e81c9a5eb68cc5c96dc194636", + version: PRE_RELEASE_GRADLE, + patch: "fabric_api_unobf" + ) + + def minecraftVersion = "25w45a_unobfuscated" + def server = ServerRunner.create(gradle.projectDir, minecraftVersion) + .withMod(gradle.getOutputFile("fabric-api-999.0.0.jar")) + + // Test that the dependent mod can be built against the previously built fabric-api + def dependentMod = gradleProject(project: "minimalBaseNoRemap", version: PRE_RELEASE_GRADLE) + dependentMod.buildGradle << """ + repositories { + mavenLocal() + } + + dependencies { + minecraft "com.mojang:minecraft:${minecraftVersion}" + + implementation "net.fabricmc.fabric-api:fabric-api:999.0.0" + } + """ + when: + def result = gradle.run(tasks: [ + "clean", + "build", + "publishToMavenLocal" + ], args: [ + "--parallel", + "-x", + "check", + "-x", + "runDatagen", + "-x", + "runGametest" + ], configurationCache: false) // Note: checkstyle does not appear to like being ran in a test runner + gradle.printOutputFiles() + + def serverResult = server.run() + def dependentModResult = dependentMod.run(task: "build") + + then: + result.task(":build").outcome == SUCCESS + + def biomeApiJar = new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/999.0.0/fabric-biome-api-v1-999.0.0.jar") + def manifest = new String(ZipUtils.unpack(biomeApiJar.toPath(), "META-INF/MANIFEST.MF")) + manifest.contains("Fabric-Mapping-Namespace: official") + + new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/999.0.0/fabric-biome-api-v1-999.0.0-sources.jar").exists() + + serverResult.successful() + serverResult.output.contains("- fabric-api 999.0.0") + + dependentModResult.task(":build").outcome == SUCCESS + } +} diff --git a/src/test/resources/patches/fabric_api_unobf.patch b/src/test/resources/patches/fabric_api_unobf.patch new file mode 100644 index 00000000..ed259c0f --- /dev/null +++ b/src/test/resources/patches/fabric_api_unobf.patch @@ -0,0 +1,37 @@ +diff --git a/build.gradle b/build.gradle +--- a/build.gradle (revision f84dc5662589fd56ac4b36a4b94920a15b1da29d) ++++ b/build.gradle (date 1749475915352) +@@ -9,7 +9,7 @@ + } + + def branchProvider = providers.of(GitBranchValueSource.class) {} +-version = project.version + "+" + (providers.environmentVariable("CI").present ? branchProvider.get().replace("/", "_") : "local") ++version = "999.0.0" + logger.lifecycle("Building Fabric: " + version) + + def metaProjects = [ +@@ -33,22 +33,8 @@ + import java.net.http.HttpRequest + import java.net.http.HttpResponse + +-def getSubprojectVersion(Project project) { +- // Get the version from the gradle.properties file +- def version = project.properties["${project.name}-version"] +- +- if (!version) { +- throw new NullPointerException("Could not find version for " + project.name) +- } +- +- if (!project.providers.environmentVariable("CI").present) { +- return version + "+local" +- } +- +- def hashProvider = project.providers.of(CommitHashValueSource.class) { +- parameters.directory = project.name +- } +- return version + "+" + hashProvider.get().substring(0, 8) + DigestUtils.sha256Hex(project.rootProject.minecraft_version).substring(0, 2) ++def getSubprojectVersion(project) { ++ return "999.0.0" + } + + def moduleDependencies(project, List depNames) {