mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-04-02 05:27:43 -05:00
Merge remote-tracking branch 'upstream/dev/1.1' into dev/1.1
# Conflicts: # src/main/java/net/fabricmc/loom/configuration/providers/minecraft/SingleJarMinecraftProvider.java
This commit is contained in:
@@ -122,4 +122,9 @@ public abstract class ModSettings implements Named {
|
||||
|
||||
@Inject
|
||||
public abstract Project getProject();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ModSettings '" + getName() + "'";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,4 +142,9 @@ public abstract class RemapConfigurationSettings implements Named {
|
||||
private Provider<Boolean> defaultDependencyTransforms() {
|
||||
return getSourceSet().map(sourceSet -> sourceSet.getName().equals(SourceSet.MAIN_SOURCE_SET_NAME) || sourceSet.getName().equals("client"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RemapConfigurationSettings '" + getName() + "'";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,12 @@ public class SingleJarMinecraftProvider extends MinecraftProvider {
|
||||
@Override
|
||||
public void provide() throws Exception {
|
||||
super.provide();
|
||||
|
||||
// Server only JARs are supported on any version, client only JARs are pretty much useless after 1.3.
|
||||
if (provideClient() && getVersionInfo().isVersionOrNewer("2012-07-25T22:00:00+00:00" /* 1.3 release date */)) {
|
||||
getProject().getLogger().warn("Using `clientOnlyMinecraftJar()` is not recommended for Minecraft versions 1.3 or newer.");
|
||||
}
|
||||
|
||||
processJar();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.nio.file.attribute.BasicFileAttributeView;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.time.Duration;
|
||||
@@ -58,7 +59,7 @@ import org.slf4j.LoggerFactory;
|
||||
import net.fabricmc.loom.util.AttributeHelper;
|
||||
import net.fabricmc.loom.util.Checksum;
|
||||
|
||||
public class Download {
|
||||
public final class Download {
|
||||
private static final String E_TAG = "ETag";
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(Download.class);
|
||||
|
||||
@@ -73,8 +74,10 @@ public class Download {
|
||||
private final boolean offline;
|
||||
private final Duration maxAge;
|
||||
private final DownloadProgressListener progressListener;
|
||||
private final HttpClient.Version httpVersion;
|
||||
private final int downloadAttempt;
|
||||
|
||||
Download(URI url, String expectedHash, boolean useEtag, boolean forceDownload, boolean offline, Duration maxAge, DownloadProgressListener progressListener) {
|
||||
Download(URI url, String expectedHash, boolean useEtag, boolean forceDownload, boolean offline, Duration maxAge, DownloadProgressListener progressListener, HttpClient.Version httpVersion, int downloadAttempt) {
|
||||
this.url = url;
|
||||
this.expectedHash = expectedHash;
|
||||
this.useEtag = useEtag;
|
||||
@@ -82,6 +85,8 @@ public class Download {
|
||||
this.offline = offline;
|
||||
this.maxAge = maxAge;
|
||||
this.progressListener = progressListener;
|
||||
this.httpVersion = httpVersion;
|
||||
this.downloadAttempt = downloadAttempt;
|
||||
}
|
||||
|
||||
private HttpClient getHttpClient() throws DownloadException {
|
||||
@@ -97,12 +102,14 @@ public class Download {
|
||||
|
||||
private HttpRequest getRequest() {
|
||||
return HttpRequest.newBuilder(url)
|
||||
.version(httpVersion)
|
||||
.GET()
|
||||
.build();
|
||||
}
|
||||
|
||||
private HttpRequest getETagRequest(String etag) {
|
||||
return HttpRequest.newBuilder(url)
|
||||
.version(httpVersion)
|
||||
.GET()
|
||||
.header("If-None-Match", etag)
|
||||
.build();
|
||||
@@ -148,7 +155,7 @@ public class Download {
|
||||
doDownload(output);
|
||||
} catch (Throwable throwable) {
|
||||
tryCleanup(output);
|
||||
throw error(throwable, "Failed to download (%s) to (%s)", url, output);
|
||||
throw error(throwable, "Failed to download file from (%s) to (%s)", url, output);
|
||||
} finally {
|
||||
progressListener.onEnd();
|
||||
}
|
||||
@@ -194,7 +201,7 @@ public class Download {
|
||||
final long length = Long.parseLong(response.headers().firstValue("Content-Length").orElse("-1"));
|
||||
AtomicLong totalBytes = new AtomicLong(0);
|
||||
|
||||
try (OutputStream outputStream = Files.newOutputStream(output)) {
|
||||
try (OutputStream outputStream = Files.newOutputStream(output, StandardOpenOption.CREATE_NEW)) {
|
||||
copyWithCallback(decodeOutput(response), outputStream, value -> {
|
||||
if (length < 0) {
|
||||
return;
|
||||
@@ -203,12 +210,26 @@ public class Download {
|
||||
progressListener.onProgress(totalBytes.addAndGet(value), length);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
tryCleanup(output);
|
||||
throw error(e, "Failed to decode and write download output");
|
||||
}
|
||||
|
||||
if (Files.notExists(output)) {
|
||||
throw error("No file was downloaded");
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
try {
|
||||
final long actualLength = Files.size(output);
|
||||
|
||||
if (actualLength != length) {
|
||||
throw error("Unexpected file length of %d bytes, expected %d bytes".formatted(actualLength, length));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw error(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tryCleanup(output);
|
||||
throw error("HTTP request to (%s) returned unsuccessful status (%d)", url, statusCode);
|
||||
throw error("HTTP request returned unsuccessful status (%d)", statusCode);
|
||||
}
|
||||
|
||||
if (useEtag) {
|
||||
@@ -261,7 +282,7 @@ public class Download {
|
||||
}
|
||||
|
||||
private boolean requiresDownload(Path output) throws DownloadException {
|
||||
if (getAndResetLock(output)) {
|
||||
if (getAndResetLock(output) & downloadAttempt == 1) {
|
||||
LOGGER.warn("Forcing downloading {} as existing lock file was found. This may happen if the gradle build was forcefully canceled.", output);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ package net.fabricmc.loom.util.download;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.http.HttpClient;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -46,6 +47,7 @@ public class DownloadBuilder {
|
||||
private DownloadProgressListener progressListener = DownloadProgressListener.NONE;
|
||||
private int maxRetries = 3;
|
||||
private boolean allowInsecureProtocol = false;
|
||||
private HttpClient.Version httpVersion = HttpClient.Version.HTTP_2;
|
||||
|
||||
private DownloadBuilder(URI url) {
|
||||
this.url = url;
|
||||
@@ -100,12 +102,17 @@ public class DownloadBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
private Download build() {
|
||||
public DownloadBuilder httpVersion(HttpClient.Version httpVersion) {
|
||||
this.httpVersion = httpVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
private Download build(int downloadAttempt) {
|
||||
if (!allowInsecureProtocol && !isSecureUrl(url)) {
|
||||
throw new IllegalArgumentException("Cannot create download for url (%s) with insecure protocol".formatted(url.toString()));
|
||||
}
|
||||
|
||||
return new Download(this.url, this.expectedHash, this.useEtag, this.forceDownload, this.offline, maxAge, progressListener);
|
||||
return new Download(this.url, this.expectedHash, this.useEtag, this.forceDownload, this.offline, maxAge, progressListener, httpVersion, downloadAttempt);
|
||||
}
|
||||
|
||||
public void downloadPathAsync(Path path, DownloadExecutor executor) {
|
||||
@@ -113,19 +120,19 @@ public class DownloadBuilder {
|
||||
}
|
||||
|
||||
public void downloadPath(Path path) throws DownloadException {
|
||||
withRetries(() -> {
|
||||
build().downloadPath(path);
|
||||
withRetries((download) -> {
|
||||
download.downloadPath(path);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public String downloadString() throws DownloadException {
|
||||
return withRetries(() -> build().downloadString());
|
||||
return withRetries(Download::downloadString);
|
||||
}
|
||||
|
||||
public String downloadString(Path cache) throws DownloadException {
|
||||
return withRetries(() -> {
|
||||
build().downloadPath(cache);
|
||||
return withRetries((download) -> {
|
||||
download.downloadPath(cache);
|
||||
|
||||
try {
|
||||
return Files.readString(cache, StandardCharsets.UTF_8);
|
||||
@@ -141,10 +148,15 @@ public class DownloadBuilder {
|
||||
});
|
||||
}
|
||||
|
||||
private <T> T withRetries(DownloadSupplier<T> supplier) throws DownloadException {
|
||||
private <T> T withRetries(DownloadFunction<T> supplier) throws DownloadException {
|
||||
for (int i = 1; i <= maxRetries; i++) {
|
||||
try {
|
||||
return supplier.get();
|
||||
if (i == maxRetries) {
|
||||
// Last ditch attempt, try over HTTP 1.1
|
||||
httpVersion(HttpClient.Version.HTTP_1_1);
|
||||
}
|
||||
|
||||
return supplier.get(build(i));
|
||||
} catch (DownloadException e) {
|
||||
if (i == maxRetries) {
|
||||
throw new DownloadException(String.format(Locale.ENGLISH, "Failed download after %d attempts", maxRetries), e);
|
||||
@@ -166,7 +178,7 @@ public class DownloadBuilder {
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface DownloadSupplier<T> {
|
||||
T get() throws DownloadException;
|
||||
private interface DownloadFunction<T> {
|
||||
T get(Download download) throws DownloadException;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,13 @@ package net.fabricmc.loom.test
|
||||
import org.gradle.util.GradleVersion
|
||||
|
||||
class LoomTestConstants {
|
||||
private final static String NIGHTLY_VERSION = "8.1-20230119104422+0000"
|
||||
private final static String NIGHTLY_VERSION = "8.1-20230217231705+0000"
|
||||
private final static boolean NIGHTLY_EXISTS = nightlyExists(NIGHTLY_VERSION)
|
||||
|
||||
// Test against the version of Gradle being used to build loom
|
||||
public final static String DEFAULT_GRADLE = GradleVersion.current().getVersion()
|
||||
// Test against Gradle 8
|
||||
public final static String GRADLE_8 = "8.0-rc-2"
|
||||
public final static String GRADLE_8 = "8.0.1"
|
||||
// Tests that depend specifically on the nightly will run on the current version when the nightly is not available.
|
||||
public final static String PRE_RELEASE_GRADLE = NIGHTLY_EXISTS ? NIGHTLY_VERSION : DEFAULT_GRADLE
|
||||
// Randomly sorted to ensure that all versions can run with a clean gradle home.
|
||||
|
||||
@@ -30,13 +30,16 @@ import net.fabricmc.loom.util.download.Download
|
||||
import net.fabricmc.loom.util.download.DownloadException
|
||||
import net.fabricmc.loom.util.download.DownloadExecutor
|
||||
import net.fabricmc.loom.util.download.DownloadProgressListener
|
||||
import spock.lang.IgnoreIf
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.attribute.FileTime
|
||||
import java.nio.file.Paths
|
||||
import java.nio.file.attribute.FileTime
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
|
||||
class DownloadFileTest extends DownloadTest {
|
||||
@IgnoreIf({ os.windows }) // Requires admin on windows.
|
||||
def "Directory: Symlink"() {
|
||||
setup:
|
||||
server.get("/symlinkFile") {
|
||||
|
||||
Reference in New Issue
Block a user