plugins { id 'java' id 'maven-publish' id 'java-gradle-plugin' id 'idea' id 'eclipse' id 'groovy' id 'checkstyle' id 'jacoco' id 'codenarc' id "org.jetbrains.kotlin.jvm" version "1.6.10" // Must match the version included with gradle. id "com.diffplug.spotless" version "6.8.0" id "org.gradle.test-retry" version "1.4.1" } java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } tasks.withType(JavaCompile).configureEach { it.options.encoding = "UTF-8" } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { kotlinOptions { jvmTarget = "17" } } group = "dev.architectury" archivesBaseName = project.name def baseVersion = '1.0' def ENV = System.getenv() def runNumber = ENV.GITHUB_RUN_NUMBER ?: "9999" def isSnapshot = ENV.PR_NUM != null if (!isSnapshot) { version = baseVersion + "." + runNumber } else { version = baseVersion + "-PR." + ENV.PR_NUM + "." + runNumber } logger.lifecycle(":building plugin v${version}") repositories { mavenCentral() maven { url "https://maven.fabricmc.net/" } maven { url "https://maven.architectury.dev/" } maven { url "https://maven.minecraftforge.net/" content { excludeGroupByRegex "org\\.eclipse\\.?.*" } } } configurations { bootstrap { transitive false } compileClasspath.extendsFrom bootstrap runtimeClasspath.extendsFrom bootstrap testRuntimeClasspath.extendsFrom bootstrap } configurations.all { resolutionStrategy { // I am sorry, for now // failOnNonReproducibleResolution() } } dependencies { implementation gradleApi() bootstrap project(":bootstrap") // libraries implementation ('commons-io:commons-io:2.11.0') implementation ('com.google.code.gson:gson:2.9.0') implementation ('com.fasterxml.jackson.core:jackson-databind:2.13.3') implementation ('com.google.guava:guava:31.1-jre') implementation ('org.ow2.asm:asm:9.3') implementation ('org.ow2.asm:asm-analysis:9.3') implementation ('org.ow2.asm:asm-commons:9.3') implementation ('org.ow2.asm:asm-tree:9.3') implementation ('org.ow2.asm:asm-util:9.3') implementation ('me.tongfei:progressbar:0.9.0') // game handling utils implementation ('net.fabricmc:stitch:0.6.2') { exclude module: 'mercury' exclude module: 'enigma' } // tinyfile management implementation ('dev.architectury:tiny-remapper:1.8.20') implementation 'net.fabricmc:access-widener:2.1.0' implementation 'net.fabricmc:mapping-io:0.2.1' implementation ('net.fabricmc:lorenz-tiny:4.0.2') { transitive = false } implementation "dev.architectury:refmap-remapper:1.0.5" // decompilers implementation ('net.fabricmc:fabric-fernflower:1.5.0') implementation ('net.fabricmc:cfr:0.1.1') // source code remapping implementation ('dev.architectury:mercury:0.1.1.11') // Kotlin implementation('org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.4.2') { transitive = false } // Kapt integration compileOnly('org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10') // Must match the version included with gradle. // Forge patches implementation ('net.minecraftforge:installertools:1.2.0') implementation ('org.cadixdev:lorenz:0.5.3') implementation ('org.cadixdev:lorenz-asm:0.5.3') implementation ('de.oceanlabs.mcp:mcinjector:3.8.0') implementation ('com.opencsv:opencsv:5.4') implementation ('net.minecraftforge:DiffPatch:2.0.7') // Testing testImplementation(gradleTestKit()) testImplementation('org.spockframework:spock-core:2.1-groovy-3.0') { exclude module: 'groovy-all' } testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.2' testImplementation ('io.javalin:javalin:4.6.1') { exclude group: 'org.jetbrains.kotlin' } testImplementation 'net.fabricmc:fabric-installer:0.9.0' testImplementation 'org.mockito:mockito-core:4.6.1' compileOnly 'org.jetbrains:annotations:23.0.0' testCompileOnly 'org.jetbrains:annotations:23.0.0' testCompileOnly ('net.fabricmc:sponge-mixin:0.11.4+mixin.0.8.5') { transitive = false } } jar { manifest { attributes 'Implementation-Version': project.version } from configurations.bootstrap.collect { it.isDirectory() ? it : zipTree(it) } } java { withSourcesJar() } spotless { java { licenseHeaderFile(rootProject.file("HEADER")).yearSeparator("-") targetExclude("**/loom/util/DownloadUtil.java", "**/loom/util/FileSystemUtil.java") } groovy { licenseHeaderFile(rootProject.file("HEADER")).yearSeparator("-") } kotlin { licenseHeaderFile(rootProject.file("HEADER")).yearSeparator("-") targetExclude("**/build.gradle.kts") targetExclude("src/test/resources/projects/*/**") ktlint() } } checkstyle { configFile = file('checkstyle.xml') toolVersion = '10.3.1' } codenarc { toolVersion = "3.1.0" configFile = file("codenarc.groovy") } gradlePlugin { plugins { fabricLoom { id = 'dev.architectury.loom' implementationClass = 'net.fabricmc.loom.bootstrap.LoomGradlePluginBootstrap' } } } jacoco { toolVersion = "0.8.7" } // Run to get test coverage. jacocoTestReport { dependsOn test reports { xml.required = false csv.required = false html.destination file("${buildDir}/jacocoHtml") } } test { maxHeapSize = "2560m" useJUnitPlatform() // Forward system prop onto tests. if (System.getProperty("fabric.loom.test.homeDir")) { systemProperty "fabric.loom.test.homeDir", System.getProperty("fabric.loom.test.homeDir") } if (ENV.CI) { retry { maxRetries = 3 } } } import org.gradle.util.GradleVersion import org.w3c.dom.Document import org.w3c.dom.Element import org.w3c.dom.Node publishing { publications { plugin(MavenPublication) { publication -> groupId project.group artifactId project.archivesBaseName version project.version from components.java } if (isSnapshot) return mavenSnapshot(MavenPublication) { publication -> groupId project.group artifactId project.archivesBaseName version baseVersion + '-SNAPSHOT' from components.java } pluginSnapshot(MavenPublication) { groupId 'dev.architectury.loom' artifactId 'dev.architectury.loom.gradle.plugin' version baseVersion + '-SNAPSHOT' pom.withXml { // Based off org.gradle.plugin.devel.plugins.MavenPluginPublishPlugin Element root = asElement() Document document = root.getOwnerDocument() Node dependencies = root.appendChild(document.createElement('dependencies')) Node dependency = dependencies.appendChild(document.createElement('dependency')) Node groupId = dependency.appendChild(document.createElement('groupId')) groupId.setTextContent(project.group) Node artifactId = dependency.appendChild(document.createElement('artifactId')) artifactId.setTextContent(project.archivesBaseName) Node version = dependency.appendChild(document.createElement('version')) version.setTextContent(baseVersion + '-SNAPSHOT') } } } repositories { if (ENV.MAVEN_PASS != null) { maven { url = "https://deploy.shedaniel.me/" credentials { username = "shedaniel" password = ENV.MAVEN_PASS } } } } } // 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 { def testMatrix = [] file('src/test/groovy/net/fabricmc/loom/test/integration').traverse { if (it.name.endsWith("Test.groovy")) { if (it.name.endsWith("ReproducibleBuildTest.groovy")) { // This test gets a special case to run across all os's return } def className = it.path.toString().replace(".groovy", "") className = className.substring(className.lastIndexOf("integration/") + "integration/".length()).replace('/', '.') // Disabled for CI, as it fails too much. if (className.endsWith("DecompileTest")) return // Disabled for CI as it hangs. if (className.endsWith("FabricAPITest")) return testMatrix.add("net.fabricmc.loom.test.integration.${className}") } } // Run all the unit tests together testMatrix.add("net.fabricmc.loom.test.unit.*") // Kotlin tests testMatrix.add("net.fabricmc.loom.test.kotlin.*") def json = groovy.json.JsonOutput.toJson(testMatrix) def output = file("build/test_matrix.json") output.parentFile.mkdir() output.text = json } } tasks.named('wrapper') { distributionType = Wrapper.DistributionType.ALL } /** * Run this task to download the gradle sources next to the api jar, you may need to manually attach the sources jar */ task downloadGradleSources() { doLast { // Awful hack to find the gradle api location def gradleApiFile = project.configurations.detachedConfiguration(dependencies.gradleApi()).files.stream() .filter { it.name.startsWith("gradle-api") }.findFirst().orElseThrow() def gradleApiSources = new File(gradleApiFile.absolutePath.replace(".jar", "-sources.jar")) def url = "https://services.gradle.org/distributions/gradle-${GradleVersion.current().getVersion()}-src.zip" gradleApiSources.delete() println("Downloading (${url}) to (${gradleApiSources})") gradleApiSources << new URL(url).newInputStream() } } tasks.withType(GenerateModuleMetadata) { enabled = false } task printActionsTestName(type: PrintActionsTestName) { } /** * Replaces invalid characters in test names for GitHub Actions artifacts. */ class PrintActionsTestName extends DefaultTask { @Input @Option(option = "name", description = "The test name") String testName @TaskAction def run() { def sanitised = testName.replace('*', '_') println "::set-output name=test::$sanitised" } }