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

@@ -115,7 +115,7 @@ dependencies {
implementation ('dev.architectury:mercury:0.1.2.15')
// Kotlin
implementation('org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.6.0') {
implementation('org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.6.2') {
transitive = false
}

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

View File

@@ -27,7 +27,7 @@ package net.fabricmc.loom.test
import org.gradle.util.GradleVersion
class LoomTestConstants {
private final static String NIGHTLY_VERSION = "8.3-20230430222526+0000"
private final static String NIGHTLY_VERSION = "8.3-20230702222859+0000"
private final static boolean NIGHTLY_EXISTS = nightlyExists(NIGHTLY_VERSION)
// Test against the version of Gradle being used to build loom

View File

@@ -45,7 +45,7 @@ class FabricAPITest extends Specification implements GradleProjectTestTrait {
setup:
def gradle = gradleProject(
repo: "https://github.com/FabricMC/fabric.git",
commit: "01af69c8709f00b6c1aaf10c3f528fed93a29cfd",
commit: "1ac061308b9d70fa6aad5db3dcc5580cb6ac71cb",
version: version,
patch: "fabric_api"
)
@@ -57,7 +57,7 @@ class FabricAPITest extends Specification implements GradleProjectTestTrait {
.replace('id "fabric-loom" version "0.9.50"', 'id "dev.architectury.loom"')
.replace('"fabric-loom"', '"dev.architectury.loom"')
def server = ServerRunner.create(gradle.projectDir, "1.19.4")
def server = ServerRunner.create(gradle.projectDir, "1.20.1")
.withMod(gradle.getOutputFile("fabric-api-${API_VERSION}.jar"))
when:
def result = gradle.run(tasks: [
@@ -79,8 +79,8 @@ class FabricAPITest extends Specification implements GradleProjectTestTrait {
result.task(":build").outcome == SUCCESS
result.task(":prepareRemapJar").outcome == SUCCESS
new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/13.0.6/fabric-biome-api-v1-13.0.6.jar").exists()
new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/13.0.6/fabric-biome-api-v1-13.0.6-sources.jar").exists()
new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/13.0.10/fabric-biome-api-v1-13.0.10.jar").exists()
new File(gradle.mavenLocalDir, "net/fabricmc/fabric-api/fabric-biome-api-v1/13.0.10/fabric-biome-api-v1-13.0.10-sources.jar").exists()
serverResult.successful()
serverResult.output.contains("- fabric-api $API_VERSION")

View File

@@ -29,7 +29,9 @@ import java.nio.file.Files
import spock.lang.Specification
import net.fabricmc.loom.util.Checksum
import net.fabricmc.loom.util.Pair
import net.fabricmc.loom.util.ZipReprocessorUtil
import net.fabricmc.loom.util.ZipUtils
class ZipUtilsTest extends Specification {
@@ -150,4 +152,24 @@ class ZipUtilsTest extends Specification {
then:
!result
}
def "append zip entry"() {
given:
// Create a reproducible input zip
def dir = Files.createTempDirectory("loom-zip-test")
def zip = Files.createTempFile("loom-zip-test", ".zip")
def fileInside = dir.resolve("text.txt")
Files.writeString(fileInside, "hello world")
ZipUtils.pack(dir, zip)
ZipReprocessorUtil.reprocessZip(zip.toFile(), true, false)
when:
// Add an entry to it
ZipReprocessorUtil.appendZipEntry(zip.toFile(), "fabric.mod.json", "Some text".getBytes(StandardCharsets.UTF_8))
then:
ZipUtils.unpack(zip, "text.txt") == "hello world".bytes
ZipUtils.unpack(zip, "fabric.mod.json") == "Some text".bytes
Checksum.sha1Hex(zip) == "232ecda4c770bde8ba618e7a194a4f7b57928dc5"
}
}

View File

@@ -1,45 +0,0 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 2023 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.kotlin
import spock.lang.Specification
import net.fabricmc.loom.util.kotlin.KotlinPluginUtils
class KotlinPluginUtilsTest extends Specification {
def "parseKotlinVersion"() {
when:
def parsedVersion = KotlinPluginUtils.parseKotlinVersion(version)
then:
parsedVersion == expected
where:
version | expected
"1.7.0-RC-release-217(1.7.0-RC)" | "1.7.0-RC"
"1.6.21-release-334(1.6.21)" | "1.6.21"
"1.9.0-Beta" | "1.9.0-Beta"
}
}

View File

@@ -31,7 +31,7 @@ import groovy.transform.Immutable
import net.fabricmc.loom.util.download.Download
class ServerRunner {
static final String LOADER_VERSION = "0.14.19"
static final String LOADER_VERSION = "0.14.21"
static final String INSTALLER_VERSION = "0.11.1"
static final Map<String, String> FABRIC_API_URLS = [
"1.16.5": "https://github.com/FabricMC/fabric/releases/download/0.37.1%2B1.16/fabric-api-0.37.1+1.16.jar",

View File

@@ -1,10 +1,10 @@
diff --git a/build.gradle b/build.gradle
--- a/build.gradle (revision 01af69c8709f00b6c1aaf10c3f528fed93a29cfd)
+++ b/build.gradle (date 1681671870023)
@@ -34,17 +34,7 @@
--- a/build.gradle (revision 14d319c0729baf781e171e3c9f845fda55670f1b)
+++ b/build.gradle (date 1688330748664)
@@ -37,17 +37,7 @@
throw new NullPointerException("Could not find version for " + project.name)
}
- if (grgit == null) {
- return version + "+nogit"
- }
@@ -18,32 +18,5 @@ diff --git a/build.gradle b/build.gradle
- return version + "+" + latestCommits.get(0).id.substring(0, 8) + DigestUtils.sha256Hex(project.rootProject.minecraft_version).substring(0, 2)
+ return version
}
def getBranch() {
@@ -410,7 +400,7 @@
productionRuntime {
extendsFrom configurations.minecraftLibraries
extendsFrom configurations.loaderLibraries
- extendsFrom configurations.minecraftRuntimeOnlyLibraries
+ extendsFrom configurations.minecraftRuntimeLibraries
}
productionRuntimeServer
}
@@ -422,8 +412,6 @@
productionRuntimeServer "net.fabricmc:fabric-installer:${project.installer_version}:server"
}
-import net.fabricmc.loom.util.OperatingSystem
-
// This is very far beyond loom's API if you copy this, you're on your own.
task runProductionAutoTestClient(type: JavaExec, dependsOn: [remapJar, remapTestmodJar]) {
classpath.from configurations.productionRuntime
@@ -444,7 +432,7 @@
"--gameDir", workingDir.absolutePath
)
- if (OperatingSystem.CURRENT_OS == OperatingSystem.MAC_OS) {
+ if (false) {
jvmArgs(
"-XstartOnFirstThread"
)