Update to Gradle 8.11 (#1214)

* Update to Gradle 8.11

* Fix 8.12 producing empty outputs

* More 8.12 fixes
This commit is contained in:
modmuss
2024-11-14 18:44:05 +00:00
committed by GitHub
parent 495aae338f
commit e387514ff7
11 changed files with 27 additions and 140 deletions

View File

@@ -14,7 +14,7 @@ import org.gradle.util.GradleVersion;
*/
@SuppressWarnings("unused")
public class LoomGradlePluginBootstrap implements Plugin<PluginAware> {
private static final String MIN_SUPPORTED_GRADLE_VERSION = "8.10";
private static final String MIN_SUPPORTED_GRADLE_VERSION = "8.11";
private static final int MIN_SUPPORTED_MAJOR_JAVA_VERSION = 17;
private static final int MIN_SUPPORTED_MAJOR_IDEA_VERSION = 2022;

View File

@@ -7,37 +7,11 @@ plugins {
id 'groovy'
id 'checkstyle'
id 'codenarc'
alias(libs.plugins.kotlin) apply false // Delay this so we can perform magic 🪄 first.
alias(libs.plugins.kotlin)
alias(libs.plugins.spotless)
alias(libs.plugins.retry)
}
/**
* Haha this is fun :) The Kotlin gradle plugin triggers deprecation warnings for custom configurations (https://youtrack.jetbrains.com/issue/KT-60879)
* We need to make DefaultConfiguration.isSpecialCaseOfChangingUsage think that our configurstion is a special case and not deprecated.
* We do this by setting DefaultConfiguration.roleAtCreation to LEGACY, thus isInLegacyRole will now return true.
*
* Yeah I know we can just ignore the deprecation warning, but doing so wouldn't alert us to issues when testing against pre-release Gradle versions. Also this is more fun :)
*/
def brokenConfigurations = [
"commonDecompilerRuntimeClasspath",
"fernflowerRuntimeClasspath",
"cfrRuntimeClasspath",
"vineflowerRuntimeClasspath"
]
configurations.configureEach {
if (brokenConfigurations.contains(it.name)) {
// For some reason Gradle stops us from using Groovy magic to do this, so lets do it the boring way.
def field = org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.class.getDeclaredField("roleAtCreation")
field.setAccessible(true)
field.set(it, ConfigurationRoles.LEGACY)
}
}
// Ensure we apply the Kotlin plugin after, to allow for the above configuration to take place first
apply plugin: libs.plugins.kotlin.get().pluginId
tasks.withType(JavaCompile).configureEach {
it.options.encoding = "UTF-8"
}
@@ -49,7 +23,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
}
group = 'net.fabricmc'
def baseVersion = '1.8'
def baseVersion = '1.9'
def ENV = System.getenv()
if (ENV.BUILD_NUMBER) {

View File

@@ -2,4 +2,6 @@ name = fabric-loom
description = The Gradle plugin for Fabric
url = https://github.com/FabricMC/fabric-loom
kotlin.stdlib.default.dependency = false
kotlin.stdlib.default.dependency = false
# Suppress a deprecation warning within the Kotlin Gradle plugin
kotlin.mpp.keepMppDependenciesIntactInPoms = true

View File

@@ -1,5 +1,5 @@
[versions]
kotlin = "1.9.24"
kotlin = "2.0.20"
asm = "9.7.1"
commons-io = "2.15.1"
gson = "2.10.1"

View File

@@ -1,12 +1,12 @@
[versions]
spock = "2.3-groovy-3.0"
junit = "5.11.1"
junit = "5.11.3"
javalin = "6.3.0"
mockito = "5.13.0"
mockito = "5.14.2"
java-debug = "0.52.0"
mixin = "0.15.3+mixin.0.8.7"
gradle-nightly = "8.12-20241009055624+0000"
gradle-nightly = "8.12-20241110002642+0000"
fabric-loader = "0.16.5"
fabric-installer = "1.0.1"

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View File

@@ -97,8 +97,8 @@ public record SpecContextImpl(List<FabricModJson> modDependencies, List<FabricMo
}
private static Stream<Project> getDependentProjects(Project project) {
final Stream<Project> runtimeProjects = getLoomProjectDependencies(project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME));
final Stream<Project> compileProjects = getLoomProjectDependencies(project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME));
final Stream<Project> runtimeProjects = getLoomProjectDependencies(project, project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME));
final Stream<Project> compileProjects = getLoomProjectDependencies(project, project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME));
return Stream.concat(runtimeProjects, compileProjects)
.distinct();
@@ -154,19 +154,19 @@ public record SpecContextImpl(List<FabricModJson> modDependencies, List<FabricMo
// Returns a list of Loom Projects found in both the runtime and compile classpath
private static Stream<Project> getCompileRuntimeProjectDependencies(Project project) {
final Stream<Project> runtimeProjects = getLoomProjectDependencies(project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME));
final List<Project> compileProjects = getLoomProjectDependencies(project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME)).toList();
final Stream<Project> runtimeProjects = getLoomProjectDependencies(project, project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME));
final List<Project> compileProjects = getLoomProjectDependencies(project, project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME)).toList();
return runtimeProjects
.filter(compileProjects::contains); // Use the intersection of the two configurations.
}
// Returns a list of Loom Projects found in the provided Configuration
private static Stream<Project> getLoomProjectDependencies(Configuration configuration) {
private static Stream<Project> getLoomProjectDependencies(Project project, Configuration configuration) {
return configuration.getAllDependencies()
.withType(ProjectDependency.class)
.stream()
.map(GradleUtils::getDependencyProject)
.map((d) -> project.project(d.getPath()))
.filter(GradleUtils::isLoomProject);
}

View File

@@ -125,6 +125,11 @@ public abstract class AbstractRemapJarTask extends Jar {
usesService(jarManifestServiceProvider);
}
@Override
protected void copy() {
// Skip the default copy behaviour of AbstractCopyTask.
}
public final <P extends AbstractRemapParams> void submitWork(Class<? extends AbstractRemapAction<P>> workAction, Action<P> action) {
final WorkQueue workQueue = getWorkerExecutor().noIsolation();

View File

@@ -25,22 +25,14 @@
package net.fabricmc.loom.util.gradle;
import java.io.File;
import java.lang.reflect.Field;
import java.util.function.Consumer;
import org.gradle.api.Project;
import org.gradle.api.artifacts.ProjectDependency;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency;
import org.gradle.api.internal.catalog.DelegatingProjectDependency;
import org.gradle.api.invocation.Gradle;
import org.gradle.api.provider.Provider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class GradleUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(GradleUtils.class);
private GradleUtils() {
}
@@ -96,33 +88,4 @@ public final class GradleUtils {
property.set(file);
return property.getAsFile().get();
}
// Get the project from the field with reflection to suppress the deprecation warning.
// If you hate it find a solution yourself and make a PR, I'm getting a bit tired of chasing Gradle updates
public static Project getDependencyProject(ProjectDependency projectDependency) {
if (projectDependency instanceof DefaultProjectDependency) {
try {
final Class<DefaultProjectDependency> clazz = DefaultProjectDependency.class;
final Field dependencyProject = clazz.getDeclaredField("dependencyProject");
dependencyProject.setAccessible(true);
return (Project) dependencyProject.get(projectDependency);
} catch (NoSuchFieldException | IllegalAccessException e) {
LOGGER.warn("Failed to reflect DefaultProjectDependency", e);
}
} else if (projectDependency instanceof DelegatingProjectDependency) {
try {
final Class<DelegatingProjectDependency> clazz = DelegatingProjectDependency.class;
final Field delgeate = clazz.getDeclaredField("delegate");
delgeate.setAccessible(true);
return getDependencyProject((ProjectDependency) delgeate.get(projectDependency));
} catch (NoSuchFieldException | IllegalAccessException e) {
LOGGER.warn("Failed to reflect DelegatingProjectDependency", e);
}
}
// Just fallback and trigger the warning, this will break in Gradle 9
final Project project = projectDependency.getDependencyProject();
LOGGER.warn("Loom was unable to suppress the deprecation warning for ProjectDependency#getDependencyProject, if you are on the latest version of Loom please report this issue to the Loom developers and provide the error above, this WILL stop working in a future Gradle version.");
return project;
}
}

View File

@@ -32,7 +32,6 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.gradle.api.Transformer;
import org.gradle.process.internal.JvmOptions;
import org.gradle.workers.internal.DaemonForkOptions;
import org.gradle.workers.internal.WorkerDaemonClientsManager;
@@ -88,8 +87,11 @@ public class WorkerDaemonClientsManagerHelper {
try {
Method getJvmOptions = forkOptions.getClass().getDeclaredMethod("getJvmOptions");
getJvmOptions.setAccessible(true);
JvmOptions jvmOptions = (JvmOptions) getJvmOptions.invoke(forkOptions);
return jvmOptions.getMutableSystemProperties();
Object jvmOptions = getJvmOptions.invoke(forkOptions);
Method getMutableSystemProperties = jvmOptions.getClass().getDeclaredMethod("getMutableSystemProperties");
getMutableSystemProperties.setAccessible(true);
//noinspection unchecked
return (Map<String, Object>) getMutableSystemProperties.invoke(jvmOptions);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException("Failed to daemon system properties", e);
}

View File

@@ -1,59 +0,0 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 2024 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 org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency
import org.gradle.api.internal.catalog.DelegatingProjectDependency
import org.gradle.api.internal.project.ProjectInternal
import spock.lang.Specification
import net.fabricmc.loom.util.gradle.GradleUtils
class GradleUtilsTest extends Specification {
def "get default project dependency"() {
given:
def project = Mock(ProjectInternal)
def dependency = new DefaultProjectDependency(project, false)
when:
def result = GradleUtils.getDependencyProject(dependency)
then:
result == project
}
def "get delegated project dependency"() {
given:
def project = Mock(ProjectInternal)
def dependency = new DefaultProjectDependency(project, true)
def delegate = new DelegatingProjectDependency(null, dependency)
when:
def result = GradleUtils.getDependencyProject(delegate)
then:
result == project
}
}