From f4791f272dbd6f4df2feb209772ce1560931b27f Mon Sep 17 00:00:00 2001
From: Joe
Date: Sun, 3 Oct 2021 16:07:37 +0100
Subject: [PATCH 01/15] Work so far
---
subprojects/gradle-plugin/build.gradle.kts | 4 +
.../gradle/vanilla/MinecraftExtension.java | 17 +++
.../internal/MinecraftExtensionImpl.java | 74 +++++++++-
.../repository/MinecraftProviderService.java | 10 +-
.../mappings/MappingsBuilderImpl.java | 132 ++++++++++++++++++
.../mappings/ProGuardMappingsReader.java | 26 ++++
.../modifier/AccessWidenerModifier.java | 3 +-
.../repository/modifier/ArtifactModifier.java | 13 +-
.../repository/modifier/MappingsModifier.java | 85 +++++++++++
.../modifier/OfficialMappingsModifier.java | 98 +++++++++++++
.../vanilla/repository/MappingsBuilder.java | 5 +
.../vanilla/repository/MappingsReader.java | 11 ++
.../vanilla/repository/MinecraftResolver.java | 23 ++-
.../repository/MinecraftResolverImpl.java | 54 ++-----
.../gradle/vanilla/task/DecompileJarTask.java | 3 +-
15 files changed, 496 insertions(+), 62 deletions(-)
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/MappingsBuilderImpl.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingsReader.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsBuilder.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsReader.java
diff --git a/subprojects/gradle-plugin/build.gradle.kts b/subprojects/gradle-plugin/build.gradle.kts
index 92cfa0d9..8b29fa0f 100644
--- a/subprojects/gradle-plugin/build.gradle.kts
+++ b/subprojects/gradle-plugin/build.gradle.kts
@@ -16,6 +16,9 @@ val jarMerge by sourceSets.creating {
val jarDecompile by sourceSets.creating {
configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
}
+val jarRemap by sourceSets.creating {
+ configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
+}
val accessWiden by sourceSets.creating {
configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
}
@@ -123,6 +126,7 @@ tasks {
jar {
from(jarMerge.output)
from(jarDecompile.output)
+ from(jarRemap.output)
from(accessWiden.output)
from(shadow.output)
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java
index 4dd0df49..28501ca5 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java
@@ -28,7 +28,10 @@
import groovy.lang.DelegatesTo;
import org.gradle.api.Action;
import org.gradle.api.Project;
+import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property;
+import org.spongepowered.gradle.vanilla.repository.MappingsBuilder;
+import org.spongepowered.gradle.vanilla.repository.MappingsReader;
import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
import org.spongepowered.gradle.vanilla.repository.MinecraftRepositoryExtension;
import org.spongepowered.gradle.vanilla.runs.RunConfigurationContainer;
@@ -113,6 +116,20 @@ public interface MinecraftExtension extends MinecraftRepositoryExtension {
*/
void accessWideners(Object... file);
+ Property useOfficialMappings();
+
+ void useOfficialMappings(boolean useOfficialMappings);
+
+ ListProperty mappingsReaders();
+
+ void mappingsReader(MappingsReader... readers);
+
+ MappingsBuilder mappings();
+
+ void mappings(Action configure);
+
+ void mappings(Closure configureClosure);
+
/**
* Get run configurations configured for this project.
*
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
index ef7caf7b..2ef2a163 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
@@ -33,12 +33,19 @@
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.invocation.Gradle;
import org.gradle.api.model.ObjectFactory;
+import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.util.ConfigureUtil;
import org.spongepowered.gradle.vanilla.MinecraftExtension;
import org.spongepowered.gradle.vanilla.internal.model.VersionClassifier;
import org.spongepowered.gradle.vanilla.internal.model.VersionDescriptor;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.MappingsBuilderImpl;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.ProGuardMappingsReader;
+import org.spongepowered.gradle.vanilla.internal.repository.modifier.MappingsModifier;
+import org.spongepowered.gradle.vanilla.internal.repository.modifier.OfficialMappingsModifier;
+import org.spongepowered.gradle.vanilla.repository.MappingsBuilder;
+import org.spongepowered.gradle.vanilla.repository.MappingsReader;
import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
import org.spongepowered.gradle.vanilla.internal.repository.MinecraftProviderService;
import org.spongepowered.gradle.vanilla.internal.repository.MinecraftRepositoryPlugin;
@@ -51,10 +58,10 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashSet;
+import java.util.List;
import java.util.Objects;
-import java.util.Set;
import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
@@ -66,6 +73,8 @@ public class MinecraftExtensionImpl implements MinecraftExtension {
private final Property version;
private final Property platform;
private final Property injectRepositories;
+ private final Property useOfficialMappings;
+ private final ListProperty mappingsReaders;
private final DirectoryProperty sharedCache;
private final DirectoryProperty projectCache;
private final ConfigurableFileCollection accessWideners;
@@ -76,16 +85,24 @@ public class MinecraftExtensionImpl implements MinecraftExtension {
// Internals
private final Project project;
+ private final MappingsBuilderImpl mappingsBuilder;
private final RunConfigurationContainer runConfigurations;
- private volatile Set lazyModifiers;
+ private volatile List lazyModifiers;
@Inject
public MinecraftExtensionImpl(final Gradle gradle, final ObjectFactory factory, final Project project, final Provider providerService) {
this.project = project;
this.providerService = providerService;
+ this.mappingsBuilder = new MappingsBuilderImpl(project);
this.version = factory.property(String.class);
this.platform = factory.property(MinecraftPlatform.class).convention(MinecraftPlatform.JOINED);
this.injectRepositories = factory.property(Boolean.class).convention(project.provider(() -> !gradle.getPlugins().hasPlugin(MinecraftRepositoryPlugin.class))); // only inject if we aren't already in Settings
+ this.useOfficialMappings = factory.property(Boolean.class).convention(project.provider(mappingsBuilder::isEmpty));
+ this.mappingsReaders = factory.listProperty(MappingsReader.class).convention(project.provider(() -> {
+ List readers = new ArrayList<>();
+ readers.add(new ProGuardMappingsReader());
+ return readers;
+ }));
this.accessWideners = factory.fileCollection();
this.assetsDirectory = factory.directoryProperty();
@@ -227,14 +244,59 @@ public ConfigurableFileCollection accessWideners() {
return this.accessWideners;
}
- public synchronized Set modifiers() {
+ @Override
+ public Property useOfficialMappings() {
+ return useOfficialMappings;
+ }
+
+ @Override
+ public void useOfficialMappings(boolean useOfficialMappings) {
+ this.useOfficialMappings.set(useOfficialMappings);
+ }
+
+ @Override
+ public ListProperty mappingsReaders() {
+ return this.mappingsReaders;
+ }
+
+ @Override
+ public void mappingsReader(MappingsReader... readers) {
+ this.mappingsReaders.addAll(readers);
+ }
+
+ @Override
+ public MappingsBuilderImpl mappings() {
+ return mappingsBuilder;
+ }
+
+ @Override
+ public void mappings(Action configure) {
+ configure.execute(mappingsBuilder);
+ }
+
+ @Override
+ public void mappings(Closure configureClosure) {
+ configureClosure.setDelegate(mappingsBuilder);
+ configureClosure.call();
+ }
+
+ public synchronized List modifiers() {
if (this.lazyModifiers == null) {
+ final List modifiers = new ArrayList<>();
+
+ if (useOfficialMappings.get()) {
+ modifiers.add(new OfficialMappingsModifier());
+ }
+
+ if (!mappingsBuilder.isEmpty()) {
+ modifiers.add(new MappingsModifier(mappingsBuilder, mappingsReaders));
+ }
+
this.accessWideners.disallowChanges();
- final Set modifiers = new HashSet<>();
if (!this.accessWideners.isEmpty()) {
modifiers.add(new AccessWidenerModifier(this.accessWideners.getFiles()));
}
- return this.lazyModifiers = Collections.unmodifiableSet(modifiers);
+ return this.lazyModifiers = Collections.unmodifiableList(modifiers);
}
return this.lazyModifiers;
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftProviderService.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftProviderService.java
index 2f0ce91f..90629a62 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftProviderService.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftProviderService.java
@@ -49,7 +49,7 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
-import java.util.Set;
+import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -97,15 +97,15 @@ public void onFinish(final FinishEvent finishEvent) {
* @param project the project to use for resolving dependencies
* @param modifiers the artifact modifiers to apply to the eventual output artifact
*/
- public void primeResolver(final Project project, final Set modifiers) {
+ public void primeResolver(final Project project, final List modifiers) {
final ResolverState state = this.activeState.get();
state.configurationSource = project.getConfigurations();
state.modifiers = modifiers;
}
- public Set peekModifiers() {
+ public List peekModifiers() {
final ResolverState state = this.activeState.get();
- final @Nullable Set modifiers = state.modifiers;
+ final @Nullable List modifiers = state.modifiers;
if (modifiers == null) {
throw new GradleException("No artifact modifiers were staged for resolution operation!");
}
@@ -222,7 +222,7 @@ public void close() throws IOException {
static final class ResolverState {
@MonotonicNonNull ConfigurationContainer configurationSource;
- @Nullable Set modifiers;
+ @Nullable List modifiers;
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/MappingsBuilderImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/MappingsBuilderImpl.java
new file mode 100644
index 00000000..a8402c75
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/MappingsBuilderImpl.java
@@ -0,0 +1,132 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import groovy.lang.GroovyObjectSupport;
+import groovy.lang.MissingMethodException;
+import org.cadixdev.lorenz.MappingSet;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.gradle.api.Project;
+import org.gradle.api.artifacts.Dependency;
+import org.gradle.api.artifacts.DependencyArtifact;
+import org.gradle.api.artifacts.FileCollectionDependency;
+import org.gradle.api.artifacts.ModuleDependency;
+import org.spongepowered.gradle.vanilla.repository.MappingsBuilder;
+import org.spongepowered.gradle.vanilla.repository.MappingsReader;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UncheckedIOException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+public class MappingsBuilderImpl extends GroovyObjectSupport implements MappingsBuilder {
+ private final Project project;
+ private final List layers = new ArrayList<>();
+
+ public MappingsBuilderImpl(final Project project) {
+ this.project = project;
+ }
+
+ @Override
+ public void add(@NonNull final String formatName, @NonNull final Object dependencyNotation) {
+ final String configName = "mappingsLayer" + layers.size();
+ project.getConfigurations().register(configName, config -> {
+ config.setVisible(false);
+ config.setCanBeConsumed(false);
+ config.setCanBeResolved(true);
+ });
+ Dependency dependency = project.getDependencies().add(configName, dependencyNotation);
+ layers.add(new Layer(formatName, configName, dependency));
+ }
+
+ public boolean isEmpty() {
+ return layers.isEmpty();
+ }
+
+ public @Nullable MappingSet create(List readers) {
+ return layers.stream().map(layer -> layer.resolve(project, readers)).reduce(MappingSet::merge).orElse(null);
+ }
+
+ public void computeStateKey(MessageDigest digest) {
+ for (Layer layer : layers) {
+ layer.computeStateKey(digest);
+ }
+ }
+
+ @Override
+ public Object invokeMethod(String name, Object arg) {
+ try {
+ return super.invokeMethod(name, arg);
+ } catch (MissingMethodException e) {
+ final Object[] args = (Object[]) arg;
+ if (args.length == 1) {
+ add(name, args[0]);
+ return null;
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ private static class Layer {
+ private final String format;
+ private final String config;
+ private final Dependency dependency;
+
+ Layer(String format, String config, Dependency dependency) {
+ this.format = format;
+ this.config = config;
+ this.dependency = dependency;
+ }
+
+ MappingSet resolve(final Project project, final List readers) {
+ Set files = project.getConfigurations().getByName(config).resolve();
+ if (files.size() != 1) {
+ throw new IllegalStateException("Mappings configuration didn't resolve to exactly one file");
+ }
+ for (MappingsReader reader : readers) {
+ if (reader.getName().equals(format)) {
+ try {
+ return reader.read(files.iterator().next().toPath());
+ } catch (IOException e) {
+ throw new UncheckedIOException("Failed to read mappings file", e);
+ }
+ }
+ }
+ throw new IllegalStateException("Could not find a mappings reader for format \"" + format + "\". Maybe there is a Gradle plugin missing.");
+ }
+
+ void computeStateKey(MessageDigest digest) {
+ // we can't resolve the dependency at this point, try some heuristics
+
+ if (dependency instanceof ModuleDependency) {
+ for (DependencyArtifact artifact : ((ModuleDependency) dependency).getArtifacts()) {
+ digest.update(artifact.getUrl().getBytes(StandardCharsets.UTF_8));
+ }
+ } else if (dependency instanceof FileCollectionDependency) {
+ for (File file : ((FileCollectionDependency) dependency).getFiles()) {
+ try (final InputStream is = new FileInputStream(file)) {
+ final byte[] buf = new byte[4096];
+ int read;
+ while ((read = is.read(buf)) != -1) {
+ digest.update(buf, 0, read);
+ }
+ } catch (final IOException ex) {
+ // ignore, will show up when we try to actually read the mappings
+ }
+ }
+ } else {
+ // the best we can do
+ byte[] bytes = new byte[32];
+ new Random().nextBytes(bytes);
+ digest.update(bytes);
+ }
+ }
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingsReader.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingsReader.java
new file mode 100644
index 00000000..25edf88a
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingsReader.java
@@ -0,0 +1,26 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.cadixdev.lorenz.io.proguard.ProGuardReader;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.gradle.vanilla.repository.MappingsReader;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class ProGuardMappingsReader implements MappingsReader {
+ @Override
+ public @NonNull String getName() {
+ return "proguard";
+ }
+
+ @Override
+ public @NonNull MappingSet read(final @NonNull Path file) throws IOException {
+ final MappingSet scratchMappings = MappingSet.create();
+ try (ProGuardReader proguard = new ProGuardReader(Files.newBufferedReader(file))) {
+ proguard.read(scratchMappings);
+ }
+ return scratchMappings.reverse(); // ProGuard mappings are backwards
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/AccessWidenerModifier.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/AccessWidenerModifier.java
index 4d96a6f2..99b06145 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/AccessWidenerModifier.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/AccessWidenerModifier.java
@@ -28,6 +28,7 @@
import org.cadixdev.bombe.jar.JarEntryTransformer;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
+import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
import org.spongepowered.gradle.vanilla.resolver.HashAlgorithm;
import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
import org.spongepowered.gradle.vanilla.internal.repository.ResolvableTool;
@@ -102,7 +103,7 @@ public CompletableFuture providePopulator(
.newInstance();
@Override
- public JarEntryTransformer provide(final AtlasTransformerContext context) {
+ public JarEntryTransformer provide(final AtlasTransformerContext context, final MinecraftResolver.MinecraftEnvironment result, MinecraftPlatform side, SharedArtifactSupplier sharedArtifactProvider) {
if (this.accessWidenerLoader == null) {
throw new IllegalStateException("Already closed!");
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/ArtifactModifier.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/ArtifactModifier.java
index e1df8ddd..c18ecb4a 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/ArtifactModifier.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/ArtifactModifier.java
@@ -27,10 +27,12 @@
import org.cadixdev.atlas.Atlas;
import org.cadixdev.atlas.AtlasTransformerContext;
import org.cadixdev.bombe.jar.JarEntryTransformer;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
import java.io.IOException;
-import java.util.Set;
+import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
@@ -42,7 +44,7 @@ public interface ArtifactModifier {
char KEY_VALUE_SEPARATOR = '-';
- static String decorateArtifactId(final String originalId, final Set modifiers) {
+ static String decorateArtifactId(final String originalId, final List modifiers) {
if (modifiers.isEmpty()) {
return originalId;
}
@@ -102,11 +104,16 @@ static String decorateArtifactId(final String originalId, final Set readers;
+ private @Nullable String stateKey;
+
+ public MappingsModifier(final MappingsBuilderImpl mappingsBuilder, ListProperty readers) {
+ this.mappingsBuilder = mappingsBuilder;
+ this.readers = readers;
+ }
+
+ @Override
+ public String key() {
+ return KEY;
+ }
+
+ @Override
+ public String stateKey() {
+ if (stateKey == null) {
+ final MessageDigest digest = HashAlgorithm.SHA1.digest();
+ mappingsBuilder.computeStateKey(digest);
+ return this.stateKey = HashAlgorithm.toHexString(digest.digest());
+ }
+ return stateKey;
+ }
+
+ @Override
+ public CompletableFuture providePopulator(MinecraftResolver.Context context) {
+ return AsyncUtils.failableFuture(() -> new AtlasPopulator() {
+ private JarFile jarFile;
+
+ @Override
+ public JarEntryTransformer provide(AtlasTransformerContext atlasContext, MinecraftResolver.MinecraftEnvironment result, MinecraftPlatform side, SharedArtifactSupplier sharedArtifactProvider) {
+ MappingSet mappings = mappingsBuilder.create(readers.get());
+ try {
+ jarFile = new JarFile(result.jar());
+ } catch (IOException e) {
+ throw new UncheckedIOException("Could not read result jar file", e);
+ }
+ ArrayList providers = new ArrayList<>();
+ providers.add(jarFile);
+ return AtlasTransformers.remap(mappings, new ClassProviderInheritanceProvider(Constants.ASM_VERSION, new CascadingClassProvider(providers)));
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (jarFile != null) {
+ jarFile.close();
+ }
+ }
+ }, context.executor());
+ }
+
+ @Override
+ public boolean requiresLocalStorage() {
+ return false;
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java
new file mode 100644
index 00000000..f726457c
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java
@@ -0,0 +1,98 @@
+package org.spongepowered.gradle.vanilla.internal.repository.modifier;
+
+import org.cadixdev.atlas.AtlasTransformerContext;
+import org.cadixdev.atlas.jar.JarFile;
+import org.cadixdev.atlas.util.CascadingClassProvider;
+import org.cadixdev.bombe.asm.analysis.ClassProviderInheritanceProvider;
+import org.cadixdev.bombe.asm.jar.ClassProvider;
+import org.cadixdev.bombe.jar.JarEntryTransformer;
+import org.cadixdev.lorenz.MappingSet;
+import org.cadixdev.lorenz.io.proguard.ProGuardReader;
+import org.spongepowered.gradle.vanilla.internal.Constants;
+import org.spongepowered.gradle.vanilla.internal.model.Download;
+import org.spongepowered.gradle.vanilla.internal.resolver.AsyncUtils;
+import org.spongepowered.gradle.vanilla.internal.transformer.AtlasTransformers;
+import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
+import org.spongepowered.gradle.vanilla.resolver.HashAlgorithm;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+
+public class OfficialMappingsModifier implements ArtifactModifier {
+ private static final String KEY = "map";
+
+ @Override
+ public String key() {
+ return KEY;
+ }
+
+ @Override
+ public String stateKey() {
+ return "";
+ }
+
+ @Override
+ public CompletableFuture providePopulator(MinecraftResolver.Context context) {
+ return AsyncUtils.failableFuture(() -> new AtlasPopulator() {
+ private JarFile jarFile;
+
+ @Override
+ public JarEntryTransformer provide(AtlasTransformerContext atlasContext, MinecraftResolver.MinecraftEnvironment result, MinecraftPlatform platform, SharedArtifactSupplier sharedArtifactProvider) {
+ @SuppressWarnings("unchecked")
+ CompletableFuture[] mappingsFutures = platform.activeSides().stream().map(side -> {
+ Download mappingsDownload = result.metadata().requireDownload(side.mappingsArtifact());
+ return context.downloader().downloadAndValidate(
+ mappingsDownload.url(),
+ sharedArtifactProvider.supply(side.name().toLowerCase(Locale.ROOT) + "_m-obf", "mappings", "txt"),
+ HashAlgorithm.SHA1,
+ mappingsDownload.sha1()
+ ).thenApplyAsync(downloadResult -> {
+ if (!downloadResult.isPresent()) {
+ throw new IllegalArgumentException("No mappings were available for Minecraft " + result.metadata().id() + "side " + side.name()
+ + "! Official mappings are only available for releases 1.14.4 and newer.");
+ }
+ MappingSet mappings = MappingSet.create();
+ try (ProGuardReader reader = new ProGuardReader(Files.newBufferedReader(downloadResult.get()))) {
+ reader.read(mappings);
+ } catch (IOException e) {
+ throw new CompletionException(e);
+ }
+ return mappings;
+ }, context.executor());
+ }).toArray(CompletableFuture[]::new);
+ CompletableFuture mappingFuture = CompletableFuture.allOf(mappingsFutures)
+ .thenApplyAsync($ -> Arrays.stream(mappingsFutures).map(CompletableFuture::join).reduce(MappingSet::merge).orElseGet(MappingSet::create));
+
+
+ MappingSet mappings = mappingFuture.join();
+ try {
+ jarFile = new JarFile(result.jar());
+ } catch (IOException e) {
+ throw new UncheckedIOException("Could not read result jar file", e);
+ }
+ ArrayList providers = new ArrayList<>();
+ providers.add(jarFile);
+ return AtlasTransformers.remap(mappings, new ClassProviderInheritanceProvider(Constants.ASM_VERSION, new CascadingClassProvider(providers)));
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (jarFile != null) {
+ jarFile.close();
+ }
+ }
+ }, context.executor());
+ }
+
+ @Override
+ public boolean requiresLocalStorage() {
+ return false;
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsBuilder.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsBuilder.java
new file mode 100644
index 00000000..255f3487
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsBuilder.java
@@ -0,0 +1,5 @@
+package org.spongepowered.gradle.vanilla.repository;
+
+public interface MappingsBuilder {
+ void add(String formatName, Object dependencyNotation);
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsReader.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsReader.java
new file mode 100644
index 00000000..d38de43b
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsReader.java
@@ -0,0 +1,11 @@
+package org.spongepowered.gradle.vanilla.repository;
+
+import org.cadixdev.lorenz.MappingSet;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public interface MappingsReader {
+ String getName();
+ MappingSet read(final Path file) throws IOException;
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolver.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolver.java
index b872824d..81c6d5ee 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolver.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolver.java
@@ -35,6 +35,8 @@
import java.net.URLClassLoader;
import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
@@ -50,14 +52,14 @@ public interface MinecraftResolver {
* detected by existing input detection, or would make data unreadable by
* older versions of the resolver, this version will be incremented.
*/
- int STORAGE_VERSION = 1;
+ int STORAGE_VERSION = 2;
/**
* A version for stored metadata.
*
* Whenever the {@link #STORAGE_VERSION} is incremented, this version
* will be reset to {@code 1}
*/
- int METADATA_VERSION = 2;
+ int METADATA_VERSION = 1;
/**
* Get the version manifest repository managed by this resolver.
@@ -73,7 +75,12 @@ public interface MinecraftResolver {
CompletableFuture> provide(final MinecraftPlatform side, final String version);
- CompletableFuture> provide(final MinecraftPlatform side, final String version, final Set modifiers);
+ CompletableFuture> provide(final MinecraftPlatform side, final String version, final List modifiers);
+
+ @Deprecated // use the version with an ordered list of modifiers instead
+ default CompletableFuture> provide(final MinecraftPlatform side, final String version, final Set modifiers) {
+ return provide(side, version, new ArrayList<>(modifiers));
+ }
/**
* Given a standard Minecraft artifact, produce a variant of that artifact.
@@ -96,7 +103,15 @@ public interface MinecraftResolver {
* environment and a target path
* @return a future returning the result of resolving a jar path
*/
- CompletableFuture> produceAssociatedArtifactSync(final MinecraftPlatform side, final String version, final Set modifiers, final String id, final Set flags, final BiConsumer action);
+ CompletableFuture> produceAssociatedArtifactSync(final MinecraftPlatform side, final String version, final List modifiers, final String id, final Set flags, final BiConsumer action);
+
+ /**
+ * @deprecated Use the version with an ordered list of modifiers instead.
+ */
+ @Deprecated
+ default CompletableFuture> produceAssociatedArtifactSync(final MinecraftPlatform side, final String version, final Set modifiers, final String id, final Set flags, final BiConsumer action) {
+ return produceAssociatedArtifactSync(side, version, new ArrayList<>(modifiers), id, flags, action);
+ }
interface MinecraftEnvironment {
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
index 2acc322f..fa8bb0f2 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
@@ -26,17 +26,10 @@
import org.cadixdev.atlas.Atlas;
import org.cadixdev.atlas.jar.JarFile;
-import org.cadixdev.atlas.util.CascadingClassProvider;
-import org.cadixdev.bombe.asm.analysis.ClassProviderInheritanceProvider;
-import org.cadixdev.bombe.asm.jar.ClassProvider;
-import org.cadixdev.lorenz.MappingSet;
-import org.cadixdev.lorenz.io.proguard.ProGuardReader;
import org.checkerframework.checker.nullness.qual.Nullable;
-import org.gradle.api.GradleException;
import org.immutables.value.Value;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.spongepowered.gradle.vanilla.internal.Constants;
import org.spongepowered.gradle.vanilla.internal.bundler.BundlerMetadata;
import org.spongepowered.gradle.vanilla.internal.model.Download;
import org.spongepowered.gradle.vanilla.internal.model.GroupArtifactVersion;
@@ -56,16 +49,15 @@
import org.spongepowered.gradle.vanilla.resolver.ResolutionResult;
import java.io.IOException;
+import java.io.UncheckedIOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
-import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
@@ -154,12 +146,15 @@ CompletableFuture> provide(final Minecraf
}
final VersionDescriptor.Full descriptor = potentialDescriptor.get();
final Download jarDownload = descriptor.requireDownload(side.executableArtifact());
- final Download mappingsDownload = descriptor.requireDownload(side.mappingsArtifact());
// download to temp path
final String tempJarPath = this.sharedArtifactFileName(platform.artifactId() + "_m-obf_b-bundled", version, null, "jar");
final String jarPath = this.sharedArtifactFileName(platform.artifactId() + "_m-obf", version, null, "jar");
- final String mappingsPath = this.sharedArtifactFileName(platform.artifactId() + "_m-obf", version, "mappings", "txt");
+ try {
+ FileUtils.createDirectoriesSymlinkSafe(this.downloader.baseDir().resolve(jarPath).getParent());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
final CompletableFuture> jarFuture = this.downloader.downloadAndValidate(
jarDownload.url(),
@@ -167,14 +162,8 @@ CompletableFuture> provide(final Minecraf
HashAlgorithm.SHA1,
jarDownload.sha1()
);
- final CompletableFuture> mappingsFuture = this.downloader.downloadAndValidate(
- mappingsDownload.url(),
- mappingsPath,
- HashAlgorithm.SHA1,
- mappingsDownload.sha1()
- );
- return jarFuture.thenCombineAsync(mappingsFuture, (jar, mappingsFile) -> {
+ return jarFuture.thenApplyAsync(jar -> {
try {
final boolean outputExists = Files.exists(outputJar);
final @Nullable BundlerMetadata bundlerMeta = BundlerMetadata.read(jar.get()).orElse(null);
@@ -184,7 +173,7 @@ CompletableFuture> provide(final Minecraf
MinecraftResolverImpl.LOGGER.info("No bundler metadata found in jar {}", jar.get());
}
final Supplier> dependencies = () -> side.dependencies(descriptor, bundlerMeta);
- if (!this.forceRefresh && jar.upToDate() && mappingsFile.upToDate() && outputExists) {
+ if (!this.forceRefresh && jar.upToDate() && outputExists) {
// Our inputs are up-to-date, and the output exists, so we can assume (for now) that the output is up-to-date
// Check meta here too, before returning
this.writeMetaIfNecessary(platform, potentialDescriptor, dependencies, outputJar.getParent());
@@ -193,9 +182,6 @@ CompletableFuture> provide(final Minecraf
} else if (!jar.isPresent()) {
throw new IllegalArgumentException("No jar was available for Minecraft " + descriptor.id() + "side " + side.name()
+ "! Are you sure the data file is correct?");
- } else if (!mappingsFile.isPresent()) {
- throw new IllegalArgumentException("No mappings were available for Minecraft " + descriptor.id() + "side " + side.name()
- + "! Official mappings are only available for releases 1.14.4 and newer.");
}
MinecraftResolverImpl.LOGGER.warn("Preparing Minecraft: Java Edition {} version {}", side, version);
this.cleanAssociatedArtifacts(platform, version);
@@ -207,16 +193,6 @@ CompletableFuture> provide(final Minecraf
final Path extracted = this.downloader.baseDir().resolve(jarPath);
side.extractJar(jar.get(), extracted, bundlerMeta);
- final MappingSet scratchMappings = MappingSet.create();
- try (
- final ProGuardReader proguard = new ProGuardReader(Files.newBufferedReader(mappingsFile.get(), StandardCharsets.UTF_8))
- ) {
- proguard.read(scratchMappings);
- } catch (final IOException ex) {
- throw new GradleException("Failed to read mappings from " + mappingsFile, ex);
- }
- final MappingSet mappings = scratchMappings.reverse();
-
try (
final Atlas atlas = new Atlas(this.executor);
final JarFile source = new JarFile(extracted)
@@ -225,13 +201,6 @@ CompletableFuture> provide(final Minecraf
atlas.install(ctx -> AtlasTransformers.filterEntries(side.allowedPackages()));
}
atlas.install(ctx -> AtlasTransformers.stripSignatures());
- final List providers = new ArrayList<>();
- providers.add(source);
- atlas.install(ctx -> AtlasTransformers.remap(
- mappings,
- // duplicated from Atlas.run, to pass our own ASM API version
- new ClassProviderInheritanceProvider(Constants.ASM_VERSION, new CascadingClassProvider(providers))
- ));
atlas.run(source, outputTmp);
}
@@ -368,7 +337,7 @@ private CompletableFuture> provide0(final
@Override
public CompletableFuture> provide(
- final MinecraftPlatform side, final String version, final Set modifiers
+ final MinecraftPlatform side, final String version, final List modifiers
) {
final CompletableFuture> unmodified = this.provide0(side, version);
if (modifiers.isEmpty()) { // no modifiers provided, follow the normal path
@@ -413,7 +382,8 @@ public CompletableFuture> provide(
try (final Atlas atlas = new Atlas(this.executor)) {
for (final CompletableFuture populator : populators) {
- atlas.install(populator.get()::provide);
+ ArtifactModifier.AtlasPopulator pop = populator.get();
+ atlas.install(ctx -> pop.provide(ctx, input.get(), side, (id, classifier, extension) -> this.sharedArtifactFileName(id, version, classifier, extension)));
}
atlas.run(input.get().jar(), outputTmp);
@@ -464,7 +434,7 @@ private void cleanAssociatedArtifacts(final MinecraftPlatform platform, final St
public CompletableFuture> produceAssociatedArtifactSync(
final MinecraftPlatform side,
final String version,
- final Set modifiers,
+ final List modifiers,
final String id,
final Set flags,
final BiConsumer action
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/DecompileJarTask.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/DecompileJarTask.java
index 227e7db2..85761110 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/DecompileJarTask.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/DecompileJarTask.java
@@ -59,6 +59,7 @@
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@@ -129,7 +130,7 @@ public void execute() {
final CompletableFuture> resultFuture;
try {
final MinecraftProviderService minecraftProvider = this.getMinecraftProvider().get();
- final Set modifiers =
+ final List modifiers =
((MinecraftExtensionImpl) this.getProject().getExtensions().getByType(MinecraftExtension.class)).modifiers();
minecraftProvider.primeResolver(this.getProject(), modifiers);
From 433e225aff8ced81bf46c485a457c2f4c117c4c7 Mon Sep 17 00:00:00 2001
From: Joe
Date: Sun, 3 Oct 2021 17:07:31 +0100
Subject: [PATCH 02/15] Fix
---
.../repository/modifier/MappingsModifier.java | 36 +-------
.../modifier/OfficialMappingsModifier.java | 83 ++++++-------------
.../repository/MinecraftResolverImpl.java | 41 ++++++++-
3 files changed, 70 insertions(+), 90 deletions(-)
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java
index a96c6ee4..c0832979 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java
@@ -1,27 +1,16 @@
package org.spongepowered.gradle.vanilla.internal.repository.modifier;
-import org.cadixdev.atlas.AtlasTransformerContext;
-import org.cadixdev.atlas.jar.JarFile;
-import org.cadixdev.atlas.util.CascadingClassProvider;
-import org.cadixdev.bombe.asm.analysis.ClassProviderInheritanceProvider;
-import org.cadixdev.bombe.asm.jar.ClassProvider;
-import org.cadixdev.bombe.jar.JarEntryTransformer;
import org.cadixdev.lorenz.MappingSet;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.gradle.api.provider.ListProperty;
-import org.spongepowered.gradle.vanilla.internal.Constants;
import org.spongepowered.gradle.vanilla.internal.repository.mappings.MappingsBuilderImpl;
import org.spongepowered.gradle.vanilla.internal.resolver.AsyncUtils;
import org.spongepowered.gradle.vanilla.internal.transformer.AtlasTransformers;
import org.spongepowered.gradle.vanilla.repository.MappingsReader;
-import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
import org.spongepowered.gradle.vanilla.resolver.HashAlgorithm;
-import java.io.IOException;
-import java.io.UncheckedIOException;
import java.security.MessageDigest;
-import java.util.ArrayList;
import java.util.concurrent.CompletableFuture;
public class MappingsModifier implements ArtifactModifier {
@@ -53,28 +42,9 @@ public String stateKey() {
@Override
public CompletableFuture providePopulator(MinecraftResolver.Context context) {
- return AsyncUtils.failableFuture(() -> new AtlasPopulator() {
- private JarFile jarFile;
-
- @Override
- public JarEntryTransformer provide(AtlasTransformerContext atlasContext, MinecraftResolver.MinecraftEnvironment result, MinecraftPlatform side, SharedArtifactSupplier sharedArtifactProvider) {
- MappingSet mappings = mappingsBuilder.create(readers.get());
- try {
- jarFile = new JarFile(result.jar());
- } catch (IOException e) {
- throw new UncheckedIOException("Could not read result jar file", e);
- }
- ArrayList providers = new ArrayList<>();
- providers.add(jarFile);
- return AtlasTransformers.remap(mappings, new ClassProviderInheritanceProvider(Constants.ASM_VERSION, new CascadingClassProvider(providers)));
- }
-
- @Override
- public void close() throws IOException {
- if (jarFile != null) {
- jarFile.close();
- }
- }
+ return AsyncUtils.failableFuture(() -> (atlasContext, result, side, sharedArtifactProvider) -> {
+ MappingSet mappings = mappingsBuilder.create(readers.get());
+ return AtlasTransformers.remap(mappings, atlasContext.inheritanceProvider());
}, context.executor());
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java
index f726457c..3ba488dd 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java
@@ -1,25 +1,15 @@
package org.spongepowered.gradle.vanilla.internal.repository.modifier;
-import org.cadixdev.atlas.AtlasTransformerContext;
-import org.cadixdev.atlas.jar.JarFile;
-import org.cadixdev.atlas.util.CascadingClassProvider;
-import org.cadixdev.bombe.asm.analysis.ClassProviderInheritanceProvider;
-import org.cadixdev.bombe.asm.jar.ClassProvider;
-import org.cadixdev.bombe.jar.JarEntryTransformer;
import org.cadixdev.lorenz.MappingSet;
import org.cadixdev.lorenz.io.proguard.ProGuardReader;
-import org.spongepowered.gradle.vanilla.internal.Constants;
import org.spongepowered.gradle.vanilla.internal.model.Download;
import org.spongepowered.gradle.vanilla.internal.resolver.AsyncUtils;
import org.spongepowered.gradle.vanilla.internal.transformer.AtlasTransformers;
-import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
import org.spongepowered.gradle.vanilla.resolver.HashAlgorithm;
import java.io.IOException;
-import java.io.UncheckedIOException;
import java.nio.file.Files;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import java.util.concurrent.CompletableFuture;
@@ -40,54 +30,35 @@ public String stateKey() {
@Override
public CompletableFuture providePopulator(MinecraftResolver.Context context) {
- return AsyncUtils.failableFuture(() -> new AtlasPopulator() {
- private JarFile jarFile;
+ return AsyncUtils.failableFuture(() -> (atlasContext, result, platform, sharedArtifactProvider) -> {
+ @SuppressWarnings("unchecked")
+ CompletableFuture[] mappingsFutures = platform.activeSides().stream().map(side -> {
+ Download mappingsDownload = result.metadata().requireDownload(side.mappingsArtifact());
+ return context.downloader().downloadAndValidate(
+ mappingsDownload.url(),
+ sharedArtifactProvider.supply(side.name().toLowerCase(Locale.ROOT) + "_m-obf", "mappings", "txt"),
+ HashAlgorithm.SHA1,
+ mappingsDownload.sha1()
+ ).thenApplyAsync(downloadResult -> {
+ if (!downloadResult.isPresent()) {
+ throw new IllegalArgumentException("No mappings were available for Minecraft " + result.metadata().id() + "side " + side.name()
+ + "! Official mappings are only available for releases 1.14.4 and newer.");
+ }
+ MappingSet mappings = MappingSet.create();
+ try (ProGuardReader reader = new ProGuardReader(Files.newBufferedReader(downloadResult.get()))) {
+ reader.read(mappings);
+ } catch (IOException e) {
+ throw new CompletionException(e);
+ }
+ return mappings.reverse(); // proguard mappings are backwards
+ }, context.executor());
+ }).toArray(CompletableFuture[]::new);
+ CompletableFuture mappingFuture = CompletableFuture.allOf(mappingsFutures)
+ .thenApplyAsync($ -> Arrays.stream(mappingsFutures).map(CompletableFuture::join).reduce(MappingSet::merge).orElseGet(MappingSet::create));
- @Override
- public JarEntryTransformer provide(AtlasTransformerContext atlasContext, MinecraftResolver.MinecraftEnvironment result, MinecraftPlatform platform, SharedArtifactSupplier sharedArtifactProvider) {
- @SuppressWarnings("unchecked")
- CompletableFuture[] mappingsFutures = platform.activeSides().stream().map(side -> {
- Download mappingsDownload = result.metadata().requireDownload(side.mappingsArtifact());
- return context.downloader().downloadAndValidate(
- mappingsDownload.url(),
- sharedArtifactProvider.supply(side.name().toLowerCase(Locale.ROOT) + "_m-obf", "mappings", "txt"),
- HashAlgorithm.SHA1,
- mappingsDownload.sha1()
- ).thenApplyAsync(downloadResult -> {
- if (!downloadResult.isPresent()) {
- throw new IllegalArgumentException("No mappings were available for Minecraft " + result.metadata().id() + "side " + side.name()
- + "! Official mappings are only available for releases 1.14.4 and newer.");
- }
- MappingSet mappings = MappingSet.create();
- try (ProGuardReader reader = new ProGuardReader(Files.newBufferedReader(downloadResult.get()))) {
- reader.read(mappings);
- } catch (IOException e) {
- throw new CompletionException(e);
- }
- return mappings;
- }, context.executor());
- }).toArray(CompletableFuture[]::new);
- CompletableFuture mappingFuture = CompletableFuture.allOf(mappingsFutures)
- .thenApplyAsync($ -> Arrays.stream(mappingsFutures).map(CompletableFuture::join).reduce(MappingSet::merge).orElseGet(MappingSet::create));
-
- MappingSet mappings = mappingFuture.join();
- try {
- jarFile = new JarFile(result.jar());
- } catch (IOException e) {
- throw new UncheckedIOException("Could not read result jar file", e);
- }
- ArrayList providers = new ArrayList<>();
- providers.add(jarFile);
- return AtlasTransformers.remap(mappings, new ClassProviderInheritanceProvider(Constants.ASM_VERSION, new CascadingClassProvider(providers)));
- }
-
- @Override
- public void close() throws IOException {
- if (jarFile != null) {
- jarFile.close();
- }
- }
+ MappingSet mappings = mappingFuture.join();
+ return AtlasTransformers.remap(mappings, atlasContext.inheritanceProvider());
}, context.executor());
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
index fa8bb0f2..71b4c7db 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
@@ -25,11 +25,16 @@
package org.spongepowered.gradle.vanilla.repository;
import org.cadixdev.atlas.Atlas;
+import org.cadixdev.atlas.AtlasTransformerContext;
import org.cadixdev.atlas.jar.JarFile;
+import org.cadixdev.bombe.analysis.InheritanceProvider;
+import org.cadixdev.bombe.asm.analysis.ClassProviderInheritanceProvider;
+import org.cadixdev.bombe.asm.jar.ClassProvider;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.immutables.value.Value;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.spongepowered.gradle.vanilla.internal.Constants;
import org.spongepowered.gradle.vanilla.internal.bundler.BundlerMetadata;
import org.spongepowered.gradle.vanilla.internal.model.Download;
import org.spongepowered.gradle.vanilla.internal.model.GroupArtifactVersion;
@@ -50,6 +55,8 @@
import java.io.IOException;
import java.io.UncheckedIOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -383,7 +390,7 @@ public CompletableFuture> provide(
try (final Atlas atlas = new Atlas(this.executor)) {
for (final CompletableFuture populator : populators) {
ArtifactModifier.AtlasPopulator pop = populator.get();
- atlas.install(ctx -> pop.provide(ctx, input.get(), side, (id, classifier, extension) -> this.sharedArtifactFileName(id, version, classifier, extension)));
+ atlas.install(ctx -> pop.provide(withAsmApi(ctx, Constants.ASM_VERSION), input.get(), side, (id, classifier, extension) -> this.sharedArtifactFileName(id, version, classifier, extension)));
}
atlas.run(input.get().jar(), outputTmp);
@@ -410,6 +417,38 @@ public CompletableFuture> provide(
));
}
+ private static final Field CPIP_CLASS_PROVIDER_FIELD;
+ private static final Constructor ATC_CONSTRUCTOR;
+ static {
+ try {
+ CPIP_CLASS_PROVIDER_FIELD = ClassProviderInheritanceProvider.class.getDeclaredField("provider");
+ CPIP_CLASS_PROVIDER_FIELD.setAccessible(true);
+ ATC_CONSTRUCTOR = AtlasTransformerContext.class.getDeclaredConstructor(InheritanceProvider.class);
+ ATC_CONSTRUCTOR.setAccessible(true);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // Hack to set the ASM api version of the atlas inheritance provider.
+ // TODO: better solution, e.g. forking or using a different library?
+ private static ClassProvider getClassProvider(ClassProviderInheritanceProvider inheritanceProvider) {
+ try {
+ return (ClassProvider) CPIP_CLASS_PROVIDER_FIELD.get(inheritanceProvider);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static AtlasTransformerContext withAsmApi(AtlasTransformerContext context, int asmApi) {
+ InheritanceProvider inheritanceProvider = new ClassProviderInheritanceProvider(asmApi, getClassProvider((ClassProviderInheritanceProvider) context.inheritanceProvider()));
+ try {
+ return ATC_CONSTRUCTOR.newInstance(inheritanceProvider);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private void cleanAssociatedArtifacts(final MinecraftPlatform platform, final String version) throws IOException {
final Path baseArtifact = this.sharedArtifactPath(platform.artifactId(), version, null, "jar");
int errorCount = 0;
From fd553c0e85b336646eaa9d70138f2fa56f4ece55 Mon Sep 17 00:00:00 2001
From: Joe
Date: Mon, 4 Oct 2021 00:05:03 +0100
Subject: [PATCH 03/15] Massive refactor, allow for tiny mappings
---
gradle.properties | 1 +
subprojects/gradle-plugin/build.gradle.kts | 8 +-
.../gradle/vanilla/MinecraftExtension.java | 29 +-
.../internal/MinecraftExtensionImpl.java | 91 +++--
.../mappings/MappingsBuilderImpl.java | 132 -------
.../mappings/OfficialMappingsEntry.java | 98 +++++
...Reader.java => ProGuardMappingFormat.java} | 15 +-
.../mappings/TinyMappingFormat.java | 27 ++
.../repository/modifier/MappingsModifier.java | 29 +-
.../modifier/OfficialMappingsModifier.java | 69 ----
.../vanilla/repository/MappingsBuilder.java | 5 -
.../vanilla/repository/MappingsReader.java | 11 -
.../mappings/DelegatingMappingsEntry.java | 47 +++
.../repository/mappings/MappingFormat.java | 32 ++
.../mappings/MappingsContainer.java | 356 ++++++++++++++++++
.../repository/mappings/MappingsEntry.java | 204 ++++++++++
.../mappings/TinyMappingsEntry.java | 36 ++
.../repository/mappings/MappingsExtensions.kt | 2 +
18 files changed, 905 insertions(+), 287 deletions(-)
delete mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/MappingsBuilderImpl.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java
rename subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/{ProGuardMappingsReader.java => ProGuardMappingFormat.java} (57%)
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java
delete mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java
delete mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsBuilder.java
delete mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsReader.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/DelegatingMappingsEntry.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingFormat.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsContainer.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/TinyMappingsEntry.java
create mode 100644 subprojects/gradle-plugin/src/main/kotlin/org/spongepowered/gradle/vanilla/repository/mappings/MappingsExtensions.kt
diff --git a/gradle.properties b/gradle.properties
index ae8b25ed..7584e303 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -11,3 +11,4 @@ junitVersion=5.7.2
mergeToolVersion=1.1.4
org.gradle.parallel=true
+kotlin.stdlib.default.dependency=false
diff --git a/subprojects/gradle-plugin/build.gradle.kts b/subprojects/gradle-plugin/build.gradle.kts
index 8b29fa0f..5483283d 100644
--- a/subprojects/gradle-plugin/build.gradle.kts
+++ b/subprojects/gradle-plugin/build.gradle.kts
@@ -6,6 +6,7 @@ plugins {
id("com.gradle.plugin-publish")
id("net.kyori.indra.publishing.gradle-plugin")
id("org.jetbrains.gradle.plugin.idea-ext")
+ kotlin("jvm") version "1.5.31"
}
val commonDeps by configurations.creating {
@@ -16,9 +17,6 @@ val jarMerge by sourceSets.creating {
val jarDecompile by sourceSets.creating {
configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
}
-val jarRemap by sourceSets.creating {
- configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
-}
val accessWiden by sourceSets.creating {
configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
}
@@ -53,6 +51,9 @@ dependencies {
}
implementation("org.cadixdev:lorenz-io-proguard:0.5.7")
+ compileOnly("net.fabricmc:lorenz-tiny:4.0.2") {
+ isTransitive = false
+ }
compileOnlyApi("org.checkerframework:checker-qual:3.15.0")
annotationProcessor("org.immutables:value:2.8.8")
@@ -126,7 +127,6 @@ tasks {
jar {
from(jarMerge.output)
from(jarDecompile.output)
- from(jarRemap.output)
from(accessWiden.output)
from(shadow.output)
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java
index 28501ca5..1e31dbcf 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java
@@ -26,14 +26,17 @@
import groovy.lang.Closure;
import groovy.lang.DelegatesTo;
+import org.checkerframework.checker.nullness.qual.NonNull;
import org.gradle.api.Action;
+import org.gradle.api.NamedDomainObjectSet;
+import org.gradle.api.PolymorphicDomainObjectContainer;
import org.gradle.api.Project;
-import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property;
-import org.spongepowered.gradle.vanilla.repository.MappingsBuilder;
-import org.spongepowered.gradle.vanilla.repository.MappingsReader;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
import org.spongepowered.gradle.vanilla.repository.MinecraftRepositoryExtension;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsContainer;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
import org.spongepowered.gradle.vanilla.runs.RunConfigurationContainer;
/**
@@ -116,19 +119,25 @@ public interface MinecraftExtension extends MinecraftRepositoryExtension {
*/
void accessWideners(Object... file);
- Property useOfficialMappings();
+ PolymorphicDomainObjectContainer> getMappingFormats();
- void useOfficialMappings(boolean useOfficialMappings);
+ void mappingFormats(Action>> configure);
- ListProperty mappingsReaders();
+ void mappingFormats(@DelegatesTo(value = NamedDomainObjectSet.class, strategy = Closure.DELEGATE_FIRST) Closure>> configureClosure);
- void mappingsReader(MappingsReader... readers);
+ MappingsContainer getMappings();
- MappingsBuilder mappings();
+ void mappings(Action configure);
- void mappings(Action configure);
+ void mappings(@DelegatesTo(value = MappingsContainer.class, strategy = Closure.DELEGATE_FIRST) Closure configureClosure);
- void mappings(Closure configureClosure);
+ Property minecraftMappings();
+
+ void minecraftMappings(MappingsEntry mappings);
+
+ void minecraftMappings(String mappings);
+
+ void noMinecraftMappings();
/**
* Get run configurations configured for this project.
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
index 2ef2a163..b916e0cc 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
@@ -26,26 +26,29 @@
import groovy.lang.Closure;
import groovy.lang.DelegatesTo;
+import org.checkerframework.checker.nullness.qual.NonNull;
import org.gradle.api.Action;
import org.gradle.api.GradleException;
+import org.gradle.api.NamedDomainObjectSet;
+import org.gradle.api.PolymorphicDomainObjectContainer;
import org.gradle.api.Project;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.invocation.Gradle;
import org.gradle.api.model.ObjectFactory;
-import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.util.ConfigureUtil;
import org.spongepowered.gradle.vanilla.MinecraftExtension;
import org.spongepowered.gradle.vanilla.internal.model.VersionClassifier;
import org.spongepowered.gradle.vanilla.internal.model.VersionDescriptor;
-import org.spongepowered.gradle.vanilla.internal.repository.mappings.MappingsBuilderImpl;
-import org.spongepowered.gradle.vanilla.internal.repository.mappings.ProGuardMappingsReader;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.OfficialMappingsEntry;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.ProGuardMappingFormat;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.TinyMappingFormat;
import org.spongepowered.gradle.vanilla.internal.repository.modifier.MappingsModifier;
-import org.spongepowered.gradle.vanilla.internal.repository.modifier.OfficialMappingsModifier;
-import org.spongepowered.gradle.vanilla.repository.MappingsBuilder;
-import org.spongepowered.gradle.vanilla.repository.MappingsReader;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsContainer;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
import org.spongepowered.gradle.vanilla.internal.repository.MinecraftProviderService;
import org.spongepowered.gradle.vanilla.internal.repository.MinecraftRepositoryPlugin;
@@ -73,8 +76,10 @@ public class MinecraftExtensionImpl implements MinecraftExtension {
private final Property version;
private final Property platform;
private final Property injectRepositories;
- private final Property useOfficialMappings;
- private final ListProperty mappingsReaders;
+ private final PolymorphicDomainObjectContainer> mappingFormats;
+ private final MappingsContainer mappings;
+ private final Property minecraftMappings;
+ private final Property noMinecraftMappings;
private final DirectoryProperty sharedCache;
private final DirectoryProperty projectCache;
private final ConfigurableFileCollection accessWideners;
@@ -85,26 +90,28 @@ public class MinecraftExtensionImpl implements MinecraftExtension {
// Internals
private final Project project;
- private final MappingsBuilderImpl mappingsBuilder;
private final RunConfigurationContainer runConfigurations;
private volatile List lazyModifiers;
+ @SuppressWarnings("unchecked")
@Inject
public MinecraftExtensionImpl(final Gradle gradle, final ObjectFactory factory, final Project project, final Provider providerService) {
this.project = project;
this.providerService = providerService;
- this.mappingsBuilder = new MappingsBuilderImpl(project);
this.version = factory.property(String.class);
this.platform = factory.property(MinecraftPlatform.class).convention(MinecraftPlatform.JOINED);
this.injectRepositories = factory.property(Boolean.class).convention(project.provider(() -> !gradle.getPlugins().hasPlugin(MinecraftRepositoryPlugin.class))); // only inject if we aren't already in Settings
- this.useOfficialMappings = factory.property(Boolean.class).convention(project.provider(mappingsBuilder::isEmpty));
- this.mappingsReaders = factory.listProperty(MappingsReader.class).convention(project.provider(() -> {
- List readers = new ArrayList<>();
- readers.add(new ProGuardMappingsReader());
- return readers;
- }));
+ this.mappingFormats = factory.polymorphicDomainObjectContainer((Class>) (Class>) MappingFormat.class);
+ this.mappings = new MappingsContainer(project, this);
+ this.minecraftMappings = factory.property(String.class).convention(OfficialMappingsEntry.NAME);
+ this.noMinecraftMappings = factory.property(Boolean.class).convention(false);
this.accessWideners = factory.fileCollection();
+ this.mappingFormats.add(new ProGuardMappingFormat());
+ this.mappingFormats.add(new TinyMappingFormat());
+ this.mappings.add(new OfficialMappingsEntry(project, this));
+
+
this.assetsDirectory = factory.directoryProperty();
this.sharedCache = factory.directoryProperty().convention(providerService.flatMap(it -> it.getParameters().getSharedCache()));
this.sharedCache.disallowChanges();
@@ -245,51 +252,61 @@ public ConfigurableFileCollection accessWideners() {
}
@Override
- public Property useOfficialMappings() {
- return useOfficialMappings;
+ public PolymorphicDomainObjectContainer> getMappingFormats() {
+ return mappingFormats;
+ }
+
+ @Override
+ public void mappingFormats(Action>> configure) {
+ configure.execute(mappingFormats);
+ }
+
+ @Override
+ public void mappingFormats(@DelegatesTo(value = NamedDomainObjectSet.class, strategy = Closure.DELEGATE_FIRST) Closure>> configureClosure) {
+ ConfigureUtil.configure(configureClosure, mappingFormats);
}
@Override
- public void useOfficialMappings(boolean useOfficialMappings) {
- this.useOfficialMappings.set(useOfficialMappings);
+ public MappingsContainer getMappings() {
+ return mappings;
}
@Override
- public ListProperty mappingsReaders() {
- return this.mappingsReaders;
+ public void mappings(Action configure) {
+ configure.execute(mappings);
}
@Override
- public void mappingsReader(MappingsReader... readers) {
- this.mappingsReaders.addAll(readers);
+ public void mappings(@DelegatesTo(value = MappingsContainer.class, strategy = Closure.DELEGATE_FIRST) Closure configureClosure) {
+ ConfigureUtil.configure(configureClosure, mappings);
}
@Override
- public MappingsBuilderImpl mappings() {
- return mappingsBuilder;
+ public Property minecraftMappings() {
+ return minecraftMappings;
}
@Override
- public void mappings(Action configure) {
- configure.execute(mappingsBuilder);
+ public void minecraftMappings(MappingsEntry mappings) {
+ minecraftMappings(mappings.getName());
}
@Override
- public void mappings(Closure configureClosure) {
- configureClosure.setDelegate(mappingsBuilder);
- configureClosure.call();
+ public void minecraftMappings(String mappings) {
+ this.minecraftMappings.set(mappings);
+ }
+
+ @Override
+ public void noMinecraftMappings() {
+ this.noMinecraftMappings.set(true);
}
public synchronized List modifiers() {
if (this.lazyModifiers == null) {
final List modifiers = new ArrayList<>();
- if (useOfficialMappings.get()) {
- modifiers.add(new OfficialMappingsModifier());
- }
-
- if (!mappingsBuilder.isEmpty()) {
- modifiers.add(new MappingsModifier(mappingsBuilder, mappingsReaders));
+ if (!noMinecraftMappings.get()) {
+ modifiers.add(new MappingsModifier(mappings.getByName(minecraftMappings.get())));
}
this.accessWideners.disallowChanges();
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/MappingsBuilderImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/MappingsBuilderImpl.java
deleted file mode 100644
index a8402c75..00000000
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/MappingsBuilderImpl.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.spongepowered.gradle.vanilla.internal.repository.mappings;
-
-import groovy.lang.GroovyObjectSupport;
-import groovy.lang.MissingMethodException;
-import org.cadixdev.lorenz.MappingSet;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import org.checkerframework.checker.nullness.qual.Nullable;
-import org.gradle.api.Project;
-import org.gradle.api.artifacts.Dependency;
-import org.gradle.api.artifacts.DependencyArtifact;
-import org.gradle.api.artifacts.FileCollectionDependency;
-import org.gradle.api.artifacts.ModuleDependency;
-import org.spongepowered.gradle.vanilla.repository.MappingsBuilder;
-import org.spongepowered.gradle.vanilla.repository.MappingsReader;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UncheckedIOException;
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-
-public class MappingsBuilderImpl extends GroovyObjectSupport implements MappingsBuilder {
- private final Project project;
- private final List layers = new ArrayList<>();
-
- public MappingsBuilderImpl(final Project project) {
- this.project = project;
- }
-
- @Override
- public void add(@NonNull final String formatName, @NonNull final Object dependencyNotation) {
- final String configName = "mappingsLayer" + layers.size();
- project.getConfigurations().register(configName, config -> {
- config.setVisible(false);
- config.setCanBeConsumed(false);
- config.setCanBeResolved(true);
- });
- Dependency dependency = project.getDependencies().add(configName, dependencyNotation);
- layers.add(new Layer(formatName, configName, dependency));
- }
-
- public boolean isEmpty() {
- return layers.isEmpty();
- }
-
- public @Nullable MappingSet create(List readers) {
- return layers.stream().map(layer -> layer.resolve(project, readers)).reduce(MappingSet::merge).orElse(null);
- }
-
- public void computeStateKey(MessageDigest digest) {
- for (Layer layer : layers) {
- layer.computeStateKey(digest);
- }
- }
-
- @Override
- public Object invokeMethod(String name, Object arg) {
- try {
- return super.invokeMethod(name, arg);
- } catch (MissingMethodException e) {
- final Object[] args = (Object[]) arg;
- if (args.length == 1) {
- add(name, args[0]);
- return null;
- } else {
- throw e;
- }
- }
- }
-
- private static class Layer {
- private final String format;
- private final String config;
- private final Dependency dependency;
-
- Layer(String format, String config, Dependency dependency) {
- this.format = format;
- this.config = config;
- this.dependency = dependency;
- }
-
- MappingSet resolve(final Project project, final List readers) {
- Set files = project.getConfigurations().getByName(config).resolve();
- if (files.size() != 1) {
- throw new IllegalStateException("Mappings configuration didn't resolve to exactly one file");
- }
- for (MappingsReader reader : readers) {
- if (reader.getName().equals(format)) {
- try {
- return reader.read(files.iterator().next().toPath());
- } catch (IOException e) {
- throw new UncheckedIOException("Failed to read mappings file", e);
- }
- }
- }
- throw new IllegalStateException("Could not find a mappings reader for format \"" + format + "\". Maybe there is a Gradle plugin missing.");
- }
-
- void computeStateKey(MessageDigest digest) {
- // we can't resolve the dependency at this point, try some heuristics
-
- if (dependency instanceof ModuleDependency) {
- for (DependencyArtifact artifact : ((ModuleDependency) dependency).getArtifacts()) {
- digest.update(artifact.getUrl().getBytes(StandardCharsets.UTF_8));
- }
- } else if (dependency instanceof FileCollectionDependency) {
- for (File file : ((FileCollectionDependency) dependency).getFiles()) {
- try (final InputStream is = new FileInputStream(file)) {
- final byte[] buf = new byte[4096];
- int read;
- while ((read = is.read(buf)) != -1) {
- digest.update(buf, 0, read);
- }
- } catch (final IOException ex) {
- // ignore, will show up when we try to actually read the mappings
- }
- }
- } else {
- // the best we can do
- byte[] bytes = new byte[32];
- new Random().nextBytes(bytes);
- digest.update(bytes);
- }
- }
- }
-}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java
new file mode 100644
index 00000000..a932d163
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java
@@ -0,0 +1,98 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.cadixdev.lorenz.io.proguard.ProGuardReader;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.gradle.api.Project;
+import org.spongepowered.gradle.vanilla.MinecraftExtension;
+import org.spongepowered.gradle.vanilla.internal.model.Download;
+import org.spongepowered.gradle.vanilla.internal.repository.modifier.ArtifactModifier;
+import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
+import org.spongepowered.gradle.vanilla.resolver.HashAlgorithm;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+
+public class OfficialMappingsEntry extends MappingsEntry {
+ public static final String NAME = "official";
+ private boolean hasInitialized = false;
+
+ public OfficialMappingsEntry(Project project, MinecraftExtension extension) {
+ super(project, extension, NAME);
+ format(ProGuardMappingFormat.NAME);
+ hasInitialized = true;
+ }
+
+ @Override
+ public void format(@NonNull String format) {
+ if (hasInitialized) {
+ throw new IllegalStateException("Cannot modify the format of \"" + NAME + "\"");
+ } else {
+ super.format(format);
+ }
+ }
+
+ @Override
+ public void dependency(@Nullable Object dependencyNotation) {
+ throw new IllegalStateException("Cannot modify the dependency of \"" + NAME + "\"");
+ }
+
+ @Override
+ public void parent(@Nullable String parent) {
+ throw new IllegalStateException("Cannot modify the parent of \"" + NAME + "\"");
+ }
+
+ @Override
+ public void inverse(boolean isInverse) {
+ throw new IllegalStateException("Cannot invert \"" + NAME + "\"");
+ }
+
+ @Override
+ protected @NonNull MappingSet doResolve(
+ MinecraftResolver.@NonNull Context context,
+ MinecraftResolver.@NonNull MinecraftEnvironment environment,
+ @NonNull MinecraftPlatform platform,
+ ArtifactModifier.@NonNull SharedArtifactSupplier sharedArtifactSupplier,
+ @NonNull Set alreadySeen) {
+ @SuppressWarnings("unchecked")
+ CompletableFuture[] mappingsFutures = platform.activeSides().stream().map(side -> {
+ Download mappingsDownload = environment.metadata().requireDownload(side.mappingsArtifact());
+ return context.downloader().downloadAndValidate(
+ mappingsDownload.url(),
+ sharedArtifactSupplier.supply(side.name().toLowerCase(Locale.ROOT) + "_m-obf", "mappings", "txt"),
+ HashAlgorithm.SHA1,
+ mappingsDownload.sha1()
+ ).thenApplyAsync(downloadResult -> {
+ if (!downloadResult.isPresent()) {
+ throw new IllegalArgumentException("No mappings were available for Minecraft " + environment.metadata().id() + "side " + side.name()
+ + "! Official mappings are only available for releases 1.14.4 and newer.");
+ }
+ MappingSet mappings = MappingSet.create();
+ try (ProGuardReader reader = new ProGuardReader(Files.newBufferedReader(downloadResult.get()))) {
+ reader.read(mappings);
+ } catch (IOException e) {
+ throw new CompletionException(e);
+ }
+ return mappings.reverse(); // proguard mappings are backwards
+ }, context.executor());
+ }).toArray(CompletableFuture[]::new);
+ CompletableFuture mappingFuture = CompletableFuture.allOf(mappingsFutures)
+ .thenApplyAsync($ -> Arrays.stream(mappingsFutures).map(CompletableFuture::join).reduce(MappingSet::merge).orElseGet(MappingSet::create));
+
+
+ return mappingFuture.join();
+ }
+
+ @Override
+ public @NonNull String computeStateKey() {
+ return "";
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingsReader.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingFormat.java
similarity index 57%
rename from subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingsReader.java
rename to subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingFormat.java
index 25edf88a..3dcec10b 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingsReader.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingFormat.java
@@ -3,20 +3,27 @@
import org.cadixdev.lorenz.MappingSet;
import org.cadixdev.lorenz.io.proguard.ProGuardReader;
import org.checkerframework.checker.nullness.qual.NonNull;
-import org.spongepowered.gradle.vanilla.repository.MappingsReader;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-public class ProGuardMappingsReader implements MappingsReader {
+public class ProGuardMappingFormat extends MappingFormat<@NonNull MappingsEntry> {
+ public static final String NAME = "proguard";
+
+ public ProGuardMappingFormat() {
+ super(MappingsEntry.class);
+ }
+
@Override
public @NonNull String getName() {
- return "proguard";
+ return NAME;
}
@Override
- public @NonNull MappingSet read(final @NonNull Path file) throws IOException {
+ public @NonNull MappingSet read(final @NonNull Path file, final @NonNull MappingsEntry entry) throws IOException {
final MappingSet scratchMappings = MappingSet.create();
try (ProGuardReader proguard = new ProGuardReader(Files.newBufferedReader(file))) {
proguard.read(scratchMappings);
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java
new file mode 100644
index 00000000..ebf961dd
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java
@@ -0,0 +1,27 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
+import org.spongepowered.gradle.vanilla.repository.mappings.TinyMappingsEntry;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public class TinyMappingFormat extends MappingFormat<@NonNull TinyMappingsEntry> {
+ public TinyMappingFormat() {
+ super(TinyMappingsEntry.class);
+ }
+
+ @Override
+ public @NonNull String getName() {
+ return "tiny";
+ }
+
+ @Override
+ public @NonNull MappingSet read(@NonNull Path file, @NonNull TinyMappingsEntry entry) throws IOException {
+ MappingSet mappings = MappingSet.create();
+ net.fabricmc.lorenztiny.TinyMappingFormat.DETECT.read(mappings, file, entry.from().get(), entry.to().get());
+ return mappings;
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java
index c0832979..350b7f06 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java
@@ -2,27 +2,23 @@
import org.cadixdev.lorenz.MappingSet;
import org.checkerframework.checker.nullness.qual.Nullable;
-import org.gradle.api.provider.ListProperty;
-import org.spongepowered.gradle.vanilla.internal.repository.mappings.MappingsBuilderImpl;
import org.spongepowered.gradle.vanilla.internal.resolver.AsyncUtils;
import org.spongepowered.gradle.vanilla.internal.transformer.AtlasTransformers;
-import org.spongepowered.gradle.vanilla.repository.MappingsReader;
import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
-import org.spongepowered.gradle.vanilla.resolver.HashAlgorithm;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
-import java.security.MessageDigest;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.util.concurrent.CompletableFuture;
public class MappingsModifier implements ArtifactModifier {
- private static final String KEY = "cm"; // custom mapped
+ private static final String KEY = "map"; // custom mapped
- private final MappingsBuilderImpl mappingsBuilder;
- private final ListProperty readers;
+ private final MappingsEntry mappings;
private @Nullable String stateKey;
- public MappingsModifier(final MappingsBuilderImpl mappingsBuilder, ListProperty readers) {
- this.mappingsBuilder = mappingsBuilder;
- this.readers = readers;
+ public MappingsModifier(final MappingsEntry mappings) {
+ this.mappings = mappings;
}
@Override
@@ -33,9 +29,7 @@ public String key() {
@Override
public String stateKey() {
if (stateKey == null) {
- final MessageDigest digest = HashAlgorithm.SHA1.digest();
- mappingsBuilder.computeStateKey(digest);
- return this.stateKey = HashAlgorithm.toHexString(digest.digest());
+ return this.stateKey = mappings.computeStateKey();
}
return stateKey;
}
@@ -43,7 +37,12 @@ public String stateKey() {
@Override
public CompletableFuture providePopulator(MinecraftResolver.Context context) {
return AsyncUtils.failableFuture(() -> (atlasContext, result, side, sharedArtifactProvider) -> {
- MappingSet mappings = mappingsBuilder.create(readers.get());
+ final MappingSet mappings;
+ try {
+ mappings = this.mappings.resolve(context, result, side, sharedArtifactProvider);
+ } catch (IOException e) {
+ throw new UncheckedIOException("An exception occurred while trying to read mappings", e);
+ }
return AtlasTransformers.remap(mappings, atlasContext.inheritanceProvider());
}, context.executor());
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java
deleted file mode 100644
index 3ba488dd..00000000
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/OfficialMappingsModifier.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.spongepowered.gradle.vanilla.internal.repository.modifier;
-
-import org.cadixdev.lorenz.MappingSet;
-import org.cadixdev.lorenz.io.proguard.ProGuardReader;
-import org.spongepowered.gradle.vanilla.internal.model.Download;
-import org.spongepowered.gradle.vanilla.internal.resolver.AsyncUtils;
-import org.spongepowered.gradle.vanilla.internal.transformer.AtlasTransformers;
-import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
-import org.spongepowered.gradle.vanilla.resolver.HashAlgorithm;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.Locale;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionException;
-
-public class OfficialMappingsModifier implements ArtifactModifier {
- private static final String KEY = "map";
-
- @Override
- public String key() {
- return KEY;
- }
-
- @Override
- public String stateKey() {
- return "";
- }
-
- @Override
- public CompletableFuture providePopulator(MinecraftResolver.Context context) {
- return AsyncUtils.failableFuture(() -> (atlasContext, result, platform, sharedArtifactProvider) -> {
- @SuppressWarnings("unchecked")
- CompletableFuture[] mappingsFutures = platform.activeSides().stream().map(side -> {
- Download mappingsDownload = result.metadata().requireDownload(side.mappingsArtifact());
- return context.downloader().downloadAndValidate(
- mappingsDownload.url(),
- sharedArtifactProvider.supply(side.name().toLowerCase(Locale.ROOT) + "_m-obf", "mappings", "txt"),
- HashAlgorithm.SHA1,
- mappingsDownload.sha1()
- ).thenApplyAsync(downloadResult -> {
- if (!downloadResult.isPresent()) {
- throw new IllegalArgumentException("No mappings were available for Minecraft " + result.metadata().id() + "side " + side.name()
- + "! Official mappings are only available for releases 1.14.4 and newer.");
- }
- MappingSet mappings = MappingSet.create();
- try (ProGuardReader reader = new ProGuardReader(Files.newBufferedReader(downloadResult.get()))) {
- reader.read(mappings);
- } catch (IOException e) {
- throw new CompletionException(e);
- }
- return mappings.reverse(); // proguard mappings are backwards
- }, context.executor());
- }).toArray(CompletableFuture[]::new);
- CompletableFuture mappingFuture = CompletableFuture.allOf(mappingsFutures)
- .thenApplyAsync($ -> Arrays.stream(mappingsFutures).map(CompletableFuture::join).reduce(MappingSet::merge).orElseGet(MappingSet::create));
-
-
- MappingSet mappings = mappingFuture.join();
- return AtlasTransformers.remap(mappings, atlasContext.inheritanceProvider());
- }, context.executor());
- }
-
- @Override
- public boolean requiresLocalStorage() {
- return false;
- }
-}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsBuilder.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsBuilder.java
deleted file mode 100644
index 255f3487..00000000
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsBuilder.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.spongepowered.gradle.vanilla.repository;
-
-public interface MappingsBuilder {
- void add(String formatName, Object dependencyNotation);
-}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsReader.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsReader.java
deleted file mode 100644
index d38de43b..00000000
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MappingsReader.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.spongepowered.gradle.vanilla.repository;
-
-import org.cadixdev.lorenz.MappingSet;
-
-import java.io.IOException;
-import java.nio.file.Path;
-
-public interface MappingsReader {
- String getName();
- MappingSet read(final Path file) throws IOException;
-}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/DelegatingMappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/DelegatingMappingsEntry.java
new file mode 100644
index 00000000..a0c1c289
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/DelegatingMappingsEntry.java
@@ -0,0 +1,47 @@
+package org.spongepowered.gradle.vanilla.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.gradle.api.NamedDomainObjectProvider;
+import org.gradle.api.Project;
+import org.spongepowered.gradle.vanilla.MinecraftExtension;
+import org.spongepowered.gradle.vanilla.internal.repository.modifier.ArtifactModifier;
+import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
+
+import java.io.IOException;
+import java.util.Set;
+
+public class DelegatingMappingsEntry extends MappingsEntry {
+ private @Nullable NamedDomainObjectProvider delegateTo;
+
+ public DelegatingMappingsEntry(Project project, MinecraftExtension extension, String name) {
+ super(project, extension, name);
+ }
+
+ public @Nullable NamedDomainObjectProvider delegateTo() {
+ return delegateTo;
+ }
+ public void delegateTo(MappingsEntry delegateTo) {
+ delegateTo(extension.getMappings().named(delegateTo.getName()));
+ }
+ public void delegateTo(NamedDomainObjectProvider delegateTo) {
+ this.delegateTo = delegateTo;
+ }
+ public void delegateTo(String delegateTo) {
+ delegateTo(extension.getMappings().named(delegateTo));
+ }
+
+ @Override
+ protected MappingSet doResolve(
+ MinecraftResolver.Context context,
+ MinecraftResolver.MinecraftEnvironment environment,
+ MinecraftPlatform platform,
+ ArtifactModifier.SharedArtifactSupplier sharedArtifactSupplier,
+ Set alreadySeen) throws IOException {
+ if (delegateTo == null) {
+ throw new IllegalStateException("\"" + getName() + "\" delegateTo has not been initialized");
+ }
+ return extension.getMappings().getByName(delegateTo.getName()).resolve(context, environment, platform, sharedArtifactSupplier, alreadySeen);
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingFormat.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingFormat.java
new file mode 100644
index 00000000..d0656b99
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingFormat.java
@@ -0,0 +1,32 @@
+package org.spongepowered.gradle.vanilla.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.gradle.api.Named;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public abstract class MappingFormat implements Named {
+ private final Class entryType;
+
+ protected MappingFormat(Class entryType) {
+ this.entryType = entryType;
+ }
+
+ public Class entryType() {
+ return entryType;
+ }
+
+ public abstract MappingSet read(final Path file, final T entry) throws IOException;
+
+ @Override
+ public int hashCode() {
+ return getName().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other instanceof MappingFormat && ((MappingFormat<@NonNull ?>) other).getName().equals(getName());
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsContainer.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsContainer.java
new file mode 100644
index 00000000..9bd96525
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsContainer.java
@@ -0,0 +1,356 @@
+package org.spongepowered.gradle.vanilla.repository.mappings;
+
+import groovy.lang.Closure;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.gradle.api.Action;
+import org.gradle.api.DomainObjectCollection;
+import org.gradle.api.InvalidUserDataException;
+import org.gradle.api.NamedDomainObjectCollectionSchema;
+import org.gradle.api.NamedDomainObjectContainer;
+import org.gradle.api.NamedDomainObjectProvider;
+import org.gradle.api.NamedDomainObjectSet;
+import org.gradle.api.Namer;
+import org.gradle.api.PolymorphicDomainObjectContainer;
+import org.gradle.api.Project;
+import org.gradle.api.Rule;
+import org.gradle.api.UnknownDomainObjectException;
+import org.gradle.api.internal.NamedDomainObjectContainerConfigureDelegate;
+import org.gradle.api.provider.Provider;
+import org.gradle.api.specs.Spec;
+import org.gradle.util.ConfigureUtil;
+import org.spongepowered.gradle.vanilla.MinecraftExtension;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+
+public class MappingsContainer implements PolymorphicDomainObjectContainer {
+ private final Project project;
+ private final MinecraftExtension extension;
+ private final PolymorphicDomainObjectContainer delegate;
+
+ public MappingsContainer(Project project, MinecraftExtension extension) {
+ this.project = project;
+ this.extension = extension;
+ delegate = project.getObjects().polymorphicDomainObjectContainer(MappingsEntry.class);
+ }
+
+ // -- Delegating to actual implementation -- //
+
+ @Override
+ public U create(String name, Class type) throws InvalidUserDataException {
+ return delegate.create(name, type);
+ }
+
+ @Override
+ public U maybeCreate(String name, Class type) throws InvalidUserDataException {
+ return delegate.maybeCreate(name, type);
+ }
+
+ @Override
+ public U create(String name, Class type, Action super U> configuration) throws InvalidUserDataException {
+ return delegate.create(name, type, configuration);
+ }
+
+ @Override
+ public NamedDomainObjectContainer containerWithType(Class type) {
+ return delegate.containerWithType(type);
+ }
+
+ @Override
+ public NamedDomainObjectProvider register(String name, Class type, Action super U> configurationAction) throws InvalidUserDataException {
+ return delegate.register(name, type, configurationAction);
+ }
+
+ @Override
+ public NamedDomainObjectProvider register(String name, Class type) throws InvalidUserDataException {
+ return delegate.register(name, type);
+ }
+
+ @Override
+ public MappingsEntry create(final String name) throws InvalidUserDataException {
+ return this.delegate.create(name);
+ }
+
+ @Override
+ public MappingsEntry maybeCreate(final String name) {
+ return this.delegate.maybeCreate(name);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public MappingsEntry create(final String name, final Closure configureClosure) throws InvalidUserDataException {
+ return this.delegate.create(name, configureClosure);
+ }
+
+ @Override
+ public MappingsEntry create(final String name, final Action super MappingsEntry> configureAction)
+ throws InvalidUserDataException {
+ return this.delegate.create(name, configureAction);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public NamedDomainObjectContainer configure(final Closure configureClosure) {
+ // TODO: This uses internal API, see if there's a more 'public' way to do this
+ return ConfigureUtil.configureSelf(configureClosure, this, new NamedDomainObjectContainerConfigureDelegate(configureClosure, this));
+ }
+
+ @Override
+ public NamedDomainObjectProvider register(final String name, final Action super MappingsEntry> configurationAction)
+ throws InvalidUserDataException {
+ return this.delegate.register(name, configurationAction);
+ }
+
+ @Override
+ public NamedDomainObjectProvider register(final String name) throws InvalidUserDataException {
+ return this.delegate.register(name);
+ }
+
+ @Override
+ public int size() {
+ return this.delegate.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return this.delegate.isEmpty();
+ }
+
+ @Override
+ public boolean contains(final Object o) {
+ return this.delegate.contains(o);
+ }
+
+ @Override
+ public Iterator iterator() {
+ return this.delegate.iterator();
+ }
+
+ @Override
+ public Object[] toArray() {
+ return this.delegate.toArray();
+ }
+
+ @Override public T[] toArray(final T[] a) {
+ return this.delegate.toArray(a);
+ }
+
+ @Override
+ public boolean add(final MappingsEntry e) {
+ return this.delegate.add(e);
+ }
+
+ @Override
+ public boolean remove(final Object o) {
+ return this.delegate.remove(o);
+ }
+
+ @Override
+ public boolean containsAll(final Collection> c) {
+ return this.delegate.containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(final Collection extends MappingsEntry> c) {
+ return this.delegate.addAll(c);
+ }
+
+ @Override
+ public boolean removeAll(final Collection> c) {
+ return this.delegate.removeAll(c);
+ }
+
+ @Override
+ public boolean retainAll(final Collection> c) {
+ return this.delegate.retainAll(c);
+ }
+
+ @Override
+ public void clear() {
+ this.delegate.clear();
+ }
+
+ @Override
+ public Namer getNamer() {
+ return this.delegate.getNamer();
+ }
+
+ @Override
+ public SortedMap getAsMap() {
+ return this.delegate.getAsMap();
+ }
+
+ @Override
+ public SortedSet getNames() {
+ return this.delegate.getNames();
+ }
+
+ @Nullable
+ @Override
+ public MappingsEntry findByName(final String name) {
+ return this.delegate.findByName(name);
+ }
+
+ @Override
+ public MappingsEntry getByName(final String name) throws UnknownDomainObjectException {
+ return this.delegate.getByName(name);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public MappingsEntry getByName(final String name, final Closure configureClosure) throws UnknownDomainObjectException {
+ return this.delegate.getByName(name, configureClosure);
+ }
+
+ @Override
+ public MappingsEntry getByName(final String name, final Action super MappingsEntry> configureAction) throws UnknownDomainObjectException {
+ return this.delegate.getByName(name, configureAction);
+ }
+
+ @Override
+ public MappingsEntry getAt(final String name) throws UnknownDomainObjectException {
+ return this.delegate.getAt(name);
+ }
+
+ @Override
+ public Rule addRule(final Rule rule) {
+ return this.delegate.addRule(rule);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public Rule addRule(final String description, final Closure ruleAction) {
+ return this.delegate.addRule(description, ruleAction);
+ }
+
+ @Override
+ public Rule addRule(final String description, final Action ruleAction) {
+ return this.delegate.addRule(description, ruleAction);
+ }
+
+ @Override
+ public List getRules() {
+ return this.delegate.getRules();
+ }
+
+ @Override
+ public void addLater(final Provider extends MappingsEntry> provider) {
+ this.delegate.addLater(provider);
+ }
+
+ @Override
+ public void addAllLater(
+ final Provider extends Iterable> provider) {
+ this.delegate.addAllLater(provider);
+ }
+
+ @Override
+ public NamedDomainObjectSet withType(final Class type) {
+ return this.delegate.withType(type);
+ }
+
+ @Override
+ public DomainObjectCollection withType(final Class type, final Action super S> configureAction) {
+ return this.delegate.withType(type, configureAction);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public DomainObjectCollection withType(final Class type, final Closure configureClosure) {
+ return this.delegate.withType(type, configureClosure);
+ }
+
+ @Override
+ public NamedDomainObjectSet matching(final Spec super MappingsEntry> spec) {
+ return this.delegate.matching(spec);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public NamedDomainObjectSet matching(final Closure spec) {
+ return this.delegate.matching(spec);
+ }
+
+ @Override
+ public Action super MappingsEntry> whenObjectAdded(final Action super MappingsEntry> action) {
+ return this.delegate.whenObjectAdded(action);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public void whenObjectAdded(final Closure action) {
+ this.delegate.whenObjectAdded(action);
+ }
+
+ @Override
+ public Action super MappingsEntry> whenObjectRemoved(final Action super MappingsEntry> action) {
+ return this.delegate.whenObjectRemoved(action);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public void whenObjectRemoved(final Closure action) {
+ this.delegate.whenObjectRemoved(action);
+ }
+
+ @Override
+ public void all(final Action super MappingsEntry> action) {
+ this.delegate.all(action);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public void all(final Closure action) {
+ this.delegate.all(action);
+ }
+
+ @Override
+ public void configureEach(final Action super MappingsEntry> action) {
+ this.delegate.configureEach(action);
+ }
+
+ @Override
+ public NamedDomainObjectProvider named(final String name) throws UnknownDomainObjectException {
+ return this.delegate.named(name);
+ }
+
+ @Override
+ public NamedDomainObjectProvider named(
+ final String name,
+ final Action super MappingsEntry> configurationAction
+ ) throws UnknownDomainObjectException {
+ return this.delegate.named(name, configurationAction);
+ }
+
+ @Override
+ public NamedDomainObjectProvider named(
+ final String name,
+ final Class type
+ ) throws UnknownDomainObjectException {
+ return this.delegate.named(name, type);
+ }
+
+ @Override
+ public NamedDomainObjectProvider named(
+ final String name,
+ final Class type,
+ final Action super S> configurationAction
+ ) throws UnknownDomainObjectException {
+ return this.delegate.named(name, type, configurationAction);
+ }
+
+ @Override
+ public NamedDomainObjectCollectionSchema getCollectionSchema() {
+ return this.delegate.getCollectionSchema();
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public Set findAll(final Closure spec) {
+ return this.delegate.findAll(spec);
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
new file mode 100644
index 00000000..8f49b135
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
@@ -0,0 +1,204 @@
+package org.spongepowered.gradle.vanilla.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.gradle.api.Named;
+import org.gradle.api.Project;
+import org.gradle.api.artifacts.Dependency;
+import org.gradle.api.artifacts.DependencyArtifact;
+import org.gradle.api.artifacts.FileCollectionDependency;
+import org.gradle.api.artifacts.ModuleDependency;
+import org.gradle.api.provider.Property;
+import org.spongepowered.gradle.vanilla.MinecraftExtension;
+import org.spongepowered.gradle.vanilla.internal.repository.modifier.ArtifactModifier;
+import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
+import org.spongepowered.gradle.vanilla.resolver.HashAlgorithm;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.security.MessageDigest;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+
+public class MappingsEntry implements Named {
+ protected final Project project;
+ protected final MinecraftExtension extension;
+ private final String name;
+ private final Property format;
+ private final String configurationName;
+ private @Nullable Object dependency;
+ private @Nullable Dependency dependencyObj;
+ private final Property parent;
+ private final Property inverse;
+
+ public MappingsEntry(Project project, MinecraftExtension extension, String name) {
+ this.project = project;
+ this.extension = extension;
+ this.name = name;
+ this.format = project.getObjects().property(String.class);
+ this.configurationName = name + "Mappings";
+ this.parent = project.getObjects().property(String.class);
+ this.inverse = project.getObjects().property(Boolean.class).convention(false);
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ public @Nullable Property format() {
+ return format;
+ }
+ public void format(MappingFormat<@NonNull ?> format) {
+ format(format.getName());
+ }
+ public void format(String format) {
+ this.format.set(format);
+ }
+
+ public @Nullable Object dependency() {
+ return dependency;
+ }
+ public void dependency(Object dependencyNotation) {
+ if (this.dependency != null) {
+ throw new IllegalStateException("MappingsEntry.dependency(Object) called twice");
+ }
+ project.getConfigurations().register(configurationName, config -> {
+ config.setVisible(false);
+ config.setCanBeConsumed(false);
+ config.setCanBeResolved(true);
+ });
+ this.dependencyObj = project.getDependencies().add(configurationName, dependencyNotation);
+ this.dependency = dependencyNotation;
+ }
+
+ public Property<@Nullable String> parent() {
+ return parent;
+ }
+ public void parent(MappingsEntry parent) {
+ parent(parent.getName());
+ }
+ public void parent(String parent) {
+ this.parent.set(parent);
+ }
+
+ public Property isInverse() {
+ return inverse;
+ }
+ public void invert() {
+ inverse(true);
+ }
+ public void inverse(boolean isInverse) {
+ inverse.set(isInverse);
+ }
+
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ public boolean equals(Object other) {
+ return other instanceof MappingsEntry && ((MappingsEntry) other).name.equals(this.name);
+ }
+
+ public final MappingSet resolve(
+ MinecraftResolver.Context context,
+ MinecraftResolver.MinecraftEnvironment environment,
+ MinecraftPlatform platform,
+ ArtifactModifier.SharedArtifactSupplier sharedArtifactSupplier
+ ) throws IOException {
+ return resolve(context, environment, platform, sharedArtifactSupplier, new HashSet<>());
+ }
+
+ final MappingSet resolve(
+ MinecraftResolver.Context context,
+ MinecraftResolver.MinecraftEnvironment environment,
+ MinecraftPlatform platform,
+ ArtifactModifier.SharedArtifactSupplier sharedArtifactSupplier,
+ Set alreadySeen
+ ) throws IOException {
+ if (!alreadySeen.add(getName())) {
+ throw new IllegalStateException("Recursive mapping dependencies for \"" + getName() + "\"");
+ }
+ MappingSet resolved = doResolve(context, environment, platform, sharedArtifactSupplier, alreadySeen);
+ if (this.inverse.get()) {
+ resolved = resolved.reverse();
+ }
+ if (parent.getOrNull() != null) {
+ resolved = extension.getMappings().getByName(parent.get()).resolve(context, environment, platform, sharedArtifactSupplier, alreadySeen).merge(resolved);
+ }
+ return resolved;
+ }
+
+ protected MappingSet doResolve(
+ MinecraftResolver.Context context,
+ MinecraftResolver.MinecraftEnvironment environment,
+ MinecraftPlatform platform,
+ ArtifactModifier.SharedArtifactSupplier sharedArtifactSupplier,
+ Set alreadySeen) throws IOException {
+ if (dependency == null) {
+ throw new IllegalStateException("Mappings entry \"" + getName() + "\" of format \"" + format.get() + "\" must have a dependency");
+ }
+ @SuppressWarnings("unchecked")
+ MappingFormat mappingFormat = (MappingFormat) extension.getMappingFormats().getByName(format.get());
+ if (!mappingFormat.entryType().isInstance(this)) {
+ throw new IllegalStateException("Mappings entry \"" + getName() + "\" of type \"" + getClass().getName() + "\" is not compatible with mapping format \"" + format.get() + "\"");
+ }
+ Set resolvedFiles = project.getConfigurations().getByName(configurationName).resolve();
+ if (resolvedFiles.size() != 1) {
+ throw new IllegalStateException("Mappings entry \"" + getName() + "\" did not resolve to exactly 1 file");
+ }
+ Path resolvedFile = resolvedFiles.iterator().next().toPath();
+ return mappingFormat.read(resolvedFile, mappingFormat.entryType().cast(this));
+ }
+
+ public String computeStateKey() {
+ final MessageDigest digest = HashAlgorithm.SHA1.digest();
+ computeHash(digest);
+ return HashAlgorithm.toHexString(digest.digest());
+ }
+
+ protected void computeHash(MessageDigest digest) {
+ digest.update((byte) 0);
+ digest.update(getName().getBytes(StandardCharsets.UTF_8));
+ digest.update((byte) 1);
+ digest.update(format.get().getBytes(StandardCharsets.UTF_8));
+ if (dependencyObj != null) {
+ digest.update((byte) 2);
+ if (dependencyObj instanceof ModuleDependency) {
+ for (DependencyArtifact artifact : ((ModuleDependency) dependencyObj).getArtifacts()) {
+ digest.update(artifact.getUrl().getBytes(StandardCharsets.UTF_8));
+ }
+ } else if (dependencyObj instanceof FileCollectionDependency) {
+ for (File file : ((FileCollectionDependency) dependencyObj).getFiles()) {
+ try (final InputStream is = new FileInputStream(file)) {
+ final byte[] buf = new byte[4096];
+ int read;
+ while ((read = is.read(buf)) != -1) {
+ digest.update(buf, 0, read);
+ }
+ } catch (final IOException ex) {
+ // ignore, will show up when we try to actually read the mappings
+ }
+ }
+ } else {
+ byte[] bytes = new byte[32];
+ new Random().nextBytes(bytes);
+ digest.update(bytes);
+ }
+ }
+ if (inverse.get()) {
+ digest.update((byte) 3);
+ }
+ if (parent.getOrNull() != null) {
+ digest.update((byte) 4);
+ extension.getMappings().getByName(parent.get()).computeHash(digest);
+ }
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/TinyMappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/TinyMappingsEntry.java
new file mode 100644
index 00000000..733e7fdc
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/TinyMappingsEntry.java
@@ -0,0 +1,36 @@
+package org.spongepowered.gradle.vanilla.repository.mappings;
+
+import org.gradle.api.Project;
+import org.gradle.api.provider.Property;
+import org.spongepowered.gradle.vanilla.MinecraftExtension;
+
+public class TinyMappingsEntry extends MappingsEntry {
+ private final Property from;
+ private final Property to;
+
+ public TinyMappingsEntry(
+ Project project,
+ MinecraftExtension extension,
+ String name
+ ) {
+ super(project, extension, name);
+ this.from = project.getObjects().property(String.class);
+ this.to = project.getObjects().property(String.class);
+ }
+
+ public Property from() {
+ return from;
+ }
+
+ public void from(String from) {
+ this.from.set(from);
+ }
+
+ public Property to() {
+ return to;
+ }
+
+ public void to(String to) {
+ this.to.set(to);
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/kotlin/org/spongepowered/gradle/vanilla/repository/mappings/MappingsExtensions.kt b/subprojects/gradle-plugin/src/main/kotlin/org/spongepowered/gradle/vanilla/repository/mappings/MappingsExtensions.kt
new file mode 100644
index 00000000..ab39223f
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/kotlin/org/spongepowered/gradle/vanilla/repository/mappings/MappingsExtensions.kt
@@ -0,0 +1,2 @@
+package org.spongepowered.gradle.vanilla.repository.mappings
+
From b42e0fa7c2c408c936855185c860cc36962c10a2 Mon Sep 17 00:00:00 2001
From: Joe
Date: Mon, 4 Oct 2021 01:32:50 +0100
Subject: [PATCH 04/15] Some fixes
---
.../repository/mappings/TinyMappingFormat.java | 17 +++++++++++++++++
.../repository/MinecraftResolverImpl.java | 3 ++-
.../repository/mappings/MappingsContainer.java | 6 +++++-
.../repository/mappings/MappingsEntry.java | 9 ++++++---
4 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java
index ebf961dd..960c6de4 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java
@@ -6,7 +6,10 @@
import org.spongepowered.gradle.vanilla.repository.mappings.TinyMappingsEntry;
import java.io.IOException;
+import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
public class TinyMappingFormat extends MappingFormat<@NonNull TinyMappingsEntry> {
public TinyMappingFormat() {
@@ -20,8 +23,22 @@ public TinyMappingFormat() {
@Override
public @NonNull MappingSet read(@NonNull Path file, @NonNull TinyMappingsEntry entry) throws IOException {
+ boolean isTempFile = false;
+ if (file.getFileName().endsWith(".jar")) {
+ try (ZipFile zip = new ZipFile(file.toFile())) {
+ ZipEntry zipEntry = zip.getEntry("mappings/mappings.tiny");
+ if (zipEntry != null) {
+ file = Files.createTempFile(null, null);
+ Files.copy(zip.getInputStream(zipEntry), file);
+ isTempFile = true;
+ }
+ }
+ }
MappingSet mappings = MappingSet.create();
net.fabricmc.lorenztiny.TinyMappingFormat.DETECT.read(mappings, file, entry.from().get(), entry.to().get());
+ if (isTempFile) {
+ Files.delete(file);
+ }
return mappings;
}
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
index 71b4c7db..ef2b47a8 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
@@ -413,7 +413,8 @@ public CompletableFuture> provide(
}
}
}
- }
+ },
+ executor
));
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsContainer.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsContainer.java
index 9bd96525..8d724ed2 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsContainer.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsContainer.java
@@ -4,6 +4,7 @@
import org.checkerframework.checker.nullness.qual.Nullable;
import org.gradle.api.Action;
import org.gradle.api.DomainObjectCollection;
+import org.gradle.api.ExtensiblePolymorphicDomainObjectContainer;
import org.gradle.api.InvalidUserDataException;
import org.gradle.api.NamedDomainObjectCollectionSchema;
import org.gradle.api.NamedDomainObjectContainer;
@@ -35,7 +36,10 @@ public class MappingsContainer implements PolymorphicDomainObjectContainer delegate = project.getObjects().polymorphicDomainObjectContainer(MappingsEntry.class);
+ delegate.registerFactory(MappingsEntry.class, name -> new MappingsEntry(this.project, this.extension, name));
+ delegate.registerFactory(TinyMappingsEntry.class, name -> new TinyMappingsEntry(this.project, this.extension, name));
+ this.delegate = delegate;
}
// -- Delegating to actual implementation -- //
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
index 8f49b135..96e70c48 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
@@ -6,7 +6,6 @@
import org.gradle.api.Named;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Dependency;
-import org.gradle.api.artifacts.DependencyArtifact;
import org.gradle.api.artifacts.FileCollectionDependency;
import org.gradle.api.artifacts.ModuleDependency;
import org.gradle.api.provider.Property;
@@ -172,8 +171,12 @@ protected void computeHash(MessageDigest digest) {
if (dependencyObj != null) {
digest.update((byte) 2);
if (dependencyObj instanceof ModuleDependency) {
- for (DependencyArtifact artifact : ((ModuleDependency) dependencyObj).getArtifacts()) {
- digest.update(artifact.getUrl().getBytes(StandardCharsets.UTF_8));
+ if (dependencyObj.getGroup() != null) {
+ digest.update(dependencyObj.getGroup().getBytes(StandardCharsets.UTF_8));
+ }
+ digest.update((":" + dependencyObj.getName()).getBytes(StandardCharsets.UTF_8));
+ if (dependencyObj.getVersion() != null) {
+ digest.update((":" + dependencyObj.getVersion()).getBytes(StandardCharsets.UTF_8));
}
} else if (dependencyObj instanceof FileCollectionDependency) {
for (File file : ((FileCollectionDependency) dependencyObj).getFiles()) {
From 7c1358d6f194c0af737df0f1d60a30fb288bd51b Mon Sep 17 00:00:00 2001
From: zml
Date: Sun, 3 Oct 2021 22:06:11 -0700
Subject: [PATCH 05/15] wip: add in a sync executor to pass tasks back to the
gradle thread in a less brittle way
starts on fixing #39
---
.../internal/bundler/BundleElement.java | 1 -
.../internal/bundler/BundlerMetadata.java | 4 +-
...taMetadataSupplierAndArtifactProducer.java | 7 ++-
.../repository/MinecraftRepositoryPlugin.java | 4 +-
.../transformer/AtlasTransformers.java | 1 -
.../vanilla/repository/MinecraftResolver.java | 40 ++++++++++---
.../repository/MinecraftResolverImpl.java | 58 +++++++++++++++++--
.../vanilla/repository/MinecraftSide.java | 1 -
.../gradle/vanilla/task/DecompileJarTask.java | 15 ++---
.../gradle/vanilla/task/GenEclipseRuns.java | 2 -
10 files changed, 104 insertions(+), 29 deletions(-)
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/bundler/BundleElement.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/bundler/BundleElement.java
index fd086892..3540a90d 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/bundler/BundleElement.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/bundler/BundleElement.java
@@ -25,7 +25,6 @@
package org.spongepowered.gradle.vanilla.internal.bundler;
import org.immutables.value.Value;
-import org.spongepowered.gradle.vanilla.internal.model.GroupArtifactVersion;
/**
* A single entry in a bundle.
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/bundler/BundlerMetadata.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/bundler/BundlerMetadata.java
index 8e82d34a..3cfc2571 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/bundler/BundlerMetadata.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/bundler/BundlerMetadata.java
@@ -59,10 +59,12 @@ public abstract class BundlerMetadata {
/**
* Attempt to read bundler metadata from a jar.
*
- * If the jar is not a Minecraft bundler jar, an empty {@link Optional} will be returned.
+ * If the jar is not a Minecraft bundler jar, an empty {@link Optional} will
+ * be returned.
*
* @param jar the jar to read
* @return parsed metadata
+ * @throws IOException if an error occurs while trying to read from the jar
*/
public static Optional read(final Path jar) throws IOException {
try (final JarFile file = new JarFile(jar)) {
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/LauncherMetaMetadataSupplierAndArtifactProducer.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/LauncherMetaMetadataSupplierAndArtifactProducer.java
index 2eff7ce9..5f23fc57 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/LauncherMetaMetadataSupplierAndArtifactProducer.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/LauncherMetaMetadataSupplierAndArtifactProducer.java
@@ -38,6 +38,7 @@
import org.spongepowered.gradle.vanilla.resolver.ResolutionResult;
import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import javax.inject.Inject;
@@ -74,8 +75,10 @@ public void execute(final ComponentMetadataSupplierDetails details) {
final MinecraftResolver resolver = providerService.resolver();
// Request the appropriate jar, block until it's provided
// TODO: maybe validate that the state keys of the provided modifiers actually match the artifact ID?
- final ResolutionResult
- resolution = resolver.provide(platform.get(), version, providerService.peekModifiers()).get();
+ final CompletableFuture> resolutionFuture = resolver
+ .provide(platform.get(), version, providerService.peekModifiers());
+
+ final ResolutionResult resolution = resolver.processSyncTasksUntilComplete(resolutionFuture);
if (!resolution.isPresent()) {
return;
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftRepositoryPlugin.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftRepositoryPlugin.java
index 2d82ac4a..f2af3a71 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftRepositoryPlugin.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftRepositoryPlugin.java
@@ -42,8 +42,8 @@
import org.gradle.api.plugins.ExtensionAware;
import org.gradle.api.provider.Provider;
import org.gradle.build.event.BuildEventsListenerRegistry;
-import org.spongepowered.gradle.vanilla.internal.Constants;
import org.spongepowered.gradle.vanilla.MinecraftExtension;
+import org.spongepowered.gradle.vanilla.internal.Constants;
import org.spongepowered.gradle.vanilla.internal.MinecraftExtensionImpl;
import org.spongepowered.gradle.vanilla.internal.model.VersionClassifier;
import org.spongepowered.gradle.vanilla.internal.repository.modifier.ArtifactModifier;
@@ -184,7 +184,7 @@ private void configureResolutionStrategy(
// If we do have a version, try to resolve that fixed version
if (version != null) {
try {
- resolver.provide(platform.get(), version, providerService.peekModifiers()).get();
+ resolver.processSyncTasksUntilComplete(resolver.provide(platform.get(), version, providerService.peekModifiers()));
} catch (final InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (final ExecutionException ex) {
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/transformer/AtlasTransformers.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/transformer/AtlasTransformers.java
index 5693dfdc..9ee5ee6a 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/transformer/AtlasTransformers.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/transformer/AtlasTransformers.java
@@ -28,7 +28,6 @@
import org.cadixdev.bombe.asm.jar.JarEntryRemappingTransformer;
import org.cadixdev.bombe.jar.JarEntryTransformer;
import org.cadixdev.lorenz.MappingSet;
-import org.cadixdev.lorenz.asm.LorenzRemapper;
import org.spongepowered.gradle.vanilla.internal.asm.EnhancedClassRemapper;
import org.spongepowered.gradle.vanilla.internal.asm.EnhancedRemapper;
import org.spongepowered.gradle.vanilla.internal.asm.LocalVariableNamingClassVisitor;
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolver.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolver.java
index b872824d..3a9f4f3c 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolver.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolver.java
@@ -27,16 +27,17 @@
import org.spongepowered.gradle.vanilla.internal.model.GroupArtifactVersion;
import org.spongepowered.gradle.vanilla.internal.model.VersionDescriptor;
import org.spongepowered.gradle.vanilla.internal.model.VersionManifestRepository;
-import org.spongepowered.gradle.vanilla.resolver.Downloader;
import org.spongepowered.gradle.vanilla.internal.repository.ResolvableTool;
import org.spongepowered.gradle.vanilla.internal.repository.modifier.ArtifactModifier;
import org.spongepowered.gradle.vanilla.internal.repository.modifier.AssociatedResolutionFlags;
+import org.spongepowered.gradle.vanilla.resolver.Downloader;
import org.spongepowered.gradle.vanilla.resolver.ResolutionResult;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
@@ -96,7 +97,21 @@ public interface MinecraftResolver {
* environment and a target path
* @return a future returning the result of resolving a jar path
*/
- CompletableFuture> produceAssociatedArtifactSync(final MinecraftPlatform side, final String version, final Set modifiers, final String id, final Set flags, final BiConsumer action);
+ CompletableFuture> produceAssociatedArtifactSync(
+ final MinecraftPlatform side, final String version, final Set modifiers, final String id,
+ final Set flags, final BiConsumer action
+ );
+
+ /**
+ * Block on the completion of a provided future, processing "sync" tasks while
+ * that occurs.
+ *
+ * @param the return value type
+ * @param future the future to await
+ * @return the result of the future
+ * @throws ExecutionException if the task execution fails
+ */
+ T processSyncTasksUntilComplete(CompletableFuture future) throws ExecutionException, InterruptedException;
interface MinecraftEnvironment {
@@ -162,13 +177,22 @@ interface Context {
Executor executor();
/**
- * Return a child classloader with a tool and its dependencies on the
- * classpath, as well as the VanillaGradle jar.
+ * An executor for performing main-thread synchronous operations, like some
+ * dependency resolution.
+ *
+ * @return the synchronous executor
+ */
+ Executor syncExecutor();
+
+ /**
+ * Return a child classloader with a tool and its dependencies on the classpath,
+ * as well as the VanillaGradle jar.
*
- * This is a very fragile arrangement but it allows some dependencies
- * to be overridden at runtime. Classes from Gradle, VanillaGradle's
- * dependencies, and the JDK can be safely shared, but VanillaGradle
- * classes CAN NOT.
+ * This is a very fragile arrangement but it allows some dependencies to be
+ * overridden at runtime. Classes from Gradle, VanillaGradle's dependencies, and
+ * the JDK can be safely shared, but VanillaGradle classes CAN NOT.
+ *
+ * This must be run on the {@link #syncExecutor()}.
*
* @param tool the tool to resolve
* @return a class loader with the tool on the classpath
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
index 2acc322f..ba372172 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
@@ -42,17 +42,17 @@
import org.spongepowered.gradle.vanilla.internal.model.GroupArtifactVersion;
import org.spongepowered.gradle.vanilla.internal.model.VersionDescriptor;
import org.spongepowered.gradle.vanilla.internal.model.VersionManifestRepository;
-import org.spongepowered.gradle.vanilla.internal.util.FunctionalUtils;
-import org.spongepowered.gradle.vanilla.resolver.Downloader;
-import org.spongepowered.gradle.vanilla.resolver.HashAlgorithm;
import org.spongepowered.gradle.vanilla.internal.repository.IvyModuleWriter;
import org.spongepowered.gradle.vanilla.internal.repository.ResolvableTool;
import org.spongepowered.gradle.vanilla.internal.repository.modifier.ArtifactModifier;
import org.spongepowered.gradle.vanilla.internal.repository.modifier.AssociatedResolutionFlags;
-import org.spongepowered.gradle.vanilla.internal.transformer.AtlasTransformers;
import org.spongepowered.gradle.vanilla.internal.resolver.AsyncUtils;
import org.spongepowered.gradle.vanilla.internal.resolver.FileUtils;
+import org.spongepowered.gradle.vanilla.internal.transformer.AtlasTransformers;
+import org.spongepowered.gradle.vanilla.internal.util.FunctionalUtils;
import org.spongepowered.gradle.vanilla.internal.util.SelfPreferringClassLoader;
+import org.spongepowered.gradle.vanilla.resolver.Downloader;
+import org.spongepowered.gradle.vanilla.resolver.HashAlgorithm;
import org.spongepowered.gradle.vanilla.resolver.ResolutionResult;
import java.io.IOException;
@@ -71,6 +71,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ConcurrentHashMap;
@@ -78,6 +79,7 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.SynchronousQueue;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -95,6 +97,8 @@ public class MinecraftResolverImpl implements MinecraftResolver, MinecraftResolv
private final ConcurrentMap>> artifacts = new ConcurrentHashMap<>();
private final ConcurrentMap>> associatedArtifacts = new ConcurrentHashMap<>();
private final boolean forceRefresh;
+ private final BlockingQueue syncTasks = new SynchronousQueue<>();
+ private final Executor syncExecutor = run -> this.syncTasks.add(run);
public MinecraftResolverImpl(
final VersionManifestRepository manifests,
@@ -127,6 +131,11 @@ public Executor executor() {
return this.executor;
}
+ @Override
+ public Executor syncExecutor() {
+ return this.syncExecutor;
+ }
+
@Override
public Supplier classLoaderWithTool(final ResolvableTool tool) {
final @Nullable Function toolResolver = this.toolResolver;
@@ -520,6 +529,32 @@ public CompletableFuture> produceAssociatedArtifactSync(
return ourResult;
}
+ @Override
+ public T processSyncTasksUntilComplete(CompletableFuture future) throws InterruptedException, ExecutionException {
+ future.handle((res, err) -> {
+ this.syncTasks.add(new CompleteEvaluation(future));
+ return res;
+ });
+
+ Runnable action;
+ for (;;) {
+ action = this.syncTasks.take();
+
+ // todo: rethrow exceptions with an ExecutionException
+ if (action instanceof CompleteEvaluation && ((CompleteEvaluation) action).completed == future) {
+ break;
+ }
+
+ try {
+ action.run();
+ } catch (final Exception ex) {
+ MinecraftResolverImpl.LOGGER.error("Failed to execute synchronous task {} while resolving {}", action, future, ex);
+ }
+ }
+
+ return future.get();
+ }
+
private String sharedArtifactFileName(
final String artifactId,
final String version,
@@ -668,4 +703,19 @@ public VersionDescriptor.Full metadata() {
}
+ static final class CompleteEvaluation implements Runnable {
+
+ final CompletableFuture> completed;
+
+ CompleteEvaluation(final CompletableFuture> completed) {
+ this.completed = completed;
+ }
+
+ @Override
+ public void run() {
+ // no-op
+ }
+
+ }
+
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftSide.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftSide.java
index b43ff0fc..d6ba6856 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftSide.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftSide.java
@@ -26,7 +26,6 @@
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.gradle.vanilla.internal.Constants;
-import org.spongepowered.gradle.vanilla.internal.bundler.BundleElement;
import org.spongepowered.gradle.vanilla.internal.bundler.BundlerMetadata;
import org.spongepowered.gradle.vanilla.internal.model.DownloadClassifier;
import org.spongepowered.gradle.vanilla.internal.model.GroupArtifactVersion;
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/DecompileJarTask.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/DecompileJarTask.java
index 227e7db2..3afa0787 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/DecompileJarTask.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/DecompileJarTask.java
@@ -43,15 +43,15 @@
import org.gradle.internal.component.external.model.ModuleComponentArtifactIdentifier;
import org.gradle.jvm.toolchain.JavaLauncher;
import org.gradle.workers.WorkerExecutor;
-import org.spongepowered.gradle.vanilla.internal.Constants;
import org.spongepowered.gradle.vanilla.MinecraftExtension;
+import org.spongepowered.gradle.vanilla.internal.Constants;
import org.spongepowered.gradle.vanilla.internal.MinecraftExtensionImpl;
-import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
import org.spongepowered.gradle.vanilla.internal.repository.MinecraftProviderService;
-import org.spongepowered.gradle.vanilla.resolver.ResolutionResult;
import org.spongepowered.gradle.vanilla.internal.repository.modifier.ArtifactModifier;
import org.spongepowered.gradle.vanilla.internal.repository.modifier.AssociatedResolutionFlags;
import org.spongepowered.gradle.vanilla.internal.worker.JarDecompileWorker;
+import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
+import org.spongepowered.gradle.vanilla.resolver.ResolutionResult;
import java.io.File;
import java.lang.management.ManagementFactory;
@@ -185,12 +185,9 @@ public void execute() {
this.getWorkerExecutor().await();
}
);
- } finally {
- DecompileJarTask.DECOMPILE_LOCK.unlock();
- }
try {
- final ResolutionResult result = resultFuture.get();
+ final ResolutionResult result = minecraftProvider.resolver().processSyncTasksUntilComplete(resultFuture);
this.setDidWork(!result.upToDate());
} catch (final ExecutionException ex) {
throw new GradleException("Failed to decompile " + this.getMinecraftVersion().get(), ex.getCause());
@@ -198,6 +195,10 @@ public void execute() {
Thread.currentThread().interrupt();
throw new GradleException("Interrupted");
}
+
+ } finally {
+ DecompileJarTask.DECOMPILE_LOCK.unlock();
+ }
}
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/GenEclipseRuns.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/GenEclipseRuns.java
index 3aa8b8cc..a5a4aae7 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/GenEclipseRuns.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/GenEclipseRuns.java
@@ -25,7 +25,6 @@
package org.spongepowered.gradle.vanilla.task;
import org.gradle.api.DefaultTask;
-import org.gradle.api.InvalidUserDataException;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.SetProperty;
@@ -37,7 +36,6 @@
import org.spongepowered.gradle.vanilla.internal.runs.EclipseRunConfigurationWriter;
import org.spongepowered.gradle.vanilla.runs.RunConfiguration;
-import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
From 52a783a7b49419562209c74e28ef68feaec62201 Mon Sep 17 00:00:00 2001
From: Joe
Date: Tue, 5 Oct 2021 01:05:48 +0100
Subject: [PATCH 06/15] Working tiny mappings reader
---
gradle.properties | 3 ++
subprojects/gradle-plugin/build.gradle.kts | 24 +++++++++---
.../gradle/vanilla/internal/Constants.java | 3 ++
.../repository/MinecraftRepositoryPlugin.java | 10 ++++-
.../internal/repository/ResolvableTool.java | 37 ++++++++++++++++---
.../mappings/ProGuardMappingFormat.java | 4 +-
.../mappings/TinyMappingFormat.java | 31 +++++++++++++---
.../repository/mappings/MappingFormat.java | 3 +-
.../repository/mappings/MappingsEntry.java | 7 +++-
.../vanilla/internal/BuildVersions.java | 4 +-
.../repository/mappings/TinyReaderImpl.java | 13 +++++++
11 files changed, 116 insertions(+), 23 deletions(-)
create mode 100644 subprojects/gradle-plugin/src/remapTiny/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyReaderImpl.java
diff --git a/gradle.properties b/gradle.properties
index 7584e303..72d6a561 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -9,6 +9,9 @@ checkerVersion=3.15.0
forgeFlowerVersion=1.5.498.12
junitVersion=5.7.2
mergeToolVersion=1.1.4
+lorenzVersion=0.5.7
+lorenzTinyVersion=4.0.2
+mappingIoVersion=0.2.1
org.gradle.parallel=true
kotlin.stdlib.default.dependency=false
diff --git a/subprojects/gradle-plugin/build.gradle.kts b/subprojects/gradle-plugin/build.gradle.kts
index 5483283d..baae3bbf 100644
--- a/subprojects/gradle-plugin/build.gradle.kts
+++ b/subprojects/gradle-plugin/build.gradle.kts
@@ -20,6 +20,9 @@ val jarDecompile by sourceSets.creating {
val accessWiden by sourceSets.creating {
configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
}
+val remapTiny by sourceSets.creating {
+ configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
+}
val shadow by sourceSets.creating {
configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
}
@@ -33,6 +36,9 @@ val asmVersion: String by project
val forgeFlowerVersion: String by project
val junitVersion: String by project
val mergeToolVersion: String by project
+val lorenzVersion: String by project
+val lorenzTinyVersion: String by project
+val mappingIoVersion: String by project
dependencies {
// All source sets
commonDeps(gradleApi())
@@ -45,15 +51,12 @@ dependencies {
// Just main
implementation("com.google.code.gson:gson:2.8.7")
- implementation("org.cadixdev:lorenz:0.5.7")
- implementation("org.cadixdev:lorenz-asm:0.5.7") {
+ implementation("org.cadixdev:lorenz:$lorenzVersion")
+ implementation("org.cadixdev:lorenz-asm:$lorenzVersion") {
exclude("org.ow2.asm") // Use our own ASM
}
implementation("org.cadixdev:lorenz-io-proguard:0.5.7")
- compileOnly("net.fabricmc:lorenz-tiny:4.0.2") {
- isTransitive = false
- }
compileOnlyApi("org.checkerframework:checker-qual:3.15.0")
annotationProcessor("org.immutables:value:2.8.8")
@@ -82,6 +85,12 @@ dependencies {
}
implementation(accessWiden.output)
+ "remapTinyCompileOnly"("org.cadixdev:lorenz:$lorenzVersion")
+ "remapTinyCompileOnly"("net.fabricmc:lorenz-tiny:$lorenzTinyVersion") {
+ isTransitive = false
+ }
+ implementation(remapTiny.output)
+
"shadowCompileOnly"("com.github.jengelman.gradle.plugins:shadow:6.1.0")
implementation(shadow.output)
@@ -101,7 +110,9 @@ tasks {
"asmVersion" to asmVersion,
"forgeFlowerVersion" to forgeFlowerVersion,
"mergeToolVersion" to mergeToolVersion,
- "accessWidenerVersion" to accessWidenerVersion
+ "accessWidenerVersion" to accessWidenerVersion,
+ "lorenzTinyVersion" to lorenzTinyVersion,
+ "mappingIoVersion" to mappingIoVersion
)
inputs.properties(properties)
@@ -128,6 +139,7 @@ tasks {
from(jarMerge.output)
from(jarDecompile.output)
from(accessWiden.output)
+ from(remapTiny.output)
from(shadow.output)
}
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/Constants.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/Constants.java
index 82a9c246..acfc6ff3 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/Constants.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/Constants.java
@@ -103,6 +103,8 @@ public static final class WorkerDependencies {
public static final String MERGE_TOOL = "net.minecraftforge:mergetool:" + BuildVersions.MERGE_TOOL;
public static final String ACCESS_WIDENER = "net.fabricmc:access-widener:" + BuildVersions.ACCESS_WIDENER;
public static final String FORGE_FLOWER = "net.minecraftforge:forgeflower:" + BuildVersions.FORGEFLOWER;
+ public static final String LORENZ_TINY = "net.fabricmc:lorenz-tiny:" + BuildVersions.LORENZ_TINY_VERSION;
+ public static final String MAPPING_IO = "net.fabricmc:mapping-io:" + BuildVersions.MAPPING_IO_VERSION;
public static final String FORCED_ASM = BuildVersions.ASM;
public static final String ASM_UTIL = "org.ow2.asm:asm-util:" + WorkerDependencies.FORCED_ASM;
@@ -135,6 +137,7 @@ public static final class Configurations {
public static final String MINECRAFT_NATIVES = "minecraftNatives";
public static final String MERGETOOL = "mergetool";
public static final String ACCESS_WIDENER = "accessWidener";
+ public static final String REMAP_TINY = "remapTiny";
public static final String FORGE_FLOWER = "forgeFlower";
public static final String CLASS_DUMP = "classDump";
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftRepositoryPlugin.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftRepositoryPlugin.java
index f2af3a71..5697384f 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftRepositoryPlugin.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftRepositoryPlugin.java
@@ -30,6 +30,8 @@
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
+import org.gradle.api.artifacts.Dependency;
+import org.gradle.api.artifacts.ModuleDependency;
import org.gradle.api.artifacts.ModuleVersionSelector;
import org.gradle.api.artifacts.ResolutionStrategy;
import org.gradle.api.artifacts.ResolvableDependencies;
@@ -122,7 +124,13 @@ private void applyToProject(final Project project) {
for (final ResolvableTool tool : ResolvableTool.values()) {
project.getConfigurations().register(tool.id(), config -> {
config.defaultDependencies(deps -> {
- deps.add(project.getDependencies().create(tool.notation()));
+ for (ResolvableTool.Dependency dependency : tool.dependencies()) {
+ Dependency dep = project.getDependencies().create(dependency.notation());
+ if (!dependency.isTransitive() && dep instanceof ModuleDependency) {
+ ((ModuleDependency) dep).setTransitive(false);
+ }
+ deps.add(dep);
+ }
});
ConfigurationUtils.markAsJavaRuntime(project.getObjects(), config);
});
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java
index 6f74414a..148a87bc 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java
@@ -26,27 +26,52 @@
import org.spongepowered.gradle.vanilla.internal.Constants;
+import java.util.Arrays;
+
/**
* Tools used for specific operations in the Minecraft preparation pipeline.
*/
public enum ResolvableTool {
JAR_MERGE(Constants.Configurations.MERGETOOL, Constants.WorkerDependencies.MERGE_TOOL),
- ACCESS_WIDENER(Constants.Configurations.ACCESS_WIDENER, Constants.WorkerDependencies.ACCESS_WIDENER)
+ ACCESS_WIDENER(Constants.Configurations.ACCESS_WIDENER, Constants.WorkerDependencies.ACCESS_WIDENER),
+ REMAP_TINY(Constants.Configurations.REMAP_TINY, new Dependency(Constants.WorkerDependencies.LORENZ_TINY, false), new Dependency(Constants.WorkerDependencies.MAPPING_IO, true)),
;
private final String id;
- private final String notation;
+ private final Dependency[] dependencies;
+
+ ResolvableTool(final String id, final String... notations) {
+ this(id, Arrays.stream(notations).map(notation -> new Dependency(notation, true)).toArray(Dependency[]::new));
+ }
- ResolvableTool(final String id, final String notation) {
+ ResolvableTool(final String id, final Dependency... dependencies) {
this.id = id;
- this.notation = notation;
+ this.dependencies = dependencies;
}
public String id() {
return this.id;
}
- public String notation() {
- return this.notation;
+ public Dependency[] dependencies() {
+ return this.dependencies;
+ }
+
+ public static class Dependency {
+ private final String notation;
+ private final boolean isTransitive;
+
+ public Dependency(final String notation, final boolean isTransitive) {
+ this.notation = notation;
+ this.isTransitive = isTransitive;
+ }
+
+ public String notation() {
+ return notation;
+ }
+
+ public boolean isTransitive() {
+ return isTransitive;
+ }
}
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingFormat.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingFormat.java
index 3dcec10b..156e516d 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingFormat.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ProGuardMappingFormat.java
@@ -3,6 +3,7 @@
import org.cadixdev.lorenz.MappingSet;
import org.cadixdev.lorenz.io.proguard.ProGuardReader;
import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
@@ -23,7 +24,8 @@ public ProGuardMappingFormat() {
}
@Override
- public @NonNull MappingSet read(final @NonNull Path file, final @NonNull MappingsEntry entry) throws IOException {
+ public @NonNull MappingSet read(final @NonNull Path file, final @NonNull MappingsEntry entry,
+ MinecraftResolver.Context context) throws IOException {
final MappingSet scratchMappings = MappingSet.create();
try (ProGuardReader proguard = new ProGuardReader(Files.newBufferedReader(file))) {
proguard.read(scratchMappings);
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java
index 960c6de4..d93db900 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyMappingFormat.java
@@ -2,12 +2,18 @@
import org.cadixdev.lorenz.MappingSet;
import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.gradle.vanilla.internal.repository.ResolvableTool;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
import org.spongepowered.gradle.vanilla.repository.mappings.TinyMappingsEntry;
import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.concurrent.CompletableFuture;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -22,20 +28,35 @@ public TinyMappingFormat() {
}
@Override
- public @NonNull MappingSet read(@NonNull Path file, @NonNull TinyMappingsEntry entry) throws IOException {
+ public @NonNull MappingSet read(
+ @NonNull Path file,
+ @NonNull TinyMappingsEntry entry,
+ MinecraftResolver.@NonNull Context context
+ ) throws IOException {
boolean isTempFile = false;
- if (file.getFileName().endsWith(".jar")) {
+ if (file.toString().endsWith(".jar")) {
try (ZipFile zip = new ZipFile(file.toFile())) {
ZipEntry zipEntry = zip.getEntry("mappings/mappings.tiny");
if (zipEntry != null) {
- file = Files.createTempFile(null, null);
- Files.copy(zip.getInputStream(zipEntry), file);
+ file = Files.createTempFile(file.getFileName().toString(), "mappings");
+ Files.copy(zip.getInputStream(zipEntry), file, StandardCopyOption.REPLACE_EXISTING);
isTempFile = true;
}
}
}
MappingSet mappings = MappingSet.create();
- net.fabricmc.lorenztiny.TinyMappingFormat.DETECT.read(mappings, file, entry.from().get(), entry.to().get());
+ URLClassLoader classLoader = CompletableFuture.supplyAsync(() -> context.classLoaderWithTool(ResolvableTool.REMAP_TINY).get(), context.syncExecutor()).join();
+ try {
+ Class> readerClass = Class.forName(
+ "org.spongepowered.gradle.vanilla.internal.repository.mappings.TinyReaderImpl",
+ true,
+ classLoader
+ );
+ Method readMethod = readerClass.getMethod("read", MappingSet.class, Path.class, String.class, String.class);
+ readMethod.invoke(null, mappings, file, entry.from().get(), entry.to().get());
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
if (isTempFile) {
Files.delete(file);
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingFormat.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingFormat.java
index d0656b99..ea9ee024 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingFormat.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingFormat.java
@@ -3,6 +3,7 @@
import org.cadixdev.lorenz.MappingSet;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.gradle.api.Named;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
import java.io.IOException;
import java.nio.file.Path;
@@ -18,7 +19,7 @@ public Class entryType() {
return entryType;
}
- public abstract MappingSet read(final Path file, final T entry) throws IOException;
+ public abstract MappingSet read(final Path file, final T entry, MinecraftResolver.Context context) throws IOException;
@Override
public int hashCode() {
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
index 96e70c48..5016e11c 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
@@ -5,6 +5,7 @@
import org.checkerframework.checker.nullness.qual.Nullable;
import org.gradle.api.Named;
import org.gradle.api.Project;
+import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.artifacts.FileCollectionDependency;
import org.gradle.api.artifacts.ModuleDependency;
@@ -25,6 +26,7 @@
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
public class MappingsEntry implements Named {
protected final Project project;
@@ -149,12 +151,13 @@ protected MappingSet doResolve(
if (!mappingFormat.entryType().isInstance(this)) {
throw new IllegalStateException("Mappings entry \"" + getName() + "\" of type \"" + getClass().getName() + "\" is not compatible with mapping format \"" + format.get() + "\"");
}
- Set resolvedFiles = project.getConfigurations().getByName(configurationName).resolve();
+ Configuration configuration = project.getConfigurations().getByName(configurationName);
+ Set resolvedFiles = CompletableFuture.supplyAsync(configuration::resolve, context.syncExecutor()).join();
if (resolvedFiles.size() != 1) {
throw new IllegalStateException("Mappings entry \"" + getName() + "\" did not resolve to exactly 1 file");
}
Path resolvedFile = resolvedFiles.iterator().next().toPath();
- return mappingFormat.read(resolvedFile, mappingFormat.entryType().cast(this));
+ return mappingFormat.read(resolvedFile, mappingFormat.entryType().cast(this), context);
}
public String computeStateKey() {
diff --git a/subprojects/gradle-plugin/src/main/templates/org/spongepowered/gradle/vanilla/internal/BuildVersions.java b/subprojects/gradle-plugin/src/main/templates/org/spongepowered/gradle/vanilla/internal/BuildVersions.java
index 3b6172a9..4cef0abf 100644
--- a/subprojects/gradle-plugin/src/main/templates/org/spongepowered/gradle/vanilla/internal/BuildVersions.java
+++ b/subprojects/gradle-plugin/src/main/templates/org/spongepowered/gradle/vanilla/internal/BuildVersions.java
@@ -36,5 +36,7 @@ private BuildVersions() {
public static final String FORGEFLOWER = "${forgeFlowerVersion}";
public static final String MERGE_TOOL = "${mergeToolVersion}";
public static final String ACCESS_WIDENER = "${accessWidenerVersion}";
+ public static final String LORENZ_TINY_VERSION = "${lorenzTinyVersion}";
+ public static final String MAPPING_IO_VERSION = "${mappingIoVersion}";
-}
\ No newline at end of file
+}
diff --git a/subprojects/gradle-plugin/src/remapTiny/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyReaderImpl.java b/subprojects/gradle-plugin/src/remapTiny/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyReaderImpl.java
new file mode 100644
index 00000000..0b6e07d4
--- /dev/null
+++ b/subprojects/gradle-plugin/src/remapTiny/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TinyReaderImpl.java
@@ -0,0 +1,13 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import net.fabricmc.lorenztiny.TinyMappingFormat;
+import org.cadixdev.lorenz.MappingSet;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public class TinyReaderImpl {
+ public static void read(MappingSet mappings, Path file, String from, String to) throws IOException {
+ TinyMappingFormat.DETECT.read(mappings, file, from, to);
+ }
+}
From 4bab920b36af09c4b65ef0c86b5eac08c98bcb9b Mon Sep 17 00:00:00 2001
From: Joe
Date: Tue, 5 Oct 2021 15:27:07 +0100
Subject: [PATCH 07/15] Parchment mappings format
---
gradle.properties | 2 +
subprojects/gradle-plugin/build.gradle.kts | 24 ++++++-
.../gradle/vanilla/internal/Constants.java | 7 +-
.../internal/MinecraftExtensionImpl.java | 2 +
.../repository/MinecraftProviderService.java | 26 ++++++-
.../internal/repository/ResolvableTool.java | 47 +++++++++++--
.../mappings/ParchmentMappingFormat.java | 65 +++++++++++++++++
.../vanilla/internal/BuildVersions.java | 5 +-
.../mappings/ParchmentReaderImpl.java | 70 +++++++++++++++++++
9 files changed, 236 insertions(+), 12 deletions(-)
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ParchmentMappingFormat.java
create mode 100644 subprojects/gradle-plugin/src/remapParchment/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ParchmentReaderImpl.java
diff --git a/gradle.properties b/gradle.properties
index 72d6a561..1404826b 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -3,6 +3,7 @@ url=https://www.spongepowered.org
organization=SpongePowered
projectUrl=https://www.spongepowered.org
+gsonVersion=2.8.7
accessWidenerVersion=1.0.2
asmVersion=9.2
checkerVersion=3.15.0
@@ -12,6 +13,7 @@ mergeToolVersion=1.1.4
lorenzVersion=0.5.7
lorenzTinyVersion=4.0.2
mappingIoVersion=0.2.1
+featherVersion=0.6.5.3-dev-SNAPSHOT
org.gradle.parallel=true
kotlin.stdlib.default.dependency=false
diff --git a/subprojects/gradle-plugin/build.gradle.kts b/subprojects/gradle-plugin/build.gradle.kts
index baae3bbf..49b5ece2 100644
--- a/subprojects/gradle-plugin/build.gradle.kts
+++ b/subprojects/gradle-plugin/build.gradle.kts
@@ -23,6 +23,9 @@ val accessWiden by sourceSets.creating {
val remapTiny by sourceSets.creating {
configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
}
+val remapParchment by sourceSets.creating {
+ configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
+}
val shadow by sourceSets.creating {
configurations.named(this.implementationConfigurationName) { extendsFrom(commonDeps) }
}
@@ -31,6 +34,7 @@ configurations {
api { extendsFrom(commonDeps) }
}
+val gsonVersion: String by project
val accessWidenerVersion: String by project
val asmVersion: String by project
val forgeFlowerVersion: String by project
@@ -39,6 +43,14 @@ val mergeToolVersion: String by project
val lorenzVersion: String by project
val lorenzTinyVersion: String by project
val mappingIoVersion: String by project
+val featherVersion: String by project
+
+repositories {
+ maven("https://maven.parchmentmc.org/") {
+ name = "ParchmentMC"
+ }
+}
+
dependencies {
// All source sets
commonDeps(gradleApi())
@@ -50,7 +62,7 @@ dependencies {
}
// Just main
- implementation("com.google.code.gson:gson:2.8.7")
+ implementation("com.google.code.gson:gson:$gsonVersion")
implementation("org.cadixdev:lorenz:$lorenzVersion")
implementation("org.cadixdev:lorenz-asm:$lorenzVersion") {
exclude("org.ow2.asm") // Use our own ASM
@@ -91,6 +103,12 @@ dependencies {
}
implementation(remapTiny.output)
+ "remapParchmentCompileOnly"("org.cadixdev:lorenz:$lorenzVersion")
+ "remapParchmentCompileOnly"("com.google.code.gson:gson:$gsonVersion")
+ "remapParchmentCompileOnly"("org.parchmentmc:feather:$featherVersion")
+ "remapParchmentCompileOnly"("org.parchmentmc.feather:io-gson:$featherVersion")
+ implementation(remapParchment.output)
+
"shadowCompileOnly"("com.github.jengelman.gradle.plugins:shadow:6.1.0")
implementation(shadow.output)
@@ -112,7 +130,8 @@ tasks {
"mergeToolVersion" to mergeToolVersion,
"accessWidenerVersion" to accessWidenerVersion,
"lorenzTinyVersion" to lorenzTinyVersion,
- "mappingIoVersion" to mappingIoVersion
+ "mappingIoVersion" to mappingIoVersion,
+ "featherVersion" to featherVersion
)
inputs.properties(properties)
@@ -140,6 +159,7 @@ tasks {
from(jarDecompile.output)
from(accessWiden.output)
from(remapTiny.output)
+ from(remapParchment.output)
from(shadow.output)
}
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/Constants.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/Constants.java
index acfc6ff3..267789ca 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/Constants.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/Constants.java
@@ -103,8 +103,10 @@ public static final class WorkerDependencies {
public static final String MERGE_TOOL = "net.minecraftforge:mergetool:" + BuildVersions.MERGE_TOOL;
public static final String ACCESS_WIDENER = "net.fabricmc:access-widener:" + BuildVersions.ACCESS_WIDENER;
public static final String FORGE_FLOWER = "net.minecraftforge:forgeflower:" + BuildVersions.FORGEFLOWER;
- public static final String LORENZ_TINY = "net.fabricmc:lorenz-tiny:" + BuildVersions.LORENZ_TINY_VERSION;
- public static final String MAPPING_IO = "net.fabricmc:mapping-io:" + BuildVersions.MAPPING_IO_VERSION;
+ public static final String LORENZ_TINY = "net.fabricmc:lorenz-tiny:" + BuildVersions.LORENZ_TINY;
+ public static final String MAPPING_IO = "net.fabricmc:mapping-io:" + BuildVersions.MAPPING_IO;
+ public static final String FEATHER = "org.parchmentmc:feather:" + BuildVersions.FEATHER;
+ public static final String FEATHER_IO_GSON = "org.parchmentmc.feather:io-gson:" + BuildVersions.FEATHER;
public static final String FORCED_ASM = BuildVersions.ASM;
public static final String ASM_UTIL = "org.ow2.asm:asm-util:" + WorkerDependencies.FORCED_ASM;
@@ -138,6 +140,7 @@ public static final class Configurations {
public static final String MERGETOOL = "mergetool";
public static final String ACCESS_WIDENER = "accessWidener";
public static final String REMAP_TINY = "remapTiny";
+ public static final String REMAP_PARCHMENT = "remapParchment";
public static final String FORGE_FLOWER = "forgeFlower";
public static final String CLASS_DUMP = "classDump";
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
index b916e0cc..5c4c4b89 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
@@ -43,6 +43,7 @@
import org.spongepowered.gradle.vanilla.internal.model.VersionClassifier;
import org.spongepowered.gradle.vanilla.internal.model.VersionDescriptor;
import org.spongepowered.gradle.vanilla.internal.repository.mappings.OfficialMappingsEntry;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.ParchmentMappingFormat;
import org.spongepowered.gradle.vanilla.internal.repository.mappings.ProGuardMappingFormat;
import org.spongepowered.gradle.vanilla.internal.repository.mappings.TinyMappingFormat;
import org.spongepowered.gradle.vanilla.internal.repository.modifier.MappingsModifier;
@@ -109,6 +110,7 @@ public MinecraftExtensionImpl(final Gradle gradle, final ObjectFactory factory,
this.mappingFormats.add(new ProGuardMappingFormat());
this.mappingFormats.add(new TinyMappingFormat());
+ this.mappingFormats.add(new ParchmentMappingFormat());
this.mappings.add(new OfficialMappingsEntry(project, this));
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftProviderService.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftProviderService.java
index 90629a62..dcac9a9d 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftProviderService.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/MinecraftProviderService.java
@@ -29,6 +29,7 @@
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.artifacts.ConfigurationContainer;
+import org.gradle.api.artifacts.ResolveException;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.services.BuildService;
@@ -45,14 +46,19 @@
import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
import org.spongepowered.gradle.vanilla.repository.MinecraftResolverImpl;
+import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
+import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
public abstract class MinecraftProviderService implements
BuildService,
@@ -99,6 +105,7 @@ public void onFinish(final FinishEvent finishEvent) {
*/
public void primeResolver(final Project project, final List modifiers) {
final ResolverState state = this.activeState.get();
+ state.logger = project.getLogger();
state.configurationSource = project.getConfigurations();
state.modifiers = modifiers;
}
@@ -169,7 +176,23 @@ private URL[] resolveTool(final ResolvableTool tool) {
if (configurations == null) {
throw new IllegalArgumentException("Tried to perform a configuration resolution outside of a project-managed context!");
}
- return configurations.getByName(tool.id()).resolve().stream()
+ Set resolvedFiles;
+ try {
+ resolvedFiles = configurations.getByName(tool.id()).resolve();
+ } catch (ResolveException e) {
+ String repoHelpStr = Arrays.stream(tool.dependencies())
+ .map(ResolvableTool.Dependency::repo)
+ .filter(Objects::nonNull)
+ .distinct()
+ .map(ResolvableTool.Repository::url)
+ .collect(Collectors.joining(", "));
+ if (!repoHelpStr.isEmpty()) {
+ String helpStr = String.format("Help: this tool requires the following repositories to be declared in the repositories {} block: %s", repoHelpStr);
+ throw new ResolvableTool.MissingToolException(helpStr, e);
+ }
+ throw new ResolvableTool.MissingToolException(e.toString(), e);
+ }
+ return resolvedFiles.stream()
.map(file -> {
try {
return file.toURI().toURL();
@@ -221,6 +244,7 @@ public void close() throws IOException {
static final class ResolverState {
+ org.gradle.api.logging.@MonotonicNonNull Logger logger;
@MonotonicNonNull ConfigurationContainer configurationSource;
@Nullable List modifiers;
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java
index 148a87bc..c31c0c01 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java
@@ -24,6 +24,7 @@
*/
package org.spongepowered.gradle.vanilla.internal.repository;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.gradle.vanilla.internal.Constants;
import java.util.Arrays;
@@ -34,14 +35,15 @@
public enum ResolvableTool {
JAR_MERGE(Constants.Configurations.MERGETOOL, Constants.WorkerDependencies.MERGE_TOOL),
ACCESS_WIDENER(Constants.Configurations.ACCESS_WIDENER, Constants.WorkerDependencies.ACCESS_WIDENER),
- REMAP_TINY(Constants.Configurations.REMAP_TINY, new Dependency(Constants.WorkerDependencies.LORENZ_TINY, false), new Dependency(Constants.WorkerDependencies.MAPPING_IO, true)),
+ REMAP_TINY(Constants.Configurations.REMAP_TINY, new Dependency(Constants.WorkerDependencies.LORENZ_TINY).setNonTransitive(), new Dependency(Constants.WorkerDependencies.MAPPING_IO)),
+ REMAP_PARCHMENT(Constants.Configurations.REMAP_PARCHMENT, new Dependency(Constants.WorkerDependencies.FEATHER).setRepo(Repository.PARCHMENT), new Dependency(Constants.WorkerDependencies.FEATHER_IO_GSON).setRepo(Repository.PARCHMENT)),
;
private final String id;
private final Dependency[] dependencies;
ResolvableTool(final String id, final String... notations) {
- this(id, Arrays.stream(notations).map(notation -> new Dependency(notation, true)).toArray(Dependency[]::new));
+ this(id, Arrays.stream(notations).map(Dependency::new).toArray(Dependency[]::new));
}
ResolvableTool(final String id, final Dependency... dependencies) {
@@ -57,21 +59,56 @@ public Dependency[] dependencies() {
return this.dependencies;
}
+ public enum Repository {
+ PARCHMENT("https://maven.parchmentmc.org/"),
+ ;
+
+ private final String url;
+
+ Repository(String url) {
+ this.url = url;
+ }
+
+ public String url() {
+ return url;
+ }
+ }
+
public static class Dependency {
private final String notation;
- private final boolean isTransitive;
+ private @Nullable Repository repo = null;
+ private boolean isTransitive = true;
- public Dependency(final String notation, final boolean isTransitive) {
+ public Dependency(final String notation) {
this.notation = notation;
- this.isTransitive = isTransitive;
+ }
+
+ public Dependency setNonTransitive() {
+ this.isTransitive = false;
+ return this;
+ }
+
+ public Dependency setRepo(Repository repo) {
+ this.repo = repo;
+ return this;
}
public String notation() {
return notation;
}
+ public Repository repo() {
+ return repo;
+ }
+
public boolean isTransitive() {
return isTransitive;
}
}
+
+ public static class MissingToolException extends RuntimeException {
+ public MissingToolException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ }
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ParchmentMappingFormat.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ParchmentMappingFormat.java
new file mode 100644
index 00000000..adb41451
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ParchmentMappingFormat.java
@@ -0,0 +1,65 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.gradle.vanilla.internal.repository.ResolvableTool;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.concurrent.CompletableFuture;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+public class ParchmentMappingFormat extends MappingFormat<@NonNull MappingsEntry> {
+ public ParchmentMappingFormat() {
+ super(MappingsEntry.class);
+ }
+
+ @Override
+ public @NonNull String getName() {
+ return "parchment";
+ }
+
+ @Override
+ public @NonNull MappingSet read(
+ @NonNull Path file,
+ @NonNull MappingsEntry entry,
+ MinecraftResolver.@NonNull Context context
+ ) throws IOException {
+ boolean isTempFile = false;
+ if (file.toString().endsWith(".zip")) {
+ try (ZipFile zip = new ZipFile(file.toFile())) {
+ ZipEntry zipEntry = zip.getEntry("parchment.json");
+ if (zipEntry != null) {
+ file = Files.createTempFile(file.getFileName().toString(), "mappings");
+ Files.copy(zip.getInputStream(zipEntry), file, StandardCopyOption.REPLACE_EXISTING);
+ isTempFile = true;
+ }
+ }
+ }
+ MappingSet mappings = MappingSet.create();
+ URLClassLoader classLoader = CompletableFuture.supplyAsync(() -> context.classLoaderWithTool(ResolvableTool.REMAP_PARCHMENT).get(), context.syncExecutor()).join();
+ try {
+ Class> readerClass = Class.forName(
+ "org.spongepowered.gradle.vanilla.internal.repository.mappings.ParchmentReaderImpl",
+ true,
+ classLoader
+ );
+ Method readMethod = readerClass.getMethod("read", MappingSet.class, Path.class);
+ readMethod.invoke(null, mappings, file);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ if (isTempFile) {
+ Files.delete(file);
+ }
+ return mappings;
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/templates/org/spongepowered/gradle/vanilla/internal/BuildVersions.java b/subprojects/gradle-plugin/src/main/templates/org/spongepowered/gradle/vanilla/internal/BuildVersions.java
index 4cef0abf..a4ea2bbc 100644
--- a/subprojects/gradle-plugin/src/main/templates/org/spongepowered/gradle/vanilla/internal/BuildVersions.java
+++ b/subprojects/gradle-plugin/src/main/templates/org/spongepowered/gradle/vanilla/internal/BuildVersions.java
@@ -36,7 +36,8 @@ private BuildVersions() {
public static final String FORGEFLOWER = "${forgeFlowerVersion}";
public static final String MERGE_TOOL = "${mergeToolVersion}";
public static final String ACCESS_WIDENER = "${accessWidenerVersion}";
- public static final String LORENZ_TINY_VERSION = "${lorenzTinyVersion}";
- public static final String MAPPING_IO_VERSION = "${mappingIoVersion}";
+ public static final String LORENZ_TINY = "${lorenzTinyVersion}";
+ public static final String MAPPING_IO = "${mappingIoVersion}";
+ public static final String FEATHER = "${featherVersion}";
}
diff --git a/subprojects/gradle-plugin/src/remapParchment/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ParchmentReaderImpl.java b/subprojects/gradle-plugin/src/remapParchment/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ParchmentReaderImpl.java
new file mode 100644
index 00000000..49140300
--- /dev/null
+++ b/subprojects/gradle-plugin/src/remapParchment/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ParchmentReaderImpl.java
@@ -0,0 +1,70 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.cadixdev.lorenz.MappingSet;
+import org.cadixdev.lorenz.model.ClassMapping;
+import org.cadixdev.lorenz.model.ExtensionKey;
+import org.cadixdev.lorenz.model.FieldMapping;
+import org.cadixdev.lorenz.model.MethodMapping;
+import org.cadixdev.lorenz.model.MethodParameterMapping;
+import org.parchmentmc.feather.io.gson.MDCGsonAdapterFactory;
+import org.parchmentmc.feather.io.gson.OffsetDateTimeAdapter;
+import org.parchmentmc.feather.io.gson.SimpleVersionAdapter;
+import org.parchmentmc.feather.io.gson.metadata.MetadataAdapterFactory;
+import org.parchmentmc.feather.mapping.MappingDataContainer;
+import org.parchmentmc.feather.mapping.VersionedMappingDataContainer;
+import org.parchmentmc.feather.util.SimpleVersion;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.time.OffsetDateTime;
+import java.util.Collections;
+import java.util.List;
+
+public class ParchmentReaderImpl {
+ @SuppressWarnings("unchecked")
+ private static final ExtensionKey> JAVADOC_EXTENSION = new ExtensionKey<>((Class>) (Class>) List.class, "javadoc");
+ private static final Gson GSON = new GsonBuilder()
+ // Required for `MappingDataContainer` and inner data classes
+ .registerTypeAdapterFactory(new MDCGsonAdapterFactory())
+ // Required for `MappingDataContainer`s and `SourceMetadata`
+ .registerTypeAdapter(SimpleVersion.class, new SimpleVersionAdapter())
+ // Required for the metadata classes (`SourceMetadata`, `MethodReference`, etc.) and `Named`
+ .registerTypeAdapterFactory(new MetadataAdapterFactory())
+ // Required for parsing manifests: `LauncherManifest`, `VersionManifest`, and their inner data classes
+ .registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeAdapter())
+ .create();
+
+ public static void read(MappingSet output, Path file) throws IOException {
+ final MappingDataContainer parchmentData;
+ try (BufferedReader reader = Files.newBufferedReader(file)) {
+ parchmentData = GSON.fromJson(reader, VersionedMappingDataContainer.class);
+ }
+ for (final MappingDataContainer.ClassData parchmentClassMapping : parchmentData.getClasses()) {
+ final ClassMapping, ?> classMapping = output.getOrCreateClassMapping(parchmentClassMapping.getName());
+ classMapping.set(JAVADOC_EXTENSION, parchmentClassMapping.getJavadoc());
+
+ for (final MappingDataContainer.FieldData field : parchmentClassMapping.getFields()) {
+ final FieldMapping fieldMapping = classMapping.getOrCreateFieldMapping(field.getName(), field.getDescriptor());
+ fieldMapping.set(JAVADOC_EXTENSION, field.getJavadoc());
+ }
+
+ for (final MappingDataContainer.MethodData method : parchmentClassMapping.getMethods()) {
+ final MethodMapping methodMapping = classMapping.getOrCreateMethodMapping(method.getName(), method.getDescriptor());
+ methodMapping.set(JAVADOC_EXTENSION, method.getJavadoc());
+ for (final MappingDataContainer.ParameterData parameter : method.getParameters()) {
+ final MethodParameterMapping parameterMapping = methodMapping.getOrCreateParameterMapping(parameter.getIndex());
+ if (parameter.getName() != null) {
+ parameterMapping.setDeobfuscatedName(parameter.getName());
+ }
+ if (parameter.getJavadoc() != null) {
+ parameterMapping.set(JAVADOC_EXTENSION, Collections.singletonList(parameter.getJavadoc()));
+ }
+ }
+ }
+ }
+ }
+}
From a92d2d4097b14816db64cc4c16f720fdfa7b4976 Mon Sep 17 00:00:00 2001
From: Joe
Date: Fri, 8 Oct 2021 17:15:20 +0100
Subject: [PATCH 08/15] Remove parchment repo, sponge now mirrors it
---
subprojects/gradle-plugin/build.gradle.kts | 6 ------
.../gradle/vanilla/internal/repository/ResolvableTool.java | 3 +--
2 files changed, 1 insertion(+), 8 deletions(-)
diff --git a/subprojects/gradle-plugin/build.gradle.kts b/subprojects/gradle-plugin/build.gradle.kts
index 49b5ece2..2e189d00 100644
--- a/subprojects/gradle-plugin/build.gradle.kts
+++ b/subprojects/gradle-plugin/build.gradle.kts
@@ -45,12 +45,6 @@ val lorenzTinyVersion: String by project
val mappingIoVersion: String by project
val featherVersion: String by project
-repositories {
- maven("https://maven.parchmentmc.org/") {
- name = "ParchmentMC"
- }
-}
-
dependencies {
// All source sets
commonDeps(gradleApi())
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java
index c31c0c01..cdef19c9 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/ResolvableTool.java
@@ -36,7 +36,7 @@ public enum ResolvableTool {
JAR_MERGE(Constants.Configurations.MERGETOOL, Constants.WorkerDependencies.MERGE_TOOL),
ACCESS_WIDENER(Constants.Configurations.ACCESS_WIDENER, Constants.WorkerDependencies.ACCESS_WIDENER),
REMAP_TINY(Constants.Configurations.REMAP_TINY, new Dependency(Constants.WorkerDependencies.LORENZ_TINY).setNonTransitive(), new Dependency(Constants.WorkerDependencies.MAPPING_IO)),
- REMAP_PARCHMENT(Constants.Configurations.REMAP_PARCHMENT, new Dependency(Constants.WorkerDependencies.FEATHER).setRepo(Repository.PARCHMENT), new Dependency(Constants.WorkerDependencies.FEATHER_IO_GSON).setRepo(Repository.PARCHMENT)),
+ REMAP_PARCHMENT(Constants.Configurations.REMAP_PARCHMENT, Constants.WorkerDependencies.FEATHER, Constants.WorkerDependencies.FEATHER_IO_GSON),
;
private final String id;
@@ -60,7 +60,6 @@ public Dependency[] dependencies() {
}
public enum Repository {
- PARCHMENT("https://maven.parchmentmc.org/"),
;
private final String url;
From 460537571da70e5078bd0c5706191633c6f126bb Mon Sep 17 00:00:00 2001
From: Joe
Date: Fri, 8 Oct 2021 17:49:12 +0100
Subject: [PATCH 09/15] Add support for srg, tsrg, csrg and xsrg, add builtin
obf mappings
---
.../gradle/vanilla/MinecraftExtension.java | 2 -
.../internal/MinecraftExtensionImpl.java | 19 +++++----
.../mappings/CSrgMappingFormat.java | 30 ++++++++++++++
.../mappings/ImmutableMappingsEntry.java | 41 +++++++++++++++++++
.../repository/mappings/ObfMappingsEntry.java | 31 ++++++++++++++
.../mappings/OfficialMappingsEntry.java | 32 +--------------
.../repository/mappings/SrgMappingFormat.java | 30 ++++++++++++++
.../mappings/TSrgMappingFormat.java | 30 ++++++++++++++
.../mappings/XSrgMappingFormat.java | 30 ++++++++++++++
9 files changed, 205 insertions(+), 40 deletions(-)
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/CSrgMappingFormat.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ImmutableMappingsEntry.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ObfMappingsEntry.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/SrgMappingFormat.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TSrgMappingFormat.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/XSrgMappingFormat.java
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java
index 1e31dbcf..b6b4ae50 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/MinecraftExtension.java
@@ -137,8 +137,6 @@ public interface MinecraftExtension extends MinecraftRepositoryExtension {
void minecraftMappings(String mappings);
- void noMinecraftMappings();
-
/**
* Get run configurations configured for this project.
*
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
index 5c4c4b89..90ae80be 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
@@ -42,10 +42,15 @@
import org.spongepowered.gradle.vanilla.MinecraftExtension;
import org.spongepowered.gradle.vanilla.internal.model.VersionClassifier;
import org.spongepowered.gradle.vanilla.internal.model.VersionDescriptor;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.CSrgMappingFormat;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.ObfMappingsEntry;
import org.spongepowered.gradle.vanilla.internal.repository.mappings.OfficialMappingsEntry;
import org.spongepowered.gradle.vanilla.internal.repository.mappings.ParchmentMappingFormat;
import org.spongepowered.gradle.vanilla.internal.repository.mappings.ProGuardMappingFormat;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.SrgMappingFormat;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.TSrgMappingFormat;
import org.spongepowered.gradle.vanilla.internal.repository.mappings.TinyMappingFormat;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.XSrgMappingFormat;
import org.spongepowered.gradle.vanilla.internal.repository.modifier.MappingsModifier;
import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
import org.spongepowered.gradle.vanilla.repository.mappings.MappingsContainer;
@@ -80,7 +85,6 @@ public class MinecraftExtensionImpl implements MinecraftExtension {
private final PolymorphicDomainObjectContainer> mappingFormats;
private final MappingsContainer mappings;
private final Property minecraftMappings;
- private final Property noMinecraftMappings;
private final DirectoryProperty sharedCache;
private final DirectoryProperty projectCache;
private final ConfigurableFileCollection accessWideners;
@@ -105,12 +109,16 @@ public MinecraftExtensionImpl(final Gradle gradle, final ObjectFactory factory,
this.mappingFormats = factory.polymorphicDomainObjectContainer((Class>) (Class>) MappingFormat.class);
this.mappings = new MappingsContainer(project, this);
this.minecraftMappings = factory.property(String.class).convention(OfficialMappingsEntry.NAME);
- this.noMinecraftMappings = factory.property(Boolean.class).convention(false);
this.accessWideners = factory.fileCollection();
this.mappingFormats.add(new ProGuardMappingFormat());
this.mappingFormats.add(new TinyMappingFormat());
this.mappingFormats.add(new ParchmentMappingFormat());
+ this.mappingFormats.add(new SrgMappingFormat());
+ this.mappingFormats.add(new TSrgMappingFormat());
+ this.mappingFormats.add(new CSrgMappingFormat());
+ this.mappingFormats.add(new XSrgMappingFormat());
+ this.mappings.add(new ObfMappingsEntry(project, this));
this.mappings.add(new OfficialMappingsEntry(project, this));
@@ -298,16 +306,11 @@ public void minecraftMappings(String mappings) {
this.minecraftMappings.set(mappings);
}
- @Override
- public void noMinecraftMappings() {
- this.noMinecraftMappings.set(true);
- }
-
public synchronized List modifiers() {
if (this.lazyModifiers == null) {
final List modifiers = new ArrayList<>();
- if (!noMinecraftMappings.get()) {
+ if (!minecraftMappings.get().equals(ObfMappingsEntry.NAME)) {
modifiers.add(new MappingsModifier(mappings.getByName(minecraftMappings.get())));
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/CSrgMappingFormat.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/CSrgMappingFormat.java
new file mode 100644
index 00000000..8621ecd4
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/CSrgMappingFormat.java
@@ -0,0 +1,30 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public class CSrgMappingFormat extends MappingFormat<@NonNull MappingsEntry> {
+ public CSrgMappingFormat() {
+ super(MappingsEntry.class);
+ }
+
+ @Override
+ public @NonNull String getName() {
+ return "csrg";
+ }
+
+ @Override
+ public @NonNull MappingSet read(
+ @NonNull Path file,
+ @NonNull MappingsEntry entry,
+ MinecraftResolver.@NonNull Context context
+ ) throws IOException {
+ return new org.cadixdev.lorenz.io.srg.csrg.CSrgMappingFormat().read(file);
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ImmutableMappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ImmutableMappingsEntry.java
new file mode 100644
index 00000000..715b8c53
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ImmutableMappingsEntry.java
@@ -0,0 +1,41 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.gradle.api.Project;
+import org.spongepowered.gradle.vanilla.MinecraftExtension;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
+
+public abstract class ImmutableMappingsEntry extends MappingsEntry {
+ private boolean hasInitialized = false;
+
+ public ImmutableMappingsEntry(Project project, MinecraftExtension extension, String name, String format) {
+ super(project, extension, name);
+ format(format);
+ hasInitialized = true;
+ }
+
+ @Override
+ public void format(@NonNull String format) {
+ if (hasInitialized) {
+ throw new IllegalStateException("Cannot modify the format of \"" + getName() + "\"");
+ } else {
+ super.format(format);
+ }
+ }
+
+ @Override
+ public void dependency(@Nullable Object dependencyNotation) {
+ throw new IllegalStateException("Cannot modify the dependency of \"" + getName() + "\"");
+ }
+
+ @Override
+ public void parent(@Nullable String parent) {
+ throw new IllegalStateException("Cannot modify the parent of \"" + getName() + "\"");
+ }
+
+ @Override
+ public void inverse(boolean isInverse) {
+ throw new IllegalStateException("Cannot invert \"" + getName() + "\"");
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ObfMappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ObfMappingsEntry.java
new file mode 100644
index 00000000..aa2d02bf
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ObfMappingsEntry.java
@@ -0,0 +1,31 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.gradle.api.Project;
+import org.spongepowered.gradle.vanilla.MinecraftExtension;
+import org.spongepowered.gradle.vanilla.internal.repository.modifier.ArtifactModifier;
+import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
+
+import java.util.Set;
+
+public class ObfMappingsEntry extends ImmutableMappingsEntry {
+ public static final String NAME = "obf";
+
+ public ObfMappingsEntry(Project project, MinecraftExtension extension) {
+ super(project, extension, NAME, ProGuardMappingFormat.NAME);
+ }
+
+ @Override
+ protected @NonNull MappingSet doResolve(
+ MinecraftResolver.@NonNull Context context,
+ MinecraftResolver.@NonNull MinecraftEnvironment environment,
+ @NonNull MinecraftPlatform platform,
+ ArtifactModifier.@NonNull SharedArtifactSupplier sharedArtifactSupplier,
+ @NonNull Set alreadySeen
+ ) {
+ return MappingSet.create();
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java
index a932d163..b6d8532d 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java
@@ -3,7 +3,6 @@
import org.cadixdev.lorenz.MappingSet;
import org.cadixdev.lorenz.io.proguard.ProGuardReader;
import org.checkerframework.checker.nullness.qual.NonNull;
-import org.checkerframework.checker.nullness.qual.Nullable;
import org.gradle.api.Project;
import org.spongepowered.gradle.vanilla.MinecraftExtension;
import org.spongepowered.gradle.vanilla.internal.model.Download;
@@ -21,38 +20,11 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
-public class OfficialMappingsEntry extends MappingsEntry {
+public class OfficialMappingsEntry extends ImmutableMappingsEntry {
public static final String NAME = "official";
- private boolean hasInitialized = false;
public OfficialMappingsEntry(Project project, MinecraftExtension extension) {
- super(project, extension, NAME);
- format(ProGuardMappingFormat.NAME);
- hasInitialized = true;
- }
-
- @Override
- public void format(@NonNull String format) {
- if (hasInitialized) {
- throw new IllegalStateException("Cannot modify the format of \"" + NAME + "\"");
- } else {
- super.format(format);
- }
- }
-
- @Override
- public void dependency(@Nullable Object dependencyNotation) {
- throw new IllegalStateException("Cannot modify the dependency of \"" + NAME + "\"");
- }
-
- @Override
- public void parent(@Nullable String parent) {
- throw new IllegalStateException("Cannot modify the parent of \"" + NAME + "\"");
- }
-
- @Override
- public void inverse(boolean isInverse) {
- throw new IllegalStateException("Cannot invert \"" + NAME + "\"");
+ super(project, extension, NAME, ProGuardMappingFormat.NAME);
}
@Override
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/SrgMappingFormat.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/SrgMappingFormat.java
new file mode 100644
index 00000000..0ced40af
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/SrgMappingFormat.java
@@ -0,0 +1,30 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public class SrgMappingFormat extends MappingFormat<@NonNull MappingsEntry> {
+ public SrgMappingFormat() {
+ super(MappingsEntry.class);
+ }
+
+ @Override
+ public @NonNull String getName() {
+ return "srg";
+ }
+
+ @Override
+ public @NonNull MappingSet read(
+ @NonNull Path file,
+ @NonNull MappingsEntry entry,
+ MinecraftResolver.@NonNull Context context
+ ) throws IOException {
+ return new org.cadixdev.lorenz.io.srg.SrgMappingFormat().read(file);
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TSrgMappingFormat.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TSrgMappingFormat.java
new file mode 100644
index 00000000..10de6300
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/TSrgMappingFormat.java
@@ -0,0 +1,30 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public class TSrgMappingFormat extends MappingFormat<@NonNull MappingsEntry> {
+ public TSrgMappingFormat() {
+ super(MappingsEntry.class);
+ }
+
+ @Override
+ public @NonNull String getName() {
+ return "tsrg";
+ }
+
+ @Override
+ public @NonNull MappingSet read(
+ @NonNull Path file,
+ @NonNull MappingsEntry entry,
+ MinecraftResolver.@NonNull Context context
+ ) throws IOException {
+ return new org.cadixdev.lorenz.io.srg.tsrg.TSrgMappingFormat().read(file);
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/XSrgMappingFormat.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/XSrgMappingFormat.java
new file mode 100644
index 00000000..86853399
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/XSrgMappingFormat.java
@@ -0,0 +1,30 @@
+package org.spongepowered.gradle.vanilla.internal.repository.mappings;
+
+import org.cadixdev.lorenz.MappingSet;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingFormat;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+public class XSrgMappingFormat extends MappingFormat<@NonNull MappingsEntry> {
+ public XSrgMappingFormat() {
+ super(MappingsEntry.class);
+ }
+
+ @Override
+ public @NonNull String getName() {
+ return "xsrg";
+ }
+
+ @Override
+ public @NonNull MappingSet read(
+ @NonNull Path file,
+ @NonNull MappingsEntry entry,
+ MinecraftResolver.@NonNull Context context
+ ) throws IOException {
+ return new org.cadixdev.lorenz.io.srg.xsrg.XSrgMappingFormat().read(file);
+ }
+}
From ddcbe80102401131664bd7b1531c3314d9f7d2c5 Mon Sep 17 00:00:00 2001
From: Joe
Date: Fri, 8 Oct 2021 20:39:57 +0100
Subject: [PATCH 10/15] Detached configuration, caching
---
subprojects/gradle-plugin/build.gradle.kts | 6 ++
.../internal/MinecraftExtensionImpl.java | 2 +-
.../repository/mappings/ObfMappingsEntry.java | 5 ++
.../mappings/OfficialMappingsEntry.java | 4 +-
.../repository/modifier/MappingsModifier.java | 18 +++--
.../repository/mappings/MappingsEntry.java | 79 +++++++++++++------
6 files changed, 81 insertions(+), 33 deletions(-)
diff --git a/subprojects/gradle-plugin/build.gradle.kts b/subprojects/gradle-plugin/build.gradle.kts
index 2e189d00..49b5ece2 100644
--- a/subprojects/gradle-plugin/build.gradle.kts
+++ b/subprojects/gradle-plugin/build.gradle.kts
@@ -45,6 +45,12 @@ val lorenzTinyVersion: String by project
val mappingIoVersion: String by project
val featherVersion: String by project
+repositories {
+ maven("https://maven.parchmentmc.org/") {
+ name = "ParchmentMC"
+ }
+}
+
dependencies {
// All source sets
commonDeps(gradleApi())
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
index 90ae80be..fa247fc2 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/MinecraftExtensionImpl.java
@@ -311,7 +311,7 @@ public synchronized List modifiers() {
final List modifiers = new ArrayList<>();
if (!minecraftMappings.get().equals(ObfMappingsEntry.NAME)) {
- modifiers.add(new MappingsModifier(mappings.getByName(minecraftMappings.get())));
+ modifiers.add(new MappingsModifier(mappings, ObfMappingsEntry.NAME, minecraftMappings.get()));
}
this.accessWideners.disallowChanges();
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ObfMappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ObfMappingsEntry.java
index aa2d02bf..6f11fe22 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ObfMappingsEntry.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/ObfMappingsEntry.java
@@ -18,6 +18,11 @@ public ObfMappingsEntry(Project project, MinecraftExtension extension) {
super(project, extension, NAME, ProGuardMappingFormat.NAME);
}
+ @Override
+ public @NonNull String computeStateKey(boolean isFrom) {
+ return isFrom ? "" : super.computeStateKey(false);
+ }
+
@Override
protected @NonNull MappingSet doResolve(
MinecraftResolver.@NonNull Context context,
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java
index b6d8532d..2f9082ed 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/mappings/OfficialMappingsEntry.java
@@ -64,7 +64,7 @@ public OfficialMappingsEntry(Project project, MinecraftExtension extension) {
}
@Override
- public @NonNull String computeStateKey() {
- return "";
+ public @NonNull String computeStateKey(boolean isFrom) {
+ return isFrom ? super.computeStateKey(true) : "";
}
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java
index 350b7f06..05097f13 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/repository/modifier/MappingsModifier.java
@@ -5,7 +5,7 @@
import org.spongepowered.gradle.vanilla.internal.resolver.AsyncUtils;
import org.spongepowered.gradle.vanilla.internal.transformer.AtlasTransformers;
import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
-import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsContainer;
import java.io.IOException;
import java.io.UncheckedIOException;
@@ -14,11 +14,15 @@
public class MappingsModifier implements ArtifactModifier {
private static final String KEY = "map"; // custom mapped
- private final MappingsEntry mappings;
+ private final MappingsContainer mappings;
+ private final String from;
+ private final String to;
private @Nullable String stateKey;
- public MappingsModifier(final MappingsEntry mappings) {
+ public MappingsModifier(final MappingsContainer mappings, final String from, final String to) {
this.mappings = mappings;
+ this.from = from;
+ this.to = to;
}
@Override
@@ -29,7 +33,11 @@ public String key() {
@Override
public String stateKey() {
if (stateKey == null) {
- return this.stateKey = mappings.computeStateKey();
+ this.stateKey = mappings.getByName(from).computeStateKey(true);
+ if (!this.stateKey.isEmpty()) {
+ this.stateKey += "-";
+ }
+ this.stateKey += mappings.getByName(to).computeStateKey(false);
}
return stateKey;
}
@@ -39,7 +47,7 @@ public CompletableFuture providePopulator(MinecraftResolver.Cont
return AsyncUtils.failableFuture(() -> (atlasContext, result, side, sharedArtifactProvider) -> {
final MappingSet mappings;
try {
- mappings = this.mappings.resolve(context, result, side, sharedArtifactProvider);
+ mappings = this.mappings.getByName(to).convertFrom(from, context, result, side, sharedArtifactProvider);
} catch (IOException e) {
throw new UncheckedIOException("An exception occurred while trying to read mappings", e);
}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
index 5016e11c..cd8eae29 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/mappings/MappingsEntry.java
@@ -11,6 +11,7 @@
import org.gradle.api.artifacts.ModuleDependency;
import org.gradle.api.provider.Property;
import org.spongepowered.gradle.vanilla.MinecraftExtension;
+import org.spongepowered.gradle.vanilla.internal.repository.mappings.ObfMappingsEntry;
import org.spongepowered.gradle.vanilla.internal.repository.modifier.ArtifactModifier;
import org.spongepowered.gradle.vanilla.repository.MinecraftPlatform;
import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
@@ -20,31 +21,33 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.ref.SoftReference;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.HashSet;
+import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
public class MappingsEntry implements Named {
protected final Project project;
protected final MinecraftExtension extension;
private final String name;
private final Property format;
- private final String configurationName;
- private @Nullable Object dependency;
- private @Nullable Dependency dependencyObj;
+ private @Nullable Configuration configuration;
+ private @Nullable Dependency dependency;
private final Property parent;
private final Property inverse;
+ private final Map> convertFromCache = new ConcurrentHashMap<>();
public MappingsEntry(Project project, MinecraftExtension extension, String name) {
this.project = project;
this.extension = extension;
this.name = name;
this.format = project.getObjects().property(String.class);
- this.configurationName = name + "Mappings";
this.parent = project.getObjects().property(String.class);
this.inverse = project.getObjects().property(Boolean.class).convention(false);
}
@@ -71,13 +74,8 @@ public void dependency(Object dependencyNotation) {
if (this.dependency != null) {
throw new IllegalStateException("MappingsEntry.dependency(Object) called twice");
}
- project.getConfigurations().register(configurationName, config -> {
- config.setVisible(false);
- config.setCanBeConsumed(false);
- config.setCanBeResolved(true);
- });
- this.dependencyObj = project.getDependencies().add(configurationName, dependencyNotation);
- this.dependency = dependencyNotation;
+ this.dependency = project.getDependencies().create(dependencyNotation);
+ this.configuration = project.getConfigurations().detachedConfiguration(this.dependency);
}
public Property<@Nullable String> parent() {
@@ -100,15 +98,46 @@ public void inverse(boolean isInverse) {
inverse.set(isInverse);
}
+ @Override
public int hashCode() {
return name.hashCode();
}
+ @Override
public boolean equals(Object other) {
return other instanceof MappingsEntry && ((MappingsEntry) other).name.equals(this.name);
}
- public final MappingSet resolve(
+ public final MappingSet convertFrom(
+ String otherMappingsName,
+ MinecraftResolver.Context context,
+ MinecraftResolver.MinecraftEnvironment environment,
+ MinecraftPlatform platform,
+ ArtifactModifier.SharedArtifactSupplier sharedArtifactSupplier
+ ) throws IOException {
+ SoftReference ref = convertFromCache.get(otherMappingsName);
+ if (ref != null) {
+ @Nullable MappingSet entry = ref.get();
+ if (entry != null) {
+ return entry;
+ }
+ }
+
+ MappingSet resolved;
+ if (otherMappingsName.equals(getName())) {
+ resolved = MappingSet.create();
+ } else if (otherMappingsName.equals(ObfMappingsEntry.NAME)) {
+ resolved = resolve(context, environment, platform, sharedArtifactSupplier);
+ } else {
+ MappingsEntry otherMappings = extension.getMappings().getByName(otherMappingsName);
+ resolved = otherMappings.resolve(context, environment, platform, sharedArtifactSupplier)
+ .reverse().merge(resolve(context, environment, platform, sharedArtifactSupplier));
+ }
+ convertFromCache.put(otherMappingsName, new SoftReference<>(resolved));
+ return resolved;
+ }
+
+ private MappingSet resolve(
MinecraftResolver.Context context,
MinecraftResolver.MinecraftEnvironment environment,
MinecraftPlatform platform,
@@ -143,16 +172,16 @@ protected MappingSet doResolve(
MinecraftPlatform platform,
ArtifactModifier.SharedArtifactSupplier sharedArtifactSupplier,
Set alreadySeen) throws IOException {
- if (dependency == null) {
+ if (this.dependency == null) {
throw new IllegalStateException("Mappings entry \"" + getName() + "\" of format \"" + format.get() + "\" must have a dependency");
}
+ assert this.configuration != null;
@SuppressWarnings("unchecked")
MappingFormat mappingFormat = (MappingFormat) extension.getMappingFormats().getByName(format.get());
if (!mappingFormat.entryType().isInstance(this)) {
throw new IllegalStateException("Mappings entry \"" + getName() + "\" of type \"" + getClass().getName() + "\" is not compatible with mapping format \"" + format.get() + "\"");
}
- Configuration configuration = project.getConfigurations().getByName(configurationName);
- Set resolvedFiles = CompletableFuture.supplyAsync(configuration::resolve, context.syncExecutor()).join();
+ Set resolvedFiles = CompletableFuture.supplyAsync(this.configuration::resolve, context.syncExecutor()).join();
if (resolvedFiles.size() != 1) {
throw new IllegalStateException("Mappings entry \"" + getName() + "\" did not resolve to exactly 1 file");
}
@@ -160,7 +189,7 @@ protected MappingSet doResolve(
return mappingFormat.read(resolvedFile, mappingFormat.entryType().cast(this), context);
}
- public String computeStateKey() {
+ public String computeStateKey(boolean isFrom) {
final MessageDigest digest = HashAlgorithm.SHA1.digest();
computeHash(digest);
return HashAlgorithm.toHexString(digest.digest());
@@ -171,18 +200,18 @@ protected void computeHash(MessageDigest digest) {
digest.update(getName().getBytes(StandardCharsets.UTF_8));
digest.update((byte) 1);
digest.update(format.get().getBytes(StandardCharsets.UTF_8));
- if (dependencyObj != null) {
+ if (dependency != null) {
digest.update((byte) 2);
- if (dependencyObj instanceof ModuleDependency) {
- if (dependencyObj.getGroup() != null) {
- digest.update(dependencyObj.getGroup().getBytes(StandardCharsets.UTF_8));
+ if (dependency instanceof ModuleDependency) {
+ if (dependency.getGroup() != null) {
+ digest.update(dependency.getGroup().getBytes(StandardCharsets.UTF_8));
}
- digest.update((":" + dependencyObj.getName()).getBytes(StandardCharsets.UTF_8));
- if (dependencyObj.getVersion() != null) {
- digest.update((":" + dependencyObj.getVersion()).getBytes(StandardCharsets.UTF_8));
+ digest.update((":" + dependency.getName()).getBytes(StandardCharsets.UTF_8));
+ if (dependency.getVersion() != null) {
+ digest.update((":" + dependency.getVersion()).getBytes(StandardCharsets.UTF_8));
}
- } else if (dependencyObj instanceof FileCollectionDependency) {
- for (File file : ((FileCollectionDependency) dependencyObj).getFiles()) {
+ } else if (dependency instanceof FileCollectionDependency) {
+ for (File file : ((FileCollectionDependency) dependency).getFiles()) {
try (final InputStream is = new FileInputStream(file)) {
final byte[] buf = new byte[4096];
int read;
From 2bb3fa918a5157e4b8fe58b3d2e5fc2699f24667 Mon Sep 17 00:00:00 2001
From: Joe
Date: Sat, 9 Oct 2021 17:26:20 +0100
Subject: [PATCH 11/15] Remap jar task
---
subprojects/gradle-plugin/build.gradle.kts | 6 -
.../task/JarEntryTransformerProvider.java | 9 +
.../vanilla/internal/task/RemapFilter.java | 69 ++++++++
.../repository/MinecraftResolverImpl.java | 6 +-
.../gradle/vanilla/task/RemapJar.java | 159 ++++++++++++++++++
5 files changed, 242 insertions(+), 7 deletions(-)
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/task/JarEntryTransformerProvider.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/task/RemapFilter.java
create mode 100644 subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/RemapJar.java
diff --git a/subprojects/gradle-plugin/build.gradle.kts b/subprojects/gradle-plugin/build.gradle.kts
index 49b5ece2..2e189d00 100644
--- a/subprojects/gradle-plugin/build.gradle.kts
+++ b/subprojects/gradle-plugin/build.gradle.kts
@@ -45,12 +45,6 @@ val lorenzTinyVersion: String by project
val mappingIoVersion: String by project
val featherVersion: String by project
-repositories {
- maven("https://maven.parchmentmc.org/") {
- name = "ParchmentMC"
- }
-}
-
dependencies {
// All source sets
commonDeps(gradleApi())
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/task/JarEntryTransformerProvider.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/task/JarEntryTransformerProvider.java
new file mode 100644
index 00000000..7c031062
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/task/JarEntryTransformerProvider.java
@@ -0,0 +1,9 @@
+package org.spongepowered.gradle.vanilla.internal.task;
+
+import org.cadixdev.bombe.jar.JarEntryTransformer;
+
+import java.io.IOException;
+
+public interface JarEntryTransformerProvider {
+ JarEntryTransformer getJarEntryTransformer() throws IOException;
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/task/RemapFilter.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/task/RemapFilter.java
new file mode 100644
index 00000000..74242631
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/internal/task/RemapFilter.java
@@ -0,0 +1,69 @@
+package org.spongepowered.gradle.vanilla.internal.task;
+
+import org.apache.tools.ant.filters.BaseFilterReader;
+import org.apache.tools.ant.util.ReaderInputStream;
+import org.cadixdev.bombe.jar.JarClassEntry;
+import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
+import org.gradle.api.Project;
+import org.gradle.api.file.CopySpec;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+
+public class RemapFilter extends BaseFilterReader {
+ private @MonotonicNonNull JarEntryTransformerProvider remapper;
+ private @MonotonicNonNull Reader delegate;
+
+ public RemapFilter(Reader in) {
+ super(in);
+ }
+
+ public JarEntryTransformerProvider getRemapper() {
+ return remapper;
+ }
+
+ public void setRemapper(JarEntryTransformerProvider remapper) {
+ this.remapper = remapper;
+ }
+
+ public static CopySpec createCopySpec(Project project, JarEntryTransformerProvider remapper) {
+ return project.copySpec(spec -> {
+ spec.include("**/*.class");
+ spec.setFilteringCharset("ISO-8859-1");
+ spec.filter(Collections.singletonMap("remapper", remapper), RemapFilter.class);
+ });
+ }
+
+ private void initialize() throws IOException {
+ InputStream in = new ReaderInputStream(this.in, StandardCharsets.ISO_8859_1);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[8192];
+ int n;
+ while ((n = in.read(buffer)) != -1) {
+ baos.write(buffer, 0, n);
+ }
+ byte[] bytes = baos.toByteArray();
+
+ JarClassEntry transformed = remapper.getJarEntryTransformer().transform(new JarClassEntry("Foo.class", 0, bytes));
+ if (transformed == null) {
+ delegate = this.in;
+ } else {
+ delegate = new InputStreamReader(new ByteArrayInputStream(transformed.getContents()), StandardCharsets.ISO_8859_1);
+ }
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+ return delegate.read();
+ }
+}
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
index cb3e3931..bab0a78d 100644
--- a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/repository/MinecraftResolverImpl.java
@@ -399,7 +399,7 @@ public CompletableFuture> provide(
try (final Atlas atlas = new Atlas(this.executor)) {
for (final CompletableFuture populator : populators) {
ArtifactModifier.AtlasPopulator pop = populator.get();
- atlas.install(ctx -> pop.provide(withAsmApi(ctx, Constants.ASM_VERSION), input.get(), side, (id, classifier, extension) -> this.sharedArtifactFileName(id, version, classifier, extension)));
+ atlas.install(ctx -> pop.provide(withAsmApi(ctx, Constants.ASM_VERSION), input.get(), side, sharedArtifactSupplier(version)));
}
atlas.run(input.get().jar(), outputTmp);
@@ -427,6 +427,10 @@ public CompletableFuture> provide(
));
}
+ public ArtifactModifier.SharedArtifactSupplier sharedArtifactSupplier(String version) {
+ return (id, classifier, extension) -> this.sharedArtifactFileName(id, version, classifier, extension);
+ }
+
private static final Field CPIP_CLASS_PROVIDER_FIELD;
private static final Constructor ATC_CONSTRUCTOR;
static {
diff --git a/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/RemapJar.java b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/RemapJar.java
new file mode 100644
index 00000000..70e5e6f5
--- /dev/null
+++ b/subprojects/gradle-plugin/src/main/java/org/spongepowered/gradle/vanilla/task/RemapJar.java
@@ -0,0 +1,159 @@
+package org.spongepowered.gradle.vanilla.task;
+
+import org.cadixdev.atlas.jar.JarFile;
+import org.cadixdev.atlas.util.CascadingClassProvider;
+import org.cadixdev.bombe.asm.analysis.ClassProviderInheritanceProvider;
+import org.cadixdev.bombe.asm.jar.ClassProvider;
+import org.cadixdev.bombe.jar.JarEntryTransformer;
+import org.cadixdev.lorenz.MappingSet;
+import org.gradle.api.GradleException;
+import org.gradle.api.Project;
+import org.gradle.api.file.FileCollection;
+import org.gradle.api.file.FileTree;
+import org.gradle.api.model.ObjectFactory;
+import org.gradle.api.provider.Property;
+import org.gradle.api.tasks.Classpath;
+import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.Internal;
+import org.gradle.jvm.tasks.Jar;
+import org.spongepowered.gradle.vanilla.MinecraftExtension;
+import org.spongepowered.gradle.vanilla.internal.Constants;
+import org.spongepowered.gradle.vanilla.internal.MinecraftExtensionImpl;
+import org.spongepowered.gradle.vanilla.internal.repository.MinecraftProviderService;
+import org.spongepowered.gradle.vanilla.internal.task.JarEntryTransformerProvider;
+import org.spongepowered.gradle.vanilla.internal.task.RemapFilter;
+import org.spongepowered.gradle.vanilla.internal.transformer.AtlasTransformers;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolver;
+import org.spongepowered.gradle.vanilla.repository.MinecraftResolverImpl;
+import org.spongepowered.gradle.vanilla.repository.mappings.MappingsEntry;
+import org.spongepowered.gradle.vanilla.resolver.ResolutionResult;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+public abstract class RemapJar extends Jar implements JarEntryTransformerProvider {
+ private final Property fromMappings;
+ private final Property toMappings;
+ private FileCollection classpath;
+ private JarEntryTransformer cachedTransformer;
+
+ public RemapJar() {
+ final Project project = getProject();
+ final ObjectFactory objects = project.getObjects();
+
+ fromMappings = objects.property(String.class).convention(project.provider(() -> {
+ final MinecraftExtension extension = project.getExtensions().findByType(MinecraftExtension.class);
+ Objects.requireNonNull(extension, "Could not find minecraft extension in project");
+ return extension.minecraftMappings().get();
+ }));
+ toMappings = objects.property(String.class);
+
+ with(RemapFilter.createCopySpec(project, this));
+ }
+
+ @Input
+ public Property