mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-03-30 05:05:20 -05:00
Major steps towards config caching support :)
This commit is contained in:
@@ -45,7 +45,7 @@ import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.configuration.ide.idea.IdeaUtils;
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets;
|
||||
import net.fabricmc.loom.extension.MixinExtension;
|
||||
import net.fabricmc.loom.task.service.MixinMappingsService;
|
||||
import net.fabricmc.loom.task.PrepareJarRemapTask;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
|
||||
/**
|
||||
@@ -94,7 +94,7 @@ public abstract class AnnotationProcessorInvoker<T extends Task> {
|
||||
String refmapName = Objects.requireNonNull(MixinExtension.getMixinInformationContainer(sourceSet)).refmapNameProvider().get();
|
||||
Map<String, String> args = new HashMap<>() {{
|
||||
put(Constants.MixinArguments.IN_MAP_FILE_NAMED_INTERMEDIARY, loom.getMappingsProvider().tinyMappings.toFile().getCanonicalPath());
|
||||
put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, MixinMappingsService.getMixinMappingFile(project, sourceSet).getCanonicalPath());
|
||||
put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, getMixinMappingsForSourceSet(project, sourceSet).getCanonicalPath());
|
||||
put(Constants.MixinArguments.OUT_REFMAP_FILE, getRefmapDestination(task, refmapName));
|
||||
put(Constants.MixinArguments.DEFAULT_OBFUSCATION_ENV, "named:" + loom.getMixin().getRefmapTargetNamespace().get());
|
||||
put(Constants.MixinArguments.QUIET, "true");
|
||||
@@ -111,6 +111,9 @@ public abstract class AnnotationProcessorInvoker<T extends Task> {
|
||||
args.put("AMSG_" + key, value);
|
||||
});
|
||||
|
||||
// Ensure that all of the mixin mappings have been generated before we create the mixin mappings.
|
||||
runBeforePrepare(project, task);
|
||||
|
||||
project.getLogger().debug("Outputting refmap to dir: " + getRefmapDestinationDir(task) + " for compile task: " + task);
|
||||
args.forEach((k, v) -> passArgument(task, k, v));
|
||||
} catch (IOException e) {
|
||||
@@ -143,6 +146,12 @@ public abstract class AnnotationProcessorInvoker<T extends Task> {
|
||||
}
|
||||
}
|
||||
|
||||
private void runBeforePrepare(Project project, Task compileTask) {
|
||||
project.getGradle().allprojects(otherProject -> {
|
||||
otherProject.getTasks().withType(PrepareJarRemapTask.class, prepareRemapTask -> prepareRemapTask.mustRunAfter(compileTask));
|
||||
});
|
||||
}
|
||||
|
||||
private static void checkPattern(String input, Pattern pattern) {
|
||||
final Matcher matcher = pattern.matcher(input);
|
||||
|
||||
@@ -150,4 +159,9 @@ public abstract class AnnotationProcessorInvoker<T extends Task> {
|
||||
throw new IllegalArgumentException("Mixin argument (%s) does not match pattern (%s)".formatted(input, pattern.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public static File getMixinMappingsForSourceSet(Project project, SourceSet sourceSet) {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
return new File(extension.getFiles().getProjectBuildCache(), "mixin-map-" + extension.getMappingsProvider().mappingsIdentifier() + "." + sourceSet.getName() + ".tiny");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.gradle.api.NamedDomainObjectProvider;
|
||||
import org.gradle.api.Project;
|
||||
@@ -63,6 +64,8 @@ import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.ExceptionUtil;
|
||||
import net.fabricmc.loom.util.gradle.GradleUtils;
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper;
|
||||
import net.fabricmc.loom.util.service.ScopedSharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
|
||||
public final class CompileConfiguration {
|
||||
private CompileConfiguration() {
|
||||
@@ -126,7 +129,7 @@ public final class CompileConfiguration {
|
||||
javadoc.setClasspath(main.getOutput().plus(main.getCompileClasspath()));
|
||||
});
|
||||
|
||||
GradleUtils.afterSuccessfulEvaluation(project, () -> {
|
||||
afterEvaluationWithService(project, (serviceManager) -> {
|
||||
MinecraftSourceSets.get(project).afterEvaluate(project);
|
||||
|
||||
final boolean previousRefreshDeps = extension.refreshDeps();
|
||||
@@ -137,14 +140,14 @@ public final class CompileConfiguration {
|
||||
}
|
||||
|
||||
try {
|
||||
setupMinecraft(project);
|
||||
setupMinecraft(project, serviceManager);
|
||||
} catch (Exception e) {
|
||||
throw ExceptionUtil.createDescriptiveWrapper(RuntimeException::new, "Failed to setup Minecraft", e);
|
||||
}
|
||||
|
||||
LoomDependencyManager dependencyManager = new LoomDependencyManager();
|
||||
extension.setDependencyManager(dependencyManager);
|
||||
dependencyManager.handleDependencies(project);
|
||||
dependencyManager.handleDependencies(project, serviceManager);
|
||||
|
||||
releaseLock(project);
|
||||
extension.setRefreshDeps(previousRefreshDeps);
|
||||
@@ -178,7 +181,7 @@ public final class CompileConfiguration {
|
||||
}
|
||||
|
||||
// This is not thread safe across projects synchronize it here just to be sure, might be possible to move this further down, but for now this will do.
|
||||
private static synchronized void setupMinecraft(Project project) throws Exception {
|
||||
private static synchronized void setupMinecraft(Project project, SharedServiceManager serviceManager) throws Exception {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final MinecraftJarConfiguration jarConfiguration = extension.getMinecraftJarConfiguration().get();
|
||||
|
||||
@@ -188,7 +191,7 @@ public final class CompileConfiguration {
|
||||
minecraftProvider.provide();
|
||||
|
||||
final DependencyInfo mappingsDep = DependencyInfo.create(project, Constants.Configurations.MAPPINGS);
|
||||
final MappingsProviderImpl mappingsProvider = MappingsProviderImpl.getInstance(project, mappingsDep, minecraftProvider);
|
||||
final MappingsProviderImpl mappingsProvider = MappingsProviderImpl.getInstance(serviceManager, project, mappingsDep, minecraftProvider);
|
||||
extension.setMappingsProvider(mappingsProvider);
|
||||
mappingsProvider.applyToProject(project, mappingsDep);
|
||||
|
||||
@@ -331,4 +334,12 @@ public final class CompileConfiguration {
|
||||
private static void finalizedBy(Project project, String a, String b) {
|
||||
project.getTasks().named(a).configure(task -> task.finalizedBy(project.getTasks().named(b)));
|
||||
}
|
||||
|
||||
private static void afterEvaluationWithService(Project project, Consumer<SharedServiceManager> consumer) {
|
||||
GradleUtils.afterSuccessfulEvaluation(project, () -> {
|
||||
try (var serviceManager = new ScopedSharedServiceManager()) {
|
||||
consumer.accept(serviceManager);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +44,10 @@ import net.fabricmc.loom.configuration.mods.ModConfigurationRemapper;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.SourceRemapper;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
|
||||
public class LoomDependencyManager {
|
||||
public void handleDependencies(Project project) {
|
||||
public void handleDependencies(Project project, SharedServiceManager serviceManager) {
|
||||
List<Runnable> afterTasks = new ArrayList<>();
|
||||
|
||||
project.getLogger().info(":setting up loom dependencies");
|
||||
@@ -78,7 +79,7 @@ public class LoomDependencyManager {
|
||||
SourceRemapper sourceRemapper = new SourceRemapper(project, true);
|
||||
String mappingsIdentifier = extension.getMappingsProvider().mappingsIdentifier();
|
||||
|
||||
ModConfigurationRemapper.supplyModConfigurations(project, mappingsIdentifier, extension, sourceRemapper);
|
||||
ModConfigurationRemapper.supplyModConfigurations(project, serviceManager, mappingsIdentifier, extension, sourceRemapper);
|
||||
|
||||
sourceRemapper.remapAll();
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.OperatingSystem;
|
||||
import net.fabricmc.loom.util.SourceRemapper;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class ModConfigurationRemapper {
|
||||
@@ -65,7 +66,7 @@ public class ModConfigurationRemapper {
|
||||
// This can happen when the dependency is a FileCollectionDependency or from a flatDir repository.
|
||||
public static final String MISSING_GROUP = "unspecified";
|
||||
|
||||
public static void supplyModConfigurations(Project project, String mappingsSuffix, LoomGradleExtension extension, SourceRemapper sourceRemapper) {
|
||||
public static void supplyModConfigurations(Project project, SharedServiceManager serviceManager, String mappingsSuffix, LoomGradleExtension extension, SourceRemapper sourceRemapper) {
|
||||
final DependencyHandler dependencies = project.getDependencies();
|
||||
|
||||
for (RemapConfigurationSettings entry : extension.getRemapConfigurations()) {
|
||||
@@ -110,7 +111,7 @@ public class ModConfigurationRemapper {
|
||||
|
||||
if (!toRemap.isEmpty()) {
|
||||
try {
|
||||
new ModProcessor(project, sourceConfig).processMods(toRemap);
|
||||
new ModProcessor(project, sourceConfig, serviceManager).processMods(toRemap);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to remap mods", e);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ import net.fabricmc.loom.util.TinyRemapperHelper;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.kotlin.KotlinClasspathService;
|
||||
import net.fabricmc.loom.util.kotlin.KotlinRemapperClassloader;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.tinyremapper.InputTag;
|
||||
import net.fabricmc.tinyremapper.NonClassCopyMode;
|
||||
import net.fabricmc.tinyremapper.OutputConsumerPath;
|
||||
@@ -64,10 +65,12 @@ public class ModProcessor {
|
||||
|
||||
private final Project project;
|
||||
private final Configuration sourceConfiguration;
|
||||
private final SharedServiceManager serviceManager;
|
||||
|
||||
public ModProcessor(Project project, Configuration sourceConfiguration) {
|
||||
public ModProcessor(Project project, Configuration sourceConfiguration, SharedServiceManager serviceManager) {
|
||||
this.project = project;
|
||||
this.sourceConfiguration = sourceConfiguration;
|
||||
this.serviceManager = serviceManager;
|
||||
}
|
||||
|
||||
public void processMods(List<ModDependency> remapList) throws IOException {
|
||||
@@ -101,7 +104,7 @@ public class ModProcessor {
|
||||
.withMappings(TinyRemapperHelper.create(mappingsProvider.getMappings(), fromM, toM, false))
|
||||
.renameInvalidLocals(false);
|
||||
|
||||
final KotlinClasspathService kotlinClasspathService = KotlinClasspathService.getOrCreateIfRequired(project);
|
||||
final KotlinClasspathService kotlinClasspathService = KotlinClasspathService.getOrCreateIfRequired(serviceManager, project);
|
||||
KotlinRemapperClassloader kotlinRemapperClassloader = null;
|
||||
|
||||
if (kotlinClasspathService != null) {
|
||||
|
||||
@@ -38,6 +38,7 @@ import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingContext;
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider;
|
||||
import net.fabricmc.loom.util.download.DownloadBuilder;
|
||||
import net.fabricmc.loom.util.service.ScopedSharedServiceManager;
|
||||
import net.fabricmc.mappingio.tree.MemoryMappingTree;
|
||||
|
||||
public class GradleMappingContext implements MappingContext {
|
||||
@@ -66,7 +67,11 @@ public class GradleMappingContext implements MappingContext {
|
||||
|
||||
@Override
|
||||
public Supplier<MemoryMappingTree> intermediaryTree() {
|
||||
return () -> IntermediateMappingsService.getInstance(project, minecraftProvider()).getMemoryMappingTree();
|
||||
return () -> {
|
||||
try (var serviceManager = new ScopedSharedServiceManager()) {
|
||||
return IntermediateMappingsService.getInstance(serviceManager, project, minecraftProvider()).getMemoryMappingTree();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -56,12 +56,12 @@ public final class IntermediateMappingsService implements SharedService {
|
||||
this.intermediaryTiny = intermediaryTiny;
|
||||
}
|
||||
|
||||
public static synchronized IntermediateMappingsService getInstance(Project project, MinecraftProvider minecraftProvider) {
|
||||
public static synchronized IntermediateMappingsService getInstance(SharedServiceManager sharedServiceManager, Project project, MinecraftProvider minecraftProvider) {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final IntermediateMappingsProvider intermediateProvider = extension.getIntermediateMappingsProvider();
|
||||
final String id = "IntermediateMappingsService:%s:%s".formatted(intermediateProvider.getName(), intermediateProvider.getMinecraftVersion().get());
|
||||
|
||||
return SharedServiceManager.get(project).getOrCreateService(id, () -> create(intermediateProvider, minecraftProvider));
|
||||
return sharedServiceManager.getOrCreateService(id, () -> create(intermediateProvider, minecraftProvider));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -98,9 +98,9 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService {
|
||||
this.intermediaryService = intermediaryService;
|
||||
}
|
||||
|
||||
public static synchronized MappingsProviderImpl getInstance(Project project, DependencyInfo dependency, MinecraftProvider minecraftProvider) {
|
||||
return SharedServiceManager.get(project).getOrCreateService("MappingsProvider:%s:%s".formatted(dependency.getDepString(), minecraftProvider.minecraftVersion()), () -> {
|
||||
Supplier<IntermediateMappingsService> intermediaryService = Suppliers.memoize(() -> IntermediateMappingsService.getInstance(project, minecraftProvider));
|
||||
public static synchronized MappingsProviderImpl getInstance(SharedServiceManager sharedServiceManager, Project project, DependencyInfo dependency, MinecraftProvider minecraftProvider) {
|
||||
return sharedServiceManager.getOrCreateService("MappingsProvider:%s:%s".formatted(dependency.getDepString(), minecraftProvider.minecraftVersion()), () -> {
|
||||
Supplier<IntermediateMappingsService> intermediaryService = Suppliers.memoize(() -> IntermediateMappingsService.getInstance(sharedServiceManager, project, minecraftProvider));
|
||||
return create(dependency, minecraftProvider, intermediaryService);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,10 +45,12 @@ import org.gradle.api.file.RegularFileProperty;
|
||||
import org.gradle.api.provider.ListProperty;
|
||||
import org.gradle.api.provider.MapProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.Internal;
|
||||
import org.gradle.build.event.BuildEventsListenerRegistry;
|
||||
import org.gradle.jvm.tasks.Jar;
|
||||
import org.gradle.workers.WorkAction;
|
||||
import org.gradle.workers.WorkParameters;
|
||||
@@ -89,15 +91,23 @@ public abstract class AbstractRemapJarTask extends Jar {
|
||||
@Inject
|
||||
protected abstract WorkerExecutor getWorkerExecutor();
|
||||
|
||||
@Inject
|
||||
protected abstract BuildEventsListenerRegistry getBuildEventsListenerRegistry();
|
||||
|
||||
@Input
|
||||
public abstract Property<Boolean> getIncludesClientOnlyClasses();
|
||||
|
||||
private final Provider<JarManifestService> jarManifestServiceProvider;
|
||||
|
||||
@Inject
|
||||
public AbstractRemapJarTask() {
|
||||
getSourceNamespace().convention(MappingsNamespace.NAMED.toString()).finalizeValueOnRead();
|
||||
getTargetNamespace().convention(MappingsNamespace.INTERMEDIARY.toString()).finalizeValueOnRead();
|
||||
getRemapperIsolation().convention(false).finalizeValueOnRead();
|
||||
getIncludesClientOnlyClasses().convention(false).finalizeValueOnRead();
|
||||
|
||||
jarManifestServiceProvider = JarManifestService.get(getProject());
|
||||
usesService(jarManifestServiceProvider);
|
||||
}
|
||||
|
||||
public final <P extends AbstractRemapParams> void submitWork(Class<? extends AbstractRemapAction<P>> workAction, Action<P> action) {
|
||||
@@ -113,7 +123,7 @@ public abstract class AbstractRemapJarTask extends Jar {
|
||||
params.getArchivePreserveFileTimestamps().set(isPreserveFileTimestamps());
|
||||
params.getArchiveReproducibleFileOrder().set(isReproducibleFileOrder());
|
||||
|
||||
params.getJarManifestService().set(JarManifestService.get(getProject()));
|
||||
params.getJarManifestService().set(jarManifestServiceProvider);
|
||||
|
||||
if (getIncludesClientOnlyClasses().get()) {
|
||||
final List<String> clientOnlyEntries = getClientOnlyEntries();
|
||||
|
||||
@@ -78,7 +78,7 @@ public abstract class PrepareJarRemapTask extends AbstractLoomTask {
|
||||
final WorkQueue workQueue = getWorkerExecutor().noIsolation();
|
||||
|
||||
workQueue.submit(ReadInputsAction.class, params -> {
|
||||
params.getTinyRemapperBuildServiceUuid().set(UnsafeWorkQueueHelper.create(getProject(), remapJarTask.getTinyRemapperService()));
|
||||
params.getTinyRemapperBuildServiceUuid().set(UnsafeWorkQueueHelper.create(remapJarTask.getTinyRemapperService()));
|
||||
params.getInputFile().set(getInputFile());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -46,11 +46,13 @@ import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.provider.ListProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.Internal;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -71,6 +73,7 @@ import net.fabricmc.loom.util.SidedClassVisitor;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJson;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
import net.fabricmc.loom.util.service.BuildSharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.UnsafeWorkQueueHelper;
|
||||
import net.fabricmc.tinyremapper.OutputConsumerPath;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
@@ -82,11 +85,18 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
@Input
|
||||
public abstract Property<Boolean> getAddNestedDependencies();
|
||||
|
||||
private Supplier<TinyRemapperService> tinyRemapperService = Suppliers.memoize(() -> TinyRemapperService.getOrCreate(this));
|
||||
@Input
|
||||
@ApiStatus.Internal
|
||||
public abstract Property<Boolean> getUseMixinAP();
|
||||
|
||||
private final Provider<BuildSharedServiceManager> serviceManagerProvider;
|
||||
private final Supplier<TinyRemapperService> tinyRemapperService;
|
||||
|
||||
@Inject
|
||||
public RemapJarTask() {
|
||||
super();
|
||||
serviceManagerProvider = BuildSharedServiceManager.createForTask(this, getBuildEventsListenerRegistry());
|
||||
tinyRemapperService = Suppliers.memoize(() -> TinyRemapperService.getOrCreate(serviceManagerProvider.get().get(), this));
|
||||
|
||||
getClasspath().from(getProject().getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME));
|
||||
getAddNestedDependencies().convention(true).finalizeValueOnRead();
|
||||
@@ -94,6 +104,8 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
Configuration includeConfiguration = getProject().getConfigurations().getByName(Constants.Configurations.INCLUDE);
|
||||
getNestedJars().from(new IncludedJarFactory(getProject()).getNestedJars(includeConfiguration));
|
||||
|
||||
getUseMixinAP().set(LoomGradleExtension.get(getProject()).getMixin().getUseLegacyMixinAp());
|
||||
|
||||
setupPreparationTask();
|
||||
}
|
||||
|
||||
@@ -115,20 +127,18 @@ public abstract class RemapJarTask extends AbstractRemapJarTask {
|
||||
|
||||
@TaskAction
|
||||
public void run() {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(getProject());
|
||||
|
||||
submitWork(RemapAction.class, params -> {
|
||||
if (getAddNestedDependencies().get()) {
|
||||
params.getNestedJars().from(getNestedJars());
|
||||
}
|
||||
|
||||
params.getTinyRemapperBuildServiceUuid().set(UnsafeWorkQueueHelper.create(getProject(), tinyRemapperService.get()));
|
||||
params.getTinyRemapperBuildServiceUuid().set(UnsafeWorkQueueHelper.create(tinyRemapperService.get()));
|
||||
params.getRemapClasspath().from(getClasspath());
|
||||
|
||||
final boolean legacyMixin = extension.getMixin().getUseLegacyMixinAp().get();
|
||||
params.getUseMixinExtension().set(!legacyMixin);
|
||||
final boolean mixinAp = getUseMixinAP().get();
|
||||
params.getUseMixinExtension().set(!mixinAp);
|
||||
|
||||
if (legacyMixin) {
|
||||
if (mixinAp) {
|
||||
setupLegacyMixinRefmapRemapping(params);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -32,6 +32,7 @@ import javax.inject.Inject;
|
||||
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.slf4j.Logger;
|
||||
@@ -39,12 +40,16 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftSourceSets;
|
||||
import net.fabricmc.loom.task.service.SourceRemapperService;
|
||||
import net.fabricmc.loom.util.service.BuildSharedServiceManager;
|
||||
import net.fabricmc.loom.util.service.UnsafeWorkQueueHelper;
|
||||
|
||||
public abstract class RemapSourcesJarTask extends AbstractRemapJarTask {
|
||||
private final Provider<BuildSharedServiceManager> serviceManagerProvider;
|
||||
|
||||
@Inject
|
||||
public RemapSourcesJarTask() {
|
||||
super();
|
||||
serviceManagerProvider = BuildSharedServiceManager.createForTask(this, getBuildEventsListenerRegistry());
|
||||
|
||||
getClasspath().from(getProject().getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME));
|
||||
}
|
||||
@@ -52,7 +57,7 @@ public abstract class RemapSourcesJarTask extends AbstractRemapJarTask {
|
||||
@TaskAction
|
||||
public void run() {
|
||||
submitWork(RemapSourcesAction.class, params -> {
|
||||
params.getSourcesRemapperServiceUuid().set(UnsafeWorkQueueHelper.create(getProject(), SourceRemapperService.create(this)));
|
||||
params.getSourcesRemapperServiceUuid().set(UnsafeWorkQueueHelper.create(SourceRemapperService.create(serviceManagerProvider.get().get(), this)));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.gradle.util.GradleVersion;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.LoomGradlePlugin;
|
||||
import net.fabricmc.loom.configuration.InstallerData;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
|
||||
@@ -63,10 +64,10 @@ public abstract class JarManifestService implements BuildService<JarManifestServ
|
||||
params.getGradleVersion().set(GradleVersion.current().getVersion());
|
||||
params.getLoomVersion().set(LoomGradlePlugin.LOOM_VERSION);
|
||||
params.getMCEVersion().set(Constants.Dependencies.Versions.MIXIN_COMPILE_EXTENSIONS);
|
||||
params.getMinecraftVersion().set(extension.getMinecraftProvider().minecraftVersion());
|
||||
params.getMinecraftVersion().set(project.provider(() -> extension.getMinecraftProvider().minecraftVersion()));
|
||||
params.getTinyRemapperVersion().set(tinyRemapperVersion.orElse("unknown"));
|
||||
params.getFabricLoaderVersion().set(getLoaderVersion(project).orElse("unknown"));
|
||||
params.getMixinVersion().set(getMixinVersion(project).orElse(new MixinVersion("unknown", "unknown")));
|
||||
params.getFabricLoaderVersion().set(project.provider(() -> Optional.ofNullable(extension.getInstallerData()).map(InstallerData::version).orElse("unknown")));
|
||||
params.getMixinVersion().set(getMixinVersion(project));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -98,31 +99,23 @@ public abstract class JarManifestService implements BuildService<JarManifestServ
|
||||
}
|
||||
}
|
||||
|
||||
private static Optional<String> getLoaderVersion(Project project) {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
|
||||
if (extension.getInstallerData() == null) {
|
||||
project.getLogger().warn("Could not determine fabric loader version for jar manifest");
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(extension.getInstallerData().version());
|
||||
}
|
||||
|
||||
private record MixinVersion(String group, String version) implements Serializable { }
|
||||
|
||||
private static Optional<MixinVersion> getMixinVersion(Project project) {
|
||||
// Not super ideal that this uses the mod compile classpath, should prob look into making this not a thing at somepoint
|
||||
Optional<Dependency> dependency = project.getConfigurations().getByName(Constants.Configurations.LOADER_DEPENDENCIES)
|
||||
.getDependencies()
|
||||
.stream()
|
||||
.filter(dep -> "sponge-mixin".equals(dep.getName()))
|
||||
.findFirst();
|
||||
private static Provider<MixinVersion> getMixinVersion(Project project) {
|
||||
return project.getConfigurations().named(Constants.Configurations.LOADER_DEPENDENCIES).map(configuration -> {
|
||||
// Not super ideal that this uses the mod compile classpath, should prob look into making this not a thing at somepoint
|
||||
Optional<Dependency> dependency = configuration
|
||||
.getDependencies()
|
||||
.stream()
|
||||
.filter(dep -> "sponge-mixin".equals(dep.getName()))
|
||||
.findFirst();
|
||||
|
||||
if (dependency.isEmpty()) {
|
||||
project.getLogger().warn("Could not determine Mixin version for jar manifest");
|
||||
}
|
||||
if (dependency.isEmpty()) {
|
||||
project.getLogger().warn("Could not determine Mixin version for jar manifest");
|
||||
}
|
||||
|
||||
return dependency.map(d -> new MixinVersion(d.getGroup(), d.getVersion()));
|
||||
return dependency.map(d -> new MixinVersion(d.getGroup(), d.getVersion()))
|
||||
.orElse(new MixinVersion("unknown", "unknown"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,21 +42,17 @@ import net.fabricmc.tinyremapper.IMappingProvider;
|
||||
public final class MappingsService implements SharedService {
|
||||
private record Options(Path mappingsFile, String from, String to, boolean remapLocals) { }
|
||||
|
||||
public static MappingsService create(Project project, String name, Path mappingsFile, String from, String to, boolean remapLocals) {
|
||||
return create(SharedServiceManager.get(project), name, mappingsFile, from, to, remapLocals);
|
||||
}
|
||||
|
||||
public static synchronized MappingsService create(SharedServiceManager sharedServiceManager, String name, Path mappingsFile, String from, String to, boolean remapLocals) {
|
||||
final Options options = new Options(mappingsFile, from, to, remapLocals);
|
||||
final String id = name + options.hashCode();
|
||||
return sharedServiceManager.getOrCreateService(id, () -> new MappingsService(options));
|
||||
}
|
||||
|
||||
public static MappingsService createDefault(Project project, String from, String to) {
|
||||
public static MappingsService createDefault(Project project, SharedServiceManager serviceManager, String from, String to) {
|
||||
final MappingsProviderImpl mappingsProvider = LoomGradleExtension.get(project).getMappingsProvider();
|
||||
|
||||
final String name = mappingsProvider.getBuildServiceName("mappingsProvider", from, to);
|
||||
return MappingsService.create(project, name, mappingsProvider.tinyMappings, from, to, false);
|
||||
return MappingsService.create(serviceManager, name, mappingsProvider.tinyMappings, from, to, false);
|
||||
}
|
||||
|
||||
private final Options options;
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 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.task.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl;
|
||||
import net.fabricmc.loom.util.service.SharedService;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.tinyremapper.IMappingProvider;
|
||||
|
||||
public final class MixinMappingsService implements SharedService {
|
||||
private final SharedServiceManager sharedServiceManager;
|
||||
private final HashSet<File> mixinMappings = new HashSet<>();
|
||||
|
||||
private MixinMappingsService(SharedServiceManager sharedServiceManager) {
|
||||
this.sharedServiceManager = sharedServiceManager;
|
||||
}
|
||||
|
||||
public static File getMixinMappingFile(Project project, SourceSet sourceSet) {
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
File mixinMapping = new File(extension.getFiles().getProjectBuildCache(), "mixin-map-" + extension.getMappingsProvider().mappingsIdentifier() + "." + sourceSet.getName() + ".tiny");
|
||||
|
||||
getService(SharedServiceManager.get(project), extension.getMappingsProvider()).mixinMappings.add(mixinMapping);
|
||||
|
||||
return mixinMapping;
|
||||
}
|
||||
|
||||
static synchronized MixinMappingsService getService(SharedServiceManager sharedServiceManager, MappingsProviderImpl mappingsProvider) {
|
||||
return sharedServiceManager.getOrCreateService("MixinMappings-" + mappingsProvider.mappingsIdentifier(), () -> new MixinMappingsService(sharedServiceManager));
|
||||
}
|
||||
|
||||
IMappingProvider getMappingProvider(String from, String to) {
|
||||
return out -> {
|
||||
for (File mixinMapping : mixinMappings) {
|
||||
if (!mixinMapping.exists()) continue;
|
||||
|
||||
MappingsService service = MappingsService.create(sharedServiceManager, mixinMapping.getAbsolutePath(), mixinMapping.toPath(), from, to, false);
|
||||
service.getMappingsProvider().load(out);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -52,16 +52,15 @@ import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
import net.fabricmc.lorenztiny.TinyMappingsReader;
|
||||
|
||||
public final class SourceRemapperService implements SharedService {
|
||||
public static synchronized SourceRemapperService create(RemapSourcesJarTask task) {
|
||||
public static synchronized SourceRemapperService create(SharedServiceManager serviceManager, RemapSourcesJarTask task) {
|
||||
final Project project = task.getProject();
|
||||
final String to = task.getTargetNamespace().get();
|
||||
final String from = task.getSourceNamespace().get();
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final SharedServiceManager sharedServiceManager = SharedServiceManager.get(project);
|
||||
final String id = extension.getMappingsProvider().getBuildServiceName("sourceremapper", from, to);
|
||||
|
||||
return sharedServiceManager.getOrCreateService(id, () ->
|
||||
new SourceRemapperService(MappingsService.createDefault(project, from, to), task.getClasspath()
|
||||
return serviceManager.getOrCreateService(id, () ->
|
||||
new SourceRemapperService(MappingsService.createDefault(project, serviceManager, from, to), task.getClasspath()
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -37,10 +37,15 @@ import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.invocation.Gradle;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.build.mixin.AnnotationProcessorInvoker;
|
||||
import net.fabricmc.loom.task.AbstractRemapJarTask;
|
||||
import net.fabricmc.loom.util.gradle.GradleUtils;
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper;
|
||||
import net.fabricmc.loom.util.kotlin.KotlinClasspath;
|
||||
import net.fabricmc.loom.util.kotlin.KotlinClasspathService;
|
||||
import net.fabricmc.loom.util.kotlin.KotlinRemapperClassloader;
|
||||
@@ -51,14 +56,13 @@ import net.fabricmc.tinyremapper.InputTag;
|
||||
import net.fabricmc.tinyremapper.TinyRemapper;
|
||||
|
||||
public class TinyRemapperService implements SharedService {
|
||||
public static synchronized TinyRemapperService getOrCreate(AbstractRemapJarTask remapJarTask) {
|
||||
public static synchronized TinyRemapperService getOrCreate(SharedServiceManager serviceManager, AbstractRemapJarTask remapJarTask) {
|
||||
final Project project = remapJarTask.getProject();
|
||||
final String to = remapJarTask.getTargetNamespace().get();
|
||||
final String from = remapJarTask.getSourceNamespace().get();
|
||||
final LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final SharedServiceManager sharedServiceManager = SharedServiceManager.get(project);
|
||||
final boolean legacyMixin = extension.getMixin().getUseLegacyMixinAp().get();
|
||||
final @Nullable KotlinClasspathService kotlinClasspathService = KotlinClasspathService.getOrCreateIfRequired(project);
|
||||
final @Nullable KotlinClasspathService kotlinClasspathService = KotlinClasspathService.getOrCreateIfRequired(serviceManager, project);
|
||||
|
||||
// Generates an id that is used to share the remapper across projects. This tasks in the remap jar task name to handle custom remap jar tasks separately.
|
||||
final var joiner = new StringJoiner(":");
|
||||
@@ -75,12 +79,12 @@ public class TinyRemapperService implements SharedService {
|
||||
|
||||
final String id = joiner.toString();
|
||||
|
||||
TinyRemapperService service = sharedServiceManager.getOrCreateService(id, () -> {
|
||||
TinyRemapperService service = serviceManager.getOrCreateService(id, () -> {
|
||||
List<IMappingProvider> mappings = new ArrayList<>();
|
||||
mappings.add(MappingsService.createDefault(project, from, to).getMappingsProvider());
|
||||
mappings.add(MappingsService.createDefault(project, serviceManager, from, to).getMappingsProvider());
|
||||
|
||||
if (legacyMixin) {
|
||||
mappings.add(MixinMappingsService.getService(SharedServiceManager.get(project), extension.getMappingsProvider()).getMappingProvider(from, to));
|
||||
mappings.add(gradleMixinMappingProvider(serviceManager, project.getGradle(), from, to));
|
||||
}
|
||||
|
||||
return new TinyRemapperService(mappings, !legacyMixin, kotlinClasspathService);
|
||||
@@ -91,6 +95,22 @@ public class TinyRemapperService implements SharedService {
|
||||
return service;
|
||||
}
|
||||
|
||||
// Add all of the mixin mappings from all loom projects.
|
||||
private static IMappingProvider gradleMixinMappingProvider(SharedServiceManager serviceManager, Gradle gradle, String from, String to) {
|
||||
return out -> GradleUtils.allLoomProjects(gradle, project -> {
|
||||
for (SourceSet sourceSet : SourceSetHelper.getSourceSets(project)) {
|
||||
final File mixinMappings = AnnotationProcessorInvoker.getMixinMappingsForSourceSet(project, sourceSet);
|
||||
|
||||
if (!mixinMappings.exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MappingsService service = MappingsService.create(serviceManager, mixinMappings.getAbsolutePath(), mixinMappings.toPath(), from, to, false);
|
||||
service.getMappingsProvider().load(out);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private TinyRemapper tinyRemapper;
|
||||
@Nullable
|
||||
private KotlinRemapperClassloader kotlinRemapperClassloader;
|
||||
|
||||
@@ -49,13 +49,6 @@ public interface DeprecationHelper {
|
||||
|
||||
public ProjectBased(Project project) {
|
||||
this.project = project;
|
||||
|
||||
project.getGradle().buildFinished(buildResult -> {
|
||||
if (usingDeprecatedApi.get()) {
|
||||
project.getLogger().lifecycle("Deprecated Loom APIs were used in this build, making it incompatible with future versions of Loom. "
|
||||
+ "Use Gradle warning modes to control the verbosity of the warnings.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,10 @@
|
||||
|
||||
package net.fabricmc.loom.util.gradle;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.invocation.Gradle;
|
||||
|
||||
public final class GradleUtils {
|
||||
private GradleUtils() {
|
||||
@@ -41,4 +44,12 @@ public final class GradleUtils {
|
||||
afterEvaluate.run();
|
||||
});
|
||||
}
|
||||
|
||||
public static void allLoomProjects(Gradle gradle, Consumer<Project> consumer) {
|
||||
gradle.allprojects(project -> {
|
||||
if (project.getPluginManager().hasPlugin("fabric-loom")) {
|
||||
consumer.accept(project);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.gradle.api.internal.tasks.DefaultSourceSetOutput;
|
||||
import org.gradle.api.internal.tasks.DefaultTaskDependency;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.SourceSetContainer;
|
||||
import org.gradle.api.tasks.SourceSetOutput;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
import org.intellij.lang.annotations.Language;
|
||||
@@ -63,20 +64,23 @@ public final class SourceSetHelper {
|
||||
private SourceSetHelper() {
|
||||
}
|
||||
|
||||
public static SourceSetContainer getSourceSets(Project project) {
|
||||
final JavaPluginExtension javaExtension = project.getExtensions().getByType(JavaPluginExtension.class);
|
||||
return javaExtension.getSourceSets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true when the provided project contains the {@link SourceSet}.
|
||||
*/
|
||||
public static boolean isSourceSetOfProject(SourceSet sourceSet, Project project) {
|
||||
if (System.getProperty("fabric-loom.unit.testing") != null) return true;
|
||||
|
||||
final JavaPluginExtension javaExtension = project.getExtensions().getByType(JavaPluginExtension.class);
|
||||
return javaExtension.getSourceSets().stream()
|
||||
return getSourceSets(project).stream()
|
||||
.anyMatch(test -> test == sourceSet); // Ensure we have an identical reference
|
||||
}
|
||||
|
||||
public static SourceSet getSourceSetByName(String name, Project project) {
|
||||
final JavaPluginExtension javaExtension = project.getExtensions().getByType(JavaPluginExtension.class);
|
||||
return javaExtension.getSourceSets().getByName(name);
|
||||
return getSourceSets(project).getByName(name);
|
||||
}
|
||||
|
||||
public static SourceSet getMainSourceSet(Project project) {
|
||||
@@ -84,8 +88,7 @@ public final class SourceSetHelper {
|
||||
}
|
||||
|
||||
public static SourceSet createSourceSet(String name, Project project) {
|
||||
final JavaPluginExtension javaExtension = project.getExtensions().getByType(JavaPluginExtension.class);
|
||||
return javaExtension.getSourceSets().create(name);
|
||||
return getSourceSets(project).create(name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,17 +39,16 @@ import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
|
||||
public record KotlinClasspathService(Set<URL> classpath, String version) implements KotlinClasspath, SharedService {
|
||||
@Nullable
|
||||
public static KotlinClasspathService getOrCreateIfRequired(Project project) {
|
||||
public static KotlinClasspathService getOrCreateIfRequired(SharedServiceManager sharedServiceManager, Project project) {
|
||||
if (!KotlinPluginUtils.hasKotlinPlugin(project)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getOrCreate(project, KotlinPluginUtils.getKotlinPluginVersion(project), KotlinPluginUtils.getKotlinMetadataVersion());
|
||||
return getOrCreate(sharedServiceManager, project, KotlinPluginUtils.getKotlinPluginVersion(project), KotlinPluginUtils.getKotlinMetadataVersion());
|
||||
}
|
||||
|
||||
public static synchronized KotlinClasspathService getOrCreate(Project project, String kotlinVersion, String kotlinMetadataVersion) {
|
||||
public static synchronized KotlinClasspathService getOrCreate(SharedServiceManager sharedServiceManager, Project project, String kotlinVersion, String kotlinMetadataVersion) {
|
||||
final String id = "kotlinclasspath:%s:%s".formatted(kotlinVersion, kotlinMetadataVersion);
|
||||
final SharedServiceManager sharedServiceManager = SharedServiceManager.get(project);
|
||||
return sharedServiceManager.getOrCreateService(id, () -> create(project, kotlinVersion, kotlinMetadataVersion));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 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.service;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.services.BuildService;
|
||||
import org.gradle.api.services.BuildServiceParameters;
|
||||
import org.gradle.build.event.BuildEventsListenerRegistry;
|
||||
import org.gradle.tooling.events.OperationCompletionListener;
|
||||
import org.gradle.tooling.events.task.TaskOperationDescriptor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class BuildSharedServiceManager implements BuildService<BuildServiceParameters.None> {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(BuildSharedServiceManager.class);
|
||||
private static final String NAME = "loom:sharedServiceManager";
|
||||
|
||||
private SharedServiceManager sharedServiceManager = new BuildSharedServiceManagerImpl();
|
||||
private final AtomicInteger refCount = new AtomicInteger(0);
|
||||
|
||||
public static Provider<BuildSharedServiceManager> createForTask(Task task, BuildEventsListenerRegistry buildEventsListenerRegistry) {
|
||||
Provider<BuildSharedServiceManager> provider = task.getProject().getGradle().getSharedServices().registerIfAbsent(NAME, BuildSharedServiceManager.class, spec -> {
|
||||
});
|
||||
task.usesService(provider);
|
||||
|
||||
final BuildSharedServiceManager serviceManager = provider.get();
|
||||
buildEventsListenerRegistry.onTaskCompletion(registerTaskCompletion(task, serviceManager::onFinish));
|
||||
int count = serviceManager.refCount.incrementAndGet();
|
||||
LOGGER.debug("Creating shared service manager provider for task: {} count: {}", task.getName(), count);
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
public SharedServiceManager get() {
|
||||
LOGGER.debug("Shared build service get");
|
||||
return Objects.requireNonNull(sharedServiceManager);
|
||||
}
|
||||
|
||||
private void onFinish() {
|
||||
int count = refCount.decrementAndGet();
|
||||
|
||||
LOGGER.debug("Build service finish. count: {}", count);
|
||||
|
||||
if (count == 0) {
|
||||
sharedServiceManager.onFinish();
|
||||
sharedServiceManager = null;
|
||||
} else if (count < 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
private static Provider<OperationCompletionListener> registerTaskCompletion(Task task, Runnable runnable) {
|
||||
return task.getProject().provider(() -> event -> {
|
||||
if (event.getDescriptor() instanceof TaskOperationDescriptor taskDescriptor) {
|
||||
if (taskDescriptor.getTaskPath().equals(task.getPath())) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final class BuildSharedServiceManagerImpl extends SharedServiceManager {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2022 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.service;
|
||||
|
||||
public final class ScopedSharedServiceManager extends SharedServiceManager implements AutoCloseable {
|
||||
public ScopedSharedServiceManager() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
onFinish();
|
||||
}
|
||||
}
|
||||
@@ -31,33 +31,21 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.gradle.BuildResult;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.invocation.Gradle;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A simple manager for {@link SharedService} to be used across gradle (sub) projects.
|
||||
* This is a basic replacement for gradle's build service api.
|
||||
*/
|
||||
public final class SharedServiceManager {
|
||||
private static final Map<Gradle, SharedServiceManager> SERVICE_FACTORY_MAP = new ConcurrentHashMap<>();
|
||||
private final Gradle gradle;
|
||||
|
||||
public abstract class SharedServiceManager {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(BuildSharedServiceManager.class);
|
||||
private final Map<String, SharedService> sharedServiceMap = new ConcurrentHashMap<>();
|
||||
|
||||
private boolean shutdown = false;
|
||||
|
||||
private SharedServiceManager(Gradle gradle) {
|
||||
this.gradle = gradle;
|
||||
this.gradle.buildFinished(this::onFinish);
|
||||
}
|
||||
|
||||
public static SharedServiceManager get(Project project) {
|
||||
return get(project.getGradle());
|
||||
}
|
||||
|
||||
public static SharedServiceManager get(Gradle gradle) {
|
||||
return SERVICE_FACTORY_MAP.computeIfAbsent(gradle, SharedServiceManager::new);
|
||||
SharedServiceManager() {
|
||||
LOGGER.info("Creating new SharedServiceManager({})", hashCode());
|
||||
}
|
||||
|
||||
public <S extends SharedService> S getOrCreateService(String id, Supplier<S> function) {
|
||||
@@ -78,12 +66,12 @@ public final class SharedServiceManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void onFinish(BuildResult buildResult) {
|
||||
protected void onFinish() {
|
||||
synchronized (sharedServiceMap) {
|
||||
shutdown = true;
|
||||
}
|
||||
|
||||
SERVICE_FACTORY_MAP.remove(gradle);
|
||||
LOGGER.info("Closing SharedServiceManager({})", hashCode());
|
||||
|
||||
final List<IOException> exceptionList = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.provider.Property;
|
||||
|
||||
// Massive hack to work around WorkerExecutor.noIsolation() doing isolation checks.
|
||||
@@ -38,12 +37,10 @@ public final class UnsafeWorkQueueHelper {
|
||||
private UnsafeWorkQueueHelper() {
|
||||
}
|
||||
|
||||
public static String create(Project project, SharedService service) {
|
||||
public static String create(SharedService service) {
|
||||
final String uuid = UUID.randomUUID().toString();
|
||||
SERVICE_MAP.put(uuid, service);
|
||||
|
||||
// Ensure we don't make a mess if things go wrong.
|
||||
project.getGradle().buildFinished(buildResult -> SERVICE_MAP.remove(uuid));
|
||||
return uuid;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user