mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-03-30 05:05:20 -05:00
Read "Fabric-Loom-Remap" manifest entry to allow an artifact to control if its remapped or not. (#749)
This allows for none mod jars to opt-into remapping, as well as mods or mod loaders to opt-out. Setting "Fabric-Loom-Remap" to true/false in the jar's manifest.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2021 FabricMC
|
||||
* Copyright (c) 2021-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
|
||||
@@ -25,6 +25,55 @@
|
||||
package net.fabricmc.loom.configuration;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.ExternalModuleDependency;
|
||||
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.LoomRepositoryPlugin;
|
||||
import net.fabricmc.loom.configuration.ide.idea.IdeaUtils;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
|
||||
public record InstallerData(String version, JsonObject installerJson) {
|
||||
public void applyToProject(Project project) {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
|
||||
if (extension.getInstallerData() != null) {
|
||||
throw new IllegalStateException("Already applied installer data");
|
||||
}
|
||||
|
||||
extension.setInstallerData(this);
|
||||
|
||||
JsonObject libraries = installerJson.get("libraries").getAsJsonObject();
|
||||
Configuration loaderDepsConfig = project.getConfigurations().getByName(Constants.Configurations.LOADER_DEPENDENCIES);
|
||||
Configuration apDepsConfig = project.getConfigurations().getByName("annotationProcessor");
|
||||
|
||||
libraries.get("common").getAsJsonArray().forEach(jsonElement -> {
|
||||
String name = jsonElement.getAsJsonObject().get("name").getAsString();
|
||||
project.getLogger().debug("Adding dependency ({}) from installer JSON", name);
|
||||
|
||||
ExternalModuleDependency modDep = (ExternalModuleDependency) project.getDependencies().create(name);
|
||||
modDep.setTransitive(false);
|
||||
loaderDepsConfig.getDependencies().add(modDep);
|
||||
|
||||
// TODO: work around until https://github.com/FabricMC/Mixin/pull/60 and https://github.com/FabricMC/fabric-mixin-compile-extensions/issues/14 is fixed.
|
||||
if (!IdeaUtils.isIdeaSync() && extension.getMixin().getUseLegacyMixinAp().get()) {
|
||||
apDepsConfig.getDependencies().add(modDep);
|
||||
}
|
||||
|
||||
// If user choose to use dependencyResolutionManagement, then they should declare
|
||||
// these repositories manually in the settings file.
|
||||
if (jsonElement.getAsJsonObject().has("url") && !project.getGradle().getPlugins().hasPlugin(LoomRepositoryPlugin.class)) {
|
||||
String url = jsonElement.getAsJsonObject().get("url").getAsString();
|
||||
long count = project.getRepositories().stream().filter(artifactRepository -> artifactRepository instanceof MavenArtifactRepository)
|
||||
.map(artifactRepository -> (MavenArtifactRepository) artifactRepository)
|
||||
.filter(mavenArtifactRepository -> mavenArtifactRepository.getUrl().toString().equalsIgnoreCase(url)).count();
|
||||
|
||||
if (count == 0) {
|
||||
project.getRepositories().maven(mavenArtifactRepository -> mavenArtifactRepository.setUrl(jsonElement.getAsJsonObject().get("url").getAsString()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,58 +24,18 @@
|
||||
|
||||
package net.fabricmc.loom.configuration;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.artifacts.ExternalModuleDependency;
|
||||
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.LoomGradlePlugin;
|
||||
import net.fabricmc.loom.LoomRepositoryPlugin;
|
||||
import net.fabricmc.loom.configuration.ide.idea.IdeaUtils;
|
||||
import net.fabricmc.loom.configuration.mods.ModConfigurationRemapper;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.SourceRemapper;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
|
||||
public class LoomDependencyManager {
|
||||
public void handleDependencies(Project project, SharedServiceManager serviceManager) {
|
||||
List<Runnable> afterTasks = new ArrayList<>();
|
||||
|
||||
project.getLogger().info(":setting up loom dependencies");
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
|
||||
if (extension.getInstallerData() == null) {
|
||||
//If we've not found the installer JSON we've probably skipped remapping Fabric loader, let's go looking
|
||||
project.getLogger().info("Searching through modCompileClasspath for installer JSON");
|
||||
final Configuration configuration = project.getConfigurations().getByName(Constants.Configurations.MOD_COMPILE_CLASSPATH);
|
||||
|
||||
for (Dependency dependency : configuration.getAllDependencies()) {
|
||||
for (File input : configuration.files(dependency)) {
|
||||
JsonObject jsonObject = readInstallerJson(input);
|
||||
|
||||
if (jsonObject != null) {
|
||||
if (extension.getInstallerData() != null) {
|
||||
project.getLogger().info("Found another installer JSON in, ignoring it! " + input);
|
||||
continue;
|
||||
}
|
||||
|
||||
project.getLogger().info("Found installer JSON in " + input);
|
||||
extension.setInstallerData(new InstallerData(dependency.getVersion(), jsonObject));
|
||||
handleInstallerJson(jsonObject, project);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SourceRemapper sourceRemapper = new SourceRemapper(project, serviceManager, true);
|
||||
String mappingsIdentifier = extension.getMappingConfiguration().mappingsIdentifier();
|
||||
|
||||
@@ -84,61 +44,7 @@ public class LoomDependencyManager {
|
||||
sourceRemapper.remapAll();
|
||||
|
||||
if (extension.getInstallerData() == null) {
|
||||
project.getLogger().warn("fabric-installer.json not found in classpath!");
|
||||
project.getLogger().warn("fabric-installer.json not found in dependencies!");
|
||||
}
|
||||
|
||||
for (Runnable runnable : afterTasks) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonObject readInstallerJson(File file) {
|
||||
try {
|
||||
byte[] bytes = ZipUtils.unpackNullable(file.toPath(), "fabric-installer.json");
|
||||
|
||||
if (bytes == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return LoomGradlePlugin.GSON.fromJson(new String(bytes, StandardCharsets.UTF_8), JsonObject.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to try and read installer json from " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleInstallerJson(JsonObject jsonObject, Project project) {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
|
||||
JsonObject libraries = jsonObject.get("libraries").getAsJsonObject();
|
||||
Configuration loaderDepsConfig = project.getConfigurations().getByName(Constants.Configurations.LOADER_DEPENDENCIES);
|
||||
Configuration apDepsConfig = project.getConfigurations().getByName("annotationProcessor");
|
||||
|
||||
libraries.get("common").getAsJsonArray().forEach(jsonElement -> {
|
||||
String name = jsonElement.getAsJsonObject().get("name").getAsString();
|
||||
|
||||
ExternalModuleDependency modDep = (ExternalModuleDependency) project.getDependencies().create(name);
|
||||
modDep.setTransitive(false);
|
||||
loaderDepsConfig.getDependencies().add(modDep);
|
||||
|
||||
// TODO: work around until https://github.com/FabricMC/Mixin/pull/60 and https://github.com/FabricMC/fabric-mixin-compile-extensions/issues/14 is fixed.
|
||||
if (!IdeaUtils.isIdeaSync() && extension.getMixin().getUseLegacyMixinAp().get()) {
|
||||
apDepsConfig.getDependencies().add(modDep);
|
||||
}
|
||||
|
||||
project.getLogger().debug("Loom adding " + name + " from installer JSON");
|
||||
|
||||
// If user choose to use dependencyResolutionManagement, then they should declare
|
||||
// these repositories manually in the settings file.
|
||||
if (jsonElement.getAsJsonObject().has("url") && !project.getGradle().getPlugins().hasPlugin(LoomRepositoryPlugin.class)) {
|
||||
String url = jsonElement.getAsJsonObject().get("url").getAsString();
|
||||
long count = project.getRepositories().stream().filter(artifactRepository -> artifactRepository instanceof MavenArtifactRepository)
|
||||
.map(artifactRepository -> (MavenArtifactRepository) artifactRepository)
|
||||
.filter(mavenArtifactRepository -> mavenArtifactRepository.getUrl().toString().equalsIgnoreCase(url)).count();
|
||||
|
||||
if (count == 0) {
|
||||
project.getRepositories().maven(mavenArtifactRepository -> mavenArtifactRepository.setUrl(jsonElement.getAsJsonObject().get("url").getAsString()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.mods;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.loom.LoomGradlePlugin;
|
||||
import net.fabricmc.loom.configuration.InstallerData;
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
|
||||
public record ArtifactMetadata(boolean isFabricMod, RemapRequirements remapRequirements, @Nullable InstallerData installerData) {
|
||||
private static final String INSTALLER_PATH = "fabric-installer.json";
|
||||
private static final String MANIFEST_PATH = "META-INF/MANIFEST.MF";
|
||||
private static final String MANIFEST_REMAP_KEY = "Fabric-Loom-Remap";
|
||||
|
||||
public static ArtifactMetadata create(ArtifactRef artifact) throws IOException {
|
||||
boolean isFabricMod;
|
||||
RemapRequirements remapRequirements = RemapRequirements.DEFAULT;
|
||||
InstallerData installerData = null;
|
||||
|
||||
try (FileSystemUtil.Delegate fs = FileSystemUtil.getJarFileSystem(artifact.path())) {
|
||||
isFabricMod = FabricModJsonFactory.containsMod(fs);
|
||||
final Path manifestPath = fs.getPath(MANIFEST_PATH);
|
||||
|
||||
if (Files.exists(manifestPath)) {
|
||||
final var manifest = new Manifest(new ByteArrayInputStream(Files.readAllBytes(manifestPath)));
|
||||
final Attributes mainAttributes = manifest.getMainAttributes();
|
||||
final String value = mainAttributes.getValue(MANIFEST_REMAP_KEY);
|
||||
|
||||
if (value != null) {
|
||||
// Support opting into and out of remapping with "Fabric-Loom-Remap" manifest entry
|
||||
remapRequirements = Boolean.parseBoolean(value) ? RemapRequirements.OPT_IN : RemapRequirements.OPT_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
final Path installerPath = fs.getPath(INSTALLER_PATH);
|
||||
|
||||
if (isFabricMod && Files.exists(installerPath)) {
|
||||
final JsonObject jsonObject = LoomGradlePlugin.GSON.fromJson(Files.readString(installerPath, StandardCharsets.UTF_8), JsonObject.class);
|
||||
installerData = new InstallerData(artifact.version(), jsonObject);
|
||||
}
|
||||
}
|
||||
|
||||
return new ArtifactMetadata(isFabricMod, remapRequirements, installerData);
|
||||
}
|
||||
|
||||
public boolean shouldRemap() {
|
||||
return remapRequirements().getShouldRemap().test(this);
|
||||
}
|
||||
|
||||
public enum RemapRequirements {
|
||||
DEFAULT(ArtifactMetadata::isFabricMod),
|
||||
OPT_IN(true),
|
||||
OPT_OUT(false);
|
||||
|
||||
private final Predicate<ArtifactMetadata> shouldRemap;
|
||||
|
||||
RemapRequirements(Predicate<ArtifactMetadata> shouldRemap) {
|
||||
this.shouldRemap = shouldRemap;
|
||||
}
|
||||
|
||||
RemapRequirements(final boolean shouldRemap) {
|
||||
this.shouldRemap = artifactMetadata -> shouldRemap;
|
||||
}
|
||||
|
||||
private Predicate<ArtifactMetadata> getShouldRemap() {
|
||||
return shouldRemap;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,6 @@ import net.fabricmc.loom.util.Checksum;
|
||||
import net.fabricmc.loom.util.Constants;
|
||||
import net.fabricmc.loom.util.OperatingSystem;
|
||||
import net.fabricmc.loom.util.SourceRemapper;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
import net.fabricmc.loom.util.service.SharedServiceManager;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@@ -89,7 +88,24 @@ public class ModConfigurationRemapper {
|
||||
final List<ModDependency> modDependencies = new ArrayList<>();
|
||||
|
||||
for (ArtifactRef artifact : resolveArtifacts(project, sourceConfig)) {
|
||||
if (!FabricModJsonFactory.isModJar(artifact.path())) {
|
||||
final ArtifactMetadata artifactMetadata;
|
||||
|
||||
try {
|
||||
artifactMetadata = ArtifactMetadata.create(artifact);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read metadata from" + artifact.path(), e);
|
||||
}
|
||||
|
||||
if (artifactMetadata.installerData() != null) {
|
||||
if (extension.getInstallerData() != null) {
|
||||
project.getLogger().info("Found another installer JSON in ({}), ignoring", artifact.path());
|
||||
} else {
|
||||
project.getLogger().info("Applying installer data from {}", artifact.path());
|
||||
artifactMetadata.installerData().applyToProject(project);
|
||||
}
|
||||
}
|
||||
|
||||
if (!artifactMetadata.shouldRemap()) {
|
||||
artifact.applyToConfiguration(project, targetConfig);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
import net.fabricmc.loom.LoomGradlePlugin;
|
||||
import net.fabricmc.loom.util.FileSystemUtil;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper;
|
||||
|
||||
@@ -124,4 +125,8 @@ public final class FabricModJsonFactory {
|
||||
public static boolean isModJar(Path input) {
|
||||
return ZipUtils.contains(input, FABRIC_MOD_JSON);
|
||||
}
|
||||
|
||||
public static boolean containsMod(FileSystemUtil.Delegate fs) {
|
||||
return Files.exists(fs.getPath(FABRIC_MOD_JSON));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class FabricAPIBenchmark implements GradleProjectTestTrait {
|
||||
|
||||
def timeStart = new Date()
|
||||
|
||||
def result = gradle.run(tasks: ["clean", "build"], args: ["--parallel", "-x", "check", "-x", "test", "-x", ":fabric-data-generation-api-v1:runDatagen", "-x", "javadoc"])
|
||||
def result = gradle.run(tasks: ["clean"], args: [])
|
||||
|
||||
def timeStop = new Date()
|
||||
TimeDuration duration = TimeCategory.minus(timeStop, timeStart)
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import net.fabricmc.loom.configuration.mods.ArtifactMetadata
|
||||
import net.fabricmc.loom.configuration.mods.ArtifactRef
|
||||
import net.fabricmc.loom.util.FileSystemUtil
|
||||
import spock.lang.Specification
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.jar.Attributes
|
||||
import java.util.jar.Manifest
|
||||
|
||||
import static net.fabricmc.loom.configuration.mods.ArtifactMetadata.RemapRequirements.*
|
||||
|
||||
class ArtifactMetadataTest extends Specification {
|
||||
def "is fabric mod"() {
|
||||
given:
|
||||
def zip = createZip(entries)
|
||||
when:
|
||||
def metadata = createMetadata(zip)
|
||||
then:
|
||||
isMod == metadata.isFabricMod()
|
||||
where:
|
||||
isMod | entries
|
||||
false | ["hello.json": "{}"] // None Mod jar
|
||||
true | ["fabric.mod.json": "{}"] // Fabric mod
|
||||
}
|
||||
|
||||
def "remap requirements"() {
|
||||
given:
|
||||
def zip = createZip(entries)
|
||||
when:
|
||||
def metadata = createMetadata(zip)
|
||||
then:
|
||||
requirements == metadata.remapRequirements()
|
||||
where:
|
||||
requirements | entries
|
||||
DEFAULT | ["fabric.mod.json": "{}"] // Default
|
||||
OPT_OUT | ["META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "false")] // opt-out
|
||||
OPT_IN | ["META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "true")] // opt-in
|
||||
}
|
||||
|
||||
def "Should Remap" () {
|
||||
given:
|
||||
def zip = createZip(entries)
|
||||
when:
|
||||
def metadata = createMetadata(zip)
|
||||
def result = metadata.shouldRemap()
|
||||
then:
|
||||
result == shouldRemap
|
||||
where:
|
||||
shouldRemap | entries
|
||||
false | ["hello.json": "{}"] // None Mod jar
|
||||
true | ["fabric.mod.json": "{}"] // Fabric mod
|
||||
false | ["fabric.mod.json": "{}",
|
||||
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "false")] // Fabric mod opt-out
|
||||
true | ["fabric.mod.json": "{}",
|
||||
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "true")] // Fabric mod opt-in
|
||||
false | ["hello.json": "{}",
|
||||
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "false")] // None opt-out
|
||||
true | ["hello.json": "{}",
|
||||
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "true")] // None opt-int
|
||||
false | ["hello.json": "{}",
|
||||
"META-INF/MANIFEST.MF": manifest("Fabric-Loom-Remap", "broken")]// Invalid format
|
||||
false | ["hello.json": "{}",
|
||||
"META-INF/MANIFEST.MF": manifest("Something", "Hello")] // Invalid format
|
||||
}
|
||||
|
||||
def "Installer data"() {
|
||||
given:
|
||||
def zip = createZip(entries)
|
||||
when:
|
||||
def metadata = createMetadata(zip)
|
||||
then:
|
||||
isLoader == (metadata.installerData() != null)
|
||||
where:
|
||||
isLoader | entries
|
||||
true | ["fabric.mod.json": "{}", "fabric-installer.json": "{}"] // Fabric mod, with installer data
|
||||
false | ["fabric.mod.json": "{}"] // Fabric mod, no installer data
|
||||
}
|
||||
|
||||
private static ArtifactMetadata createMetadata(Path zip) {
|
||||
return ArtifactMetadata.create(createArtifact(zip))
|
||||
}
|
||||
|
||||
private static ArtifactRef createArtifact(Path zip) {
|
||||
return new ArtifactRef.FileArtifactRef(zip, "net.fabric", "loom-test", "1.0")
|
||||
}
|
||||
|
||||
private static Path createZip(Map<String, String> entries) {
|
||||
def file = Files.createTempFile("loom-test", ".zip")
|
||||
Files.delete(file)
|
||||
|
||||
FileSystemUtil.getJarFileSystem(file, true).withCloseable { zip ->
|
||||
entries.forEach { path, value ->
|
||||
def fsPath = zip.getPath(path)
|
||||
def fsPathParent = fsPath.getParent()
|
||||
if (fsPathParent != null) Files.createDirectories(fsPathParent)
|
||||
Files.writeString(fsPath, value, StandardCharsets.UTF_8)
|
||||
}
|
||||
}
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
private String manifest(String key, String value) {
|
||||
def manifest = new Manifest()
|
||||
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0")
|
||||
manifest.getMainAttributes().putValue(key, value)
|
||||
|
||||
def out = new ByteArrayOutputStream()
|
||||
manifest.write(out)
|
||||
return out.toString(StandardCharsets.UTF_8)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user