diff --git a/src/main/java/net/fabricmc/loom/AbstractPlugin.java b/src/main/java/net/fabricmc/loom/AbstractPlugin.java index 9299ac8..0b247c5 100644 --- a/src/main/java/net/fabricmc/loom/AbstractPlugin.java +++ b/src/main/java/net/fabricmc/loom/AbstractPlugin.java @@ -82,10 +82,11 @@ public class AbstractPlugin implements Plugin { // Force add Mojang repository addMavenRepo(target, "Mojang", "https://libraries.minecraft.net/"); - Configuration compileModsConfig = project.getConfigurations().maybeCreate(Constants.COMPILE_MODS); - compileModsConfig.setTransitive(true); - Configuration compileModsMappedConfig = project.getConfigurations().maybeCreate(Constants.COMPILE_MODS_MAPPED); - compileModsMappedConfig.setTransitive(false); // Don't get transitive deps of already remapped mods + Configuration modCompileClasspathConfig = project.getConfigurations().maybeCreate(Constants.MOD_COMPILE_CLASSPATH); + modCompileClasspathConfig.setTransitive(true); + Configuration modCompileClasspathMappedConfig = project.getConfigurations().maybeCreate(Constants.MOD_COMPILE_CLASSPATH_MAPPED); + modCompileClasspathMappedConfig.setTransitive(false); + Configuration minecraftNamedConfig = project.getConfigurations().maybeCreate(Constants.MINECRAFT_NAMED); minecraftNamedConfig.setTransitive(false); // The launchers do not recurse dependencies Configuration minecraftIntermediaryConfig = project.getConfigurations().maybeCreate(Constants.MINECRAFT_INTERMEDIARY); @@ -100,18 +101,32 @@ public class AbstractPlugin implements Plugin { project.getConfigurations().maybeCreate(Constants.MAPPINGS); - configureIDEs(); - configureCompile(); + for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) { + Configuration compileModsConfig = project.getConfigurations().maybeCreate(entry.getSourceConfiguration()); + compileModsConfig.setTransitive(true); + Configuration compileModsMappedConfig = project.getConfigurations().maybeCreate(entry.getRemappedConfiguration()); + compileModsMappedConfig.setTransitive(false); // Don't get transitive deps of already remapped mods + + extendsFrom(entry.getTargetConfiguration(project.getConfigurations()), entry.getRemappedConfiguration()); + if (entry.isOnModCompileClasspath()) { + extendsFrom(Constants.MOD_COMPILE_CLASSPATH, entry.getSourceConfiguration()); + extendsFrom(Constants.MOD_COMPILE_CLASSPATH_MAPPED, entry.getRemappedConfiguration()); + } + } + + extendsFrom("compile", Constants.MINECRAFT_NAMED); + extendsFrom("annotationProcessor", Constants.MINECRAFT_NAMED); + extendsFrom("annotationProcessor", Constants.MOD_COMPILE_CLASSPATH_MAPPED); extendsFrom(Constants.MINECRAFT_NAMED, Constants.MINECRAFT_DEPENDENCIES); extendsFrom(Constants.MINECRAFT_INTERMEDIARY, Constants.MINECRAFT_DEPENDENCIES); - extendsFrom(Constants.COMPILE_MODS_MAPPED, Constants.MINECRAFT_NAMED); - extendsFrom("compile", Constants.COMPILE_MODS_MAPPED); extendsFrom("compile", Constants.MAPPINGS); - extendsFrom("annotationProcessor", Constants.COMPILE_MODS_MAPPED); extendsFrom("annotationProcessor", Constants.MAPPINGS); + configureIDEs(); + configureCompile(); + Map> taskMap = project.getAllTasks(true); for (Map.Entry> entry : taskMap.entrySet()) { Project project = entry.getKey(); @@ -331,45 +346,51 @@ public class AbstractPlugin implements Plugin { protected void configureMaven() { project.afterEvaluate((p) -> { - Configuration compileModsConfig = p.getConfigurations().getByName(Constants.COMPILE_MODS); + for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) { + if (!entry.hasMavenScope()) { + continue; + } - // add modsCompile to maven-publish - PublishingExtension mavenPublish = p.getExtensions().findByType(PublishingExtension.class); - if (mavenPublish != null) { - mavenPublish.publications((publications) -> { - for (Publication publication : publications) { - if (publication instanceof MavenPublication) { - ((MavenPublication) publication).pom((pom) -> { - pom.withXml((xml) -> { - Node dependencies = GroovyXmlUtil.getOrCreateNode(xml.asNode(), "dependencies"); - Set foundArtifacts = new HashSet<>(); + Configuration compileModsConfig = p.getConfigurations().getByName(entry.getSourceConfiguration()); - GroovyXmlUtil.childrenNodesStream(dependencies) - .filter((n) -> "dependency".equals(n.name())) - .forEach((n) -> { - Optional groupId = GroovyXmlUtil.getNode(n, "groupId"); - Optional artifactId = GroovyXmlUtil.getNode(n, "artifactId"); - if (groupId.isPresent() && artifactId.isPresent()) { - foundArtifacts.add(groupId.get().text() + ":" + artifactId.get().text()); - } - }); + // add modsCompile to maven-publish + PublishingExtension mavenPublish = p.getExtensions().findByType(PublishingExtension.class); + if (mavenPublish != null) { + mavenPublish.publications((publications) -> { + for (Publication publication : publications) { + if (publication instanceof MavenPublication) { + ((MavenPublication) publication).pom((pom) -> { + pom.withXml((xml) -> { + Node dependencies = GroovyXmlUtil.getOrCreateNode(xml.asNode(), "dependencies"); + Set foundArtifacts = new HashSet<>(); - for (Dependency dependency : compileModsConfig.getAllDependencies()) { - if (foundArtifacts.contains(dependency.getGroup() + ":" + dependency.getName())) { - continue; + GroovyXmlUtil.childrenNodesStream(dependencies) + .filter((n) -> "dependency".equals(n.name())) + .forEach((n) -> { + Optional groupId = GroovyXmlUtil.getNode(n, "groupId"); + Optional artifactId = GroovyXmlUtil.getNode(n, "artifactId"); + if (groupId.isPresent() && artifactId.isPresent()) { + foundArtifacts.add(groupId.get().text() + ":" + artifactId.get().text()); + } + }); + + for (Dependency dependency : compileModsConfig.getAllDependencies()) { + if (foundArtifacts.contains(dependency.getGroup() + ":" + dependency.getName())) { + continue; + } + + Node depNode = dependencies.appendNode("dependency"); + depNode.appendNode("groupId", dependency.getGroup()); + depNode.appendNode("artifactId", dependency.getName()); + depNode.appendNode("version", dependency.getVersion()); + depNode.appendNode("scope", entry.getMavenScope()); } - - Node depNode = dependencies.appendNode("dependency"); - depNode.appendNode("groupId", dependency.getGroup()); - depNode.appendNode("artifactId", dependency.getName()); - depNode.appendNode("version", dependency.getVersion()); - depNode.appendNode("scope", "compile"); - } + }); }); - }); + } } - } - }); + }); + } } }); } diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index a703413..1e5d6f9 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -30,6 +30,7 @@ import net.fabricmc.loom.providers.MinecraftMappedProvider; import net.fabricmc.loom.providers.MinecraftProvider; import net.fabricmc.loom.util.LoomDependencyManager; import org.cadixdev.lorenz.MappingSet; +import org.cadixdev.mercury.Mercury; import org.gradle.api.Project; import org.gradle.api.UnknownDomainObjectException; import org.gradle.api.artifacts.Configuration; @@ -62,11 +63,16 @@ public class LoomGradleExtension { private JsonObject installerJson; private int installerJsonPriority = Integer.MAX_VALUE; // 0+, higher = less prioritized private MappingSet[] srcMappingCache = new MappingSet[2]; + private Mercury[] srcMercuryCache = new Mercury[2]; public MappingSet getOrCreateSrcMappingCache(int id, Supplier factory) { return srcMappingCache[id] != null ? srcMappingCache[id] : (srcMappingCache[id] = factory.get()); } + public Mercury getOrCreateSrcMercuryCache(int id, Supplier factory) { + return srcMercuryCache[id] != null ? srcMercuryCache[id] : (srcMercuryCache[id] = factory.get()); + } + public LoomGradleExtension(Project project) { this.project = project; } diff --git a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java index 2721084..cc18fa7 100644 --- a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java +++ b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java @@ -107,7 +107,7 @@ public class MigrateMappingsTask extends AbstractLoomTask { mercury.getClassPath().add(file.toPath()); } - for (File file : project.getConfigurations().getByName(Constants.COMPILE_MODS_MAPPED).getFiles()) { + for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) { mercury.getClassPath().add(file.toPath()); } diff --git a/src/main/java/net/fabricmc/loom/util/Constants.java b/src/main/java/net/fabricmc/loom/util/Constants.java index 71d6a93..48526cf 100644 --- a/src/main/java/net/fabricmc/loom/util/Constants.java +++ b/src/main/java/net/fabricmc/loom/util/Constants.java @@ -25,6 +25,10 @@ package net.fabricmc.loom.util; +import com.google.common.collect.ImmutableList; + +import java.util.List; + public class Constants { public static final String DEFAULT_FABRIC_CLIENT_TWEAKER = "net.fabricmc.loader.launch.FabricClientTweaker"; @@ -35,8 +39,15 @@ public class Constants { public static final String SYSTEM_ARCH = System.getProperty("os.arch").equals("64") ? "64" : "32"; - public static final String COMPILE_MODS = "modCompile"; - public static final String COMPILE_MODS_MAPPED = "modCompileMapped"; + public static final String MOD_COMPILE_CLASSPATH = "modCompileClasspath"; + public static final String MOD_COMPILE_CLASSPATH_MAPPED = "modCompileClasspathMapped"; + public static final List MOD_COMPILE_ENTRIES = ImmutableList.of( + new RemappedConfigurationEntry("modCompile", "compile", true, "compile"), + new RemappedConfigurationEntry("modApi", "api", true, "compile"), + new RemappedConfigurationEntry("modImplementation", "implementation", true, "runtime"), + new RemappedConfigurationEntry("modRuntime", "runtimeOnly", false, "") + ); + public static final String INCLUDE = "include"; public static final String MINECRAFT = "minecraft"; public static final String MINECRAFT_DEPENDENCIES = "minecraftLibraries"; diff --git a/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java b/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java index c571018..727b415 100644 --- a/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java +++ b/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java @@ -110,20 +110,24 @@ public class LoomDependencyManager { }); } - ModCompileRemapper.remapDependencies( - project, - mappingsProvider.mappingsName + "." + mappingsProvider.mappingsVersion, - extension, - project.getConfigurations().getByName(Constants.COMPILE_MODS), - project.getConfigurations().getByName(Constants.COMPILE_MODS_MAPPED), - project.getConfigurations().getByName("compile"), - afterTasks::add - ); + { + String mappingsKey = mappingsProvider.mappingsName + "." + mappingsProvider.mappingsVersion; + + for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) { + ModCompileRemapper.remapDependencies( + project, mappingsKey, extension, + project.getConfigurations().getByName(entry.getSourceConfiguration()), + project.getConfigurations().getByName(entry.getRemappedConfiguration()), + project.getConfigurations().getByName(entry.getTargetConfiguration(project.getConfigurations())), + afterTasks::add + ); + } + } if (extension.getInstallerJson() == null) { //If we've not found the installer JSON we've probably skipped remapping Fabric loader, let's go looking - project.getLogger().info("Didn't find installer JSON, searching through compileMods"); - Configuration configuration = project.getConfigurations().getByName(Constants.COMPILE_MODS); + project.getLogger().info("Didn't find installer JSON, searching through modCompileClasspath"); + Configuration configuration = project.getConfigurations().getByName(Constants.MOD_COMPILE_CLASSPATH); Set seenFiles = new HashSet<>(); diff --git a/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java b/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java index 3c64f02..6b3fa2d 100644 --- a/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java @@ -82,7 +82,7 @@ public class ModCompileRemapper { File modStore = extension.getRemappedModCache(); - remapArtifact(project, artifact, remappedFilename, modStore); + remapArtifact(project, modCompileRemapped, artifact, remappedFilename, modStore); project.getDependencies().add(modCompileRemapped.getName(), project.getDependencies().module(remappedNotation)); @@ -118,13 +118,13 @@ public class ModCompileRemapper { dependencies.add(regularCompile.getName(), dep); } - private static void remapArtifact(Project project, ResolvedArtifact artifact, String remappedFilename, File modStore) { + private static void remapArtifact(Project project, Configuration config, ResolvedArtifact artifact, String remappedFilename, File modStore) { File input = artifact.getFile(); File output = new File(modStore, remappedFilename + ".jar"); if (!output.exists() || input.lastModified() <= 0 || input.lastModified() > output.lastModified()) { //If the output doesn't exist, or appears to be outdated compared to the input we'll remap it try { - ModProcessor.handleMod(input, output, project); + ModProcessor.processMod(input, output, project, config); } catch (IOException e) { throw new RuntimeException("Failed to remap mod", e); } @@ -137,6 +137,8 @@ public class ModCompileRemapper { } else { project.getLogger().info(output.getName() + " is up to date with " + input.getName()); } + + ModProcessor.acknowledgeMod(input, output, project, config); } private static File findSources(DependencyHandler dependencies, ResolvedArtifact artifact) { diff --git a/src/main/java/net/fabricmc/loom/util/ModProcessor.java b/src/main/java/net/fabricmc/loom/util/ModProcessor.java index dfb250c..6a91a72 100644 --- a/src/main/java/net/fabricmc/loom/util/ModProcessor.java +++ b/src/main/java/net/fabricmc/loom/util/ModProcessor.java @@ -32,9 +32,9 @@ import net.fabricmc.loom.providers.MappingsProvider; import net.fabricmc.loom.providers.MinecraftMappedProvider; import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; -import net.fabricmc.tinyremapper.TinyUtils; import org.apache.commons.io.IOUtils; import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; import org.gradle.internal.impldep.aQute.lib.strings.Strings; import org.zeroturnaround.zip.ZipUtil; import org.zeroturnaround.zip.commons.FileUtils; @@ -48,7 +48,8 @@ import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collection; +import java.util.HashSet; +import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipEntry; @@ -56,21 +57,24 @@ import java.util.zip.ZipEntry; public class ModProcessor { private static final Gson GSON = new Gson(); - public static void handleMod(File input, File output, Project project) throws IOException { + public static void processMod(File input, File output, Project project, Configuration config) throws IOException { if(output.exists()){ output.delete(); } remapJar(input, output, project); - readInstallerJson(input, project); //Enable this if you want your nested jars to be extracted, this will extract **all** jars if(project.getExtensions().getByType(LoomGradleExtension.class).extractJars){ - handleNestedJars(input, project); + handleNestedJars(input, project, config); } //Always strip the nested jars stripNestedJars(output); } - private static void handleNestedJars(File input, Project project) throws IOException { + public static void acknowledgeMod(File input, File output, Project project, Configuration config) { + readInstallerJson(input, project); + } + + private static void handleNestedJars(File input, Project project, Configuration config) throws IOException { JarFile jarFile = new JarFile(input); JarEntry modJsonEntry = jarFile.getJarEntry("fabric.mod.json"); if(modJsonEntry == null){ @@ -86,12 +90,12 @@ public class ModProcessor { JsonObject jsonObject = jsonArray.get(i).getAsJsonObject(); String fileName = jsonObject.get("file").getAsString(); project.getLogger().lifecycle(String.format("Found %s nested in %s", fileName, input.getName())); - processNestedJar(jarFile, fileName, project); + processNestedJar(jarFile, fileName, project, config); } } } - private static void processNestedJar(JarFile parentJar, String fileName, Project project) throws IOException { + private static void processNestedJar(JarFile parentJar, String fileName, Project project, Configuration config) throws IOException { LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); JarEntry entry = parentJar.getJarEntry(fileName); @@ -105,14 +109,14 @@ public class ModProcessor { } File remappedFile = new File(extension.getRemappedModCache(), fileName.substring(fileName.lastIndexOf("/"))); - handleMod(nestedFile, remappedFile, project); + processMod(nestedFile, remappedFile, project, config); if(!remappedFile.exists()){ throw new RuntimeException("Failed to find processed nested jar"); } //Add the project right onto the remapped mods, hopefully this works - project.getDependencies().add(Constants.COMPILE_MODS_MAPPED, project.files(remappedFile)); + project.getDependencies().add(config.getName(), project.files(remappedFile)); } private static void stripNestedJars(File file){ @@ -142,16 +146,20 @@ public class ModProcessor { Path[] mcDeps = mappedProvider.getMapperPaths().stream() .map(File::toPath) .toArray(Path[]::new); - Path[] modCompiles = project.getConfigurations().getByName(Constants.COMPILE_MODS).getFiles().stream() - .filter((f) -> !f.equals(input)) - .map(p -> { - if (p.equals(input)) { - return inputPath; - } else { - return p.toPath(); - } - }) - .toArray(Path[]::new); + Set modCompiles = new HashSet<>(); + for (RemappedConfigurationEntry entry : Constants.MOD_COMPILE_ENTRIES) { + project.getConfigurations().getByName(entry.getSourceConfiguration()).getFiles().stream() + .filter((f) -> !f.equals(input)) + .map(p -> { + if (p.equals(input)) { + return inputPath; + } else { + return p.toPath(); + } + }) + .forEach(modCompiles::add); + } + project.getLogger().lifecycle(":remapping " + input.getName() + " (TinyRemapper, " + fromM + " -> " + toM + ")"); @@ -161,7 +169,7 @@ public class ModProcessor { try (OutputConsumerPath outputConsumer = new OutputConsumerPath(Paths.get(output.getAbsolutePath()))) { outputConsumer.addNonClassFiles(inputPath); - remapper.readClassPath(modCompiles); + remapper.readClassPath(modCompiles.toArray(new Path[0])); remapper.readClassPath(mc); remapper.readClassPath(mcDeps); remapper.readInputs(inputPath); @@ -194,7 +202,7 @@ public class ModProcessor { if (entry == null) { entry = jarFile.getEntry("fabric-installer.json"); - priority = 1; + priority++; if (entry == null) { return; } diff --git a/src/main/java/net/fabricmc/loom/util/RemappedConfigurationEntry.java b/src/main/java/net/fabricmc/loom/util/RemappedConfigurationEntry.java new file mode 100644 index 0000000..59f9b69 --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/RemappedConfigurationEntry.java @@ -0,0 +1,45 @@ +package net.fabricmc.loom.util; + +import org.gradle.api.artifacts.ConfigurationContainer; + +public class RemappedConfigurationEntry { + private final String sourceConfiguration; + private final String targetConfiguration; + private final String mavenScope; + private final boolean isOnModCompileClasspath; + + public RemappedConfigurationEntry(String sourceConfiguration, String targetConfiguration, boolean isOnModCompileClasspath, String mavenScope) { + this.sourceConfiguration = sourceConfiguration; + this.targetConfiguration = targetConfiguration; + this.isOnModCompileClasspath = isOnModCompileClasspath; + this.mavenScope = mavenScope; + } + + public String getMavenScope() { + return mavenScope; + } + + public boolean hasMavenScope() { + return mavenScope != null && !mavenScope.isEmpty(); + } + + public boolean isOnModCompileClasspath() { + return isOnModCompileClasspath; + } + + public String getSourceConfiguration() { + return sourceConfiguration; + } + + public String getRemappedConfiguration() { + return sourceConfiguration + "Mapped"; + } + + public String getTargetConfiguration(ConfigurationContainer container) { + if (container.findByName(targetConfiguration) == null) { + return "compile"; + } + + return targetConfiguration; + } +} diff --git a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java index a0337bc..5a9e486 100644 --- a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java @@ -73,26 +73,30 @@ public class SourceRemapper { project.getLogger().lifecycle(":remapping source jar"); - Mercury mercury = new Mercury(); + Mercury mercury = extension.getOrCreateSrcMercuryCache(toNamed ? 1 : 0, () -> { + Mercury m = new Mercury(); - for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) { - mercury.getClassPath().add(file.toPath()); - } - if (!toNamed) { - for (File file : project.getConfigurations().getByName(Constants.COMPILE_MODS_MAPPED).getFiles()) { - mercury.getClassPath().add(file.toPath()); + for (File file : project.getConfigurations().getByName(Constants.MINECRAFT_DEPENDENCIES).getFiles()) { + m.getClassPath().add(file.toPath()); } - } - for (Path file : extension.getUnmappedMods()) { - if (Files.isRegularFile(file)) { - mercury.getClassPath().add(file); + if (!toNamed) { + for (File file : project.getConfigurations().getByName("compileClasspath").getFiles()) { + m.getClassPath().add(file.toPath()); + } + } + for (Path file : extension.getUnmappedMods()) { + if (Files.isRegularFile(file)) { + m.getClassPath().add(file); + } } - } - mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_MAPPED_JAR.toPath()); - mercury.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_INTERMEDIARY_JAR.toPath()); + m.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_MAPPED_JAR.toPath()); + m.getClassPath().add(extension.getMinecraftMappedProvider().MINECRAFT_INTERMEDIARY_JAR.toPath()); - mercury.getProcessors().add(MercuryRemapper.create(mappings)); + m.getProcessors().add(MercuryRemapper.create(mappings)); + + return m; + }); if (source.equals(destination)) { if (source.isDirectory()) {