From b4beaed968c59901ea88359777ab7e8eb2ad53fb Mon Sep 17 00:00:00 2001 From: Adrian Siekierka Date: Mon, 22 Apr 2019 13:41:16 +0200 Subject: [PATCH] make modCompile() transitive --- .../net/fabricmc/loom/AbstractPlugin.java | 7 +- .../loom/providers/MappingsProvider.java | 2 +- .../loom/providers/ModRemapperProvider.java | 103 ------------ .../loom/util/LoomDependencyManager.java | 79 ++++++--- .../loom/util/ModCompileRemapper.java | 153 ++++++++++++++++++ 5 files changed, 214 insertions(+), 130 deletions(-) delete mode 100644 src/main/java/net/fabricmc/loom/providers/ModRemapperProvider.java create mode 100644 src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java diff --git a/src/main/java/net/fabricmc/loom/AbstractPlugin.java b/src/main/java/net/fabricmc/loom/AbstractPlugin.java index 0a8b1e1..de99053 100644 --- a/src/main/java/net/fabricmc/loom/AbstractPlugin.java +++ b/src/main/java/net/fabricmc/loom/AbstractPlugin.java @@ -28,7 +28,6 @@ import com.google.common.collect.ImmutableMap; import groovy.util.Node; import net.fabricmc.loom.providers.MappingsProvider; import net.fabricmc.loom.providers.MinecraftProvider; -import net.fabricmc.loom.providers.ModRemapperProvider; import net.fabricmc.loom.task.RemapJar; import net.fabricmc.loom.task.RemapSourcesJar; import net.fabricmc.loom.util.*; @@ -81,9 +80,9 @@ public class AbstractPlugin implements Plugin { addMavenRepo(target, "Mojang", "https://libraries.minecraft.net/"); Configuration compileModsConfig = project.getConfigurations().maybeCreate(Constants.COMPILE_MODS); - compileModsConfig.setTransitive(false); + compileModsConfig.setTransitive(true); Configuration compileModsMappedConfig = project.getConfigurations().maybeCreate(Constants.COMPILE_MODS_MAPPED); - compileModsMappedConfig.setTransitive(false); // Dont get transitive deps of mods + compileModsMappedConfig.setTransitive(false); // Don't get transitive deps of already remapped mods 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); @@ -224,7 +223,7 @@ public class AbstractPlugin implements Plugin { dependencyManager.addProvider(new MinecraftProvider()); dependencyManager.addProvider(new MappingsProvider()); - dependencyManager.addProvider(new ModRemapperProvider()); + dependencyManager.handleDependencies(project1); project1.getTasks().getByName("idea").finalizedBy(project1.getTasks().getByName("genIdeaWorkspace")); diff --git a/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java b/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java index 835779f..1416d7a 100644 --- a/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java +++ b/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java @@ -62,7 +62,7 @@ public class MappingsProvider extends DependencyProvider { String version = dependency.getResolvedVersion(); File mappingsJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not find dependency " + dependency)); - this.mappingsName = dependency.getDependency().getName(); + this.mappingsName = dependency.getDependency().getGroup() + "." + dependency.getDependency().getName(); Version mappingsVersion = new Version(version); this.minecraftVersion = mappingsVersion.getMinecraftVersion(); diff --git a/src/main/java/net/fabricmc/loom/providers/ModRemapperProvider.java b/src/main/java/net/fabricmc/loom/providers/ModRemapperProvider.java deleted file mode 100644 index 0c99220..0000000 --- a/src/main/java/net/fabricmc/loom/providers/ModRemapperProvider.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of fabric-loom, licensed under the MIT License (MIT). - * - * Copyright (c) 2016, 2017, 2018 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.providers; - -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.DependencyProvider; -import net.fabricmc.loom.util.ModProcessor; -import net.fabricmc.loom.util.SourceRemapper; -import org.gradle.api.Project; - -import java.io.File; -import java.util.Optional; -import java.util.function.Consumer; - -public class ModRemapperProvider extends DependencyProvider { - @Override - public void provide(DependencyInfo dependency, Project project, LoomGradleExtension extension, Consumer postPopulationScheduler) { - // Provide JAR - File input = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not find dependency " + dependency)); - - String rds = dependency.getResolvedDepString(); - project.getLogger().lifecycle(":providing " + rds); - - MappingsProvider mappingsProvider = getDependencyManager().getProvider(MappingsProvider.class); - String verSuffix = ".mapped." + mappingsProvider.mappingsName + "." + mappingsProvider.mappingsVersion; - - //Output name should match whatever it's under as a dependency so Gradle finds it - String outputNamePrefix = rds.substring(rds.indexOf(':') + 1).replace(':', '-') + verSuffix; //group:name:version -> name-version.mapped.yarn.5 - File modStore = extension.getRemappedModCache(); - - File output = new File(modStore, outputNamePrefix + ".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 - ModProcessor.handleMod(input, output, project); - - if (!output.exists()){ - throw new RuntimeException("Failed to remap mod"); - } - - output.setLastModified(input.lastModified()); - } else { - project.getLogger().info(output.getName() + " is up to date with " + input.getName()); - } - - project.getDependencies().add(Constants.COMPILE_MODS_MAPPED, project.getDependencies().module( - rds + verSuffix - )); - - postPopulationScheduler.accept(() -> { - // Provide sources JAR, if present - Optional sourcesFile = dependency.resolveFile("sources"); - if (sourcesFile.isPresent()) { - project.getLogger().lifecycle(":providing " + rds + " sources"); - - File sources = sourcesFile.get(); - File remappedSources = new File(modStore, outputNamePrefix + "-sources.jar"); - - if (!remappedSources.exists() || sources.lastModified() <= 0 || sources.lastModified() > remappedSources.lastModified()) { - try { - SourceRemapper.remapSources(project, sources, remappedSources, true); - - //Set the remapped sources creation date to match the sources if we're likely succeeded in making it - remappedSources.setLastModified(sources.lastModified()); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - project.getLogger().info(remappedSources.getName() + " is up to date with " + sources.getName()); - } - } else { - project.getLogger().info(":skipping " + rds + " sources, not found"); - } - }); - } - - @Override - public String getTargetConfig() { - return Constants.COMPILE_MODS; - } -} diff --git a/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java b/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java index 1e88eee..346a154 100644 --- a/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java +++ b/src/main/java/net/fabricmc/loom/util/LoomDependencyManager.java @@ -26,6 +26,7 @@ package net.fabricmc.loom.util; import com.google.gson.JsonObject; import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.providers.MappingsProvider; import net.fabricmc.loom.util.DependencyProvider.DependencyInfo; import org.gradle.api.Project; @@ -35,12 +36,17 @@ import org.gradle.api.artifacts.ExternalModuleDependency; import org.gradle.api.artifacts.repositories.MavenArtifactRepository; import java.io.File; -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class LoomDependencyManager { + private static class ProviderList { + private final String key; + private final List providers = new ArrayList<>(); + + ProviderList(String key) { + this.key = key; + } + } private List dependencyProviderList = new ArrayList<>(); @@ -67,41 +73,70 @@ public class LoomDependencyManager { public void handleDependencies(Project project){ List afterTasks = new ArrayList<>(); + MappingsProvider mappingsProvider = null; + project.getLogger().lifecycle(":setting up loom dependencies"); LoomGradleExtension extension = project.getExtensions().getByType(LoomGradleExtension.class); - Set targetConfigs = new LinkedHashSet<>(); + Map providerListMap = new HashMap<>(); + List targetProviders = new ArrayList<>(); + for(DependencyProvider provider : dependencyProviderList){ - targetConfigs.add(provider.getTargetConfig()); + providerListMap.computeIfAbsent(provider.getTargetConfig(), (k) -> { + ProviderList list = new ProviderList(k); + targetProviders.add(list); + return list; + }).providers.add(provider); + + if (provider instanceof MappingsProvider) { + mappingsProvider = (MappingsProvider) provider; + } } - for(String config : targetConfigs){ - Configuration configuration = project.getConfigurations().getByName(config); + + if (mappingsProvider == null) { + throw new RuntimeException("Could not find MappingsProvider instance!"); + } + + for (ProviderList list : targetProviders) { + Configuration configuration = project.getConfigurations().getByName(list.key); configuration.getDependencies().forEach(dependency -> { - for(DependencyProvider provider : dependencyProviderList){ - if(provider.getTargetConfig().equals(config)){ - DependencyProvider.DependencyInfo info = DependencyInfo.create(project, dependency, configuration); - try { - provider.provide(info, project, extension, afterTasks::add); - } catch (Exception e) { - throw new RuntimeException("Failed to provide", e); - } + for (DependencyProvider provider : list.providers) { + DependencyProvider.DependencyInfo info = DependencyInfo.create(project, dependency, configuration); + try { + provider.provide(info, project, extension, afterTasks::add); + } catch (Exception e) { + throw new RuntimeException("Failed to provide " + dependency.getGroup() + ":" + dependency.getName() + ":" + dependency.getVersion(), e); } } }); } + 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 + ); + 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); + Set seenFiles = new HashSet<>(); + for (Dependency dependency : configuration.getDependencies()) { DependencyInfo info = DependencyInfo.create(project, dependency, configuration); - File input = info.resolveFile().orElseThrow(() -> new RuntimeException("Could not find dependency " + info)); - - ModProcessor.readInstallerJson(input, project); - if (extension.getInstallerJson() != null) { - project.getLogger().info("Found installer JSON in " + info); - break; //Found it, probably don't need to look any further + for (File input : info.resolve("")) { + if (seenFiles.add(input)) { + ModProcessor.readInstallerJson(input, project); + if (extension.getInstallerJson() != null) { + project.getLogger().info("Found installer JSON in " + info); + break; //Found it, probably don't need to look any further + } + } } } } diff --git a/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java b/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java new file mode 100644 index 0000000..4e0071e --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/ModCompileRemapper.java @@ -0,0 +1,153 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2016, 2017, 2018 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; + +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.providers.MappingsProvider; +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.ModProcessor; +import net.fabricmc.loom.util.SourceRemapper; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.Dependency; +import org.gradle.api.artifacts.ModuleDependency; +import org.gradle.api.artifacts.component.ModuleComponentIdentifier; +import org.gradle.api.artifacts.dsl.DependencyHandler; +import org.gradle.api.artifacts.query.ArtifactResolutionQuery; +import org.gradle.api.artifacts.result.ArtifactResult; +import org.gradle.api.artifacts.result.ComponentArtifactsResult; +import org.gradle.api.artifacts.result.ResolvedArtifactResult; +import org.gradle.api.logging.Logger; +import org.gradle.jvm.JvmLibrary; +import org.gradle.language.base.artifact.SourcesArtifact; + +import java.io.File; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +public class ModCompileRemapper { + public static void remapDependencies(Project project, String mappingsPrefix, LoomGradleExtension extension, Configuration modCompile, Configuration modCompileRemapped, Configuration regularCompile, Consumer postPopulationScheduler) { + Logger logger = project.getLogger(); + DependencyHandler dependencies = project.getDependencies(); + + for (ResolvedArtifactResult artifact : modCompile.getIncoming().getArtifacts().getArtifacts()) { + String group; + String name; + String version; + + if (artifact.getId().getComponentIdentifier() instanceof ModuleComponentIdentifier) { + group = ((ModuleComponentIdentifier) artifact.getId().getComponentIdentifier()).getGroup(); + name = ((ModuleComponentIdentifier) artifact.getId().getComponentIdentifier()).getModule(); + version = ((ModuleComponentIdentifier) artifact.getId().getComponentIdentifier()).getVersion(); + } else { + group = "net.fabricmc.synthetic"; + name = artifact.getId().getComponentIdentifier().getDisplayName().replace('.', '-'); + version = "0.1.0"; + } + + String notation = group + ":" + name + ":" + version; + + File input = artifact.getFile(); + AtomicBoolean isFabricMod = new AtomicBoolean(false); + project.zipTree(input).visit(f -> { + if (f.getName().endsWith("fabric.mod.json")) { + logger.info("Found Fabric mod in modCompile: {}", notation); + isFabricMod.set(true); + f.stopVisiting(); + } + }); + + if (!isFabricMod.get()) { + project.getLogger().lifecycle(":providing " + notation); + Dependency dep = dependencies.module(notation); + if (dep instanceof ModuleDependency) { + ((ModuleDependency) dep).setTransitive(false); + } + dependencies.add(regularCompile.getName(), dep); + continue; + } + + AtomicReference sources = new AtomicReference<>(); + @SuppressWarnings ("unchecked") + ArtifactResolutionQuery query = dependencies.createArtifactResolutionQuery()// + .forComponents(artifact.getId().getComponentIdentifier())// + .withArtifacts(JvmLibrary.class, SourcesArtifact.class); + outer: + for (ComponentArtifactsResult result : query.execute().getResolvedComponents()) { + for (ArtifactResult srcArtifact : result.getArtifacts(SourcesArtifact.class)) { + if (srcArtifact instanceof ResolvedArtifactResult) { + sources.set(((ResolvedArtifactResult) srcArtifact).getFile()); + break outer; + } + } + } + + String remappedLog = group + ":" + name + ":" + version + " (" + mappingsPrefix + ")"; + String remappedNotation = "net.fabricmc.mapped:" + mappingsPrefix + "." + group + "." + name + ":" + version; + String remappedFilename = mappingsPrefix + "." + group + "." + name + "-" + version; + project.getLogger().lifecycle(":providing " + remappedLog); + + File modStore = extension.getRemappedModCache(); + + 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 + ModProcessor.handleMod(input, output, project); + + if (!output.exists()){ + throw new RuntimeException("Failed to remap mod"); + } + + output.setLastModified(input.lastModified()); + } else { + project.getLogger().info(output.getName() + " is up to date with " + input.getName()); + } + + project.getDependencies().add(modCompileRemapped.getName(), project.getDependencies().module(remappedNotation)); + + if (sources.get() != null) { + postPopulationScheduler.accept(() -> { + project.getLogger().lifecycle(":providing " + remappedLog + " sources"); + File remappedSources = new File(modStore, remappedFilename + "-sources.jar"); + + if (!remappedSources.exists() || sources.get().lastModified() <= 0 || sources.get().lastModified() > remappedSources.lastModified()) { + try { + SourceRemapper.remapSources(project, sources.get(), remappedSources, true); + + //Set the remapped sources creation date to match the sources if we're likely succeeded in making it + remappedSources.setLastModified(sources.get().lastModified()); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + project.getLogger().info(remappedSources.getName() + " is up to date with " + sources.get().getName()); + } + }); + } + } + } +}