diff --git a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java index 40751f45..55cd775c 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java +++ b/src/main/java/net/fabricmc/loom/LoomGradlePlugin.java @@ -24,6 +24,7 @@ package net.fabricmc.loom; +import java.util.List; import java.util.Objects; import java.util.Arrays; import java.util.HashSet; @@ -41,6 +42,7 @@ import net.fabricmc.loom.api.LoomGradleExtensionAPI; import net.fabricmc.loom.bootstrap.BootstrappedPlugin; import net.fabricmc.loom.configuration.CompileConfiguration; import net.fabricmc.loom.configuration.FabricApiExtension; +import net.fabricmc.loom.configuration.LoomConfigurations; import net.fabricmc.loom.configuration.MavenPublication; import net.fabricmc.loom.configuration.ide.IdeConfiguration; import net.fabricmc.loom.configuration.ide.idea.IdeaConfiguration; @@ -48,6 +50,7 @@ import net.fabricmc.loom.decompilers.DecompilerConfiguration; import net.fabricmc.loom.extension.LoomFiles; import net.fabricmc.loom.extension.LoomGradleExtensionImpl; import net.fabricmc.loom.task.LoomTasks; +import net.fabricmc.loom.task.RemapTaskConfiguration; import net.fabricmc.loom.util.LibraryLocationLogger; public class LoomGradlePlugin implements BootstrappedPlugin { @@ -55,6 +58,20 @@ public class LoomGradlePlugin implements BootstrappedPlugin { 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"); + /** + * An ordered list of setup job classes. + */ + private static final List> SETUP_JOBS = List.of( + LoomConfigurations.class, + CompileConfiguration.class, + MavenPublication.class, + RemapTaskConfiguration.class, + LoomTasks.class, + DecompilerConfiguration.class, + IdeaConfiguration.class, + IdeConfiguration.class + ); + @Override public void apply(PluginAware target) { target.getPlugins().apply(LoomRepositoryPlugin.class); @@ -84,14 +101,8 @@ public class LoomGradlePlugin implements BootstrappedPlugin { project.getExtensions().create(LoomGradleExtensionAPI.class, "loom", LoomGradleExtensionImpl.class, project, LoomFiles.create(project)); project.getExtensions().create("fabricApi", FabricApiExtension.class, project); - final CompileConfiguration compileConfiguration = new CompileConfiguration(project); - - compileConfiguration.setupConfigurations(); - IdeConfiguration.setup(project); - compileConfiguration.configureCompile(); - MavenPublication.configure(project); - LoomTasks.registerTasks(project); - DecompilerConfiguration.setup(project); - IdeaConfiguration.setup(project); + for (Class jobClass : SETUP_JOBS) { + project.getObjects().newInstance(jobClass).run(); + } } } diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index a7f0ef6f..ba3ba76d 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -33,15 +33,14 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.function.Consumer; -import org.gradle.api.NamedDomainObjectProvider; +import javax.inject.Inject; + import org.gradle.api.Project; -import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.ConfigurationContainer; -import org.gradle.api.attributes.Usage; 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.TaskContainer; import org.gradle.api.tasks.compile.JavaCompile; import org.gradle.api.tasks.javadoc.Javadoc; @@ -77,161 +76,37 @@ import net.fabricmc.loom.configuration.providers.minecraft.mapped.SrgMinecraftPr import net.fabricmc.loom.configuration.sources.ForgeSourcesRemapper; import net.fabricmc.loom.extension.MixinExtension; import net.fabricmc.loom.util.Checksum; -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 final Project project; - private final ConfigurationContainer configurations; +public abstract class CompileConfiguration implements Runnable { + @Inject + protected abstract Project getProject(); - public CompileConfiguration(Project project) { - this.project = project; - this.configurations = project.getConfigurations(); - } + @Inject + protected abstract TaskContainer getTasks(); - public void setupConfigurations() { - final LoomGradleExtension extension = LoomGradleExtension.get(project); + @Override + public void run() { + LoomGradleExtension extension = LoomGradleExtension.get(getProject()); - project.afterEvaluate(project1 -> { - if (extension.shouldGenerateSrgTiny()) { - configurations.register(Constants.Configurations.SRG, configuration -> configuration.setTransitive(false)); - } - - if (extension.isDataGenEnabled()) { - project.getExtensions().getByType(JavaPluginExtension.class).getSourceSets().getByName("main").resources(files -> { - files.srcDir(project.file("src/generated/resources")); - }); - } - }); - - configurations.register(Configurations.MOD_COMPILE_CLASSPATH); - createNonTransitive(Configurations.MOD_COMPILE_CLASSPATH_MAPPED); - - // Set up the Minecraft compile configurations. - var minecraftClientCompile = createNonTransitive(Configurations.MINECRAFT_CLIENT_COMPILE_LIBRARIES); - var minecraftServerCompile = createNonTransitive(Configurations.MINECRAFT_SERVER_COMPILE_LIBRARIES); - var minecraftCompile = createNonTransitive(Configurations.MINECRAFT_COMPILE_LIBRARIES); - minecraftCompile.configure(configuration -> { - configuration.extendsFrom(minecraftClientCompile.get()); - configuration.extendsFrom(minecraftServerCompile.get()); - }); - - // Set up the minecraft runtime configurations, this extends from the compile configurations. - var minecraftClientRuntime = createNonTransitive(Configurations.MINECRAFT_CLIENT_RUNTIME_LIBRARIES); - var minecraftServerRuntime = createNonTransitive(Configurations.MINECRAFT_SERVER_RUNTIME_LIBRARIES); - - // Runtime extends from compile - minecraftClientRuntime.configure(configuration -> configuration.extendsFrom(minecraftClientCompile.get())); - minecraftServerRuntime.configure(configuration -> configuration.extendsFrom(minecraftServerCompile.get())); - - createNonTransitive(Configurations.MINECRAFT_RUNTIME_LIBRARIES).configure(minecraftRuntime -> { - minecraftRuntime.extendsFrom(minecraftClientRuntime.get()); - minecraftRuntime.extendsFrom(minecraftServerRuntime.get()); - }); - - createNonTransitive(Configurations.MINECRAFT_NATIVES); - createNonTransitive(Configurations.LOADER_DEPENDENCIES); - - createNonTransitive(Configurations.MINECRAFT); - createNonTransitive(Configurations.INCLUDE); - createNonTransitive(Configurations.MAPPING_CONSTANTS); - - configurations.register(Configurations.NAMED_ELEMENTS, configuration -> { - configuration.setCanBeConsumed(true); - configuration.setCanBeResolved(false); - configuration.extendsFrom(configurations.getByName(JavaPlugin.API_CONFIGURATION_NAME)); - }); - - extendsFrom(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME, Configurations.MAPPING_CONSTANTS); - - if (extension.isForge()) { - createNonTransitive(Constants.Configurations.FORGE); - createNonTransitive(Constants.Configurations.FORGE_USERDEV); - createNonTransitive(Constants.Configurations.FORGE_INSTALLER); - createNonTransitive(Constants.Configurations.FORGE_UNIVERSAL); - configurations.register(Constants.Configurations.FORGE_DEPENDENCIES); - createNonTransitive(Constants.Configurations.FORGE_NAMED); - createNonTransitive(Constants.Configurations.FORGE_EXTRA); - createNonTransitive(Constants.Configurations.MCP_CONFIG); - configurations.register(Constants.Configurations.FORGE_RUNTIME_LIBRARY).configure(configuration -> { - // Resolve for runtime usage - Usage javaRuntime = project.getObjects().named(Usage.class, Usage.JAVA_RUNTIME); - configuration.attributes(attributes -> attributes.attribute(Usage.USAGE_ATTRIBUTE, javaRuntime)); - }); - - extendsFrom(Configurations.MINECRAFT_COMPILE_LIBRARIES, Constants.Configurations.FORGE_DEPENDENCIES); - extendsFrom(Configurations.MINECRAFT_RUNTIME_LIBRARIES, Constants.Configurations.FORGE_DEPENDENCIES); - - extendsFrom(Constants.Configurations.FORGE_RUNTIME_LIBRARY, Constants.Configurations.FORGE_DEPENDENCIES); - extendsFrom(Constants.Configurations.FORGE_RUNTIME_LIBRARY, Configurations.MINECRAFT_RUNTIME_LIBRARIES); - extendsFrom(Constants.Configurations.FORGE_RUNTIME_LIBRARY, Constants.Configurations.FORGE_EXTRA); - extendsFrom(Constants.Configurations.FORGE_RUNTIME_LIBRARY, Constants.Configurations.FORGE_NAMED); - // Include any user-defined libraries on the runtime CP. - // (All the other superconfigurations are already on there.) - extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_RUNTIME_LIBRARY); - - extendsFrom(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_NAMED); - extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_NAMED); - extendsFrom(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_NAMED); - extendsFrom(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_NAMED); - extendsFrom(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_EXTRA); - extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_EXTRA); - extendsFrom(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_EXTRA); - extendsFrom(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.FORGE_EXTRA); - } - - configurations.register(Configurations.MAPPINGS); - configurations.register(Configurations.MAPPINGS_FINAL); - configurations.register(Configurations.LOOM_DEVELOPMENT_DEPENDENCIES); - configurations.register(Configurations.UNPICK_CLASSPATH); - configurations.register(Configurations.LOCAL_RUNTIME); - extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Configurations.LOCAL_RUNTIME); - - extension.createRemapConfigurations(SourceSetHelper.getMainSourceSet(project)); - - extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Configurations.MAPPINGS_FINAL); - extendsFrom(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME, Configurations.MAPPINGS_FINAL); - - extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Configurations.MINECRAFT_RUNTIME_LIBRARIES); - - // Add the dev time dependencies - project.getDependencies().add(Configurations.LOOM_DEVELOPMENT_DEPENDENCIES, Constants.Dependencies.DEV_LAUNCH_INJECTOR + Constants.Dependencies.Versions.DEV_LAUNCH_INJECTOR); - project.getDependencies().add(Configurations.LOOM_DEVELOPMENT_DEPENDENCIES, Constants.Dependencies.TERMINAL_CONSOLE_APPENDER + Constants.Dependencies.Versions.TERMINAL_CONSOLE_APPENDER); - project.getDependencies().add(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME, Constants.Dependencies.JETBRAINS_ANNOTATIONS + Constants.Dependencies.Versions.JETBRAINS_ANNOTATIONS); - project.getDependencies().add(JavaPlugin.TEST_COMPILE_ONLY_CONFIGURATION_NAME, Constants.Dependencies.JETBRAINS_ANNOTATIONS + Constants.Dependencies.Versions.JETBRAINS_ANNOTATIONS); - - if (extension.isForge()) { - project.getDependencies().add(Constants.Configurations.FORGE_EXTRA, Constants.Dependencies.FORGE_RUNTIME + Constants.Dependencies.Versions.FORGE_RUNTIME); - project.getDependencies().add(Constants.Configurations.FORGE_EXTRA, Constants.Dependencies.UNPROTECT + Constants.Dependencies.Versions.UNPROTECT); - project.getDependencies().add(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME, Constants.Dependencies.JAVAX_ANNOTATIONS + Constants.Dependencies.Versions.JAVAX_ANNOTATIONS); - } - } - - private NamedDomainObjectProvider createNonTransitive(String name) { - return configurations.register(name, configuration -> configuration.setTransitive(false)); - } - - public void configureCompile() { - LoomGradleExtension extension = LoomGradleExtension.get(project); - - project.getTasks().named(JavaPlugin.JAVADOC_TASK_NAME, Javadoc.class).configure(javadoc -> { - final SourceSet main = SourceSetHelper.getMainSourceSet(project); + getTasks().named(JavaPlugin.JAVADOC_TASK_NAME, Javadoc.class).configure(javadoc -> { + final SourceSet main = SourceSetHelper.getMainSourceSet(getProject()); javadoc.setClasspath(main.getOutput().plus(main.getCompileClasspath())); }); - afterEvaluationWithService(project, (serviceManager) -> { - final ConfigContext configContext = new ConfigContextImpl(project, serviceManager, extension); + afterEvaluationWithService((serviceManager) -> { + final ConfigContext configContext = new ConfigContextImpl(getProject(), serviceManager, extension); - MinecraftSourceSets.get(project).afterEvaluate(project); + MinecraftSourceSets.get(getProject()).afterEvaluate(getProject()); final boolean previousRefreshDeps = extension.refreshDeps(); if (getAndLock()) { - project.getLogger().lifecycle("Found existing cache lock file, rebuilding loom cache. This may have been caused by a failed or canceled build."); + getProject().getLogger().lifecycle("Found existing cache lock file, rebuilding loom cache. This may have been caused by a failed or canceled build."); extension.setRefreshDeps(true); } @@ -243,12 +118,12 @@ public final class CompileConfiguration { LoomDependencyManager dependencyManager = new LoomDependencyManager(); extension.setDependencyManager(dependencyManager); - dependencyManager.handleDependencies(project, serviceManager); + dependencyManager.handleDependencies(getProject(), serviceManager); releaseLock(); extension.setRefreshDeps(previousRefreshDeps); - MixinExtension mixin = LoomGradleExtension.get(project).getMixin(); + MixinExtension mixin = LoomGradleExtension.get(getProject()).getMixin(); if (mixin.getUseLegacyMixinAp().get()) { setupMixinAp(mixin); @@ -262,7 +137,7 @@ public final class CompileConfiguration { // because of https://github.com/architectury/architectury-loom/issues/72. if (!ModConfigurationRemapper.isCIBuild()) { try { - ForgeSourcesRemapper.addBaseForgeSources(project); + ForgeSourcesRemapper.addBaseForgeSources(getProject()); } catch (IOException e) { e.printStackTrace(); } @@ -275,35 +150,35 @@ public final class CompileConfiguration { finalizedBy("cleanEclipse", "cleanEclipseRuns"); // Add the "dev" jar to the "namedElements" configuration - project.artifacts(artifactHandler -> artifactHandler.add(Configurations.NAMED_ELEMENTS, project.getTasks().named("jar"))); + getProject().artifacts(artifactHandler -> artifactHandler.add(Configurations.NAMED_ELEMENTS, getTasks().named("jar"))); // Ensure that the encoding is set to UTF-8, no matter what the system default is // this fixes some edge cases with special characters not displaying correctly // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html - project.getTasks().withType(AbstractCopyTask.class).configureEach(abstractCopyTask -> abstractCopyTask.setFilteringCharset(StandardCharsets.UTF_8.name())); - project.getTasks().withType(JavaCompile.class).configureEach(javaCompile -> javaCompile.getOptions().setEncoding(StandardCharsets.UTF_8.name())); + getTasks().withType(AbstractCopyTask.class).configureEach(abstractCopyTask -> abstractCopyTask.setFilteringCharset(StandardCharsets.UTF_8.name())); + getTasks().withType(JavaCompile.class).configureEach(javaCompile -> javaCompile.getOptions().setEncoding(StandardCharsets.UTF_8.name())); if (extension.isForge()) { // Create default mod from main source set extension.mods(mods -> { - final SourceSet main = project.getExtensions().getByType(JavaPluginExtension.class).getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); + final SourceSet main = getProject().getExtensions().getByType(JavaPluginExtension.class).getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); mods.create("main").sourceSet(main); }); } - if (project.getPluginManager().hasPlugin("org.jetbrains.kotlin.kapt")) { + if (getProject().getPluginManager().hasPlugin("org.jetbrains.kotlin.kapt")) { // If loom is applied after kapt, then kapt will use the AP arguments too early for loom to pass the arguments we need for mixin. throw new IllegalArgumentException("fabric-loom must be applied BEFORE kapt in the plugins { } block."); } } - // 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. + // This is not thread safe across getProject()s synchronize it here just to be sure, might be possible to move this further down, but for now this will do. private synchronized void setupMinecraft(ConfigContext configContext) throws Exception { final Project project = configContext.project(); final LoomGradleExtension extension = configContext.extension(); final MinecraftJarConfiguration jarConfiguration = extension.getMinecraftJarConfiguration().get(); - // Provide the vanilla mc jars -- TODO share across projects. + // Provide the vanilla mc jars -- TODO share across getProject()s. final MinecraftProvider minecraftProvider = jarConfiguration.getMinecraftProviderFunction().apply(configContext); if (extension.isForge() && !(minecraftProvider instanceof ForgeMinecraftProvider)) { @@ -321,8 +196,8 @@ public final class CompileConfiguration { minecraftProvider.provide(); } - final DependencyInfo mappingsDep = DependencyInfo.create(project, Configurations.MAPPINGS); - final MappingConfiguration mappingConfiguration = MappingConfiguration.create(project, configContext.serviceManager(), mappingsDep, minecraftProvider); + final DependencyInfo mappingsDep = DependencyInfo.create(getProject(), Configurations.MAPPINGS); + final MappingConfiguration mappingConfiguration = MappingConfiguration.create(getProject(), configContext.serviceManager(), mappingsDep, minecraftProvider); extension.setMappingConfiguration(mappingConfiguration); if (extension.isForge()) { @@ -331,7 +206,7 @@ public final class CompileConfiguration { } mappingConfiguration.setupPost(project); - mappingConfiguration.applyToProject(project, mappingsDep); + mappingConfiguration.applyToProject(getProject(), mappingsDep); if (extension.isForge()) { extension.setForgeRunsProvider(ForgeRunsProvider.create(project)); @@ -346,7 +221,7 @@ public final class CompileConfiguration { NamedMinecraftProvider namedMinecraftProvider = jarConfiguration.getNamedMinecraftProviderBiFunction().apply(configContext, minecraftProvider); registerGameProcessors(configContext); - MinecraftJarProcessorManager minecraftJarProcessorManager = MinecraftJarProcessorManager.create(project); + MinecraftJarProcessorManager minecraftJarProcessorManager = MinecraftJarProcessorManager.create(getProject()); if (minecraftJarProcessorManager != null) { // Wrap the named MC provider for one that will provide the processed jars @@ -395,23 +270,23 @@ public final class CompileConfiguration { System.setProperty("log4j.shutdownHookEnabled", "false"); System.setProperty("log4j.skipJansi", "true"); - project.getLogger().info("Configuring compiler arguments for Java"); + getProject().getLogger().info("Configuring compiler arguments for Java"); - new JavaApInvoker(project).configureMixin(); + new JavaApInvoker(getProject()).configureMixin(); - if (project.getPluginManager().hasPlugin("scala")) { - project.getLogger().info("Configuring compiler arguments for Scala"); - new ScalaApInvoker(project).configureMixin(); + if (getProject().getPluginManager().hasPlugin("scala")) { + getProject().getLogger().info("Configuring compiler arguments for Scala"); + new ScalaApInvoker(getProject()).configureMixin(); } - if (project.getPluginManager().hasPlugin("org.jetbrains.kotlin.kapt")) { - project.getLogger().info("Configuring compiler arguments for Kapt plugin"); - new KaptApInvoker(project).configureMixin(); + if (getProject().getPluginManager().hasPlugin("org.jetbrains.kotlin.kapt")) { + getProject().getLogger().info("Configuring compiler arguments for Kapt plugin"); + new KaptApInvoker(getProject()).configureMixin(); } - if (project.getPluginManager().hasPlugin("groovy")) { - project.getLogger().info("Configuring compiler arguments for Groovy"); - new GroovyApInvoker(project).configureMixin(); + if (getProject().getPluginManager().hasPlugin("groovy")) { + getProject().getLogger().info("Configuring compiler arguments for Groovy"); + new GroovyApInvoker(getProject()).configureMixin(); } } @@ -423,9 +298,9 @@ public final class CompileConfiguration { } private Path getLockFile() { - final LoomGradleExtension extension = LoomGradleExtension.get(project); + final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); final Path cacheDirectory = extension.getFiles().getUserCache().toPath(); - final String pathHash = Checksum.projectHash(project); + final String pathHash = Checksum.projectHash(getProject()); return cacheDirectory.resolve("." + pathHash + ".lock"); } @@ -439,7 +314,7 @@ public final class CompileConfiguration { try { Files.createFile(lock); } catch (IOException e) { - throw new UncheckedIOException("Failed to acquire project configuration lock", e); + throw new UncheckedIOException("Failed to acquire getProject() configuration lock", e); } return false; @@ -461,19 +336,15 @@ public final class CompileConfiguration { Files.move(lock, del); Files.delete(del); } catch (IOException e2) { - var exception = new UncheckedIOException("Failed to release project configuration lock", e2); + var exception = new UncheckedIOException("Failed to release getProject() configuration lock", e2); exception.addSuppressed(e1); throw exception; } } } - public void extendsFrom(String a, String b) { - project.getConfigurations().getByName(a, configuration -> configuration.extendsFrom(project.getConfigurations().getByName(b))); - } - private void finalizedBy(String a, String b) { - project.getTasks().named(a).configure(task -> task.finalizedBy(project.getTasks().named(b))); + getTasks().named(a).configure(task -> task.finalizedBy(getTasks().named(b))); } public static void setupDependencyProviders(Project project, LoomGradleExtension extension) { @@ -498,8 +369,8 @@ public final class CompileConfiguration { dependencyProviders.handleDependencies(project); } - private static void afterEvaluationWithService(Project project, Consumer consumer) { - GradleUtils.afterSuccessfulEvaluation(project, () -> { + private void afterEvaluationWithService(Consumer consumer) { + GradleUtils.afterSuccessfulEvaluation(getProject(), () -> { try (var serviceManager = new ScopedSharedServiceManager()) { consumer.accept(serviceManager); } diff --git a/src/main/java/net/fabricmc/loom/configuration/LoomConfigurations.java b/src/main/java/net/fabricmc/loom/configuration/LoomConfigurations.java new file mode 100644 index 00000000..d71c8c74 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/LoomConfigurations.java @@ -0,0 +1,145 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2023 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration; + +import javax.inject.Inject; + +import org.gradle.api.NamedDomainObjectProvider; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.ConfigurationContainer; +import org.gradle.api.artifacts.dsl.DependencyHandler; +import org.gradle.api.plugins.JavaPlugin; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.gradle.SourceSetHelper; + +public abstract class LoomConfigurations implements Runnable { + @Inject + protected abstract Project getProject(); + + @Inject + protected abstract ConfigurationContainer getConfigurations(); + + @Inject + protected abstract DependencyHandler getDependencies(); + + @Override + public void run() { + final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); + + register(Constants.Configurations.MOD_COMPILE_CLASSPATH, Type.CONSUMABLE); + registerNonTransitive(Constants.Configurations.MOD_COMPILE_CLASSPATH_MAPPED, Type.DEFAULT); + + // Set up the Minecraft compile configurations. + var minecraftClientCompile = registerNonTransitive(Constants.Configurations.MINECRAFT_CLIENT_COMPILE_LIBRARIES, Type.DEFAULT); + var minecraftServerCompile = registerNonTransitive(Constants.Configurations.MINECRAFT_SERVER_COMPILE_LIBRARIES, Type.DEFAULT); + var minecraftCompile = registerNonTransitive(Constants.Configurations.MINECRAFT_COMPILE_LIBRARIES, Type.RESOLVABLE); + minecraftCompile.configure(configuration -> { + configuration.extendsFrom(minecraftClientCompile.get()); + configuration.extendsFrom(minecraftServerCompile.get()); + }); + + // Set up the minecraft runtime configurations, this extends from the compile configurations. + var minecraftClientRuntime = registerNonTransitive(Constants.Configurations.MINECRAFT_CLIENT_RUNTIME_LIBRARIES, Type.DEFAULT); + var minecraftServerRuntime = registerNonTransitive(Constants.Configurations.MINECRAFT_SERVER_RUNTIME_LIBRARIES, Type.DEFAULT); + + // Runtime extends from compile + minecraftClientRuntime.configure(configuration -> configuration.extendsFrom(minecraftClientCompile.get())); + minecraftServerRuntime.configure(configuration -> configuration.extendsFrom(minecraftServerCompile.get())); + + registerNonTransitive(Constants.Configurations.MINECRAFT_RUNTIME_LIBRARIES, Type.RESOLVABLE).configure(minecraftRuntime -> { + minecraftRuntime.extendsFrom(minecraftClientRuntime.get()); + minecraftRuntime.extendsFrom(minecraftServerRuntime.get()); + }); + + registerNonTransitive(Constants.Configurations.MINECRAFT_NATIVES, Type.DEFAULT); + registerNonTransitive(Constants.Configurations.LOADER_DEPENDENCIES, Type.CONSUMABLE); + + registerNonTransitive(Constants.Configurations.MINECRAFT, Type.CONSUMABLE); + registerNonTransitive(Constants.Configurations.INCLUDE, Type.DEFAULT); + registerNonTransitive(Constants.Configurations.MAPPING_CONSTANTS, Type.DEFAULT); + + register(Constants.Configurations.NAMED_ELEMENTS, Type.CONSUMABLE).configure(configuration -> { + configuration.extendsFrom(getConfigurations().getByName(JavaPlugin.API_CONFIGURATION_NAME)); + }); + + extendsFrom(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME, Constants.Configurations.MAPPING_CONSTANTS); + + register(Constants.Configurations.MAPPINGS, Type.DEFAULT); + register(Constants.Configurations.MAPPINGS_FINAL, Type.DEFAULT); + register(Constants.Configurations.LOOM_DEVELOPMENT_DEPENDENCIES, Type.CONSUMABLE); + register(Constants.Configurations.UNPICK_CLASSPATH, Type.DEFAULT); + register(Constants.Configurations.LOCAL_RUNTIME, Type.CONSUMABLE); + extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.LOCAL_RUNTIME); + + extension.createRemapConfigurations(SourceSetHelper.getMainSourceSet(getProject())); + + extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.MAPPINGS_FINAL); + extendsFrom(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.MAPPINGS_FINAL); + + extendsFrom(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME, Constants.Configurations.MINECRAFT_RUNTIME_LIBRARIES); + + // Add the dev time dependencies + getDependencies().add(Constants.Configurations.LOOM_DEVELOPMENT_DEPENDENCIES, Constants.Dependencies.DEV_LAUNCH_INJECTOR + Constants.Dependencies.Versions.DEV_LAUNCH_INJECTOR); + getDependencies().add(Constants.Configurations.LOOM_DEVELOPMENT_DEPENDENCIES, Constants.Dependencies.TERMINAL_CONSOLE_APPENDER + Constants.Dependencies.Versions.TERMINAL_CONSOLE_APPENDER); + getDependencies().add(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME, Constants.Dependencies.JETBRAINS_ANNOTATIONS + Constants.Dependencies.Versions.JETBRAINS_ANNOTATIONS); + getDependencies().add(JavaPlugin.TEST_COMPILE_ONLY_CONFIGURATION_NAME, Constants.Dependencies.JETBRAINS_ANNOTATIONS + Constants.Dependencies.Versions.JETBRAINS_ANNOTATIONS); + } + + private NamedDomainObjectProvider register(String name, Type type) { + return getConfigurations().register(name, type::apply); + } + + private NamedDomainObjectProvider registerNonTransitive(String name, Type type) { + final NamedDomainObjectProvider provider = register(name, type); + provider.configure(configuration -> configuration.setTransitive(false)); + return provider; + } + + public void extendsFrom(String a, String b) { + getConfigurations().getByName(a, configuration -> configuration.extendsFrom(getConfigurations().getByName(b))); + } + + enum Type { + CONSUMABLE(true, false), + RESOLVABLE(false, true), + DEFAULT(true, true); + + private final boolean canBeConsumed; + private final boolean canBeResolved; + + Type(boolean canBeConsumed, boolean canBeResolved) { + this.canBeConsumed = canBeConsumed; + this.canBeResolved = canBeResolved; + } + + void apply(Configuration configuration) { + configuration.setCanBeConsumed(canBeConsumed); + configuration.setCanBeResolved(canBeResolved); + } + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/MavenPublication.java b/src/main/java/net/fabricmc/loom/configuration/MavenPublication.java index 7f629238..6d0cd290 100644 --- a/src/main/java/net/fabricmc/loom/configuration/MavenPublication.java +++ b/src/main/java/net/fabricmc/loom/configuration/MavenPublication.java @@ -33,6 +33,8 @@ import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.atomic.AtomicBoolean; +import javax.inject.Inject; + import com.google.common.collect.ImmutableMap; import groovy.util.Node; import org.gradle.api.Project; @@ -49,7 +51,7 @@ import net.fabricmc.loom.util.DeprecationHelper; import net.fabricmc.loom.util.GroovyXmlUtil; import net.fabricmc.loom.util.gradle.GradleUtils; -public final class MavenPublication { +public abstract class MavenPublication implements Runnable { // ImmutableMap is needed since it guarantees ordering // (compile must go before runtime, or otherwise dependencies might get the "weaker" runtime scope). private static final Map CONFIGURATION_TO_SCOPE = ImmutableMap.of( @@ -58,22 +60,22 @@ public final class MavenPublication { ); private static final Set EXCLUDED_PUBLICATIONS = Collections.newSetFromMap(new WeakHashMap<>()); - private MavenPublication() { - } + @Inject + protected abstract Project getProject(); - public static void configure(Project project) { - GradleUtils.afterSuccessfulEvaluation(project, () -> { + @Override + public void run() { + GradleUtils.afterSuccessfulEvaluation(getProject(), () -> { AtomicBoolean reportedDeprecation = new AtomicBoolean(false); CONFIGURATION_TO_SCOPE.forEach((configurationName, scope) -> { - Configuration config = project.getConfigurations().getByName(configurationName); + Configuration config = getProject().getConfigurations().getByName(configurationName); // add modsCompile to maven-publish - PublishingExtension mavenPublish = project.getExtensions().findByType(PublishingExtension.class); + PublishingExtension mavenPublish = getProject().getExtensions().findByType(PublishingExtension.class); if (mavenPublish != null) { - project.getLogger().info("Processing maven publication for project [" + project.getName() + "] of " + configurationName); - processEntry(project, scope, config, mavenPublish, reportedDeprecation); + processEntry(scope, config, mavenPublish, reportedDeprecation); } }); }); @@ -89,7 +91,7 @@ public final class MavenPublication { } } - private static void processEntry(Project project, String scope, Configuration config, PublishingExtension mavenPublish, AtomicBoolean reportedDeprecation) { + private void processEntry(String scope, Configuration config, PublishingExtension mavenPublish, AtomicBoolean reportedDeprecation) { mavenPublish.publications((publications) -> { for (Publication publication : publications) { if (!(publication instanceof org.gradle.api.publish.maven.MavenPublication mavenPublication)) { @@ -99,12 +101,11 @@ public final class MavenPublication { if (hasSoftwareComponent(publication) || EXCLUDED_PUBLICATIONS.contains(publication)) { continue; } else if (!reportedDeprecation.get() && !LoomGradleExtension.get(project).isForge()) { - DeprecationHelper deprecationHelper = LoomGradleExtension.get(project).getDeprecationHelper(); + DeprecationHelper deprecationHelper = LoomGradleExtension.get(getProject()).getDeprecationHelper(); deprecationHelper.warn("Loom is applying dependency data manually to publications instead of using a software component (from(components[\"java\"])). This is deprecated."); reportedDeprecation.set(true); } - project.getLogger().info("Processing maven publication [" + publication.getName() + "]"); mavenPublication.pom((pom) -> pom.withXml((xml) -> { Node dependencies = GroovyXmlUtil.getOrCreateNode(xml.asNode(), "dependencies"); Set foundArtifacts = new HashSet<>(); @@ -120,12 +121,9 @@ public final class MavenPublication { for (Dependency dependency : config.getAllDependencies()) { if (foundArtifacts.contains(dependency.getGroup() + ":" + dependency.getName())) { - project.getLogger().info("Found inserted artifact " + dependency.getGroup() + ":" + dependency.getName()); continue; } - project.getLogger().info("Inserting artifact " + dependency.getGroup() + ":" + dependency.getName()); - Node depNode = dependencies.appendNode("dependency"); depNode.appendNode("groupId", dependency.getGroup()); depNode.appendNode("artifactId", dependency.getName()); diff --git a/src/main/java/net/fabricmc/loom/configuration/ide/IdeConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/ide/IdeConfiguration.java index 0c2ec2ef..a4c73c4a 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ide/IdeConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/ide/IdeConfiguration.java @@ -24,17 +24,20 @@ package net.fabricmc.loom.configuration.ide; +import javax.inject.Inject; + import org.gradle.api.Project; import org.gradle.plugins.ide.idea.model.IdeaModel; -public final class IdeConfiguration { - private IdeConfiguration() { - } +public abstract class IdeConfiguration implements Runnable { + @Inject + protected abstract Project getProject(); - public static void setup(Project project) { - IdeaModel ideaModel = (IdeaModel) project.getExtensions().getByName("idea"); + @Override + public void run() { + IdeaModel ideaModel = (IdeaModel) getProject().getExtensions().getByName("idea"); - ideaModel.getModule().getExcludeDirs().addAll(project.files(".gradle", "build", ".idea", "out").getFiles()); + ideaModel.getModule().getExcludeDirs().addAll(getProject().files(".gradle", "build", ".idea", "out").getFiles()); ideaModel.getModule().setDownloadJavadoc(true); ideaModel.getModule().setDownloadSources(true); ideaModel.getModule().setInheritOutputDirs(true); diff --git a/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java index 6bd1d7d3..145b2a03 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/ide/idea/IdeaConfiguration.java @@ -34,6 +34,8 @@ import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.inject.Inject; + import org.gradle.StartParameter; import org.gradle.TaskExecutionRequest; import org.gradle.api.Project; @@ -47,22 +49,25 @@ import net.fabricmc.loom.configuration.ide.RunConfigSettings; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration; import net.fabricmc.loom.task.LoomTasks; -public class IdeaConfiguration { +public abstract class IdeaConfiguration implements Runnable { private static final String INIT_SCRIPT_NAME = "ijmiscinit"; private static final Pattern NOTATION_PATTERN = Pattern.compile("'net\\.minecraft:(?.*):(.*):sources'"); - public static void setup(Project project) { - TaskProvider ideaSyncTask = project.getTasks().register("ideaSyncTask", IdeaSyncTask.class, task -> { - if (LoomGradleExtension.get(project).getRunConfigs().stream().anyMatch(RunConfigSettings::isIdeConfigGenerated)) { - task.dependsOn(LoomTasks.getIDELaunchConfigureTaskName(project)); + @Inject + protected abstract Project getProject(); + + public void run() { + TaskProvider ideaSyncTask = getProject().getTasks().register("ideaSyncTask", IdeaSyncTask.class, task -> { + if (LoomGradleExtension.get(getProject()).getRunConfigs().stream().anyMatch(RunConfigSettings::isIdeConfigGenerated)) { + task.dependsOn(LoomTasks.getIDELaunchConfigureTaskName(getProject())); } else { task.setEnabled(false); } }); - project.getTasks().configureEach(task -> { + getProject().getTasks().configureEach(task -> { if (task.getName().equals("DownloadSources")) { - hookDownloadSources(project, task); + hookDownloadSources(getProject(), task); } }); @@ -70,7 +75,7 @@ public class IdeaConfiguration { return; } - final StartParameter startParameter = project.getGradle().getStartParameter(); + final StartParameter startParameter = getProject().getGradle().getStartParameter(); final List taskRequests = new ArrayList<>(startParameter.getTaskRequests()); taskRequests.add(new DefaultTaskExecutionRequest(List.of("ideaSyncTask"))); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/LibraryContext.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/LibraryContext.java index 0b80189a..b344383e 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/LibraryContext.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/LibraryContext.java @@ -29,6 +29,7 @@ import java.util.Arrays; import org.gradle.api.JavaVersion; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta; +import net.fabricmc.loom.util.Platform; public final class LibraryContext { private final MinecraftVersionMeta versionMeta; @@ -42,9 +43,15 @@ public final class LibraryContext { /** * @return True when the Minecraft libraries support ARM64 MacOS */ - public boolean supportsArm64MacOS() { + public boolean supportsArm64(Platform.OperatingSystem operatingSystem) { + final String osName = switch (operatingSystem) { + case MAC_OS -> "macos"; + case WINDOWS -> "windows"; + case LINUX -> "linux"; + }; + return versionMeta.libraries().stream() - .anyMatch(library -> library.name().startsWith("org.lwjgl:lwjgl:3") && library.name().endsWith(":natives-macos-arm64")); + .anyMatch(library -> library.name().startsWith("org.lwjgl:lwjgl:3") && library.name().endsWith(":natives-%s-arm64".formatted(osName))); } /** diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/ArmNativesLibraryProcessor.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/ArmNativesLibraryProcessor.java index 7763c7cb..584e4a80 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/ArmNativesLibraryProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/ArmNativesLibraryProcessor.java @@ -57,13 +57,13 @@ public class ArmNativesLibraryProcessor extends LibraryProcessor { return ApplicationResult.DONT_APPLY; } - if (platform.getOperatingSystem().isMacOS()) { - if (context.supportsArm64MacOS()) { - // This version already supports arm64 macOS, nothing to do. - return ApplicationResult.DONT_APPLY; - } + if (context.supportsArm64(platform.getOperatingSystem())) { + // This version already supports arm64, nothing to do. + return ApplicationResult.DONT_APPLY; + } - // Must upgrade natives to support macos ARM + if (platform.getOperatingSystem().isMacOS()) { + // Must upgrade natives to support macos ARM, even if not using classpath natives. return ApplicationResult.MUST_APPLY; } @@ -78,8 +78,14 @@ public class ArmNativesLibraryProcessor extends LibraryProcessor { @Override public Predicate apply(Consumer dependencyConsumer) { + final String osName = switch (platform.getOperatingSystem()) { + case MAC_OS -> "macos"; + case WINDOWS -> "windows"; + case LINUX -> "linux"; + }; + return library -> { - if (library.is(LWJGL_GROUP) && library.target() == Library.Target.NATIVES && (library.classifier() != null && library.classifier().startsWith("natives-"))) { + if (library.is(LWJGL_GROUP) && library.target() == Library.Target.NATIVES && (library.classifier() != null && library.classifier().equals("natives-" + osName))) { // Add the arm64 natives. dependencyConsumer.accept(library.withClassifier(library.classifier() + "-arm64")); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/LWJGL3UpgradeLibraryProcessor.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/LWJGL3UpgradeLibraryProcessor.java index d238fd6c..ae53ff0a 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/LWJGL3UpgradeLibraryProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/LWJGL3UpgradeLibraryProcessor.java @@ -85,6 +85,6 @@ public class LWJGL3UpgradeLibraryProcessor extends LibraryProcessor { // Add support for macOS private boolean upgradeMacOSArm() { - return platform.getOperatingSystem().isMacOS() && platform.getArchitecture().isArm() && !context.supportsArm64MacOS() && !context.hasClasspathNatives(); + return platform.getOperatingSystem().isMacOS() && platform.getArchitecture().isArm() && !context.supportsArm64(Platform.OperatingSystem.MAC_OS) && !context.hasClasspathNatives(); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/LoomNativeSupportLibraryProcessor.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/LoomNativeSupportLibraryProcessor.java index 7c195024..89f85f82 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/LoomNativeSupportLibraryProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/LoomNativeSupportLibraryProcessor.java @@ -45,7 +45,7 @@ public class LoomNativeSupportLibraryProcessor extends LibraryProcessor { return ApplicationResult.DONT_APPLY; } - if (platform.getOperatingSystem().isMacOS() && platform.getArchitecture().isArm() && !context.supportsArm64MacOS()) { + if (platform.getOperatingSystem().isMacOS() && platform.getArchitecture().isArm() && !context.supportsArm64(Platform.OperatingSystem.MAC_OS)) { // Add the loom native support mod when adding ARM64 macOS support return ApplicationResult.MUST_APPLY; } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/ObjcBridgeUpgradeLibraryProcessor.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/ObjcBridgeUpgradeLibraryProcessor.java index 0d55a887..ed4f3633 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/ObjcBridgeUpgradeLibraryProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/library/processors/ObjcBridgeUpgradeLibraryProcessor.java @@ -54,7 +54,7 @@ public class ObjcBridgeUpgradeLibraryProcessor extends LibraryProcessor { } // Apply when Arm64 macOS is unsupported by Minecraft - return context.supportsArm64MacOS() ? ApplicationResult.DONT_APPLY : ApplicationResult.MUST_APPLY; + return context.supportsArm64(Platform.OperatingSystem.MAC_OS) ? ApplicationResult.DONT_APPLY : ApplicationResult.MUST_APPLY; } @Override diff --git a/src/main/java/net/fabricmc/loom/decompilers/DecompilerConfiguration.java b/src/main/java/net/fabricmc/loom/decompilers/DecompilerConfiguration.java index 8bc63e20..adf8650d 100644 --- a/src/main/java/net/fabricmc/loom/decompilers/DecompilerConfiguration.java +++ b/src/main/java/net/fabricmc/loom/decompilers/DecompilerConfiguration.java @@ -24,6 +24,8 @@ package net.fabricmc.loom.decompilers; +import javax.inject.Inject; + import org.gradle.api.Project; import net.fabricmc.loom.LoomGradleExtension; @@ -31,16 +33,17 @@ import net.fabricmc.loom.api.decompilers.LoomDecompiler; import net.fabricmc.loom.decompilers.cfr.LoomCFRDecompiler; import net.fabricmc.loom.decompilers.fernflower.FabricFernFlowerDecompiler; -public final class DecompilerConfiguration { - private DecompilerConfiguration() { +public abstract class DecompilerConfiguration implements Runnable { + @Inject + protected abstract Project getProject(); + + @Override + public void run() { + registerDecompiler(getProject(), "fernFlower", FabricFernFlowerDecompiler.class); + registerDecompiler(getProject(), "cfr", LoomCFRDecompiler.class); } - public static void setup(Project project) { - registerDecompiler(project, "fernFlower", FabricFernFlowerDecompiler.class); - registerDecompiler(project, "cfr", LoomCFRDecompiler.class); - } - - private static void registerDecompiler(Project project, String name, Class decompilerClass) { + private void registerDecompiler(Project project, String name, Class decompilerClass) { LoomGradleExtension.get(project).getDecompilerOptions().register(name, options -> options.getDecompilerClassName().set(decompilerClass.getName())); } } diff --git a/src/main/java/net/fabricmc/loom/task/LoomTasks.java b/src/main/java/net/fabricmc/loom/task/LoomTasks.java index c0bb9651..c73a3aca 100644 --- a/src/main/java/net/fabricmc/loom/task/LoomTasks.java +++ b/src/main/java/net/fabricmc/loom/task/LoomTasks.java @@ -24,6 +24,8 @@ package net.fabricmc.loom.task; +import javax.inject.Inject; + import com.google.common.base.Preconditions; import org.gradle.api.Project; import org.gradle.api.Task; @@ -41,55 +43,55 @@ import net.fabricmc.loom.task.launch.GenerateRemapClasspathTask; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.gradle.GradleUtils; -public final class LoomTasks { - private LoomTasks() { - } +public abstract class LoomTasks implements Runnable { + @Inject + protected abstract Project getProject(); - public static void registerTasks(Project project) { - TaskContainer tasks = project.getTasks(); + @Inject + protected abstract TaskContainer getTasks(); - tasks.register("migrateMappings", MigrateMappingsTask.class, t -> { + @Override + public void run() { + getTasks().register("migrateMappings", MigrateMappingsTask.class, t -> { t.setDescription("Migrates mappings to a new version."); t.getOutputs().upToDateWhen(o -> false); }); - - RemapTaskConfiguration.setupRemap(project); - tasks.register("generateDLIConfig", GenerateDLIConfigTask.class, t -> { + getTasks().register("generateDLIConfig", GenerateDLIConfigTask.class, t -> { t.setDescription("Generate the DevLaunchInjector config file"); // Must allow these IDE files to be generated first - t.mustRunAfter(tasks.named("eclipse")); - t.mustRunAfter(tasks.named("idea")); + t.mustRunAfter(getTasks().named("eclipse")); + t.mustRunAfter(getTasks().named("idea")); }); - tasks.register("generateLog4jConfig", GenerateLog4jConfigTask.class, t -> { + getTasks().register("generateLog4jConfig", GenerateLog4jConfigTask.class, t -> { t.setDescription("Generate the log4j config file"); }); - tasks.register("generateRemapClasspath", GenerateRemapClasspathTask.class, t -> { + getTasks().register("generateRemapClasspath", GenerateRemapClasspathTask.class, t -> { t.setDescription("Generate the remap classpath file"); }); - tasks.register("configureLaunch", task -> { - task.dependsOn(tasks.named("generateDLIConfig")); - task.dependsOn(tasks.named("generateLog4jConfig")); - task.dependsOn(tasks.named("generateRemapClasspath")); + getTasks().register("configureLaunch", task -> { + task.dependsOn(getTasks().named("generateDLIConfig")); + task.dependsOn(getTasks().named("generateLog4jConfig")); + task.dependsOn(getTasks().named("generateRemapClasspath")); task.setDescription("Setup the required files to launch Minecraft"); task.setGroup(Constants.TaskGroup.FABRIC); }); - TaskProvider validateAccessWidener = tasks.register("validateAccessWidener", ValidateAccessWidenerTask.class, t -> { + TaskProvider validateAccessWidener = getTasks().register("validateAccessWidener", ValidateAccessWidenerTask.class, t -> { t.setDescription("Validate all the rules in the access widener against the Minecraft jar"); t.setGroup("verification"); }); - tasks.named("check").configure(task -> task.dependsOn(validateAccessWidener)); + getTasks().named("check").configure(task -> task.dependsOn(validateAccessWidener)); - registerIDETasks(tasks); - registerRunTasks(tasks, project); + registerIDETasks(); + registerRunTasks(); // Must be done in afterEvaluate to allow time for the build script to configure the jar config. - GradleUtils.afterSuccessfulEvaluation(project, () -> { - LoomGradleExtension extension = LoomGradleExtension.get(project); + GradleUtils.afterSuccessfulEvaluation(getProject(), () -> { + LoomGradleExtension extension = LoomGradleExtension.get(getProject()); if (extension.getMinecraftJarConfiguration().get() == MinecraftJarConfiguration.SERVER_ONLY) { // Server only, nothing more to do. @@ -103,37 +105,37 @@ public final class LoomTasks { return; } - registerClientSetupTasks(project.getTasks(), versionInfo.hasNativesToExtract()); + registerClientSetupTasks(getTasks(), versionInfo.hasNativesToExtract()); }); } - private static void registerIDETasks(TaskContainer tasks) { - tasks.register("genIdeaWorkspace", GenIdeaProjectTask.class, t -> { + private void registerIDETasks() { + getTasks().register("genIdeaWorkspace", GenIdeaProjectTask.class, t -> { t.setDescription("Generates an IntelliJ IDEA workspace from this project."); - t.dependsOn("idea", getIDELaunchConfigureTaskName(t.getProject())); + t.dependsOn("idea", getIDELaunchConfigureTaskName(getProject())); t.setGroup(Constants.TaskGroup.IDE); }); - tasks.register("genEclipseRuns", GenEclipseRunsTask.class, t -> { + getTasks().register("genEclipseRuns", GenEclipseRunsTask.class, t -> { t.setDescription("Generates Eclipse run configurations for this project."); - t.dependsOn(getIDELaunchConfigureTaskName(t.getProject())); + t.dependsOn(getIDELaunchConfigureTaskName(getProject())); t.setGroup(Constants.TaskGroup.IDE); }); - tasks.register("cleanEclipseRuns", CleanEclipseRunsTask.class, t -> { + getTasks().register("cleanEclipseRuns", CleanEclipseRunsTask.class, t -> { t.setDescription("Removes Eclipse run configurations for this project."); t.setGroup(Constants.TaskGroup.IDE); }); - tasks.register("vscode", GenVsCodeProjectTask.class, t -> { + getTasks().register("vscode", GenVsCodeProjectTask.class, t -> { t.setDescription("Generates VSCode launch configurations."); - t.dependsOn(getIDELaunchConfigureTaskName(t.getProject())); + t.dependsOn(getIDELaunchConfigureTaskName(getProject())); t.setGroup(Constants.TaskGroup.IDE); }); } - private static void registerRunTasks(TaskContainer tasks, Project project) { - LoomGradleExtension extension = LoomGradleExtension.get(project); + private void registerRunTasks() { + LoomGradleExtension extension = LoomGradleExtension.get(getProject()); Preconditions.checkArgument(extension.getRunConfigs().size() == 0, "Run configurations must not be registered before loom"); @@ -141,7 +143,7 @@ public final class LoomTasks { String configName = config.getName(); String taskName = "run" + configName.substring(0, 1).toUpperCase() + configName.substring(1); - tasks.register(taskName, RunGameTask.class, config).configure(t -> { + getTasks().register(taskName, RunGameTask.class, config).configure(t -> { t.setDescription("Starts the '" + config.getConfigName() + "' run configuration"); t.dependsOn(config.getEnvironment().equals("client") ? "configureClientLaunch" : "configureLaunch"); @@ -151,7 +153,7 @@ public final class LoomTasks { extension.getRunConfigs().create("server", RunConfigSettings::server); // Remove the client or server run config when not required. Done by name to not remove any possible custom run configs - GradleUtils.afterSuccessfulEvaluation(project, () -> { + GradleUtils.afterSuccessfulEvaluation(getProject(), () -> { String taskName = switch (extension.getMinecraftJarConfiguration().get()) { case SERVER_ONLY -> "client"; case CLIENT_ONLY -> "server"; diff --git a/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java b/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java index 48b63f15..93ec877f 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java +++ b/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java @@ -28,9 +28,13 @@ import java.io.File; import java.util.Map; import java.util.Set; +import javax.inject.Inject; + import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.ConfigurationContainer; +import org.gradle.api.artifacts.dsl.ArtifactHandler; import org.gradle.api.plugins.BasePlugin; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.tasks.TaskContainer; @@ -45,45 +49,56 @@ import net.fabricmc.loom.util.aw2at.Aw2At; import net.fabricmc.loom.util.gradle.GradleUtils; import net.fabricmc.loom.util.gradle.SourceSetHelper; -public class RemapTaskConfiguration { +public abstract class RemapTaskConfiguration implements Runnable { public static final String REMAP_JAR_TASK_NAME = "remapJar"; public static final String REMAP_SOURCES_JAR_TASK_NAME = "remapSourcesJar"; - public static void setupRemap(Project project) { - final TaskContainer tasks = project.getTasks(); - final LoomGradleExtension extension = LoomGradleExtension.get(project); + @Inject + protected abstract Project getProject(); - if (GradleUtils.getBooleanProperty(project, Constants.Properties.DONT_REMAP)) { - extension.getUnmappedModCollection().from(project.getTasks().getByName(JavaPlugin.JAR_TASK_NAME)); + @Inject + protected abstract TaskContainer getTasks(); + + @Inject + protected abstract ArtifactHandler getArtifacts(); + + @Inject + protected abstract ConfigurationContainer getConfigurations(); + + public void run() { + final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); + + if (GradleUtils.getBooleanProperty(getProject(), Constants.Properties.DONT_REMAP)) { + extension.getUnmappedModCollection().from(getTasks().getByName(JavaPlugin.JAR_TASK_NAME)); return; } // Register the default remap jar task - must not be lazy to ensure that the prepare tasks get setup for other projects to depend on. - RemapJarTask remapJarTask = tasks.create(REMAP_JAR_TASK_NAME, RemapJarTask.class, task -> { - final AbstractArchiveTask jarTask = tasks.named(JavaPlugin.JAR_TASK_NAME, AbstractArchiveTask.class).get(); + RemapJarTask remapJarTask = getTasks().create(REMAP_JAR_TASK_NAME, RemapJarTask.class, task -> { + final AbstractArchiveTask jarTask = getTasks().named(JavaPlugin.JAR_TASK_NAME, AbstractArchiveTask.class).get(); // Basic task setup task.dependsOn(jarTask); task.setDescription("Remaps the built project jar to intermediary mappings."); task.setGroup(Constants.TaskGroup.FABRIC); - project.getArtifacts().add(JavaPlugin.API_ELEMENTS_CONFIGURATION_NAME, task); - project.getArtifacts().add(JavaPlugin.RUNTIME_ELEMENTS_CONFIGURATION_NAME, task); + getArtifacts().add(JavaPlugin.API_ELEMENTS_CONFIGURATION_NAME, task); + getArtifacts().add(JavaPlugin.RUNTIME_ELEMENTS_CONFIGURATION_NAME, task); // Setup the input file and the nested deps task.getInputFile().convention(jarTask.getArchiveFile()); - task.dependsOn(tasks.named(JavaPlugin.JAR_TASK_NAME)); - task.getIncludesClientOnlyClasses().set(project.provider(extension::areEnvironmentSourceSetsSplit)); + task.dependsOn(getTasks().named(JavaPlugin.JAR_TASK_NAME)); + task.getIncludesClientOnlyClasses().set(getProject().provider(extension::areEnvironmentSourceSetsSplit)); }); // Configure the default jar task - tasks.named(JavaPlugin.JAR_TASK_NAME, AbstractArchiveTask.class).configure(task -> { + getTasks().named(JavaPlugin.JAR_TASK_NAME, AbstractArchiveTask.class).configure(task -> { task.getArchiveClassifier().convention("dev"); - task.getDestinationDirectory().set(new File(project.getBuildDir(), "devlibs")); + task.getDestinationDirectory().set(new File(getProject().getBuildDir(), "devlibs")); }); - tasks.named(BasePlugin.ASSEMBLE_TASK_NAME).configure(task -> task.dependsOn(remapJarTask)); + getTasks().named(BasePlugin.ASSEMBLE_TASK_NAME).configure(task -> task.dependsOn(remapJarTask)); - trySetupSourceRemapping(project); + trySetupSourceRemapping(); project.afterEvaluate(p -> { if (extension.isForge()) { @@ -103,15 +118,15 @@ public class RemapTaskConfiguration { } }); - if (GradleUtils.getBooleanProperty(project, Constants.Properties.DISABLE_REMAPPED_VARIANTS)) { + if (GradleUtils.getBooleanProperty(getProject(), Constants.Properties.DISABLE_REMAPPED_VARIANTS)) { return; } - GradleUtils.afterSuccessfulEvaluation(project, () -> { + GradleUtils.afterSuccessfulEvaluation(getProject(), () -> { // Remove -dev jars from the default jar task for (String configurationName : new String[] { JavaPlugin.API_ELEMENTS_CONFIGURATION_NAME, JavaPlugin.RUNTIME_ELEMENTS_CONFIGURATION_NAME }) { - Configuration configuration = project.getConfigurations().getByName(configurationName); - final Jar jarTask = (Jar) project.getTasks().getByName(JavaPlugin.JAR_TASK_NAME); + Configuration configuration = getConfigurations().getByName(configurationName); + final Jar jarTask = (Jar) getTasks().getByName(JavaPlugin.JAR_TASK_NAME); configuration.getArtifacts().removeIf(artifact -> { // if the artifact is built by the jar task, and has the same output path. return artifact.getFile().getAbsolutePath().equals(jarTask.getArchiveFile().get().getAsFile().getAbsolutePath()) && artifact.getBuildDependencies().getDependencies(null).contains(jarTask); @@ -120,60 +135,59 @@ public class RemapTaskConfiguration { }); } - private static void trySetupSourceRemapping(Project project) { - final TaskContainer tasks = project.getTasks(); - final LoomGradleExtension extension = LoomGradleExtension.get(project); - final String sourcesJarTaskName = SourceSetHelper.getMainSourceSet(project).getSourcesJarTaskName(); + private void trySetupSourceRemapping() { + final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); + final String sourcesJarTaskName = SourceSetHelper.getMainSourceSet(getProject()).getSourcesJarTaskName(); - TaskProvider remapSourcesTask = tasks.register(REMAP_SOURCES_JAR_TASK_NAME, RemapSourcesJarTask.class, task -> { + TaskProvider remapSourcesTask = getTasks().register(REMAP_SOURCES_JAR_TASK_NAME, RemapSourcesJarTask.class, task -> { task.setDescription("Remaps the default sources jar to intermediary mappings."); task.setGroup(Constants.TaskGroup.FABRIC); - final Task sourcesTask = project.getTasks().findByName(sourcesJarTaskName); + final Task sourcesTask = getTasks().findByName(sourcesJarTaskName); if (sourcesTask == null) { - project.getLogger().info("{} task was not found, not remapping sources", sourcesJarTaskName); + getProject().getLogger().info("{} task was not found, not remapping sources", sourcesJarTaskName); task.setEnabled(false); return; } if (!(sourcesTask instanceof Jar sourcesJarTask)) { - project.getLogger().info("{} task is not a Jar task, not remapping sources", sourcesJarTaskName); + getProject().getLogger().info("{} task is not a Jar task, not remapping sources", sourcesJarTaskName); task.setEnabled(false); return; } sourcesJarTask.getArchiveClassifier().convention("dev-sources"); - sourcesJarTask.getDestinationDirectory().set(new File(project.getBuildDir(), "devlibs")); + sourcesJarTask.getDestinationDirectory().set(new File(getProject().getBuildDir(), "devlibs")); task.getArchiveClassifier().convention("sources"); task.dependsOn(sourcesJarTask); task.getInputFile().convention(sourcesJarTask.getArchiveFile()); - task.getIncludesClientOnlyClasses().set(project.provider(extension::areEnvironmentSourceSetsSplit)); + task.getIncludesClientOnlyClasses().set(getProject().provider(extension::areEnvironmentSourceSetsSplit)); }); - tasks.named(BasePlugin.ASSEMBLE_TASK_NAME).configure(task -> task.dependsOn(remapSourcesTask)); + getTasks().named(BasePlugin.ASSEMBLE_TASK_NAME).configure(task -> task.dependsOn(remapSourcesTask)); - if (GradleUtils.getBooleanProperty(project, "fabric.loom.disableRemappedVariants")) { + if (GradleUtils.getBooleanProperty(getProject(), "fabric.loom.disableRemappedVariants")) { return; } - GradleUtils.afterSuccessfulEvaluation(project, () -> { - final Task sourcesTask = project.getTasks().findByName(sourcesJarTaskName); + GradleUtils.afterSuccessfulEvaluation(getProject(), () -> { + final Task sourcesTask = getTasks().findByName(sourcesJarTaskName); if (!(sourcesTask instanceof Jar sourcesJarTask)) { return; } - if (project.getConfigurations().getNames().contains(JavaPlugin.SOURCES_ELEMENTS_CONFIGURATION_NAME)) { - project.getArtifacts().add(JavaPlugin.SOURCES_ELEMENTS_CONFIGURATION_NAME, remapSourcesTask); + if (getConfigurations().getNames().contains(JavaPlugin.SOURCES_ELEMENTS_CONFIGURATION_NAME)) { + getArtifacts().add(JavaPlugin.SOURCES_ELEMENTS_CONFIGURATION_NAME, remapSourcesTask); // Remove the dev sources artifact - Configuration configuration = project.getConfigurations().getByName(JavaPlugin.SOURCES_ELEMENTS_CONFIGURATION_NAME); + Configuration configuration = getConfigurations().getByName(JavaPlugin.SOURCES_ELEMENTS_CONFIGURATION_NAME); configuration.getArtifacts().removeIf(a -> a.getFile().equals(sourcesJarTask.getArchiveFile().get().getAsFile())); } else { // Sources jar may not have been created with withSourcesJar - project.getLogger().warn("Not publishing sources jar as it was not found. Use java.withSourcesJar() to fix."); + getProject().getLogger().warn("Not publishing sources jar as it was not found. Use java.withSourcesJar() to fix."); } }); } diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/library/LibraryContextTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/library/LibraryContextTest.groovy index 458ac837..871d318d 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/library/LibraryContextTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/library/LibraryContextTest.groovy @@ -30,6 +30,7 @@ import spock.lang.Specification import net.fabricmc.loom.configuration.providers.minecraft.MinecraftVersionMeta import net.fabricmc.loom.configuration.providers.minecraft.library.LibraryContext import net.fabricmc.loom.test.util.MinecraftTestUtils +import net.fabricmc.loom.util.Platform class LibraryContextTest extends Specification { def "Supports ARM64 macOS"() { @@ -37,7 +38,7 @@ class LibraryContextTest extends Specification { def context = new LibraryContext(MinecraftTestUtils.getVersionMeta(id), JavaVersion.VERSION_17) then: - context.supportsArm64MacOS() == supported + context.supportsArm64(Platform.OperatingSystem.MAC_OS) == supported where: id || supported @@ -47,6 +48,22 @@ class LibraryContextTest extends Specification { "1.4.7" || false } + def "Supports ARM64 windows"() { + when: + def context = new LibraryContext(MinecraftTestUtils.getVersionMeta(id), JavaVersion.VERSION_17) + + then: + context.supportsArm64(Platform.OperatingSystem.WINDOWS) == supported + + where: + id || supported + "23w16a" || true + "1.19.4" || false + "1.18.2" || false + "1.16.5" || false + "1.4.7" || false + } + def "Uses LWJGL 3"() { when: def context = new LibraryContext(MinecraftTestUtils.getVersionMeta(id), JavaVersion.VERSION_17) diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/library/processors/ArmNativesLibraryProcessorTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/library/processors/ArmNativesLibraryProcessorTest.groovy index d1897064..7a7af5c9 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/library/processors/ArmNativesLibraryProcessorTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/library/processors/ArmNativesLibraryProcessorTest.groovy @@ -57,6 +57,7 @@ class ArmNativesLibraryProcessorTest extends LibraryProcessorTest { where: id || result + "23w16a" || LibraryProcessor.ApplicationResult.DONT_APPLY // Supports ARM64 Windows "1.19.4" || LibraryProcessor.ApplicationResult.MUST_APPLY "1.18.2" || LibraryProcessor.ApplicationResult.DONT_APPLY // Only support versions with classpath natives. "1.12.2" || LibraryProcessor.ApplicationResult.DONT_APPLY // Not LWJGL 3