Add a lock file around building the loom cache. Regenerate if the lock file exists.

This helps to ensure that failed or canceled builds do not cause the cache to be left in an undetectable invalid state.
This commit is contained in:
modmuss50
2022-07-30 19:21:56 +01:00
parent c7e10a596e
commit 3913c2e897
17 changed files with 97 additions and 35 deletions

View File

@@ -109,4 +109,8 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI {
void addTransitiveAccessWideners(List<AccessWidenerFile> accessWidenerFiles);
DownloadBuilder download(String url);
boolean refreshDeps();
void setRefreshDeps(boolean refreshDeps);
}

View File

@@ -48,7 +48,6 @@ import net.fabricmc.loom.task.LoomTasks;
import net.fabricmc.loom.util.LibraryLocationLogger;
public class LoomGradlePlugin implements BootstrappedPlugin {
public static boolean refreshDeps;
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
public static final String LOOM_VERSION = Objects.requireNonNullElse(LoomGradlePlugin.class.getPackage().getImplementationVersion(), "0.0.0+unknown");
@@ -66,12 +65,6 @@ public class LoomGradlePlugin implements BootstrappedPlugin {
project.getLogger().lifecycle("Fabric Loom: " + LOOM_VERSION);
LibraryLocationLogger.logLibraryVersions();
refreshDeps = project.getGradle().getStartParameter().isRefreshDependencies() || Boolean.getBoolean("loom.refresh");
if (refreshDeps) {
project.getLogger().lifecycle("Refresh dependencies is in use, loom will be significantly slower.");
}
// Apply default plugins
project.apply(ImmutableMap.of("plugin", "java-library"));
project.apply(ImmutableMap.of("plugin", "eclipse"));

View File

@@ -57,4 +57,6 @@ public interface MappingContext {
Logger getLogger();
DownloadBuilder download(String url);
boolean refreshDeps();
}

View File

@@ -24,7 +24,11 @@
package net.fabricmc.loom.configuration;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.gradle.api.NamedDomainObjectProvider;
@@ -32,7 +36,6 @@ import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.tasks.AbstractCopyTask;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.compile.JavaCompile;
@@ -114,7 +117,6 @@ public final class CompileConfiguration {
}
public static void configureCompile(Project p) {
final JavaPluginExtension javaPluginExtension = p.getExtensions().getByType(JavaPluginExtension.class);
LoomGradleExtension extension = LoomGradleExtension.get(p);
p.getTasks().named(JavaPlugin.JAVADOC_TASK_NAME, Javadoc.class).configure(javadoc -> {
@@ -125,6 +127,13 @@ public final class CompileConfiguration {
p.afterEvaluate(project -> {
MinecraftSourceSets.get(project).afterEvaluate(project);
final boolean previousRefreshDeps = extension.refreshDeps();
if (getAndLock(project)) {
project.getLogger().lifecycle("Found existing cache lock file, rebuilding loom cache. This may have been caused by a failed or canceled build.");
extension.setRefreshDeps(true);
}
try {
setupMinecraft(project);
} catch (Exception e) {
@@ -135,6 +144,9 @@ public final class CompileConfiguration {
extension.setDependencyManager(dependencyManager);
dependencyManager.handleDependencies(project);
releaseLock(project);
extension.setRefreshDeps(previousRefreshDeps);
MixinExtension mixin = LoomGradleExtension.get(project).getMixin();
if (mixin.getUseLegacyMixinAp().get()) {
@@ -270,6 +282,38 @@ public final class CompileConfiguration {
.apply(project, extension.getNamedMinecraftProvider()).afterEvaluation();
}
private static Path getLockFile(Project project) {
final LoomGradleExtension extension = LoomGradleExtension.get(project);
final Path cacheDirectory = extension.getFiles().getProjectPersistentCache().toPath();
return cacheDirectory.resolve("configuration.lock");
}
private static boolean getAndLock(Project project) {
final Path lock = getLockFile(project);
if (Files.exists(lock)) {
return true;
}
try {
Files.createFile(lock);
} catch (IOException e) {
throw new UncheckedIOException("Failed to acquire project configuration lock", e);
}
return false;
}
private static void releaseLock(Project project) {
final Path lock = getLockFile(project);
try {
Files.deleteIfExists(lock);
} catch (IOException e) {
throw new UncheckedIOException("Failed to release project configuration lock", e);
}
}
public static void extendsFrom(List<String> parents, String b, Project project) {
for (String parent : parents) {
extendsFrom(parent, b, project);

View File

@@ -49,7 +49,6 @@ import org.gradle.language.base.artifact.SourcesArtifact;
import org.jetbrains.annotations.Nullable;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.LoomGradlePlugin;
import net.fabricmc.loom.api.RemapConfigurationSettings;
import net.fabricmc.loom.configuration.processors.dependency.ModDependencyInfo;
import net.fabricmc.loom.configuration.processors.dependency.RemapData;
@@ -67,7 +66,6 @@ public class ModConfigurationRemapper {
public static void supplyModConfigurations(Project project, String mappingsSuffix, LoomGradleExtension extension, SourceRemapper sourceRemapper) {
final DependencyHandler dependencies = project.getDependencies();
final boolean refreshDeps = LoomGradlePlugin.refreshDeps;
final File modStore = extension.getFiles().getRemappedModCache();
final RemapData remapData = new RemapData(mappingsSuffix, modStore);
@@ -99,7 +97,7 @@ public class ModConfigurationRemapper {
final ModDependencyInfo info = new ModDependencyInfo(artifact, remappedConfig, clientRemappedConfig, remapData);
if (refreshDeps) {
if (extension.refreshDeps()) {
info.forceRemap();
}
@@ -198,7 +196,7 @@ public class ModConfigurationRemapper {
return;
}
if (!output.exists() || input.lastModified() <= 0 || input.lastModified() > output.lastModified() || LoomGradlePlugin.refreshDeps) {
if (!output.exists() || input.lastModified() <= 0 || input.lastModified() > output.lastModified() || LoomGradleExtension.get(project).refreshDeps()) {
sourceRemapper.scheduleRemapSources(input, output, false, true); // Depenedency sources are used in ide only so don't need to be reproducable
} else {
project.getLogger().info(output.getName() + " is up to date with " + input.getName());

View File

@@ -89,6 +89,11 @@ public class GradleMappingContext implements MappingContext {
return extension.download(url);
}
@Override
public boolean refreshDeps() {
return extension.refreshDeps();
}
public Project getProject() {
return project;
}

View File

@@ -34,7 +34,6 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.fabricmc.loom.LoomGradlePlugin;
import net.fabricmc.loom.api.mappings.intermediate.IntermediateMappingsProvider;
public abstract class IntermediaryMappingsProvider extends IntermediateMappingsProvider {
@@ -42,9 +41,11 @@ public abstract class IntermediaryMappingsProvider extends IntermediateMappingsP
public abstract Property<String> getIntermediaryUrl();
public abstract Property<Boolean> getRefreshDeps();
@Override
public void provide(Path tinyMappings) throws IOException {
if (Files.exists(tinyMappings) && !LoomGradlePlugin.refreshDeps) {
if (Files.exists(tinyMappings) && !getRefreshDeps().get()) {
return;
}

View File

@@ -76,7 +76,7 @@ public class LayeredMappingsDependency implements SelfResolvingDependency, FileC
Path mappingsDir = mappingContext.minecraftProvider().dir("layered").toPath();
Path mappingsFile = mappingsDir.resolve(String.format("%s.%s-%s.tiny", GROUP, MODULE, getVersion()));
if (!Files.exists(mappingsFile) || LoomGradlePlugin.refreshDeps) {
if (!Files.exists(mappingsFile) || mappingContext.refreshDeps()) {
try {
var processor = new LayeredMappingsProcessor(layeredMappingSpec);
List<MappingLayer> layers = processor.resolveLayers(mappingContext);

View File

@@ -137,11 +137,11 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService {
}
private void setup(MinecraftProvider minecraftProvider, Path inputJar) throws IOException {
if (isRefreshDeps()) {
if (minecraftProvider.refreshDeps()) {
cleanWorkingDirectory(mappingsWorkingDir);
}
if (Files.notExists(tinyMappings) || isRefreshDeps()) {
if (Files.notExists(tinyMappings) || minecraftProvider.refreshDeps()) {
storeMappings(minecraftProvider, inputJar);
} else {
try (FileSystem fileSystem = FileSystems.newFileSystem(inputJar, (ClassLoader) null)) {
@@ -149,7 +149,7 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService {
}
}
if (Files.notExists(tinyMappingsJar) || isRefreshDeps()) {
if (Files.notExists(tinyMappingsJar) || minecraftProvider.refreshDeps()) {
Files.deleteIfExists(tinyMappingsJar);
ZipUtils.add(tinyMappingsJar, "mappings/mappings.tiny", Files.readAllBytes(tinyMappings));
}
@@ -364,10 +364,6 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService {
public record UnpickMetadata(String unpickGroup, String unpickVersion) {
}
protected static boolean isRefreshDeps() {
return LoomGradlePlugin.refreshDeps;
}
@Override
public void close() throws IOException {
mappingTree = null;

View File

@@ -61,7 +61,7 @@ public final class MergedMinecraftProvider extends MinecraftProvider {
throw new UnsupportedOperationException("Minecraft versions 1.2.5 and older cannot be merged. Please use `loom { server/clientOnlyMinecraftJar() }`");
}
if (!Files.exists(minecraftMergedJar) || isRefreshDeps()) {
if (!Files.exists(minecraftMergedJar) || getExtension().refreshDeps()) {
try {
mergeJars();
} catch (Throwable e) {

View File

@@ -277,7 +277,7 @@ public abstract class MinecraftProvider {
return LoomGradleExtension.get(getProject());
}
protected boolean isRefreshDeps() {
return LoomGradlePlugin.refreshDeps;
public boolean refreshDeps() {
return getExtension().refreshDeps();
}
}

View File

@@ -69,7 +69,7 @@ public final class SingleJarMinecraftProvider extends MinecraftProvider {
public void provide() throws Exception {
super.provide();
boolean requiresRefresh = isRefreshDeps() || Files.notExists(minecraftEnvOnlyJar);
boolean requiresRefresh = getExtension().refreshDeps() || Files.notExists(minecraftEnvOnlyJar);
if (!requiresRefresh) {
return;

View File

@@ -57,7 +57,7 @@ public final class SplitMinecraftProvider extends MinecraftProvider {
public void provide() throws Exception {
super.provide();
boolean requiresRefresh = isRefreshDeps() || Files.notExists(minecraftClientOnlyJar) || Files.notExists(minecraftCommonJar);
boolean requiresRefresh = getExtension().refreshDeps() || Files.notExists(minecraftClientOnlyJar) || Files.notExists(minecraftCommonJar);
if (!requiresRefresh) {
return;

View File

@@ -34,7 +34,6 @@ import java.util.Map;
import org.gradle.api.Project;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.LoomGradlePlugin;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider;
@@ -67,7 +66,7 @@ public abstract class AbstractMappedMinecraftProvider<M extends MinecraftProvide
final List<RemappedJars> remappedJars = getRemappedJars();
assert !remappedJars.isEmpty();
if (!areOutputsValid(remappedJars) || LoomGradlePlugin.refreshDeps) {
if (!areOutputsValid(remappedJars) || extension.refreshDeps()) {
try {
remapInputs(remappedJars);
} catch (Throwable t) {

View File

@@ -32,7 +32,6 @@ import java.nio.file.StandardCopyOption;
import java.util.List;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.LoomGradlePlugin;
import net.fabricmc.loom.configuration.processors.JarProcessorManager;
import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider;
@@ -64,7 +63,7 @@ public abstract class ProcessedNamedMinecraftProvider<M extends MinecraftProvide
parentMinecraftProvider.provide(false);
final List<Path> inputJars = parentMinecraftProvider.getMinecraftJars();
boolean requiresProcessing = LoomGradlePlugin.refreshDeps || inputJars.stream()
boolean requiresProcessing = extension.refreshDeps() || inputJars.stream()
.map(this::getProcessedPath)
.map(Path::toFile)
.anyMatch(jarProcessorManager::isInvalid);

View File

@@ -69,6 +69,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen
private NamedMinecraftProvider<?> namedMinecraftProvider;
private IntermediaryMinecraftProvider<?> intermediaryMinecraftProvider;
private InstallerData installerData;
private boolean refreshDeps;
public LoomGradleExtensionImpl(Project project, LoomFiles files) {
super(project, files);
@@ -83,7 +84,15 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen
provider.getIntermediaryUrl()
.convention(getIntermediaryUrl())
.finalizeValueOnRead();
provider.getRefreshDeps().set(project.provider(() -> LoomGradleExtension.get(project).refreshDeps()));
});
refreshDeps = project.getGradle().getStartParameter().isRefreshDependencies() || Boolean.getBoolean("loom.refresh");
if (refreshDeps) {
project.getLogger().lifecycle("Refresh dependencies is in use, loom will be significantly slower.");
}
}
@Override
@@ -227,12 +236,19 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen
builder.forceDownload();
}
// TODO
//builder.executor();
return builder;
}
@Override
public boolean refreshDeps() {
return refreshDeps;
}
@Override
public void setRefreshDeps(boolean refreshDeps) {
this.refreshDeps = refreshDeps;
}
@Override
protected <T extends IntermediateMappingsProvider> void configureIntermediateMappingsProviderInternal(T provider) {
provider.getMinecraftVersion().set(getProject().provider(() -> getMinecraftProvider().minecraftVersion()));