diff --git a/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileMappingsSpecBuilder.java b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileMappingsSpecBuilder.java index 1dc71f69..1504725c 100644 --- a/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileMappingsSpecBuilder.java +++ b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileMappingsSpecBuilder.java @@ -71,6 +71,13 @@ public interface FileMappingsSpecBuilder { */ FileMappingsSpecBuilder enigmaMappings(); + /** + * Marks that the zip file contains unpick data. + * + * @return this builder + */ + FileMappingsSpecBuilder containsUnpick(); + /** * Sets the merge namespace of this mappings spec. * diff --git a/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileSpec.java b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileSpec.java index 2f9bd593..faff73e8 100644 --- a/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileSpec.java +++ b/src/main/java/net/fabricmc/loom/api/mappings/layered/spec/FileSpec.java @@ -25,6 +25,8 @@ package net.fabricmc.loom.api.mappings.layered.spec; import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; import java.nio.file.Path; import java.util.Objects; @@ -36,6 +38,7 @@ import org.jetbrains.annotations.ApiStatus; import net.fabricmc.loom.api.mappings.layered.MappingContext; import net.fabricmc.loom.configuration.providers.mappings.utils.DependencyFileSpec; +import net.fabricmc.loom.configuration.providers.mappings.utils.URLFileSpec; import net.fabricmc.loom.configuration.providers.mappings.utils.LocalFileSpec; import net.fabricmc.loom.configuration.providers.mappings.utils.MavenFileSpec; @@ -63,6 +66,14 @@ public interface FileSpec { Objects.requireNonNull(o, "Object cannot be null"); if (o instanceof CharSequence s) { + if (s.toString().startsWith("https://") || s.toString().startsWith("http://")) { + try { + return create(new URL(s.toString())); + } catch (MalformedURLException e) { + throw new RuntimeException("Failed to convert string to URL", e); + } + } + return createFromMavenDependency(s.toString()); } else if (o instanceof Dependency d) { return createFromDependency(d); @@ -74,6 +85,8 @@ public interface FileSpec { return createFromFile(p); } else if (o instanceof FileSystemLocation l) { return createFromFile(l); + } else if (o instanceof URL url) { + return createFromUrl(url); } else if (o instanceof FileSpec s) { return s; } @@ -101,6 +114,10 @@ public interface FileSpec { return createFromFile(path.toFile()); } + static FileSpec createFromUrl(URL url) { + return new URLFileSpec(url); + } + // Note resolved instantly, this is not lazy static FileSpec createFromFile(RegularFileProperty regularFileProperty) { return createFromFile(regularFileProperty.get()); diff --git a/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java b/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java index 3088439b..0fa5a5b8 100644 --- a/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java +++ b/src/main/java/net/fabricmc/loom/build/mixin/AnnotationProcessorInvoker.java @@ -1,7 +1,7 @@ /* * This file is part of fabric-loom, licensed under the MIT License (MIT). * - * Copyright (c) 2020-2021 FabricMC + * Copyright (c) 2020-2022 FabricMC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -91,6 +91,7 @@ public abstract class AnnotationProcessorInvoker { put(Constants.MixinArguments.OUT_MAP_FILE_NAMED_INTERMEDIARY, MixinMappingsService.getMixinMappingFile(project, sourceSet).getCanonicalPath()); put(Constants.MixinArguments.OUT_REFMAP_FILE, getRefmapDestination(task, refmapName)); put(Constants.MixinArguments.DEFAULT_OBFUSCATION_ENV, "named:intermediary"); + put(Constants.MixinArguments.QUIET, "true"); }}; project.getLogger().debug("Outputting refmap to dir: " + getRefmapDestinationDir(task) + " for compile task: " + task); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java index 6a47ed71..d529a333 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsDependency.java @@ -59,6 +59,7 @@ import net.fabricmc.loom.LoomGradlePlugin; import net.fabricmc.loom.api.mappings.layered.MappingContext; import net.fabricmc.loom.api.mappings.layered.MappingLayer; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.configuration.providers.mappings.extras.unpick.UnpickLayer; import net.fabricmc.loom.util.ZipUtils; import net.fabricmc.mappingio.adapter.MappingDstNsReorder; import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; @@ -96,6 +97,7 @@ public class LayeredMappingsDependency extends AbstractModuleDependency implemen writeMapping(processor, layers, mappingsFile); writeSignatureFixes(processor, layers, mappingsFile); + writeUnpickData(processor, layers, mappingsFile); } catch (IOException e) { throw new RuntimeException("Failed to resolve layered mappings", e); } @@ -131,6 +133,17 @@ public class LayeredMappingsDependency extends AbstractModuleDependency implemen ZipUtils.add(mappingsFile, "extras/record_signatures.json", data); } + private void writeUnpickData(LayeredMappingsProcessor processor, List layers, Path mappingsFile) throws IOException { + UnpickLayer.UnpickData unpickData = processor.getUnpickData(layers); + + if (unpickData == null) { + return; + } + + ZipUtils.add(mappingsFile, "extras/definitions.unpick", unpickData.definitions()); + ZipUtils.add(mappingsFile, "extras/unpick.json", unpickData.metadata().asJson()); + } + @Override public Set resolve(boolean transitive) { return resolve(); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java index f2edfb2b..6f4a9f63 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/LayeredMappingsProcessor.java @@ -39,6 +39,7 @@ import net.fabricmc.loom.api.mappings.layered.MappingLayer; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; import net.fabricmc.loom.api.mappings.layered.spec.MappingsSpec; import net.fabricmc.loom.configuration.providers.mappings.extras.signatures.SignatureFixesLayer; +import net.fabricmc.loom.configuration.providers.mappings.extras.unpick.UnpickLayer; import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch; import net.fabricmc.mappingio.tree.MemoryMappingTree; @@ -122,4 +123,29 @@ public class LayeredMappingsProcessor { return Collections.unmodifiableMap(signatureFixes); } + + @Nullable + public UnpickLayer.UnpickData getUnpickData(List layers) throws IOException { + List unpickDataList = new ArrayList<>(); + + for (MappingLayer layer : layers) { + if (layer instanceof UnpickLayer unpickLayer) { + UnpickLayer.UnpickData data = unpickLayer.getUnpickData(); + if (data == null) continue; + + unpickDataList.add(data); + } + } + + if (unpickDataList.isEmpty()) { + return null; + } + + if (unpickDataList.size() != 1) { + // TODO merge + throw new UnsupportedOperationException("Only one unpick layer is currently supported."); + } + + return unpickDataList.get(0); + } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/extras/unpick/UnpickLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/extras/unpick/UnpickLayer.java new file mode 100644 index 00000000..ce53e64b --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/extras/unpick/UnpickLayer.java @@ -0,0 +1,61 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.extras.unpick; + +import java.io.IOException; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import net.fabricmc.loom.LoomGradlePlugin; + +@ApiStatus.Experimental +public interface UnpickLayer { + @Nullable + UnpickData getUnpickData() throws IOException; + + record UnpickData(Metadata metadata, byte[] definitions) { + public static UnpickData read(Path metadataPath, Path definitionPath) throws IOException { + final byte[] definitions = Files.readAllBytes(definitionPath); + final Metadata metadata; + + try (Reader reader = Files.newBufferedReader(metadataPath, StandardCharsets.UTF_8)) { + metadata = LoomGradlePlugin.OBJECT_MAPPER.readValue(reader, Metadata.class); + } + + return new UnpickData(metadata, definitions); + } + + public record Metadata(int version, String unpickGroup, String unpickVersion) { + public String asJson() throws IOException { + return LoomGradlePlugin.OBJECT_MAPPER.writeValueAsString(this); + } + } + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsLayer.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsLayer.java index 9cc0a5cc..06b79461 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsLayer.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsLayer.java @@ -25,12 +25,16 @@ package net.fabricmc.loom.configuration.providers.mappings.file; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.util.List; import java.util.Map; +import org.jetbrains.annotations.Nullable; + import net.fabricmc.loom.api.mappings.layered.MappingLayer; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.configuration.providers.mappings.extras.unpick.UnpickLayer; import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingLayer; import net.fabricmc.loom.util.FileSystemUtil; import net.fabricmc.loom.util.ZipUtils; @@ -45,8 +49,12 @@ public record FileMappingsLayer( Path path, String mappingPath, String fallbackSourceNamespace, String fallbackTargetNamespace, boolean enigma, // Enigma cannot be automatically detected since it's stored in a directory. + boolean unpick, String mergeNamespace -) implements MappingLayer { +) implements MappingLayer, UnpickLayer { + private static final String UNPICK_METADATA_PATH = "extras/unpick.json"; + private static final String UNPICK_DEFINITIONS_PATH = "extras/definitions.unpick"; + @Override public void visit(MappingVisitor mappingVisitor) throws IOException { // Bare file @@ -82,4 +90,27 @@ public record FileMappingsLayer( public List> dependsOn() { return List.of(IntermediaryMappingLayer.class); } + + @Override + public @Nullable UnpickData getUnpickData() throws IOException { + if (!unpick) { + return null; + } + + if (!ZipUtils.isZip(path)) { + throw new UnsupportedOperationException("Unpick is only supported for zip file mapping layers."); + } + + try (FileSystemUtil.Delegate fileSystem = FileSystemUtil.getJarFileSystem(path)) { + final Path unpickMetadata = fileSystem.get().getPath(UNPICK_METADATA_PATH); + final Path unpickDefinitions = fileSystem.get().getPath(UNPICK_DEFINITIONS_PATH); + + if (!Files.exists(unpickMetadata)) { + // No unpick in this zip + return null; + } + + return UnpickData.read(unpickMetadata, unpickDefinitions); + } + } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsSpec.java index 5d8a1669..cdf3a266 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsSpec.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsSpec.java @@ -31,11 +31,11 @@ import net.fabricmc.loom.api.mappings.layered.spec.MappingsSpec; public record FileMappingsSpec( FileSpec fileSpec, String mappingPath, String fallbackSourceNamespace, String fallbackTargetNamespace, - boolean enigma, + boolean enigma, boolean unpick, String mergeNamespace ) implements MappingsSpec { @Override public FileMappingsLayer createLayer(MappingContext context) { - return new FileMappingsLayer(fileSpec.get(context), mappingPath, fallbackSourceNamespace, fallbackTargetNamespace, enigma, mergeNamespace); + return new FileMappingsLayer(fileSpec.get(context), mappingPath, fallbackSourceNamespace, fallbackTargetNamespace, enigma, unpick, mergeNamespace); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsSpecBuilderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsSpecBuilderImpl.java index 53681ad6..441d5120 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsSpecBuilderImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/file/FileMappingsSpecBuilderImpl.java @@ -41,6 +41,7 @@ public class FileMappingsSpecBuilderImpl implements FileMappingsSpecBuilder { private String fallbackSourceNamespace = MappingsNamespace.INTERMEDIARY.toString(); private String fallbackTargetNamespace = MappingsNamespace.NAMED.toString(); private boolean enigma = false; + private boolean unpick = false; private String mergeNamespace = MappingsNamespace.INTERMEDIARY.toString(); private FileMappingsSpecBuilderImpl(FileSpec fileSpec) { @@ -70,6 +71,12 @@ public class FileMappingsSpecBuilderImpl implements FileMappingsSpecBuilder { return this; } + @Override + public FileMappingsSpecBuilderImpl containsUnpick() { + unpick = true; + return this; + } + @Override public FileMappingsSpecBuilderImpl mergeNamespace(MappingsNamespace namespace) { mergeNamespace = Objects.requireNonNull(namespace, "merge namespace cannot be null").toString(); @@ -89,6 +96,6 @@ public class FileMappingsSpecBuilderImpl implements FileMappingsSpecBuilder { } public FileMappingsSpec build() { - return new FileMappingsSpec(fileSpec, mappingPath, fallbackSourceNamespace, fallbackTargetNamespace, enigma, mergeNamespace); + return new FileMappingsSpec(fileSpec, mappingPath, fallbackSourceNamespace, fallbackTargetNamespace, enigma, unpick, mergeNamespace); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/URLFileSpec.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/URLFileSpec.java new file mode 100644 index 00000000..88a6808a --- /dev/null +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/utils/URLFileSpec.java @@ -0,0 +1,59 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.configuration.providers.mappings.utils; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.URL; +import java.nio.file.Path; +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.fabricmc.loom.api.mappings.layered.MappingContext; +import net.fabricmc.loom.api.mappings.layered.spec.FileSpec; +import net.fabricmc.loom.util.DownloadUtil; + +public record URLFileSpec(URL url) implements FileSpec { + private static final Logger LOGGER = LoggerFactory.getLogger(URLFileSpec.class); + @Override + public Path get(MappingContext context) { + try { + Path output = context.workingDirectory("%d.URLFileSpec".formatted(Objects.hash(url.toString()))); + LOGGER.info("Downloading {} to {}", url, output); + DownloadUtil.downloadIfChanged(url, output.toFile(), LOGGER); + return output; + } catch (IOException e) { + throw new UncheckedIOException("Failed to download: " + url, e); + } + } + + @Override + public int hashCode() { + // URL performs DNS requests if you .hashCode it (: + return Objects.hash(url.toString()); + } +} diff --git a/src/main/java/net/fabricmc/loom/util/Constants.java b/src/main/java/net/fabricmc/loom/util/Constants.java index 995f77ba..7ac8f43c 100644 --- a/src/main/java/net/fabricmc/loom/util/Constants.java +++ b/src/main/java/net/fabricmc/loom/util/Constants.java @@ -1,7 +1,7 @@ /* * This file is part of fabric-loom, licensed under the MIT License (MIT). * - * Copyright (c) 2016-2021 FabricMC + * Copyright (c) 2016-2022 FabricMC * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -134,7 +134,7 @@ public class Constants { * Constants for versions of dependencies. */ public static final class Versions { - public static final String MIXIN_COMPILE_EXTENSIONS = "0.4.6"; + public static final String MIXIN_COMPILE_EXTENSIONS = "0.4.7"; public static final String DEV_LAUNCH_INJECTOR = "0.2.1+build.8"; public static final String TERMINAL_CONSOLE_APPENDER = "1.2.0"; public static final String JETBRAINS_ANNOTATIONS = "23.0.0"; @@ -154,6 +154,7 @@ public class Constants { public static final String OUT_MAP_FILE_NAMED_INTERMEDIARY = "outMapFileNamedIntermediary"; public static final String OUT_REFMAP_FILE = "outRefMapFile"; public static final String DEFAULT_OBFUSCATION_ENV = "defaultObfuscationEnv"; + public static final String QUIET = "quiet"; private MixinArguments() { } diff --git a/src/main/java/net/fabricmc/loom/util/ZipUtils.java b/src/main/java/net/fabricmc/loom/util/ZipUtils.java index d1e2f1bd..c4a35a3a 100644 --- a/src/main/java/net/fabricmc/loom/util/ZipUtils.java +++ b/src/main/java/net/fabricmc/loom/util/ZipUtils.java @@ -131,6 +131,10 @@ public class ZipUtils { } } + public static void add(Path zip, String path, String str) throws IOException { + add(zip, path, str.getBytes(StandardCharsets.UTF_8)); + } + public static void add(Path zip, String path, byte[] bytes) throws IOException { add(zip, Collections.singleton(new Pair<>(path, bytes))); } diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/FileMappingLayerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/FileMappingLayerTest.groovy index b983cf45..087ed059 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/FileMappingLayerTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/FileMappingLayerTest.groovy @@ -107,6 +107,9 @@ class FileMappingLayerTest extends LayeredMappingsSpecification { }, { it.mappingPath("mappings").enigmaMappings() }), + YARN_V2_URL('yarn url', { + YARN_1_17_URL + }, { }) ; final String displayName diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy index 5d7bdec8..16905cb9 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingSpecBuilderTest.groovy @@ -113,7 +113,7 @@ class LayeredMappingSpecBuilderTest extends LayeredMappingsSpecification { } def layers = spec.layers() then: - spec.version == "layered+hash.1284206205" + spec.version == "layered+hash.1133958200" layers.size() == 2 layers[0].class == IntermediaryMappingsSpec layers[1].class == FileMappingsSpec diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy index e0ce582b..13a94047 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/LayeredMappingsSpecification.groovy @@ -31,6 +31,7 @@ import net.fabricmc.loom.api.mappings.layered.spec.MappingsSpec import net.fabricmc.loom.configuration.providers.mappings.IntermediaryService import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingSpec import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsProcessor +import net.fabricmc.loom.configuration.providers.mappings.extras.unpick.UnpickLayer import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider import net.fabricmc.mappingio.adapter.MappingDstNsReorder import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch @@ -87,6 +88,12 @@ abstract class LayeredMappingsSpecification extends Specification implements Lay return processor.getMappings(processor.resolveLayers(mappingContext)) } + UnpickLayer.UnpickData getUnpickData(MappingsSpec... specs) { + LayeredMappingSpec spec = new LayeredMappingSpec(specs.toList()) + LayeredMappingsProcessor processor = new LayeredMappingsProcessor(spec) + return processor.getUnpickData(processor.resolveLayers(mappingContext)) + } + String getTiny(MemoryMappingTree mappingTree) { def sw = new StringWriter() mappingTree.accept(new Tiny2Writer(sw, false)) diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/UnpickLayerTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/UnpickLayerTest.groovy new file mode 100644 index 00000000..0e43bcad --- /dev/null +++ b/src/test/groovy/net/fabricmc/loom/test/unit/layeredmappings/UnpickLayerTest.groovy @@ -0,0 +1,50 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2022 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.test.unit.layeredmappings + +import net.fabricmc.loom.api.mappings.layered.spec.FileSpec +import net.fabricmc.loom.configuration.providers.mappings.file.FileMappingsSpecBuilderImpl +import net.fabricmc.loom.configuration.providers.mappings.intermediary.IntermediaryMappingsSpec + +class UnpickLayerTest extends LayeredMappingsSpecification { + def "read unpick data from yarn"() { + setup: + intermediaryUrl = INTERMEDIARY_1_17_URL + mockMinecraftProvider.getVersionInfo() >> VERSION_META_1_17 + when: + def builder = FileMappingsSpecBuilderImpl.builder(FileSpec.create(YARN_1_17_URL)).containsUnpick() + def unpickData = getUnpickData( + new IntermediaryMappingsSpec(), + builder.build() + ) + def metadata = unpickData.metadata() + then: + metadata.version() == 1 + metadata.unpickGroup() == "net.fabricmc.unpick" + metadata.unpickVersion() == "2.2.0" + + unpickData.definitions().length == 56119 + } +}