Skip to content

Commit 9fb8767

Browse files
authored
Check minimum Gradle version in middle-man plugin entry point (#1017)
1 parent 0f9a40c commit 9fb8767

File tree

5 files changed

+110
-1
lines changed

5 files changed

+110
-1
lines changed

build.gradle

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,31 @@ java {
2626
withJavadocJar()
2727
}
2828

29+
shadow {
30+
addTargetJvmVersionAttribute = false
31+
}
32+
2933
gradleutils.pluginDevDefaults(configurations, libs.versions.gradle)
3034

35+
configurations {
36+
dependencyScope('runtimeCheckerOnly') {
37+
description = 'Contains the dependencies for the runtime environment checker used to check the Gradle version.'
38+
}
39+
40+
resolvable('runtimeCheckerClasspath') {
41+
description = 'Contains the classpath for the runtime environment checker used to check the Gradle version.'
42+
transitive = false
43+
extendsFrom runtimeCheckerOnly
44+
}
45+
46+
named('runtimeClasspath') {
47+
extendsFrom runtimeCheckerClasspath
48+
}
49+
}
50+
3151
dependencies {
52+
runtimeCheckerOnly projects.runtimeEnvironmentCheck
53+
3254
// Static Analysis
3355
api libs.annotations.jspecify
3456

@@ -51,16 +73,27 @@ license {
5173
exclude '**/*.properties'
5274
}
5375

76+
def includeRuntimeChecker = { Jar jar ->
77+
jar.dependsOn(configurations.runtimeCheckerClasspath.buildDependencies)
78+
jar.from(provider { zipTree(configurations.runtimeCheckerClasspath.singleFile) }) {
79+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
80+
}
81+
}
82+
5483
tasks.named('jar', Jar) {
84+
includeRuntimeChecker(it)
5585
archiveClassifier = 'thin'
5686
}
5787

5888
tasks.named('shadowJar', ShadowJar) {
89+
includeRuntimeChecker(it)
90+
5991
enableAutoRelocation = true
6092
archiveClassifier = null
6193
relocationPrefix = 'net.minecraftforge.gradle.shadow'
6294

6395
dependencies {
96+
exclude dependency(projects.runtimeEnvironmentCheck)
6497
exclude dependency(libs.annotations.jspecify)
6598
}
6699
}
@@ -79,7 +112,7 @@ gradlePlugin {
79112

80113
plugins.register('forgegradle') {
81114
id = 'net.minecraftforge.gradle'
82-
implementationClass = 'net.minecraftforge.gradle.internal.ForgeGradlePlugin'
115+
implementationClass = 'net.minecraftforge.gradle.internal.ForgeGradlePluginEntry'
83116
displayName = gradleutils.displayName.get()
84117
description = project.description
85118
tags = ['minecraftforge', 'minecraft']
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
plugins {
2+
id 'java'
3+
id 'idea'
4+
id 'eclipse'
5+
alias libs.plugins.gradleutils
6+
alias libs.plugins.licenser
7+
}
8+
9+
gradleutils.displayName = 'Runtime Environment Check'
10+
description = 'A small Gradle plugin entry point that checks for the required Gradle version.'
11+
12+
java.toolchain.languageVersion = JavaLanguageVersion.of(8)
13+
14+
dependencies {
15+
// Static Analysis
16+
implementation libs.annotations.jspecify
17+
18+
// Gradle API
19+
compileOnly libs.gradle
20+
}
21+
22+
license {
23+
header = rootProject.file('LICENSE-header.txt')
24+
newLine = false
25+
exclude '**/*.properties'
26+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) Forge Development LLC and contributors
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
5+
package net.minecraftforge.gradle.internal;
6+
7+
import org.gradle.api.Plugin;
8+
import org.gradle.api.logging.Logger;
9+
import org.gradle.api.logging.Logging;
10+
import org.gradle.api.plugins.PluginAware;
11+
import org.gradle.util.GradleVersion;
12+
13+
import javax.inject.Inject;
14+
15+
// TODO [GradleRuntimeCheck] Move this into its own repository? The idea is that it just checked for a required version.
16+
// All of our projects could benefit from this, it could also be something in GradleUtils Shared.
17+
@SuppressWarnings("unused")
18+
abstract class ForgeGradlePluginEntry implements Plugin<PluginAware> {
19+
private static final Logger LOGGER = Logging.getLogger(ForgeGradlePluginEntry.class);
20+
21+
private static final GradleVersion CURRENT_GRADLE = GradleVersion.current();
22+
private static final GradleVersion MINIMUM_GRADLE = GradleVersion.version("9.3.0-rc-1");
23+
24+
@Inject
25+
public ForgeGradlePluginEntry() { }
26+
27+
@Override
28+
public void apply(PluginAware target) {
29+
if (CURRENT_GRADLE.compareTo(MINIMUM_GRADLE) < 0) {
30+
String message = String.format(
31+
"ForgeGradle 7 requires %s or later to run. You are currently using %s.",
32+
MINIMUM_GRADLE,
33+
CURRENT_GRADLE
34+
);
35+
LOGGER.error("ERROR: {}", message);
36+
throw new IllegalStateException(message);
37+
}
38+
39+
try {
40+
target.getPluginManager().apply(Class.forName("net.minecraftforge.gradle.internal.ForgeGradlePlugin"));
41+
} catch (ClassNotFoundException e) {
42+
throw new RuntimeException("Failed to find the ForgeGradle entry-point.", e);
43+
}
44+
}
45+
}

settings.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ plugins {
44

55
rootProject.name = 'forgegradle'
66

7+
include 'runtime-environment-check'
8+
9+
enableFeaturePreview 'TYPESAFE_PROJECT_ACCESSORS'
10+
711
// Applying plugins causes them to not have any IDE support when also applied to any build.gradle files
812
// The workaround for now is to use this listener here so that it can stay in settings.gradle
913
// See: https://youtrack.jetbrains.com/issue/IDEA-332061/Gradle-Missing-Code-Completion-Suggestions-for-Settings-Plugins-in-Groovy-DSL

src/main/java/net/minecraftforge/gradle/internal/ForgeGradlePlugin.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.gradle.api.logging.Logger;
1212
import org.gradle.api.logging.Logging;
1313
import org.gradle.api.plugins.ExtensionAware;
14+
import org.gradle.util.GradleVersion;
1415
import org.jspecify.annotations.Nullable;
1516

1617
import javax.inject.Inject;

0 commit comments

Comments
 (0)