Improve error messages when using outdated Java or Gradle.
This commit is contained in:
		
							parent
							
								
									1f80e00e88
								
							
						
					
					
						commit
						8238db1778
					
				
					 12 changed files with 218 additions and 6 deletions
				
			
		
							
								
								
									
										52
									
								
								.github/workflows/test-push.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								.github/workflows/test-push.yml
									
									
									
									
										vendored
									
									
								
							|  | @ -89,4 +89,54 @@ jobs: | |||
|         if: ${{ failure() }} | ||||
|         with: | ||||
|           name: Reproducible Build ${{ matrix.os }} (${{ matrix.java }}) Results | ||||
|           path: build/reports/ | ||||
|           path: build/reports/ | ||||
| 
 | ||||
|   bootstrap_tests: | ||||
|     needs: build | ||||
| 
 | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         java: [ 8, 11, 15, 16 ] | ||||
|         gradle: [ 4.9, 5.2, 6.0.1, 6.9, 7.0.2 ] | ||||
|         exclude: | ||||
|           - java: 16 | ||||
|             gradle: 6.9 | ||||
|           - java: 16 | ||||
|             gradle: 6.0.1 | ||||
|           - java: 16 | ||||
|             gradle: 5.2 | ||||
|           - java: 16 | ||||
|             gradle: 4.9 | ||||
|           - java: 15 | ||||
|             gradle: 6.0.1 | ||||
|           - java: 15 | ||||
|             gradle: 5.2 | ||||
|           - java: 15 | ||||
|             gradle: 4.9 | ||||
|     runs-on: ubuntu-20.04 | ||||
|     container: | ||||
|       image: gradle:7.0.2-jdk16 | ||||
|       options: --user root | ||||
| 
 | ||||
|     steps: | ||||
|       # Build loom and publish to maven local | ||||
|       - uses: actions/checkout@v2 | ||||
|       - run: gradle build publishToMavenLocal -x test -x check | ||||
| 
 | ||||
|       - run: gradle wrapper --gradle-version=${{ matrix.gradle }} | ||||
|         working-directory: bootstrap/test-project | ||||
|       - run: gradle --stop | ||||
| 
 | ||||
|       - uses: actions/setup-java@v2 | ||||
|         with: | ||||
|           java-version: ${{ matrix.java }} | ||||
|           distribution: 'adopt' | ||||
| 
 | ||||
|       - run: ./gradlew --version | ||||
|         working-directory: bootstrap/test-project | ||||
|       - run: ./gradlew build | ||||
|         working-directory: bootstrap/test-project | ||||
|         continue-on-error: true | ||||
| 
 | ||||
|       # TODO check the output of the previous step here | ||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -20,4 +20,5 @@ | |||
| !/settings.gradle | ||||
| !/Jenkinsfile | ||||
| !/checkstyle.xml | ||||
| !/codenarc.groovy | ||||
| !/codenarc.groovy | ||||
| !/bootstrap | ||||
							
								
								
									
										7
									
								
								bootstrap/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								bootstrap/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| # Ignore everything | ||||
| /* | ||||
| 
 | ||||
| !/src | ||||
| !/build.gradle | ||||
| !/.gitignore | ||||
| !/test-project | ||||
							
								
								
									
										30
									
								
								bootstrap/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								bootstrap/build.gradle
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | |||
| plugins { | ||||
| 	id 'java' | ||||
| 	id 'groovy' | ||||
| } | ||||
| 
 | ||||
| sourceCompatibility = 8 | ||||
| targetCompatibility = 8 | ||||
| 
 | ||||
| tasks.withType(JavaCompile).configureEach { | ||||
| 	it.options.encoding = "UTF-8" | ||||
| 	it.options.release = 8 | ||||
| } | ||||
| 
 | ||||
| repositories { | ||||
| 	mavenCentral() | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
| 	implementation gradleApi() | ||||
| 
 | ||||
| 	testImplementation(gradleTestKit()) | ||||
| 	testImplementation('org.spockframework:spock-core:2.0-M5-groovy-3.0') { | ||||
| 		exclude module: 'groovy-all' | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| test { | ||||
| 	maxHeapSize = "4096m" | ||||
| 	useJUnitPlatform() | ||||
| } | ||||
|  | @ -0,0 +1,7 @@ | |||
| package net.fabricmc.loom.bootstrap; | ||||
| 
 | ||||
| import org.gradle.api.plugins.PluginAware; | ||||
| 
 | ||||
| public interface BootstrappedPlugin { | ||||
| 	void apply(PluginAware project); | ||||
| } | ||||
|  | @ -0,0 +1,67 @@ | |||
| package net.fabricmc.loom.bootstrap; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.gradle.api.JavaVersion; | ||||
| import org.gradle.api.Plugin; | ||||
| import org.gradle.api.plugins.PluginAware; | ||||
| import org.gradle.util.GradleVersion; | ||||
| 
 | ||||
| /** | ||||
|  * This bootstrap is compiled against a minimal gradle API and java 8, this allows us to show a nice error to users who run on unsupported configurations. | ||||
|  */ | ||||
| @SuppressWarnings("unused") | ||||
| public class LoomGradlePluginBootstrap implements Plugin<PluginAware> { | ||||
| 	private static final int MIN_SUPPORTED_MAJOR_GRADLE_VERSION = 7; | ||||
| 	private static final int MIN_SUPPORTED_MAJOR_JAVA_VERSION = 16; | ||||
| 
 | ||||
| 	private static final String PLUGIN_CLASS_NAME = "net.fabricmc.loom.LoomGradlePlugin"; | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void apply(PluginAware project) { | ||||
| 		List<String> errors = new ArrayList<>(); | ||||
| 
 | ||||
| 		if (!isValidGradleRuntime()) { | ||||
| 			errors.add(String.format("You are using an outdated version of Gradle (%s). Gradle %d or higher is required.", GradleVersion.current().getVersion(), MIN_SUPPORTED_MAJOR_GRADLE_VERSION)); | ||||
| 		} | ||||
| 
 | ||||
| 		if (!isValidJavaRuntime()) { | ||||
| 			errors.add(String.format("You are using an outdated version of Java (%s). Java %d or higher is required.", JavaVersion.current().getMajorVersion(), MIN_SUPPORTED_MAJOR_JAVA_VERSION)); | ||||
| 
 | ||||
| 			String javaHome = System.getenv("JAVA_HOME"); | ||||
| 
 | ||||
| 			if (javaHome != null) { | ||||
| 				errors.add(String.format("The JAVA_HOME environment variable is currently set to (%s).", javaHome)); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (!errors.isEmpty()) { | ||||
| 			throw new UnsupportedOperationException(String.join("\n", errors)); | ||||
| 		} | ||||
| 
 | ||||
| 		getActivePlugin().apply(project); | ||||
| 	} | ||||
| 
 | ||||
| 	private static boolean isValidJavaRuntime() { | ||||
| 		// Note use compareTo to ensure compatibility with gradle < 6.0 | ||||
| 		return JavaVersion.current().compareTo(JavaVersion.toVersion(MIN_SUPPORTED_MAJOR_JAVA_VERSION)) >= 0; | ||||
| 	} | ||||
| 
 | ||||
| 	private static boolean isValidGradleRuntime() { | ||||
| 		return getMajorGradleVersion() >= MIN_SUPPORTED_MAJOR_GRADLE_VERSION; | ||||
| 	} | ||||
| 
 | ||||
| 	private static int getMajorGradleVersion() { | ||||
| 		String version = GradleVersion.current().getVersion(); | ||||
| 		return Integer.parseInt(version.substring(0, version.indexOf("."))); | ||||
| 	} | ||||
| 
 | ||||
| 	BootstrappedPlugin getActivePlugin() { | ||||
| 		try { | ||||
| 			return (BootstrappedPlugin) Class.forName(PLUGIN_CLASS_NAME).getConstructor().newInstance(); | ||||
| 		} catch (Exception e) { | ||||
| 			throw new RuntimeException("Failed to bootstrap loom", e); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,4 @@ | |||
| Trick gradle into thinking that loom is signed to skip over transforming all classes in the jar. | ||||
| This is required to get the bootstrap to well bootstrap on older gradle versions that dont support java 16. | ||||
| 
 | ||||
| See https://github.com/gradle/gradle/blob/master/subprojects/core/src/main/java/org/gradle/internal/classpath/InstrumentingClasspathFileTransformer.java#L129 | ||||
							
								
								
									
										8
									
								
								bootstrap/test-project/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								bootstrap/test-project/build.gradle
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| plugins { | ||||
| 	id 'fabric-loom' version '0.8.local' | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
| 	minecraft "com.mojang:minecraft:1.16.5" | ||||
| 	mappings loom.officialMojangMappings() | ||||
| } | ||||
							
								
								
									
										10
									
								
								bootstrap/test-project/settings.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								bootstrap/test-project/settings.gradle
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | |||
| pluginManagement { | ||||
|     repositories { | ||||
|         maven { | ||||
|             name = 'Fabric' | ||||
|             url = 'https://maven.fabricmc.net/' | ||||
|         } | ||||
|         gradlePluginPortal() | ||||
| 		mavenLocal() | ||||
|     } | ||||
| } | ||||
							
								
								
									
										31
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								build.gradle
									
									
									
									
									
								
							|  | @ -39,9 +39,19 @@ repositories { | |||
| 	mavenCentral() | ||||
| } | ||||
| 
 | ||||
| configurations { | ||||
| 	bootstrap { | ||||
| 		transitive false | ||||
| 	} | ||||
| 	compileClasspath.extendsFrom bootstrap | ||||
| 	runtimeClasspath.extendsFrom bootstrap | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
| 	implementation gradleApi() | ||||
| 
 | ||||
| 	bootstrap project(":bootstrap") | ||||
| 
 | ||||
| 	// libraries | ||||
| 	implementation ('commons-io:commons-io:2.8.0') | ||||
| 	implementation ('org.zeroturnaround:zt-zip:1.14') | ||||
|  | @ -71,7 +81,7 @@ dependencies { | |||
| 	implementation ('org.cadixdev:lorenz-io-proguard:0.5.6') | ||||
| 
 | ||||
| 	// decompilers | ||||
| 	implementation ('net.fabricmc:fabric-fernflower:1.4.0') | ||||
| 	implementation ('net.fabricmc:fabric-fernflower:1.4.1') | ||||
| 	implementation ('org.benf:cfr:0.151') | ||||
| 
 | ||||
| 	// source code remapping | ||||
|  | @ -94,6 +104,8 @@ jar { | |||
| 	manifest { | ||||
| 		attributes 'Implementation-Version': project.version | ||||
| 	} | ||||
| 
 | ||||
| 	from configurations.bootstrap.collect { it.isDirectory() ? it : zipTree(it) } | ||||
| } | ||||
| 
 | ||||
| task sourcesJar(type: Jar, dependsOn: classes) { | ||||
|  | @ -128,7 +140,7 @@ gradlePlugin { | |||
| 	plugins { | ||||
| 		fabricLoom { | ||||
| 			id = 'fabric-loom' | ||||
| 			implementationClass = 'net.fabricmc.loom.LoomGradlePlugin' | ||||
| 			implementationClass = 'net.fabricmc.loom.bootstrap.LoomGradlePluginBootstrap' | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -215,6 +227,21 @@ publishing { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Need to tweak this file to pretend we are compatible with j8 so the bootstrap will run. | ||||
| tasks.withType(GenerateModuleMetadata) { | ||||
| 	doLast { | ||||
| 		def file = outputFile.get().asFile | ||||
| 
 | ||||
| 		def metadata = new groovy.json.JsonSlurper().parseText(file.text) | ||||
| 
 | ||||
| 		metadata.variants.each { | ||||
| 			it.attributes["org.gradle.jvm.version"] = 8 | ||||
| 		} | ||||
| 
 | ||||
| 		file.text = groovy.json.JsonOutput.toJson(metadata) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // A task to output a json file with a list of all the test to run | ||||
| task writeActionsTestMatrix() { | ||||
| 	doLast { | ||||
|  |  | |||
|  | @ -1,2 +1,3 @@ | |||
| rootProject.name = name | ||||
| 
 | ||||
| include "bootstrap" | ||||
|  | @ -29,10 +29,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; | |||
| import com.google.common.collect.ImmutableMap; | ||||
| import com.google.gson.Gson; | ||||
| import com.google.gson.GsonBuilder; | ||||
| import org.gradle.api.Plugin; | ||||
| import org.gradle.api.Project; | ||||
| import org.gradle.api.plugins.PluginAware; | ||||
| 
 | ||||
| import net.fabricmc.loom.bootstrap.BootstrappedPlugin; | ||||
| import net.fabricmc.loom.configuration.CompileConfiguration; | ||||
| import net.fabricmc.loom.configuration.FabricApiExtension; | ||||
| import net.fabricmc.loom.configuration.MavenPublication; | ||||
|  | @ -41,7 +41,7 @@ import net.fabricmc.loom.configuration.providers.mappings.MappingsCache; | |||
| import net.fabricmc.loom.decompilers.DecompilerConfiguration; | ||||
| import net.fabricmc.loom.task.LoomTasks; | ||||
| 
 | ||||
| public class LoomGradlePlugin implements Plugin<PluginAware> { | ||||
| public class LoomGradlePlugin implements BootstrappedPlugin { | ||||
| 	public static boolean refreshDeps; | ||||
| 	public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); | ||||
| 	public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue