From 993973b1122595aec8db4dcf0375794e55f17843 Mon Sep 17 00:00:00 2001 From: KitsuneAlex Date: Sun, 15 Sep 2024 00:00:32 +0200 Subject: [PATCH 1/3] Fix duplicated dependency being added by version catalog deobf() overload --- .../DependencyManagementExtension.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java b/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java index 049871cfa..585d39935 100644 --- a/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java +++ b/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java @@ -18,7 +18,11 @@ import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; +import org.gradle.api.artifacts.MinimalExternalModuleDependency; +import org.gradle.api.artifacts.ModuleIdentifier; import org.gradle.api.artifacts.repositories.ArtifactRepository; +import org.gradle.api.internal.artifacts.dependencies.DependencyVariant; +import org.gradle.api.provider.Provider; import org.gradle.api.publish.maven.MavenPublication; import org.gradle.api.publish.tasks.GenerateModuleMetadata; @@ -51,7 +55,6 @@ public ArtifactRepository getRepository() { return repository; } - @SuppressWarnings("unused") public Dependency deobf(Object dependency) { return deobf(dependency, null); } @@ -63,6 +66,21 @@ public Dependency deobf(Object dependency, Closure configure) { return remapper.remap(baseDependency); } + public Dependency deobf(Provider provider) { + MinimalExternalModuleDependency dependency = provider.get(); + + ModuleIdentifier module = dependency.getModule(); + if (dependency instanceof DependencyVariant) { + DependencyVariant variant = (DependencyVariant) dependency; + return deobf(String.format("%s:%s:%s:%s", + module.getGroup(), + module.getName(), + dependency.getVersion(), + variant.getClassifier())); + } + return deobf(String.format("%s:%s:%s", module.getGroup(), module.getName(), dependency.getVersion())); + } + @SuppressWarnings({"ConstantConditions", "unchecked"}) public MavenPublication component(MavenPublication mavenPublication) { project.getTasks().withType(GenerateModuleMetadata.class).forEach(generateModuleMetadata -> generateModuleMetadata.setEnabled(false)); From 3cb3cae26cf030306a691ac8624131644bda02c0 Mon Sep 17 00:00:00 2001 From: KitsuneAlex Date: Sun, 15 Sep 2024 00:10:59 +0200 Subject: [PATCH 2/3] Remove usages of internal Gradle APIs --- .../DependencyManagementExtension.java | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java b/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java index 585d39935..e2e24fcb6 100644 --- a/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java +++ b/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java @@ -15,13 +15,13 @@ import net.minecraftforge.gradle.userdev.util.DeobfuscatingVersionUtils; import net.minecraftforge.gradle.userdev.util.DependencyRemapper; import net.minecraftforge.gradle.userdev.util.MavenPomUtils; +import org.gradle.api.Action; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; import org.gradle.api.artifacts.MinimalExternalModuleDependency; -import org.gradle.api.artifacts.ModuleIdentifier; +import org.gradle.api.artifacts.dsl.ExternalModuleDependencyVariantSpec; import org.gradle.api.artifacts.repositories.ArtifactRepository; -import org.gradle.api.internal.artifacts.dependencies.DependencyVariant; import org.gradle.api.provider.Provider; import org.gradle.api.publish.maven.MavenPublication; import org.gradle.api.publish.tasks.GenerateModuleMetadata; @@ -62,23 +62,19 @@ public Dependency deobf(Object dependency) { public Dependency deobf(Object dependency, Closure configure) { Dependency baseDependency = project.getDependencies().create(dependency, configure); project.getConfigurations().getByName(UserDevPlugin.OBF).getDependencies().add(baseDependency); - return remapper.remap(baseDependency); } public Dependency deobf(Provider provider) { MinimalExternalModuleDependency dependency = provider.get(); + project.getConfigurations().getByName(UserDevPlugin.OBF).getDependencies().add(dependency); + return remapper.remap(dependency); + } - ModuleIdentifier module = dependency.getModule(); - if (dependency instanceof DependencyVariant) { - DependencyVariant variant = (DependencyVariant) dependency; - return deobf(String.format("%s:%s:%s:%s", - module.getGroup(), - module.getName(), - dependency.getVersion(), - variant.getClassifier())); - } - return deobf(String.format("%s:%s:%s", module.getGroup(), module.getName(), dependency.getVersion())); + public Dependency deobf(Provider provider, Action variantSpec) { + MinimalExternalModuleDependency dependency = project.getDependencies().variantOf(provider, variantSpec).get(); + project.getConfigurations().getByName(UserDevPlugin.OBF).getDependencies().add(dependency); + return remapper.remap(dependency); } @SuppressWarnings({"ConstantConditions", "unchecked"}) From dd8dd0191ebc4ec284bac7b12d4dce34d064e30e Mon Sep 17 00:00:00 2001 From: KitsuneAlex Date: Sun, 15 Sep 2024 02:27:20 +0200 Subject: [PATCH 3/3] Implement RemappedExternalModuleDependency & MutableAttributeContainer --- .../DependencyManagementExtension.java | 36 ++-- .../gradle/userdev/UserDevPlugin.java | 6 +- .../RemappedExternalModuleDependency.java | 186 ++++++++++++++++++ .../userdev/util/DependencyRemapper.java | 59 ------ .../util/MutableAttributeContainer.java | 64 ++++++ 5 files changed, 273 insertions(+), 78 deletions(-) create mode 100644 src/userdev/java/net/minecraftforge/gradle/userdev/dependency/RemappedExternalModuleDependency.java delete mode 100644 src/userdev/java/net/minecraftforge/gradle/userdev/util/DependencyRemapper.java create mode 100644 src/userdev/java/net/minecraftforge/gradle/userdev/util/MutableAttributeContainer.java diff --git a/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java b/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java index e2e24fcb6..4390defa2 100644 --- a/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java +++ b/src/userdev/java/net/minecraftforge/gradle/userdev/DependencyManagementExtension.java @@ -11,15 +11,13 @@ import groovy.util.NodeList; import net.minecraftforge.gradle.common.util.BaseRepo; import net.minecraftforge.gradle.common.util.MinecraftExtension; +import net.minecraftforge.gradle.userdev.dependency.RemappedExternalModuleDependency; import net.minecraftforge.gradle.userdev.util.DeobfuscatingRepo; import net.minecraftforge.gradle.userdev.util.DeobfuscatingVersionUtils; -import net.minecraftforge.gradle.userdev.util.DependencyRemapper; import net.minecraftforge.gradle.userdev.util.MavenPomUtils; import org.gradle.api.Action; import org.gradle.api.Project; -import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.Dependency; -import org.gradle.api.artifacts.MinimalExternalModuleDependency; +import org.gradle.api.artifacts.*; import org.gradle.api.artifacts.dsl.ExternalModuleDependencyVariantSpec; import org.gradle.api.artifacts.repositories.ArtifactRepository; import org.gradle.api.provider.Provider; @@ -34,19 +32,29 @@ public class DependencyManagementExtension extends GroovyObjectSupport { public static final String EXTENSION_NAME = "fg"; private final Project project; - private final DependencyRemapper remapper; private final DeobfuscatingRepo deobfuscatingRepo; private final ArtifactRepository repository; - public DependencyManagementExtension(Project project, DependencyRemapper remapper, DeobfuscatingRepo deobfuscatingRepo) { + public DependencyManagementExtension(Project project, DeobfuscatingRepo deobfuscatingRepo) { this.project = project; - this.remapper = remapper; this.deobfuscatingRepo = deobfuscatingRepo; this.repository = new BaseRepo.Builder() .add(deobfuscatingRepo) .attach(project, "bundled_deobf_repo"); } + private Dependency createRemappedDependency(Dependency dependency) { + if(dependency instanceof ExternalModuleDependency) { + return new RemappedExternalModuleDependency((ExternalModuleDependency) dependency); + } + if(dependency instanceof FileCollectionDependency) { + project.getLogger().warn("Dependency {} will not be deobfuscated. Use a flatDir repository instead: https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver", dependency); + } else { + project.getLogger().warn("Dependency {} is not being deobfuscated", dependency); + } + return dependency; + } + public DeobfuscatingRepo getDeobfuscatingRepo() { return deobfuscatingRepo; } @@ -62,19 +70,19 @@ public Dependency deobf(Object dependency) { public Dependency deobf(Object dependency, Closure configure) { Dependency baseDependency = project.getDependencies().create(dependency, configure); project.getConfigurations().getByName(UserDevPlugin.OBF).getDependencies().add(baseDependency); - return remapper.remap(baseDependency); + return createRemappedDependency(baseDependency); } public Dependency deobf(Provider provider) { - MinimalExternalModuleDependency dependency = provider.get(); - project.getConfigurations().getByName(UserDevPlugin.OBF).getDependencies().add(dependency); - return remapper.remap(dependency); + MinimalExternalModuleDependency baseDependency = provider.get(); + project.getConfigurations().getByName(UserDevPlugin.OBF).getDependencies().add(baseDependency); + return createRemappedDependency(baseDependency); } public Dependency deobf(Provider provider, Action variantSpec) { - MinimalExternalModuleDependency dependency = project.getDependencies().variantOf(provider, variantSpec).get(); - project.getConfigurations().getByName(UserDevPlugin.OBF).getDependencies().add(dependency); - return remapper.remap(dependency); + MinimalExternalModuleDependency baseDependency = project.getDependencies().variantOf(provider, variantSpec).get(); + project.getConfigurations().getByName(UserDevPlugin.OBF).getDependencies().add(baseDependency); + return createRemappedDependency(baseDependency); } @SuppressWarnings({"ConstantConditions", "unchecked"}) diff --git a/src/userdev/java/net/minecraftforge/gradle/userdev/UserDevPlugin.java b/src/userdev/java/net/minecraftforge/gradle/userdev/UserDevPlugin.java index dc7fb8624..0b1396a95 100644 --- a/src/userdev/java/net/minecraftforge/gradle/userdev/UserDevPlugin.java +++ b/src/userdev/java/net/minecraftforge/gradle/userdev/UserDevPlugin.java @@ -29,7 +29,6 @@ import net.minecraftforge.gradle.userdev.tasks.RenameJarInPlace; import net.minecraftforge.gradle.userdev.util.DeobfuscatingRepo; import net.minecraftforge.gradle.userdev.util.Deobfuscator; -import net.minecraftforge.gradle.userdev.util.DependencyRemapper; import net.minecraftforge.srgutils.IMappingFile; import org.apache.commons.lang3.StringUtils; @@ -104,8 +103,7 @@ public void apply(@Nonnull Project project) { // Create extension for dependency remapping // Can't create at top-level or put in `minecraft` ext due to configuration name conflict final Deobfuscator deobfuscator = new Deobfuscator(project, Utils.getCache(project, "deobf_dependencies")); - final DependencyRemapper remapper = new DependencyRemapper(project, deobfuscator); - DependencyManagementExtension fgExtension = project.getExtensions().create(DependencyManagementExtension.EXTENSION_NAME, DependencyManagementExtension.class, project, remapper, new DeobfuscatingRepo(project, internalObfConfiguration, deobfuscator)); + DependencyManagementExtension fgExtension = project.getExtensions().create(DependencyManagementExtension.EXTENSION_NAME, DependencyManagementExtension.class, project, new DeobfuscatingRepo(project, internalObfConfiguration, deobfuscator)); JarJarProjectExtension jarJarExtension = project.getExtensions().create(JarJarProjectExtension.EXTENSION_NAME, JarJarProjectExtension.class, project); final TaskContainer tasks = project.getTasks(); @@ -254,8 +252,6 @@ public void apply(@Nonnull Project project) { }); }); - remapper.attachMappings(extension.getMappings().get()); - if (fgExtension.getDeobfuscatingRepo().getResolvedOrigin() == null) { project.getLogger().error("DeobfRepo attempted to resolve an origin repo early but failed, this may cause issues with some IDEs"); } diff --git a/src/userdev/java/net/minecraftforge/gradle/userdev/dependency/RemappedExternalModuleDependency.java b/src/userdev/java/net/minecraftforge/gradle/userdev/dependency/RemappedExternalModuleDependency.java new file mode 100644 index 000000000..5bd412e5a --- /dev/null +++ b/src/userdev/java/net/minecraftforge/gradle/userdev/dependency/RemappedExternalModuleDependency.java @@ -0,0 +1,186 @@ +package net.minecraftforge.gradle.userdev.dependency; + +import groovy.lang.Closure; +import net.minecraftforge.gradle.userdev.util.MutableAttributeContainer; +import org.gradle.api.Action; +import org.gradle.api.artifacts.*; +import org.gradle.api.attributes.Attribute; +import org.gradle.api.attributes.AttributeContainer; +import org.gradle.api.capabilities.Capability; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +public class RemappedExternalModuleDependency implements ExternalModuleDependency { + public static final Attribute ATTRIBUTE = Attribute.of("remapped", Boolean.class); + + private final ExternalModuleDependency dependency; + private final MutableAttributeContainer attributes; + + public RemappedExternalModuleDependency(ExternalModuleDependency dependency) { + this.dependency = dependency; + attributes = new MutableAttributeContainer(); + attributes.attributes(dependency.getAttributes()); // Copy base attributes + attributes.attribute(ATTRIBUTE, true); // Add marker for remapped dependencies + } + + @Override + public boolean isChanging() { + return dependency.isChanging(); + } + + @Override + public @Nonnull ExternalModuleDependency setChanging(boolean changing) { + return dependency.setChanging(changing); + } + + @Override + public @Nonnull ExternalModuleDependency copy() { + return new RemappedExternalModuleDependency(dependency); + } + + @Override + public boolean isForce() { + return dependency.isForce(); + } + + @Override + public void version(@Nonnull Action configureAction) { + dependency.version(configureAction); + } + + @Override + public @Nonnull VersionConstraint getVersionConstraint() { + return dependency.getVersionConstraint(); + } + + @Override + public @Nonnull ModuleDependency exclude(@Nonnull Map excludeProperties) { + return dependency.exclude(excludeProperties); + } + + @Override + public @Nonnull Set getExcludeRules() { + return dependency.getExcludeRules(); + } + + @Override + public @Nonnull Set getArtifacts() { + return dependency.getArtifacts(); + } + + @Override + public @Nonnull ModuleDependency addArtifact(@Nonnull DependencyArtifact artifact) { + return dependency.addArtifact(artifact); + } + + @Override + public @Nonnull DependencyArtifact artifact(@Nonnull Closure configureClosure) { + return dependency.artifact(configureClosure); + } + + @Override + public @Nonnull DependencyArtifact artifact(@Nonnull Action configureAction) { + return dependency.artifact(configureAction); + } + + @Override + public boolean isTransitive() { + return dependency.isTransitive(); + } + + @Override + public @Nonnull ModuleDependency setTransitive(boolean transitive) { + return dependency.setTransitive(transitive); + } + + @Override + public @Nullable String getTargetConfiguration() { + return dependency.getTargetConfiguration(); + } + + @Override + public void setTargetConfiguration(@Nullable String name) { + dependency.setTargetConfiguration(name); + } + + @Override + public @Nonnull AttributeContainer getAttributes() { + return attributes; + } + + @Override + public @Nonnull ModuleDependency attributes(@Nonnull Action configureAction) { + configureAction.execute(attributes); + return this; + } + + @Override + public @Nonnull ModuleDependency capabilities(@Nonnull Action configureAction) { + return dependency.capabilities(configureAction); + } + + @Override + public @Nonnull List getRequestedCapabilities() { + return dependency.getRequestedCapabilities(); + } + + @Override + public void endorseStrictVersions() { + dependency.endorseStrictVersions(); + } + + @Override + public void doNotEndorseStrictVersions() { + dependency.doNotEndorseStrictVersions(); + } + + @Override + public boolean isEndorsingStrictVersions() { + return dependency.isEndorsingStrictVersions(); + } + + @Override + public @Nonnull String getGroup() { + return Objects.requireNonNull(dependency.getGroup()); + } + + @Override + public @Nonnull String getName() { + return dependency.getName(); + } + + @Override + public @Nullable String getVersion() { + return dependency.getVersion(); + } + + @Override + public boolean contentEquals(@Nonnull Dependency dependency) { + return dependency.contentEquals(dependency); + } + + @Override + public @Nullable String getReason() { + return dependency.getReason(); + } + + @Override + public void because(@Nullable String reason) { + dependency.because(reason); + } + + @Override + public boolean matchesStrictly(@Nonnull ModuleVersionIdentifier identifier) { + return dependency.matchesStrictly(identifier); + } + + @Override + public @Nonnull ModuleIdentifier getModule() { + return dependency.getModule(); + } +} diff --git a/src/userdev/java/net/minecraftforge/gradle/userdev/util/DependencyRemapper.java b/src/userdev/java/net/minecraftforge/gradle/userdev/util/DependencyRemapper.java deleted file mode 100644 index 3c721d873..000000000 --- a/src/userdev/java/net/minecraftforge/gradle/userdev/util/DependencyRemapper.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.gradle.userdev.util; - -import org.gradle.api.Project; -import org.gradle.api.artifacts.Dependency; -import org.gradle.api.artifacts.ExternalModuleDependency; -import org.gradle.api.artifacts.FileCollectionDependency; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -public class DependencyRemapper { - private final Project project; - @SuppressWarnings("unused") - private Deobfuscator deobfuscator; - private final List> mappingListeners = new ArrayList<>(); - - public DependencyRemapper(Project project, Deobfuscator deobfuscator) { - this.project = project; - this.deobfuscator = deobfuscator; - } - - /* - * Impl note: Gradle uses a lot of internal instanceof checking, - * so it's more reliable to use the same classes gradle uses. - * - * Best way to do it is Dependency#copy. If that's not possible, - * internal classes starting with Default are an option. It should be a last resort, - * as that is a part of internal unstable APIs. - */ - public Dependency remap(Dependency dependency) { - if (dependency instanceof ExternalModuleDependency) { - return remapExternalModule((ExternalModuleDependency) dependency); - } - - if (dependency instanceof FileCollectionDependency) { - project.getLogger().warn("files(...) dependencies are not deobfuscated. Use a flatDir repository instead: https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver"); - } - - project.getLogger().warn("Cannot deobfuscate dependency of type {}, using obfuscated version!", dependency.getClass().getSimpleName()); - return dependency; - } - - private ExternalModuleDependency remapExternalModule(ExternalModuleDependency dependency) { - ExternalModuleDependency newDep = dependency.copy(); - mappingListeners.add(m -> newDep.version(v -> v.strictly(newDep.getVersion() + "_mapped_" + m))); - return newDep; - } - - public void attachMappings(String mappings) { - mappingListeners.forEach(l -> l.accept(mappings)); - } - -} diff --git a/src/userdev/java/net/minecraftforge/gradle/userdev/util/MutableAttributeContainer.java b/src/userdev/java/net/minecraftforge/gradle/userdev/util/MutableAttributeContainer.java new file mode 100644 index 000000000..0fca1ae57 --- /dev/null +++ b/src/userdev/java/net/minecraftforge/gradle/userdev/util/MutableAttributeContainer.java @@ -0,0 +1,64 @@ +package net.minecraftforge.gradle.userdev.util; + +import org.gradle.api.attributes.Attribute; +import org.gradle.api.attributes.AttributeContainer; +import org.gradle.api.provider.Provider; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Set; + +public class MutableAttributeContainer implements AttributeContainer { + private final HashMap, Object> values = new HashMap<>(); + + public void attributes(AttributeContainer container) { + Set> keys = container.keySet(); + for (Attribute key : keys) { + values.put(key, container.getAttribute(key)); + } + } + + @Override + public @Nonnull Set> keySet() { + return values.keySet(); + } + + @Override + public @Nonnull AttributeContainer attribute(@Nonnull Attribute key, @Nonnull T value) { + values.put(key, value); + return this; + } + + @Override + public @Nonnull AttributeContainer attributeProvider(@Nonnull Attribute key, + @Nonnull Provider provider) { + values.put(key, provider.get()); + return this; + } + + @SuppressWarnings("unchecked") + @Override + public @Nullable T getAttribute(@Nonnull Attribute key) { + Object value = values.get(key); + if (value == null || !key.getType().isInstance(value)) { + return null; + } + return (T) value; + } + + @Override + public boolean isEmpty() { + return values.isEmpty(); + } + + @Override + public boolean contains(@Nonnull Attribute key) { + return values.containsKey(key); + } + + @Override + public @Nonnull AttributeContainer getAttributes() { + return this; + } +}