mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-03-30 21:05:58 -05:00
Merge remote-tracking branch 'upstream/dev/1.3' into dev/1.3
# Conflicts: # src/main/java/net/fabricmc/loom/build/nesting/IncludedJarFactory.java
This commit is contained in:
@@ -60,7 +60,7 @@ import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.LoomGradlePlugin;
|
||||
import net.fabricmc.loom.task.RemapTaskConfiguration;
|
||||
import net.fabricmc.loom.util.Pair;
|
||||
import net.fabricmc.loom.util.ZipUtils;
|
||||
import net.fabricmc.loom.util.ZipReprocessorUtil;
|
||||
import net.fabricmc.loom.util.fmj.FabricModJsonFactory;
|
||||
|
||||
public final class IncludedJarFactory {
|
||||
@@ -190,7 +190,7 @@ public final class IncludedJarFactory {
|
||||
FileUtils.copyFile(input, tempFile);
|
||||
|
||||
// TODO generate Quilt qmjs natively
|
||||
ZipUtils.add(tempFile.toPath(), "fabric.mod.json", generateModForDependency(metadata).getBytes(StandardCharsets.UTF_8));
|
||||
ZipReprocessorUtil.appendZipEntry(tempFile, "fabric.mod.json", generateModForDependency(metadata).getBytes(StandardCharsets.UTF_8));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to add dummy mod while including %s".formatted(input), e);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.gradle.api.Named;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.provider.Property;
|
||||
@@ -49,7 +51,7 @@ import net.fabricmc.loom.util.ModPlatform;
|
||||
import net.fabricmc.loom.util.Platform;
|
||||
import net.fabricmc.loom.util.gradle.SourceSetHelper;
|
||||
|
||||
public final class RunConfigSettings implements Named {
|
||||
public class RunConfigSettings implements Named {
|
||||
/**
|
||||
* Arguments for the JVM, such as system properties.
|
||||
*/
|
||||
@@ -70,7 +72,7 @@ public final class RunConfigSettings implements Named {
|
||||
*
|
||||
* <p>By default this is determined from the base name.
|
||||
*/
|
||||
private String name;
|
||||
private String configName;
|
||||
|
||||
/**
|
||||
* The default main class of the run configuration.
|
||||
@@ -101,7 +103,7 @@ public final class RunConfigSettings implements Named {
|
||||
/**
|
||||
* The base name of the run configuration, which is the name it is created with, i.e. 'client'
|
||||
*/
|
||||
private final String baseName;
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* When true a run configuration file will be generated for IDE's.
|
||||
@@ -117,14 +119,15 @@ public final class RunConfigSettings implements Named {
|
||||
private final List<Runnable> evaluateLater = new ArrayList<>();
|
||||
private boolean evaluated = false;
|
||||
|
||||
public RunConfigSettings(Project project, String baseName) {
|
||||
this.baseName = baseName;
|
||||
@Inject
|
||||
public RunConfigSettings(Project project, String name) {
|
||||
this.name = name;
|
||||
this.project = project;
|
||||
this.extension = LoomGradleExtension.get(project);
|
||||
this.ideConfigGenerated = extension.isRootProject();
|
||||
this.mainClass = project.getObjects().property(String.class).convention(project.provider(() -> {
|
||||
Objects.requireNonNull(environment, "Run config " + baseName + " must specify environment");
|
||||
Objects.requireNonNull(defaultMainClass, "Run config " + baseName + " must specify default main class");
|
||||
Objects.requireNonNull(environment, "Run config " + name + " must specify environment");
|
||||
Objects.requireNonNull(defaultMainClass, "Run config " + name + " must specify default main class");
|
||||
return RunConfig.getMainClass(environment, extension, defaultMainClass);
|
||||
}));
|
||||
|
||||
@@ -169,7 +172,11 @@ public final class RunConfigSettings implements Named {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return baseName;
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.configName = name;
|
||||
}
|
||||
|
||||
public List<String> getVmArgs() {
|
||||
@@ -189,11 +196,11 @@ public final class RunConfigSettings implements Named {
|
||||
}
|
||||
|
||||
public String getConfigName() {
|
||||
return name;
|
||||
return configName;
|
||||
}
|
||||
|
||||
public void setConfigName(String name) {
|
||||
this.name = name;
|
||||
this.configName = name;
|
||||
}
|
||||
|
||||
public String getDefaultMainClass() {
|
||||
@@ -394,7 +401,7 @@ public final class RunConfigSettings implements Named {
|
||||
environmentVariables.putAll(parent.environmentVariables);
|
||||
|
||||
environment = parent.environment;
|
||||
name = parent.name;
|
||||
configName = parent.configName;
|
||||
defaultMainClass = parent.defaultMainClass;
|
||||
source = parent.source;
|
||||
ideConfigGenerated = parent.ideConfigGenerated;
|
||||
|
||||
@@ -96,6 +96,7 @@ public class ModConfigurationRemapper {
|
||||
final Configuration sourceCopy = entry.getSourceConfiguration().get().copyRecursive();
|
||||
final Usage usage = project.getObjects().named(Usage.class, runtime ? Usage.JAVA_RUNTIME : Usage.JAVA_API);
|
||||
sourceCopy.attributes(attributes -> attributes.attribute(Usage.USAGE_ATTRIBUTE, usage));
|
||||
sourceCopy.setCanBeConsumed(false);
|
||||
configsToRemap.put(sourceCopy, target);
|
||||
|
||||
// If our remap configuration entry targets the client source set as well,
|
||||
|
||||
@@ -129,6 +129,7 @@ public record SpecContextImpl(List<FabricModJson> modDependencies, List<FabricMo
|
||||
|
||||
return settings -> {
|
||||
final Configuration configuration = settings.getSourceConfiguration().get().copyRecursive();
|
||||
configuration.setCanBeConsumed(false);
|
||||
configuration.attributes(attributes -> attributes.attribute(Usage.USAGE_ATTRIBUTE, usage));
|
||||
return configuration.resolve().stream().map(File::toPath);
|
||||
};
|
||||
|
||||
@@ -194,6 +194,9 @@ public abstract sealed class MinecraftSourceSets permits MinecraftSourceSets.Sin
|
||||
extendsFrom(project, MINECRAFT_CLIENT_ONLY_NAMED.runtime(), MINECRAFT_COMMON_NAMED.runtime());
|
||||
extendsFrom(project, MINECRAFT_CLIENT_ONLY_NAMED.compile(), MINECRAFT_COMMON_NAMED.compile());
|
||||
|
||||
// Client annotation processor configuration extendsFrom "annotationProcessor"
|
||||
extendsFrom(project, clientOnlySourceSet.getAnnotationProcessorConfigurationName(), JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME);
|
||||
|
||||
clientOnlySourceSet.setCompileClasspath(
|
||||
clientOnlySourceSet.getCompileClasspath()
|
||||
.plus(mainSourceSet.getCompileClasspath())
|
||||
|
||||
@@ -138,7 +138,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA
|
||||
this.deprecationHelper = new DeprecationHelper.ProjectBased(project);
|
||||
|
||||
this.runConfigs = project.container(RunConfigSettings.class,
|
||||
baseName -> new RunConfigSettings(project, baseName));
|
||||
baseName -> project.getObjects().newInstance(RunConfigSettings.class, project, baseName));
|
||||
this.decompilers = project.getObjects().domainObjectContainer(DecompilerOptions.class);
|
||||
this.mods = project.getObjects().domainObjectContainer(ModSettings.class);
|
||||
this.remapConfigurations = project.getObjects().namedDomainObjectList(RemapConfigurationSettings.class);
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.Comparator;
|
||||
@@ -95,44 +96,85 @@ public class ZipReprocessorUtil {
|
||||
return;
|
||||
}
|
||||
|
||||
try (ZipFile zipFile = new ZipFile(file)) {
|
||||
try (var zipFile = new ZipFile(file)) {
|
||||
ZipEntry[] entries;
|
||||
|
||||
if (reproducibleFileOrder) {
|
||||
entries = zipFile.stream().sorted(Comparator.comparing(ZipEntry::getName, ZipReprocessorUtil::specialOrdering)).toArray(ZipEntry[]::new);
|
||||
entries = zipFile.stream()
|
||||
.sorted(Comparator.comparing(ZipEntry::getName, ZipReprocessorUtil::specialOrdering))
|
||||
.toArray(ZipEntry[]::new);
|
||||
} else {
|
||||
entries = zipFile.stream().toArray(ZipEntry[]::new);
|
||||
entries = zipFile.stream()
|
||||
.toArray(ZipEntry[]::new);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream outZip = new ByteArrayOutputStream(zipFile.size());
|
||||
final var outZip = new ByteArrayOutputStream(entries.length);
|
||||
|
||||
try (ZipOutputStream zipOutputStream = new ZipOutputStream(outZip)) {
|
||||
try (var zipOutputStream = new ZipOutputStream(outZip)) {
|
||||
for (ZipEntry entry : entries) {
|
||||
ZipEntry newEntry = entry;
|
||||
|
||||
if (!preserveFileTimestamps) {
|
||||
newEntry = new ZipEntry(entry.getName());
|
||||
newEntry.setTime(CONSTANT_TIME_FOR_ZIP_ENTRIES);
|
||||
newEntry.setLastModifiedTime(FileTime.fromMillis(CONSTANT_TIME_FOR_ZIP_ENTRIES));
|
||||
newEntry.setLastAccessTime(FileTime.fromMillis(CONSTANT_TIME_FOR_ZIP_ENTRIES));
|
||||
setConstantFileTime(newEntry);
|
||||
}
|
||||
|
||||
zipOutputStream.putNextEntry(newEntry);
|
||||
InputStream inputStream = zipFile.getInputStream(entry);
|
||||
byte[] buf = new byte[1024];
|
||||
int length;
|
||||
|
||||
while ((length = inputStream.read(buf)) > 0) {
|
||||
zipOutputStream.write(buf, 0, length);
|
||||
}
|
||||
|
||||
zipOutputStream.closeEntry();
|
||||
copyZipEntry(zipOutputStream, newEntry, zipFile.getInputStream(entry));
|
||||
}
|
||||
}
|
||||
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
|
||||
try (var fileOutputStream = new FileOutputStream(file)) {
|
||||
outZip.writeTo(fileOutputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an entry to a zip file, persevering the existing entry order and time stamps.
|
||||
* The new entry is added with a constant time stamp to ensure reproducibility.
|
||||
* This method should only be used when a reproducible output is required, use {@link ZipUtils#add(Path, String, byte[])} normally.
|
||||
*/
|
||||
public static void appendZipEntry(File file, String path, byte[] data) throws IOException {
|
||||
try (var zipFile = new ZipFile(file)) {
|
||||
ZipEntry[] entries = zipFile.stream().toArray(ZipEntry[]::new);
|
||||
|
||||
final var outZip = new ByteArrayOutputStream(entries.length);
|
||||
|
||||
try (var zipOutputStream = new ZipOutputStream(outZip)) {
|
||||
// Copy existing entries
|
||||
for (ZipEntry entry : entries) {
|
||||
copyZipEntry(zipOutputStream, entry, zipFile.getInputStream(entry));
|
||||
}
|
||||
|
||||
// Append the new entry
|
||||
var entry = new ZipEntry(path);
|
||||
setConstantFileTime(entry);
|
||||
zipOutputStream.putNextEntry(entry);
|
||||
zipOutputStream.write(data, 0, data.length);
|
||||
zipOutputStream.closeEntry();
|
||||
}
|
||||
|
||||
try (var fileOutputStream = new FileOutputStream(file)) {
|
||||
outZip.writeTo(fileOutputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyZipEntry(ZipOutputStream zipOutputStream, ZipEntry entry, InputStream inputStream) throws IOException {
|
||||
zipOutputStream.putNextEntry(entry);
|
||||
byte[] buf = new byte[1024];
|
||||
int length;
|
||||
|
||||
while ((length = inputStream.read(buf)) > 0) {
|
||||
zipOutputStream.write(buf, 0, length);
|
||||
}
|
||||
|
||||
zipOutputStream.closeEntry();
|
||||
}
|
||||
|
||||
private static void setConstantFileTime(ZipEntry entry) {
|
||||
entry.setTime(ZipReprocessorUtil.CONSTANT_TIME_FOR_ZIP_ENTRIES);
|
||||
entry.setLastModifiedTime(FileTime.fromMillis(ZipReprocessorUtil.CONSTANT_TIME_FOR_ZIP_ENTRIES));
|
||||
entry.setLastAccessTime(FileTime.fromMillis(ZipReprocessorUtil.CONSTANT_TIME_FOR_ZIP_ENTRIES));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,17 +24,16 @@
|
||||
|
||||
package net.fabricmc.loom.util.kotlin;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import kotlinx.metadata.jvm.KotlinClassMetadata;
|
||||
import org.gradle.api.Project;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
public class KotlinPluginUtils {
|
||||
private static final String KOTLIN_PLUGIN_ID = "org.jetbrains.kotlin.jvm";
|
||||
private static final Pattern VERSION_PATTERN = Pattern.compile("\\((?<version>.*?)\\)|(?<newVersion>^[^(]*$)");
|
||||
|
||||
public static boolean hasKotlinPlugin(Project project) {
|
||||
return project.getPluginManager().hasPlugin(KOTLIN_PLUGIN_ID);
|
||||
@@ -42,30 +41,20 @@ public class KotlinPluginUtils {
|
||||
|
||||
public static String getKotlinPluginVersion(Project project) {
|
||||
final Class<?> kotlinPluginClass = project.getPlugins().getPlugin(KOTLIN_PLUGIN_ID).getClass();
|
||||
/*
|
||||
1.7.0-RC-release-217(1.7.0-RC)
|
||||
1.6.21-release-334(1.6.21)
|
||||
1.9.0-Beta
|
||||
*/
|
||||
final String implVersion = kotlinPluginClass.getPackage().getImplementationVersion();
|
||||
return parseKotlinVersion(implVersion);
|
||||
// See KotlinPluginWrapper.loadKotlinPluginVersionFromResourcesOf
|
||||
return loadPropertyFromResources(kotlinPluginClass, "project.properties", "project.version");
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static String parseKotlinVersion(String implVersion) {
|
||||
final Matcher matcher = VERSION_PATTERN.matcher(implVersion);
|
||||
private static String loadPropertyFromResources(Class<?> kotlinPluginClass, String propFileName, String property) {
|
||||
var props = new Properties();
|
||||
|
||||
if (!matcher.find()) {
|
||||
throw new IllegalStateException("Unable to match Kotlin version from: " + implVersion);
|
||||
try (InputStream is = kotlinPluginClass.getClassLoader().getResourceAsStream(propFileName)) {
|
||||
props.load(is);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to read: " + propFileName, e);
|
||||
}
|
||||
|
||||
String version = matcher.group("version");
|
||||
|
||||
if (version == null) {
|
||||
version = matcher.group("newVersion");
|
||||
}
|
||||
|
||||
return Objects.requireNonNull(version);
|
||||
return props.getProperty(property);
|
||||
}
|
||||
|
||||
public static String getKotlinMetadataVersion() {
|
||||
|
||||
Reference in New Issue
Block a user