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:
Juuz
2023-07-19 12:56:27 +03:00
15 changed files with 134 additions and 141 deletions

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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,

View File

@@ -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);
};

View File

@@ -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())

View File

@@ -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);

View File

@@ -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));
}
}

View File

@@ -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() {