Initial config caching work (#1053)

This commit is contained in:
modmuss
2024-04-15 18:56:59 +01:00
committed by GitHub
parent b8da4e5498
commit 9a3b82c8a3
13 changed files with 353 additions and 68 deletions

View File

@@ -6,7 +6,6 @@ plugins {
id 'eclipse'
id 'groovy'
id 'checkstyle'
id 'jacoco'
id 'codenarc'
alias(libs.plugins.kotlin) apply false // Delay this so we can perform magic 🪄 first.
alias(libs.plugins.spotless)
@@ -267,20 +266,6 @@ gradlePlugin {
}
}
jacoco {
toolVersion = libs.versions.jacoco.get()
}
// Run to get test coverage.
jacocoTestReport {
dependsOn test
reports {
xml.required = false
csv.required = false
html.outputLocation = file("${layout.buildDirectory.get().asFile}/jacocoHtml")
}
}
test {
maxHeapSize = "2560m"
jvmArgs "-XX:+HeapDumpOnOutOfMemoryError"

View File

@@ -125,4 +125,6 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI {
Collection<LayeredMappingsFactory> getLayeredMappingFactories();
LoomProblemReporter getProblemReporter();
boolean isConfigurationCacheActive();
}

View File

@@ -32,7 +32,10 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import javax.inject.Inject;
import org.gradle.api.Project;
import org.gradle.api.configuration.BuildFeatures;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.FileCollection;
import org.gradle.api.provider.ListProperty;
@@ -57,7 +60,7 @@ import net.fabricmc.loom.util.download.Download;
import net.fabricmc.loom.util.download.DownloadBuilder;
import net.fabricmc.loom.util.gradle.GradleUtils;
public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implements LoomGradleExtension {
public abstract class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implements LoomGradleExtension {
private final Project project;
private final MixinExtension mixinApExtension;
private final LoomFiles loomFiles;
@@ -72,10 +75,16 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen
private IntermediaryMinecraftProvider<?> intermediaryMinecraftProvider;
private InstallerData installerData;
private boolean refreshDeps;
private Provider<Boolean> multiProjectOptimisation;
private final Provider<Boolean> multiProjectOptimisation;
private final ListProperty<LibraryProcessorManager.LibraryProcessorFactory> libraryProcessorFactories;
private final LoomProblemReporter problemReporter;
private final boolean configurationCacheActive;
private final boolean isolatedProjectsActive;
@Inject
protected abstract BuildFeatures getBuildFeatures();
@Inject
public LoomGradleExtensionImpl(Project project, LoomFiles files) {
super(project, files);
this.project = project;
@@ -99,6 +108,22 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen
libraryProcessorFactories.addAll(LibraryProcessorManager.DEFAULT_LIBRARY_PROCESSORS);
libraryProcessorFactories.finalizeValueOnRead();
configurationCacheActive = getBuildFeatures().getConfigurationCache().getActive().get();
isolatedProjectsActive = getBuildFeatures().getIsolatedProjects().getActive().get();
// Fundamentally impossible to support multi-project optimisation with the configuration cache and/or isolated projects.
if (multiProjectOptimisation.get() && configurationCacheActive) {
throw new UnsupportedOperationException("Multi-project optimisation is not supported with the configuration cache");
}
if (multiProjectOptimisation.get() && isolatedProjectsActive) {
throw new UnsupportedOperationException("Isolated projects are not supported with multi-project optimisation");
}
if (configurationCacheActive) {
project.getLogger().warn("Loom support for the Gradle configuration cache is highly experimental and may not work as expected. Please report any issues you encounter.");
}
if (refreshDeps) {
project.getLogger().lifecycle("Refresh dependencies is in use, loom will be significantly slower.");
}
@@ -286,4 +311,9 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen
public LoomProblemReporter getProblemReporter() {
return problemReporter;
}
@Override
public boolean isConfigurationCacheActive() {
return configurationCacheActive;
}
}

View File

@@ -34,17 +34,18 @@ import javax.inject.Inject;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
import org.gradle.internal.logging.progress.ProgressLoggerFactory;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.LoomGradlePlugin;
import net.fabricmc.loom.configuration.ide.RunConfigSettings;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
import net.fabricmc.loom.configuration.providers.minecraft.assets.AssetIndex;
import net.fabricmc.loom.util.MirrorUtil;
import net.fabricmc.loom.util.download.DownloadExecutor;
import net.fabricmc.loom.util.download.DownloadFactory;
import net.fabricmc.loom.util.download.GradleDownloadProgressListener;
import net.fabricmc.loom.util.gradle.ProgressGroup;
@@ -58,12 +59,24 @@ public abstract class DownloadAssetsTask extends AbstractLoomTask {
@Input
public abstract Property<String> getMinecraftVersion();
@Input
public abstract Property<String> getResourcesBaseUrl();
@Input
protected abstract Property<String> getAssetsIndexJson();
@OutputDirectory
public abstract RegularFileProperty getAssetsDirectory();
@OutputDirectory
public abstract RegularFileProperty getLegacyResourcesDirectory();
@Inject
protected abstract ProgressLoggerFactory getProgressLoggerFactory();
@Nested
protected abstract DownloadFactory getDownloadFactory();
@Inject
public DownloadAssetsTask() {
final MinecraftVersionMeta versionInfo = getExtension().getMinecraftProvider().getVersionInfo();
@@ -83,6 +96,11 @@ public abstract class DownloadAssetsTask extends AbstractLoomTask {
getLegacyResourcesDirectory().set(new File(getProject().getProjectDir(), client.getRunDir() + "/resources"));
}
getResourcesBaseUrl().set(MirrorUtil.getResourcesBase(getProject()));
getResourcesBaseUrl().finalizeValue();
getAssetsIndexJson().set(LoomGradlePlugin.GSON.toJson(getExtension().getMinecraftProvider().getVersionInfo().assetIndex()));
getAssetsHash().finalizeValue();
getAssetsDirectory().finalizeValueOnRead();
getLegacyResourcesDirectory().finalizeValueOnRead();
@@ -92,13 +110,13 @@ public abstract class DownloadAssetsTask extends AbstractLoomTask {
public void downloadAssets() throws IOException {
final AssetIndex assetIndex = getAssetIndex();
try (ProgressGroup progressGroup = new ProgressGroup(getProject(), "Download Assets");
try (ProgressGroup progressGroup = new ProgressGroup("Download Assets", getProgressLoggerFactory());
DownloadExecutor executor = new DownloadExecutor(getDownloadThreads().get())) {
for (AssetIndex.Object object : assetIndex.getObjects()) {
final String sha1 = object.hash();
final String url = MirrorUtil.getResourcesBase(getProject()) + sha1.substring(0, 2) + "/" + sha1;
final String url = getResourcesBaseUrl().get() + sha1.substring(0, 2) + "/" + sha1;
getExtension()
getDownloadFactory()
.download(url)
.sha1(sha1)
.progress(new GradleDownloadProgressListener(object.name(), progressGroup::createProgressLogger))
@@ -107,18 +125,11 @@ public abstract class DownloadAssetsTask extends AbstractLoomTask {
}
}
private MinecraftVersionMeta.AssetIndex getAssetIndexMeta() {
MinecraftVersionMeta versionInfo = getExtension().getMinecraftProvider().getVersionInfo();
return versionInfo.assetIndex();
}
private AssetIndex getAssetIndex() throws IOException {
final LoomGradleExtension extension = getExtension();
final MinecraftProvider minecraftProvider = extension.getMinecraftProvider();
final MinecraftVersionMeta.AssetIndex assetIndex = getAssetIndexMeta();
final File indexFile = new File(getAssetsDirectory().get().getAsFile(), "indexes" + File.separator + assetIndex.fabricId(minecraftProvider.minecraftVersion()) + ".json");
final MinecraftVersionMeta.AssetIndex assetIndex = LoomGradlePlugin.GSON.fromJson(getAssetsIndexJson().get(), MinecraftVersionMeta.AssetIndex.class);
final File indexFile = new File(getAssetsDirectory().get().getAsFile(), "indexes" + File.separator + assetIndex.fabricId(getMinecraftVersion().get()) + ".json");
final String json = extension.download(assetIndex.url())
final String json = getDownloadFactory().download(assetIndex.url())
.sha1(assetIndex.sha1())
.downloadString(indexFile.toPath());

View File

@@ -56,18 +56,22 @@ public abstract class LoomTasks implements Runnable {
t.setDescription("Migrates mappings to a new version.");
t.getOutputs().upToDateWhen(o -> false);
});
var generateLog4jConfig = getTasks().register("generateLog4jConfig", GenerateLog4jConfigTask.class, t -> {
t.setDescription("Generate the log4j config file");
});
var generateRemapClasspath = getTasks().register("generateRemapClasspath", GenerateRemapClasspathTask.class, t -> {
t.setDescription("Generate the remap classpath file");
});
getTasks().register("generateDLIConfig", GenerateDLIConfigTask.class, t -> {
t.setDescription("Generate the DevLaunchInjector config file");
// Must allow these IDE files to be generated first
t.mustRunAfter(getTasks().named("eclipse"));
t.mustRunAfter(getTasks().named("idea"));
});
getTasks().register("generateLog4jConfig", GenerateLog4jConfigTask.class, t -> {
t.setDescription("Generate the log4j config file");
});
getTasks().register("generateRemapClasspath", GenerateRemapClasspathTask.class, t -> {
t.setDescription("Generate the remap classpath file");
t.dependsOn(generateLog4jConfig);
t.getRemapClasspathFile().set(generateRemapClasspath.get().getRemapClasspathFile());
});
getTasks().register("configureLaunch", task -> {

View File

@@ -36,19 +36,93 @@ import java.util.StringJoiner;
import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
import org.gradle.api.Project;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.logging.configuration.ConsoleOutput;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.LoomGradlePlugin;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta;
import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider;
import net.fabricmc.loom.task.AbstractLoomTask;
import net.fabricmc.loom.util.gradle.SourceSetHelper;
public abstract class GenerateDLIConfigTask extends AbstractLoomTask {
@Input
protected abstract Property<String> getVersionInfoJson();
@Input
protected abstract Property<String> getMinecraftVersion();
@Input
protected abstract Property<Boolean> getSplitSourceSets();
@Input
protected abstract Property<Boolean> getPlainConsole();
@Input
protected abstract Property<Boolean> getANSISupportedIDE();
@Input
@Optional
protected abstract Property<String> getClassPathGroups();
@Input
protected abstract Property<String> getLog4jConfigPaths();
@Input
@Optional
protected abstract Property<String> getClientGameJarPath();
@Input
@Optional
protected abstract Property<String> getCommonGameJarPath();
@Input
protected abstract Property<String> getAssetsDirectoryPath();
@Input
protected abstract Property<String> getNativesDirectoryPath();
@InputFile
public abstract RegularFileProperty getRemapClasspathFile();
@OutputFile
protected abstract RegularFileProperty getDevLauncherConfig();
public GenerateDLIConfigTask() {
getVersionInfoJson().set(LoomGradlePlugin.GSON.toJson(getExtension().getMinecraftProvider().getVersionInfo()));
getMinecraftVersion().set(getExtension().getMinecraftProvider().minecraftVersion());
getSplitSourceSets().set(getExtension().areEnvironmentSourceSetsSplit());
getANSISupportedIDE().set(ansiSupportedIde(getProject()));
getPlainConsole().set(getProject().getGradle().getStartParameter().getConsoleOutput() == ConsoleOutput.Plain);
if (!getExtension().getMods().isEmpty()) {
getClassPathGroups().set(buildClassPathGroups(getProject()));
}
getLog4jConfigPaths().set(getAllLog4JConfigFiles(getProject()));
if (getSplitSourceSets().get()) {
getClientGameJarPath().set(getGameJarPath("client"));
getCommonGameJarPath().set(getGameJarPath("common"));
}
getAssetsDirectoryPath().set(new File(getExtension().getFiles().getUserCache(), "assets").getAbsolutePath());
getNativesDirectoryPath().set(getExtension().getFiles().getNativesDirectory(getProject()).getAbsolutePath());
getDevLauncherConfig().set(getExtension().getFiles().getDevLauncherConfig());
}
@TaskAction
public void run() throws IOException {
final MinecraftVersionMeta versionInfo = getExtension().getMinecraftProvider().getVersionInfo();
File assetsDirectory = new File(getExtension().getFiles().getUserCache(), "assets");
final MinecraftVersionMeta versionInfo = LoomGradlePlugin.GSON.fromJson(getVersionInfoJson().get(), MinecraftVersionMeta.class);
File assetsDirectory = new File(getAssetsDirectoryPath().get());
if (versionInfo.assets().equals("legacy")) {
assetsDirectory = new File(assetsDirectory, "/legacy/" + versionInfo.id());
@@ -56,48 +130,42 @@ public abstract class GenerateDLIConfigTask extends AbstractLoomTask {
final LaunchConfig launchConfig = new LaunchConfig()
.property("fabric.development", "true")
.property("fabric.remapClasspathFile", getExtension().getFiles().getRemapClasspathFile().getAbsolutePath())
.property("log4j.configurationFile", getAllLog4JConfigFiles())
.property("fabric.remapClasspathFile", getRemapClasspathFile().get().getAsFile().getAbsolutePath())
.property("log4j.configurationFile", getLog4jConfigPaths().get())
.property("log4j2.formatMsgNoLookups", "true")
.argument("client", "--assetIndex")
.argument("client", getExtension().getMinecraftProvider().getVersionInfo().assetIndex().fabricId(getExtension().getMinecraftProvider().minecraftVersion()))
.argument("client", versionInfo.assetIndex().fabricId(getMinecraftVersion().get()))
.argument("client", "--assetsDir")
.argument("client", assetsDirectory.getAbsolutePath());
if (versionInfo.hasNativesToExtract()) {
String nativesPath = getExtension().getFiles().getNativesDirectory(getProject()).getAbsolutePath();
String nativesPath = getNativesDirectoryPath().get();
launchConfig
.property("client", "java.library.path", nativesPath)
.property("client", "org.lwjgl.librarypath", nativesPath);
}
if (getExtension().areEnvironmentSourceSetsSplit()) {
launchConfig.property("client", "fabric.gameJarPath.client", getGameJarPath("client"));
launchConfig.property("fabric.gameJarPath", getGameJarPath("common"));
if (getSplitSourceSets().get()) {
launchConfig.property("client", "fabric.gameJarPath.client", getClientGameJarPath().get());
launchConfig.property("fabric.gameJarPath", getCommonGameJarPath().get());
}
if (!getExtension().getMods().isEmpty()) {
launchConfig.property("fabric.classPathGroups", getClassPathGroups());
if (getClassPathGroups().isPresent()) {
launchConfig.property("fabric.classPathGroups", getClassPathGroups().get());
}
final boolean plainConsole = getProject().getGradle().getStartParameter().getConsoleOutput() == ConsoleOutput.Plain;
final boolean ansiSupportedIDE = new File(getProject().getRootDir(), ".vscode").exists()
|| new File(getProject().getRootDir(), ".idea").exists()
|| new File(getProject().getRootDir(), ".project").exists()
|| (Arrays.stream(getProject().getRootDir().listFiles()).anyMatch(file -> file.getName().endsWith(".iws")));
//Enable ansi by default for idea and vscode when gradle is not ran with plain console.
if (ansiSupportedIDE && !plainConsole) {
if (getANSISupportedIDE().get() && !getPlainConsole().get()) {
launchConfig.property("fabric.log.disableAnsi", "false");
}
FileUtils.writeStringToFile(getExtension().getFiles().getDevLauncherConfig(), launchConfig.asString(), StandardCharsets.UTF_8);
FileUtils.writeStringToFile(getDevLauncherConfig().getAsFile().get(), launchConfig.asString(), StandardCharsets.UTF_8);
}
private String getAllLog4JConfigFiles() {
return getExtension().getLog4jConfigs().getFiles().stream()
private static String getAllLog4JConfigFiles(Project project) {
return LoomGradleExtension.get(project).getLog4jConfigs().getFiles().stream()
.map(File::getAbsolutePath)
.collect(Collectors.joining(","));
}
@@ -115,16 +183,24 @@ public abstract class GenerateDLIConfigTask extends AbstractLoomTask {
/**
* See: https://github.com/FabricMC/fabric-loader/pull/585.
*/
private String getClassPathGroups() {
return getExtension().getMods().stream()
private static String buildClassPathGroups(Project project) {
return LoomGradleExtension.get(project).getMods().stream()
.map(modSettings ->
SourceSetHelper.getClasspath(modSettings, getProject()).stream()
SourceSetHelper.getClasspath(modSettings, project).stream()
.map(File::getAbsolutePath)
.collect(Collectors.joining(File.pathSeparator))
)
.collect(Collectors.joining(File.pathSeparator+File.pathSeparator));
}
private static boolean ansiSupportedIde(Project project) {
File rootDir = project.getRootDir();
return new File(rootDir, ".vscode").exists()
|| new File(rootDir, ".idea").exists()
|| new File(rootDir, ".project").exists()
|| (Arrays.stream(rootDir.listFiles()).anyMatch(file -> file.getName().endsWith(".iws")));
}
public static class LaunchConfig {
private final Map<String, List<String>> values = new HashMap<>();

View File

@@ -29,14 +29,26 @@ import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.inject.Inject;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import net.fabricmc.loom.task.AbstractLoomTask;
public abstract class GenerateLog4jConfigTask extends AbstractLoomTask {
@OutputFile
public abstract RegularFileProperty getOutputFile();
@Inject
public GenerateLog4jConfigTask() {
getOutputFile().set(getExtension().getFiles().getDefaultLog4jConfigFile());
}
@TaskAction
public void run() {
Path outputFile = getExtension().getFiles().getDefaultLog4jConfigFile().toPath();
Path outputFile = getOutputFile().get().getAsFile().toPath();
try (InputStream is = GenerateLog4jConfigTask.class.getClassLoader().getResourceAsStream("log4j2.fabric.xml")) {
Files.deleteIfExists(outputFile);

View File

@@ -60,6 +60,10 @@ public abstract class GenerateRemapClasspathTask extends AbstractLoomTask {
.map(configurations::named)
.forEach(getRemapClasspath()::from);
for (Path minecraftJar : getExtension().getMinecraftJars(MappingsNamespace.INTERMEDIARY)) {
getRemapClasspath().from(minecraftJar.toFile());
}
getRemapClasspathFile().set(getExtension().getFiles().getRemapClasspathFile());
}
@@ -67,10 +71,6 @@ public abstract class GenerateRemapClasspathTask extends AbstractLoomTask {
public void run() {
final List<File> remapClasspath = new ArrayList<>(getRemapClasspath().getFiles());
for (Path minecraftJar : getExtension().getMinecraftJars(MappingsNamespace.INTERMEDIARY)) {
remapClasspath.add(minecraftJar.toFile());
}
String str = remapClasspath.stream()
.map(File::getAbsolutePath)
.collect(Collectors.joining(File.pathSeparator));

View File

@@ -0,0 +1,76 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 2024 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.util.download;
import java.net.URISyntaxException;
import javax.inject.Inject;
import org.gradle.api.Project;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import net.fabricmc.loom.LoomGradleExtension;
/**
* Can be used to create a {@link DownloadBuilder} with the correct settings for the project within a task.
*/
public abstract class DownloadFactory {
@Input
protected abstract Property<Boolean> getIsOffline();
@Input
protected abstract Property<Boolean> getIsManualRefreshDependencies();
@Inject
public abstract Project getProject();
@Inject
public DownloadFactory() {
getIsOffline().set(getProject().getGradle().getStartParameter().isOffline());
getIsManualRefreshDependencies().set(LoomGradleExtension.get(getProject()).refreshDeps());
}
// Matches the logic in LoomGradleExtensionImpl
public DownloadBuilder download(String url) {
DownloadBuilder builder;
try {
builder = Download.create(url);
} catch (URISyntaxException e) {
throw new RuntimeException("Failed to create downloader for: " + e);
}
if (getIsOffline().get()) {
builder.offline();
}
if (getIsManualRefreshDependencies().get()) {
builder.forceDownload();
}
return builder;
}
}

View File

@@ -43,6 +43,11 @@ public class ProgressGroup implements Closeable {
this.progressLoggerFactory = ((ProjectInternal) project).getServices().get(ProgressLoggerFactory.class);
}
public ProgressGroup(String name, ProgressLoggerFactory progressLoggerFactory) {
this.name = name;
this.progressLoggerFactory = progressLoggerFactory;
}
private void start() {
this.progressGroup = this.progressLoggerFactory.newOperation(name).setDescription(name);
this.progressGroup.started();

View File

@@ -50,6 +50,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
import org.xml.sax.InputSource;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.api.ModSettings;
import net.fabricmc.loom.configuration.ide.idea.IdeaUtils;
@@ -236,6 +237,15 @@ public final class SourceSetHelper {
Objects.requireNonNull(sourceSet);
Objects.requireNonNull(path);
final Project project = getSourceSetProject(sourceSet);
final LoomGradleExtension extension = LoomGradleExtension.get(project);
if (extension.isConfigurationCacheActive()) {
// TODO config cache, figure this out
project.getLogger().warn("Unable to find resource ({}) in source set ({}) when configuration cache is active", path, sourceSet.getName());
return null;
}
try {
return sourceSet.getResources()
.matching(patternFilterable -> patternFilterable.include(path))

View File

@@ -0,0 +1,61 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 2024 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
import spock.lang.Specification
import spock.lang.Unroll
import net.fabricmc.loom.test.util.GradleProjectTestTrait
import static net.fabricmc.loom.test.LoomTestConstants.PRE_RELEASE_GRADLE
import static org.gradle.testkit.runner.TaskOutcome.FAILED
class ConfigurationCacheTest extends Specification implements GradleProjectTestTrait {
@Unroll
def "Configuration cache (task #task)"() {
setup:
def gradle = gradleProject(project: "minimalBase", version: PRE_RELEASE_GRADLE)
gradle.buildGradle << """
dependencies {
minecraft 'com.mojang:minecraft:1.20.4'
mappings 'net.fabricmc:yarn:1.20.4+build.3:v2'
modImplementation 'net.fabricmc:fabric-loader:0.15.6'
modImplementation 'net.fabricmc.fabric-api:fabric-api:0.95.4+1.20.4'
}
""".stripIndent()
when:
def result = gradle.run(task: task, configurationCache: true, isloatedProjects: false)
def result2 = gradle.run(task: task, configurationCache: true, isloatedProjects: false)
then:
result.task(":${task}").outcome != FAILED
result2.task(":${task}").outcome != FAILED
where:
task | _
"help" | _
"configureClientLaunch" | _
}
}

View File

@@ -150,6 +150,7 @@ trait GradleProjectTestTrait {
private String gradleHomeDir
private String warningMode
private boolean useBuildSrc
private boolean enableDebugging = true
BuildResult run(Map options) {
// Setup the system props to tell loom that its running in a test env
@@ -165,6 +166,14 @@ trait GradleProjectTestTrait {
args << options.task
}
if (options.configurationCache || System.getenv("LOOM_TEST_CONFIGURATION_CACHE") != null) {
args << "--configuration-cache"
}
if (options.isloatedProjects) {
args << "-Dorg.gradle.unsafe.isolated-projects=true"
}
args.addAll(options.tasks ?: [])
args << "--stacktrace"
@@ -179,6 +188,10 @@ trait GradleProjectTestTrait {
writeBuildSrcDeps(runner)
}
if (options.disableDebugging) {
enableDebugging = false
}
return options.expectFailure ? runner.buildAndFail() : runner.build()
}
@@ -188,7 +201,7 @@ trait GradleProjectTestTrait {
.withPluginClasspath()
.withGradleVersion(gradleVersion)
.forwardOutput()
.withDebug(true)
.withDebug(enableDebugging)
}
File getProjectDir() {