diff --git a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java index 2577b8bf5..3759cf3a2 100644 --- a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java @@ -93,6 +93,7 @@ import net.fabricmc.loom.util.FileSystemUtil; import net.fabricmc.loom.util.IOStringConsumer; import net.fabricmc.loom.util.Platform; +import net.fabricmc.loom.util.gradle.GradleUtils; import net.fabricmc.loom.util.gradle.SyncTaskBuildService; import net.fabricmc.loom.util.gradle.ThreadedProgressLoggerConsumer; import net.fabricmc.loom.util.gradle.ThreadedSimpleProgressLogger; @@ -174,6 +175,14 @@ public abstract class GenerateSourcesTask extends AbstractLoomTask { @Internal protected abstract RegularFileProperty getDecompileCacheFile(); + @ApiStatus.Internal + @Input + protected abstract Property getMaxCachedFiles(); + + @ApiStatus.Internal + @Input + protected abstract Property getMaxCacheFileAge(); + // Injects @Inject protected abstract WorkerExecutor getWorkerExecutor(); @@ -238,6 +247,9 @@ public GenerateSourcesTask(DecompilerOptions decompilerOptions) { getMappings().set(SourceMappingsService.create(getProject())); + getMaxCachedFiles().set(GradleUtils.getIntegerPropertyProvider(getProject(), Constants.Properties.DECOMPILE_CACHE_MAX_FILES).orElse(50_000)); + getMaxCacheFileAge().set(GradleUtils.getIntegerPropertyProvider(getProject(), Constants.Properties.DECOMPILE_CACHE_MAX_AGE).orElse(90)); + mustRunAfter(getProject().getTasks().withType(AbstractRemapJarTask.class)); } @@ -273,9 +285,17 @@ public void run() throws IOException { } // TODO ensure we have a lock on this file to prevent multiple tasks from running at the same time - // TODO handle being unable to read the cache file Files.createDirectories(cacheFile.getParent()); + if (Files.exists(cacheFile)) { + try (FileSystemUtil.Delegate fs = FileSystemUtil.getJarFileSystem(cacheFile, true)) { + // Success, cache exists and can be read + } catch (IOException e) { + getLogger().warn("Discarding invalid decompile cache file: {}", cacheFile, e); + Files.delete(cacheFile); + } + } + try (FileSystemUtil.Delegate fs = FileSystemUtil.getJarFileSystem(cacheFile, true)) { runWithCache(fs.getRoot()); } @@ -289,13 +309,14 @@ private void runWithCache(Path cacheRoot) throws IOException { final Path classesInputJar = getClassesInputJar().getSingleFile().toPath(); final Path sourcesOutputJar = getSourcesOutputJar().get().getAsFile().toPath(); final Path classesOutputJar = getClassesOutputJar().getSingleFile().toPath(); - final var cacheRules = new CachedFileStoreImpl.CacheRules(50_000, Duration.ofDays(90)); + final var cacheRules = new CachedFileStoreImpl.CacheRules(getMaxCachedFiles().get(), Duration.ofDays(getMaxCacheFileAge().get())); final var decompileCache = new CachedFileStoreImpl<>(cacheRoot, CachedData.SERIALIZER, cacheRules); final String cacheKey = getCacheKey(); final CachedJarProcessor cachedJarProcessor = new CachedJarProcessor(decompileCache, cacheKey); final CachedJarProcessor.WorkRequest workRequest; getLogger().info("Decompile cache key: {}", cacheKey); + getLogger().debug("Decompile cache rules: {}", cacheRules); try (var timer = new Timer("Prepare job")) { workRequest = cachedJarProcessor.prepareJob(classesInputJar); diff --git a/src/main/java/net/fabricmc/loom/util/Constants.java b/src/main/java/net/fabricmc/loom/util/Constants.java index b03c6a21c..b197ee992 100644 --- a/src/main/java/net/fabricmc/loom/util/Constants.java +++ b/src/main/java/net/fabricmc/loom/util/Constants.java @@ -139,6 +139,8 @@ public static final class Properties { * Only set this when you have a good reason to do so, the default should be fine for almost all cases. */ public static final String RUNTIME_JAVA_COMPATIBILITY_VERSION = "fabric.loom.runtimeJavaCompatibilityVersion"; + public static final String DECOMPILE_CACHE_MAX_FILES = "fabric.loom.decompileCacheMaxFiles"; + public static final String DECOMPILE_CACHE_MAX_AGE = "fabric.loom.decompileCacheMaxAge"; } public static final class Manifest { diff --git a/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java b/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java index f977cbf97..15685104b 100644 --- a/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java +++ b/src/main/java/net/fabricmc/loom/util/gradle/GradleUtils.java @@ -86,6 +86,22 @@ public static Provider getBooleanPropertyProvider(Project project, Stri }); } + public static Provider getIntegerPropertyProvider(Project project, String key) { + return project.provider(() -> { + final Object value = project.findProperty(key); + + if (value == null) { + return null; + } + + try { + return Integer.parseInt(value.toString()); + } catch (final NumberFormatException ex) { + throw new IllegalArgumentException("Property " + key + " must be an integer", ex); + } + }); + } + public static boolean getBooleanProperty(Project project, String key) { return getBooleanPropertyProvider(project, key).getOrElse(false); }