1027 lines
34 KiB
Groovy
1027 lines
34 KiB
Groovy
/*
|
|
* DO NOT CHANGE THIS FILE!
|
|
* Also, you may replace this file at any time if there is an update available.
|
|
* Please check https://github.com/GregTechCEu/Buildscripts/blob/master/build.gradle for updates.
|
|
* You can also run ./gradlew updateBuildScript to update your buildscript.
|
|
*/
|
|
|
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
|
import com.gtnewhorizons.retrofuturagradle.mcp.ReobfuscatedJar
|
|
import com.modrinth.minotaur.dependencies.ModDependency
|
|
import com.modrinth.minotaur.dependencies.VersionDependency
|
|
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
|
|
import org.gradle.api.tasks.testing.logging.TestLogEvent
|
|
import org.gradle.internal.logging.text.StyledTextOutputFactory
|
|
import org.jetbrains.gradle.ext.Gradle
|
|
|
|
import static org.gradle.internal.logging.text.StyledTextOutput.Style
|
|
|
|
plugins {
|
|
id 'java'
|
|
id 'java-library'
|
|
id 'eclipse'
|
|
id 'maven-publish'
|
|
id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7'
|
|
id 'com.gtnewhorizons.retrofuturagradle' version '1.3.19'
|
|
id 'net.darkhax.curseforgegradle' version '1.0.14' apply false
|
|
id 'com.modrinth.minotaur' version '2.8.0' apply false
|
|
id 'com.diffplug.spotless' version '6.13.0' apply false
|
|
id 'com.palantir.git-version' version '3.0.0' apply false
|
|
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
|
|
}
|
|
|
|
if (verifySettingsGradle()) {
|
|
throw new GradleException("Settings has been updated, please re-run task.")
|
|
}
|
|
|
|
def out = services.get(StyledTextOutputFactory).create('an-output')
|
|
|
|
// Project properties
|
|
|
|
// Required properties: we don't know how to handle these being missing gracefully
|
|
checkPropertyExists("modName")
|
|
checkPropertyExists("modId")
|
|
checkPropertyExists("modGroup")
|
|
checkPropertyExists("minecraftVersion") // hard-coding this makes it harder to immediately tell what version a mod is in (even though this only really supports 1.12.2)
|
|
checkPropertyExists("apiPackage")
|
|
checkPropertyExists("accessTransformersFile")
|
|
checkPropertyExists("usesMixins")
|
|
checkPropertyExists("mixinsPackage")
|
|
checkPropertyExists("coreModClass")
|
|
checkPropertyExists("containsMixinsAndOrCoreModOnly")
|
|
|
|
propertyDefaultIfUnset("customMavenPublishUrl", "")
|
|
|
|
// Project property assertions
|
|
|
|
final String javaSourceDir = 'src/main/java/'
|
|
final String scalaSourceDir = 'src/main/scala/'
|
|
// If Kotlin is supported, add the path here
|
|
|
|
final String modGroupPath = modGroup.toString().replace('.' as char, '/' as char)
|
|
final String apiPackagePath = apiPackage.toString().replace('.' as char, '/' as char)
|
|
|
|
String targetPackageJava = javaSourceDir + modGroupPath
|
|
String targetPackageScala = scalaSourceDir + modGroupPath
|
|
|
|
// If Kotlin is supported, add the path here
|
|
|
|
if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists()) {
|
|
throw new GradleException("Could not resolve \"modGroup\"! Could not find ${targetPackageJava} or ${targetPackageScala}")
|
|
}
|
|
|
|
if (apiPackage) {
|
|
targetPackageJava = 'src/api/java/' + modGroupPath + '/api'
|
|
targetPackageScala = 'src/api/java/' + modGroupPath + '/api'
|
|
if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists()) {
|
|
throw new GradleException("Could not resolve \"apiPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala}")
|
|
}
|
|
}
|
|
|
|
if (accessTransformersFile) {
|
|
for (atFile in accessTransformersFile.split(",")) {
|
|
String targetFile = 'src/main/resources/' + atFile.trim()
|
|
if (!getFile(targetFile).exists()) {
|
|
throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
|
|
}
|
|
tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(targetFile)
|
|
tasks.srgifyBinpatchedJar.accessTransformerFiles.from(targetFile)
|
|
}
|
|
}
|
|
|
|
if (usesMixins.toBoolean()) {
|
|
if (mixinsPackage.isEmpty()) {
|
|
throw new GradleException("\"usesMixins\" requires \"mixinsPackage\" to be set!")
|
|
}
|
|
final String mixinPackagePath = mixinsPackage.toString().replaceAll('\\.', '/')
|
|
targetPackageJava = javaSourceDir + modGroupPath + '/' + mixinPackagePath
|
|
targetPackageScala = scalaSourceDir + modGroupPath + '/' + mixinPackagePath
|
|
if (!getFile(targetPackageJava).exists()) {
|
|
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala}")
|
|
}
|
|
}
|
|
|
|
if (coreModClass) {
|
|
final String coreModPath = coreModClass.toString().replaceAll('\\.', '/')
|
|
String targetFileJava = javaSourceDir + modGroupPath + '/' + coreModPath + '.java'
|
|
String targetFileScala = scalaSourceDir + modGroupPath + '/' + coreModPath + '.scala'
|
|
String targetFileScalaJava = scalaSourceDir + modGroupPath + '/' + coreModPath + '.java'
|
|
if (!getFile(targetFileJava).exists() && !getFile(targetFileScala).exists() && !getFile(targetFileScalaJava).exists()) {
|
|
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava)
|
|
}
|
|
}
|
|
|
|
// Plugin application
|
|
|
|
// Git version checking, also checking for if this is a submodule
|
|
if (project.file('.git/HEAD').isFile() || project.file('.git').isFile()) {
|
|
apply plugin: 'com.palantir.git-version'
|
|
}
|
|
|
|
// Shadowing
|
|
if (usesShadowedDependencies.toBoolean()) {
|
|
apply plugin: 'com.github.johnrengelman.shadow'
|
|
}
|
|
|
|
java {
|
|
toolchain {
|
|
if (enableModernJavaSyntax.toBoolean()) {
|
|
languageVersion.set(JavaLanguageVersion.of(17))
|
|
} else {
|
|
languageVersion.set(JavaLanguageVersion.of(8))
|
|
}
|
|
// Azul covers the most platforms for Java 8+ toolchains, crucially including MacOS arm64
|
|
vendor.set(JvmVendorSpec.AZUL)
|
|
}
|
|
if (!noPublishedSources.toBoolean()) {
|
|
withSourcesJar()
|
|
}
|
|
}
|
|
|
|
tasks.withType(JavaCompile).configureEach {
|
|
options.encoding = 'UTF-8'
|
|
|
|
if (enableModernJavaSyntax.toBoolean()) {
|
|
if (it.name in ['compileMcLauncherJava', 'compilePatchedMcJava']) {
|
|
return
|
|
}
|
|
|
|
sourceCompatibility = 17
|
|
options.release.set(8)
|
|
|
|
javaCompiler.set(javaToolchains.compilerFor {
|
|
languageVersion.set(JavaLanguageVersion.of(17))
|
|
vendor.set(JvmVendorSpec.AZUL)
|
|
})
|
|
}
|
|
}
|
|
|
|
tasks.withType(ScalaCompile).configureEach {
|
|
options.encoding = 'UTF-8'
|
|
}
|
|
|
|
|
|
// Allow others using this buildscript to have custom gradle code run
|
|
if (getFile('addon.gradle').exists()) {
|
|
apply from: 'addon.gradle'
|
|
}
|
|
|
|
// Configure Minecraft
|
|
|
|
// Try to gather mod version from git tags if version is not manually specified
|
|
if (!modVersion) {
|
|
try {
|
|
modVersion = gitVersion()
|
|
} catch (Exception ignored) {
|
|
out.style(Style.Failure).text(
|
|
"Mod version could not be determined! Property 'modVersion' is not set, and either git is not installed or no git tags exist.\n" +
|
|
"Either specify a mod version in 'gradle.properties', or create at least one tag in git for this project."
|
|
)
|
|
modVersion = 'NO-GIT-TAG-SET'
|
|
}
|
|
}
|
|
|
|
if (includeMCVersionJar.toBoolean()) {
|
|
version = "${minecraftVersion}-${modVersion}"
|
|
} else {
|
|
version = modVersion
|
|
}
|
|
|
|
group = modGroup
|
|
archivesBaseName = modArchivesBaseName
|
|
|
|
minecraft {
|
|
mcVersion = minecraftVersion
|
|
username = developmentEnvironmentUserName.toString()
|
|
useDependencyAccessTransformers = true
|
|
|
|
setMcpMappingChannel("stable")
|
|
setMcpMappingVersion("39")
|
|
|
|
// Automatic token injection with RetroFuturaGradle
|
|
if (gradleTokenModId) {
|
|
injectedTags.put gradleTokenModId, modId
|
|
}
|
|
if (gradleTokenModName) {
|
|
injectedTags.put gradleTokenModName, modName
|
|
}
|
|
if (gradleTokenVersion) {
|
|
injectedTags.put gradleTokenVersion, modVersion
|
|
}
|
|
|
|
injectedTags.put("VERSION", project.version)
|
|
injectedTags.put("AEVERSION", aeversion)
|
|
injectedTags.put("AECHANNEL", aechannel)
|
|
injectedTags.put("AEBUILD", aebuild)
|
|
|
|
// JVM arguments
|
|
extraRunJvmArguments.add("-ea:${modGroup}")
|
|
if (usesMixins.toBoolean()) {
|
|
extraRunJvmArguments.addAll([
|
|
'-Dmixin.hotSwap=true',
|
|
'-Dmixin.checks.interfaces=true',
|
|
'-Dmixin.debug.export=true'
|
|
])
|
|
}
|
|
if (coreModClass) {
|
|
extraRunJvmArguments.add("-Dfml.coreMods.load=${modGroup}.${coreModClass}")
|
|
}
|
|
}
|
|
|
|
if (generateGradleTokenClass) {
|
|
tasks.injectTags.outputClassName.set(generateGradleTokenClass)
|
|
}
|
|
|
|
tasks.named('processIdeaSettings').configure {
|
|
dependsOn('injectTags')
|
|
}
|
|
|
|
tasks.register("generateMcModInfo") {
|
|
|
|
}
|
|
|
|
tasks.register("generatePackMcMeta") {
|
|
|
|
}
|
|
|
|
tasks.named('processIdeaSettings').configure {
|
|
dependsOn('injectTags')
|
|
}
|
|
|
|
// Repositories
|
|
|
|
// Allow unsafe repos but warn
|
|
repositories.configureEach { repo ->
|
|
if (repo instanceof UrlArtifactRepository) {
|
|
if (repo.getUrl() != null && repo.getUrl().getScheme() == "http" && !repo.allowInsecureProtocol) {
|
|
logger.warn("Deprecated: Allowing insecure connections for repo '${repo.name}' - add 'allowInsecureProtocol = true'")
|
|
repo.allowInsecureProtocol = true
|
|
}
|
|
}
|
|
}
|
|
|
|
// Allow adding custom repositories to the buildscript
|
|
if (getFile('repositories.gradle').exists()) {
|
|
apply from: 'repositories.gradle'
|
|
}
|
|
|
|
repositories {
|
|
exclusiveContent {
|
|
forRepository {
|
|
//noinspection ForeignDelegate
|
|
maven {
|
|
name = 'Curse Maven'
|
|
url = 'https://www.cursemaven.com'
|
|
}
|
|
}
|
|
filter {
|
|
includeGroup 'curse.maven'
|
|
}
|
|
}
|
|
exclusiveContent {
|
|
forRepository {
|
|
//noinspection ForeignDelegate
|
|
maven {
|
|
name = 'Modrinth'
|
|
url = 'https://api.modrinth.com/maven'
|
|
}
|
|
}
|
|
filter {
|
|
includeGroup 'maven.modrinth'
|
|
}
|
|
}
|
|
maven {
|
|
name 'Cleanroom Maven'
|
|
url 'https://maven.cleanroommc.com'
|
|
}
|
|
maven {
|
|
name 'BlameJared Maven'
|
|
url 'https://maven.blamejared.com'
|
|
}
|
|
gradlePluginPortal()
|
|
mavenCentral()
|
|
mavenLocal()
|
|
}
|
|
|
|
// Dependencies
|
|
|
|
// Configure dependency configurations
|
|
configurations {
|
|
embed
|
|
implementation.extendsFrom(embed)
|
|
|
|
if (usesShadowedDependencies.toBoolean()) {
|
|
for (config in [compileClasspath, runtimeClasspath, testCompileClasspath, testRuntimeClasspath]) {
|
|
config.extendsFrom(shadowImplementation)
|
|
config.extendsFrom(shadowCompile)
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) {
|
|
implementation 'zone.rong:mixinbooter:7.0'
|
|
String mixin = 'org.spongepowered:mixin:0.8.3'
|
|
if (usesMixins.toBoolean()) {
|
|
mixin = modUtils.enableMixins(mixin, "mixins.${modId}.refmap.json")
|
|
}
|
|
|
|
api(mixin) {
|
|
transitive = false
|
|
}
|
|
|
|
annotationProcessor(mixin) {
|
|
transitive = false
|
|
}
|
|
|
|
annotationProcessor 'org.ow2.asm:asm-debug-all:5.2'
|
|
// should use 24.1.1 but 30.0+ has a vulnerability fix
|
|
annotationProcessor 'com.google.guava:guava:30.0-jre'
|
|
// should use 2.8.6 but 2.8.9+ has a vulnerability fix
|
|
annotationProcessor 'com.google.code.gson:gson:2.8.9'
|
|
}
|
|
|
|
if (enableJUnit.toBoolean()) {
|
|
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
|
|
testImplementation 'org.hamcrest:hamcrest:2.2'
|
|
}
|
|
|
|
if (enableModernJavaSyntax.toBoolean()) {
|
|
annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0'
|
|
compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') {
|
|
transitive = false
|
|
}
|
|
// workaround for https://github.com/bsideup/jabel/issues/174
|
|
annotationProcessor 'net.java.dev.jna:jna-platform:5.13.0'
|
|
// Allow jdk.unsupported classes like sun.misc.Unsafe, workaround for JDK-8206937 and fixes Forge crashes in tests.
|
|
patchedMinecraft 'me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0'
|
|
|
|
// allow Jabel to work in tests
|
|
testAnnotationProcessor "com.github.bsideup.jabel:jabel-javac-plugin:1.0.0"
|
|
testCompileOnly("com.github.bsideup.jabel:jabel-javac-plugin:1.0.0") {
|
|
transitive = false // We only care about the 1 annotation class
|
|
}
|
|
testCompileOnly "me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0"
|
|
}
|
|
|
|
compileOnlyApi 'org.jetbrains:annotations:23.0.0'
|
|
annotationProcessor 'org.jetbrains:annotations:23.0.0'
|
|
|
|
if (includeCommonDevEnvMods.toBoolean()) {
|
|
implementation 'mezz.jei:jei_1.12.2:4.16.1.302'
|
|
//noinspection DependencyNotationArgument
|
|
implementation rfg.deobf('curse.maven:top-245211:2667280') // TOP 1.4.28
|
|
}
|
|
}
|
|
|
|
if (getFile('gradle/scripts/dependencies.gradle').exists()) {
|
|
apply from: 'gradle/scripts/dependencies.gradle'
|
|
}
|
|
|
|
apply from: 'gradle/scripts/optional.gradle'
|
|
|
|
// Test configuration
|
|
|
|
// Ensure tests have access to minecraft classes
|
|
sourceSets {
|
|
test {
|
|
java {
|
|
compileClasspath += patchedMc.output + mcLauncher.output
|
|
runtimeClasspath += patchedMc.output + mcLauncher.output
|
|
}
|
|
}
|
|
}
|
|
|
|
test {
|
|
// ensure tests are run with java8
|
|
javaLauncher = javaToolchains.launcherFor {
|
|
languageVersion = JavaLanguageVersion.of(8)
|
|
}.get()
|
|
|
|
testLogging {
|
|
events TestLogEvent.STARTED, TestLogEvent.PASSED, TestLogEvent.FAILED
|
|
exceptionFormat TestExceptionFormat.FULL
|
|
showExceptions true
|
|
showStackTraces true
|
|
showCauses true
|
|
showStandardStreams true
|
|
}
|
|
|
|
if (enableJUnit.toBoolean()) {
|
|
useJUnitPlatform()
|
|
}
|
|
}
|
|
|
|
// Resource processing and jar building
|
|
|
|
processResources {
|
|
// this will ensure that this task is redone when the versions change.
|
|
inputs.property 'version', modVersion
|
|
inputs.property 'mcversion', minecraftVersion
|
|
// Blowdryer puts these files into the resource directory, so
|
|
// exclude them from builds (doesn't hurt to exclude even if not present)
|
|
exclude('spotless.importorder')
|
|
exclude('spotless.eclipseformat.xml')
|
|
|
|
// replace stuff in mcmod.info, nothing else
|
|
filesMatching('mcmod.info') { fcd ->
|
|
fcd.expand(
|
|
'version': modVersion,
|
|
'mcversion': minecraftVersion,
|
|
'modid': modId,
|
|
'modname': modName
|
|
)
|
|
}
|
|
|
|
if (accessTransformersFile) {
|
|
String[] ats = accessTransformersFile.split(',')
|
|
ats.each { at ->
|
|
rename "(${at})", 'META-INF/$1'
|
|
}
|
|
}
|
|
}
|
|
|
|
// Automatically generate a mixin json file if it does not already exist
|
|
tasks.register('generateAssets') {
|
|
group = 'GT Buildscript'
|
|
description = 'Generates a pack.mcmeta, mcmod.info, or mixins.{modid}.json if needed'
|
|
doLast {
|
|
// pack.mcmeta
|
|
def packMcmetaFile = getFile('src/main/resources/pack.mcmeta')
|
|
if (!packMcmetaFile.exists()) {
|
|
packMcmetaFile.text = """{
|
|
"pack": {
|
|
"pack_format": 3,
|
|
"description": "${modName} Resource Pack"
|
|
}
|
|
}
|
|
"""
|
|
}
|
|
|
|
// mcmod.info
|
|
def mcmodInfoFile = getFile('src/main/resources/mcmod.info')
|
|
if (!mcmodInfoFile.exists()) {
|
|
mcmodInfoFile.text = """[{
|
|
"modid": "\${modid}",
|
|
"name": "\${modname}",
|
|
"description": "A Mod about Matter, Energy and using them to conquer the world..",
|
|
"version": "\${version}",
|
|
"mcversion": "\${mcversion}",
|
|
"logoFile": "assets/appliedenergistics2/meta/logo.png",
|
|
"url": "https://github.com/PrototypeTrousers/Applied-Energistics-2",
|
|
"authorList": ["AlgorithmX2"],
|
|
"credits": "AlgorithmX2",
|
|
"dependencies": []
|
|
}]
|
|
"""
|
|
}
|
|
|
|
// mixins.{modid}.json
|
|
if (usesMixins.toBoolean()) {
|
|
def mixinConfigFile = getFile("src/main/resources/mixins.${modId}.json")
|
|
if (!mixinConfigFile.exists()) {
|
|
def mixinConfigRefmap = "mixins.${modId}.refmap.json"
|
|
|
|
mixinConfigFile.text = """{
|
|
"package": "${modGroup}.${mixinsPackage}",
|
|
"refmap": "${mixinConfigRefmap}",
|
|
"target": "@env(DEFAULT)",
|
|
"minVersion": "0.8",
|
|
"compatibilityLevel": "JAVA_8",
|
|
"mixins": [],
|
|
"client": [],
|
|
"server": []
|
|
}
|
|
"""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.named('processResources').configure {
|
|
dependsOn('generateAssets')
|
|
}
|
|
|
|
jar {
|
|
manifest {
|
|
attributes(getManifestAttributes())
|
|
}
|
|
|
|
// Add all embedded dependencies into the jar
|
|
from provider {
|
|
configurations.embed.collect {
|
|
it.isDirectory() ? it : zipTree(it)
|
|
}
|
|
}
|
|
|
|
from sourceSets.api.output
|
|
dependsOn apiClasses
|
|
|
|
// specify which files are really included, can control which APIs should be in
|
|
include "appeng/**"
|
|
include "assets/**"
|
|
include "mcmod.info"
|
|
include "pack.mcmeta"
|
|
include "META-INF/appliedenergistics2_at.cfg"
|
|
}
|
|
|
|
// Create API library jar
|
|
tasks.register('apiJar', Jar) {
|
|
archiveClassifier.set 'api'
|
|
from(sourceSets.api.java) {
|
|
include "${modGroupPath}/${apiPackagePath}/**"
|
|
}
|
|
|
|
from(sourceSets.api.output) {
|
|
include "${modGroupPath}/${apiPackagePath}/**"
|
|
}
|
|
}
|
|
|
|
// Configure shadow jar task
|
|
if (usesShadowedDependencies.toBoolean()) {
|
|
tasks.named('shadowJar', ShadowJar).configure {
|
|
manifest {
|
|
attributes(getManifestAttributes())
|
|
}
|
|
// Only shadow classes that are actually used, if enabled
|
|
if (minimizeShadowedDependencies.toBoolean()) {
|
|
minimize()
|
|
}
|
|
configurations = [
|
|
project.configurations.shadowImplementation,
|
|
project.configurations.shadowCompile
|
|
]
|
|
archiveClassifier.set('dev')
|
|
if (relocateShadowedDependencies.toBoolean()) {
|
|
relocationPrefix = modGroup + '.shadow'
|
|
enableRelocation = true
|
|
}
|
|
}
|
|
configurations.runtimeElements.outgoing.artifacts.clear()
|
|
configurations.apiElements.outgoing.artifacts.clear()
|
|
configurations.runtimeElements.outgoing.artifact(tasks.named('shadowJar', ShadowJar))
|
|
configurations.apiElements.outgoing.artifact(tasks.named('shadowJar', ShadowJar))
|
|
tasks.named('jar', Jar) {
|
|
enabled = false
|
|
finalizedBy(tasks.shadowJar)
|
|
}
|
|
tasks.named('reobfJar', ReobfuscatedJar) {
|
|
inputJar.set(tasks.named('shadowJar', ShadowJar).flatMap({ it.archiveFile }))
|
|
}
|
|
AdhocComponentWithVariants javaComponent = (AdhocComponentWithVariants) project.components.findByName('java')
|
|
javaComponent.withVariantsFromConfiguration(configurations.shadowRuntimeElements) {
|
|
skip()
|
|
}
|
|
for (runTask in ['runClient', 'runServer']) {
|
|
tasks.named(runTask).configure {
|
|
dependsOn('shadowJar')
|
|
}
|
|
}
|
|
}
|
|
|
|
def getManifestAttributes() {
|
|
def attributes = [:]
|
|
if (coreModClass) {
|
|
attributes['FMLCorePlugin'] = "${modGroup}.${coreModClass}"
|
|
}
|
|
if (!containsMixinsAndOrCoreModOnly.toBoolean() && (usesMixins.toBoolean() || coreModClass)) {
|
|
attributes['FMLCorePluginContainsFMLMod'] = true
|
|
}
|
|
if (accessTransformersFile) {
|
|
attributes['FMLAT'] = accessTransformersFile.toString()
|
|
}
|
|
|
|
if (usesMixins.toBoolean()) {
|
|
attributes['ForceLoadAsMod'] = !containsMixinsAndOrCoreModOnly.toBoolean()
|
|
}
|
|
return attributes
|
|
}
|
|
|
|
|
|
// IDE Configuration
|
|
|
|
eclipse {
|
|
classpath {
|
|
downloadSources = true
|
|
downloadJavadoc = true
|
|
}
|
|
}
|
|
|
|
idea {
|
|
module {
|
|
inheritOutputDirs true
|
|
downloadJavadoc true
|
|
downloadSources true
|
|
}
|
|
project {
|
|
settings {
|
|
runConfigurations {
|
|
'1. Setup Workspace'(Gradle) {
|
|
taskNames = ['setupDecompWorkspace']
|
|
}
|
|
'2. Run Client'(Gradle) {
|
|
taskNames = ['runClient']
|
|
}
|
|
'3. Run Server'(Gradle) {
|
|
taskNames = ['runServer']
|
|
}
|
|
'4. Run Obfuscated Client'(Gradle) {
|
|
taskNames = ['runObfClient']
|
|
}
|
|
'5. Run Obfuscated Server'(Gradle) {
|
|
taskNames = ['runObfServer']
|
|
}
|
|
if (enableSpotless.toBoolean()) {
|
|
'6. Apply Spotless'(Gradle) {
|
|
taskNames = ["spotlessApply"]
|
|
}
|
|
'7. Build Jars'(Gradle) {
|
|
taskNames = ['build']
|
|
}
|
|
} else {
|
|
'6. Build Jars'(Gradle) {
|
|
taskNames = ['build']
|
|
}
|
|
}
|
|
'Update Buildscript'(Gradle) {
|
|
taskNames = ['updateBuildScript']
|
|
}
|
|
'FAQ'(Gradle) {
|
|
taskNames = ['faq']
|
|
}
|
|
}
|
|
compiler.javac {
|
|
afterEvaluate {
|
|
javacAdditionalOptions = '-encoding utf8'
|
|
moduleJavacAdditionalOptions = [
|
|
(project.name + '.main'): tasks.compileJava.options.compilerArgs.collect {
|
|
'"' + it + '"'
|
|
}.join(' ')
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Deployment
|
|
def final modrinthApiKey = providers.environmentVariable('MODRINTH_API_KEY')
|
|
def final cfApiKey = providers.environmentVariable('CURSEFORGE_API_KEY')
|
|
final boolean isCIEnv = providers.environmentVariable('CI').getOrElse('false').toBoolean()
|
|
|
|
if (isCIEnv || deploymentDebug.toBoolean()) {
|
|
artifacts {
|
|
if (!noPublishedSources.toBoolean()) {
|
|
archives sourcesJar
|
|
}
|
|
if (apiPackage) {
|
|
archives apiJar
|
|
}
|
|
}
|
|
}
|
|
|
|
// Changelog generation
|
|
tasks.register('generateChangelog') {
|
|
group = 'GT Buildscript'
|
|
description = 'Generate a default changelog of all commits since the last tagged git commit'
|
|
onlyIf {
|
|
generateDefaultChangelog.toBoolean()
|
|
}
|
|
doLast {
|
|
def lastTag = getLastTag()
|
|
|
|
def changelog = runShell(([
|
|
"git",
|
|
"log",
|
|
"--date=format:%d %b %Y",
|
|
"--pretty=%s - **%an** (%ad)",
|
|
"${lastTag}..HEAD"
|
|
] + (sourceSets.main.java.srcDirs + sourceSets.main.resources.srcDirs)
|
|
.collect { ['--', it] }).flatten())
|
|
|
|
if (changelog) {
|
|
changelog = "Changes since ${lastTag}:\n${{ ("\n" + changelog).replaceAll("\n", "\n* ") }}"
|
|
}
|
|
def f = getFile('build/changelog.md')
|
|
changelog = changelog ?: 'There have been no changes.'
|
|
f.write(changelog, 'UTF-8')
|
|
|
|
// Set changelog for Modrinth
|
|
if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
|
|
modrinth.changelog.set(changelog)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) {
|
|
apply plugin: 'net.darkhax.curseforgegradle'
|
|
//noinspection UnnecessaryQualifiedReference
|
|
tasks.register('curseforge', net.darkhax.curseforgegradle.TaskPublishCurseForge) {
|
|
disableVersionDetection()
|
|
debugMode = deploymentDebug.toBoolean()
|
|
apiToken = cfApiKey.getOrElse('debug_token')
|
|
|
|
doFirst {
|
|
def mainFile = upload(curseForgeProjectId, reobfJar)
|
|
def changelogFile = getChangelog()
|
|
def changelogRaw = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
|
|
|
|
mainFile.displayName = "${modName}: ${modVersion}"
|
|
mainFile.releaseType = getReleaseType()
|
|
mainFile.changelog = changelogRaw
|
|
mainFile.changelogType = 'markdown'
|
|
mainFile.addModLoader 'Forge'
|
|
mainFile.addJavaVersion "Java 8"
|
|
mainFile.addGameVersion minecraftVersion
|
|
|
|
if (curseForgeRelations.size() != 0) {
|
|
String[] deps = curseForgeRelations.split(';')
|
|
deps.each { dep ->
|
|
if (dep.size() == 0) {
|
|
return
|
|
}
|
|
String[] parts = dep.split(':')
|
|
String type = parts[0], slug = parts[1]
|
|
if (!(type in ['requiredDependency', 'embeddedLibrary', 'optionalDependency', 'tool', 'incompatible'])) {
|
|
throw new Exception('Invalid Curseforge dependency type: ' + type)
|
|
}
|
|
mainFile.addRelation(slug, type)
|
|
}
|
|
}
|
|
|
|
for (artifact in getSecondaryArtifacts()) {
|
|
def additionalFile = mainFile.withAdditionalFile(artifact)
|
|
additionalFile.changelog = changelogRaw
|
|
}
|
|
}
|
|
}
|
|
tasks.curseforge.dependsOn(build)
|
|
tasks.curseforge.dependsOn('generateChangelog')
|
|
}
|
|
|
|
if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
|
|
apply plugin: 'com.modrinth.minotaur'
|
|
def final changelogFile = getChangelog()
|
|
|
|
modrinth {
|
|
token = modrinthApiKey.getOrElse('debug_token')
|
|
projectId = modrinthProjectId
|
|
changelog = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
|
|
versionType = getReleaseType()
|
|
versionNumber = modVersion
|
|
gameVersions = [minecraftVersion]
|
|
loaders = ["forge"]
|
|
debugMode = deploymentDebug.toBoolean()
|
|
uploadFile = reobfJar
|
|
additionalFiles = getSecondaryArtifacts()
|
|
}
|
|
if (modrinthRelations.size() != 0) {
|
|
String[] deps = modrinthRelations.split(';')
|
|
deps.each { dep ->
|
|
if (dep.size() == 0) {
|
|
return
|
|
}
|
|
String[] parts = dep.split(':')
|
|
String[] qual = parts[0].split('-')
|
|
addModrinthDep(qual[0], qual[1], parts[1])
|
|
}
|
|
}
|
|
tasks.modrinth.dependsOn(build)
|
|
tasks.modrinth.dependsOn('generateChangelog')
|
|
}
|
|
|
|
def addModrinthDep(String scope, String type, String name) {
|
|
com.modrinth.minotaur.dependencies.Dependency dep
|
|
if (!(scope in ['required', 'optional', 'incompatible', 'embedded'])) {
|
|
throw new Exception('Invalid modrinth dependency scope: ' + scope)
|
|
}
|
|
switch (type) {
|
|
case 'project':
|
|
dep = new ModDependency(name, scope)
|
|
break
|
|
case 'version':
|
|
dep = new VersionDependency(name, scope)
|
|
break
|
|
default:
|
|
throw new Exception('Invalid modrinth dependency type: ' + type)
|
|
}
|
|
project.modrinth.dependencies.add(dep)
|
|
}
|
|
|
|
if (customMavenPublishUrl) {
|
|
String publishedVersion = modVersion
|
|
|
|
publishing {
|
|
publications {
|
|
create('maven', MavenPublication) {
|
|
//noinspection GroovyAssignabilityCheck
|
|
from components.java
|
|
|
|
if (apiPackage) {
|
|
artifact apiJar
|
|
}
|
|
|
|
// providers is not available here, use System for getting env vars
|
|
groupId = System.getenv('ARTIFACT_GROUP_ID') ?: project.group
|
|
artifactId = System.getenv('ARTIFACT_ID') ?: project.name
|
|
version = System.getenv('RELEASE_VERSION') ?: publishedVersion
|
|
}
|
|
}
|
|
|
|
repositories {
|
|
maven {
|
|
url = customMavenPublishUrl
|
|
allowInsecureProtocol = !customMavenPublishUrl.startsWith('https')
|
|
credentials {
|
|
username = providers.environmentVariable('MAVEN_USER').getOrElse('NONE')
|
|
password = providers.environmentVariable('MAVEN_PASSWORD').getOrElse('NONE')
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
def getSecondaryArtifacts() {
|
|
def secondaryArtifacts = [usesShadowedDependencies.toBoolean() ? tasks.shadowJar : tasks.jar]
|
|
if (!noPublishedSources.toBoolean()) secondaryArtifacts += [sourcesJar]
|
|
if (apiPackage) secondaryArtifacts += [apiJar]
|
|
return secondaryArtifacts
|
|
}
|
|
|
|
def getReleaseType() {
|
|
String type = project.releaseType
|
|
if (!(type in ['release', 'beta', 'alpha'])) {
|
|
throw new Exception("Release type invalid! Found \"" + type + "\", allowed: \"release\", \"beta\", \"alpha\"")
|
|
}
|
|
return type
|
|
}
|
|
|
|
/*
|
|
* If CHANGELOG_LOCATION env var is set, that takes highest precedence.
|
|
* Next, if 'generateDefaultChangelog' option is enabled, use that.
|
|
* Otherwise, try to use a CHANGELOG.md file at root directory.
|
|
*/
|
|
|
|
def getChangelog() {
|
|
def final changelogEnv = providers.environmentVariable('CHANGELOG_LOCATION')
|
|
if (changelogEnv.isPresent()) {
|
|
return new File(changelogEnv.get())
|
|
}
|
|
if (generateDefaultChangelog.toBoolean()) {
|
|
return getFile('build/changelog.md')
|
|
}
|
|
return getFile('CHANGELOG.md')
|
|
}
|
|
|
|
|
|
// Buildscript updating
|
|
|
|
def buildscriptGradleVersion = '8.1.1'
|
|
|
|
tasks.named('wrapper', Wrapper).configure {
|
|
gradleVersion = buildscriptGradleVersion
|
|
}
|
|
|
|
tasks.register('updateBuildScript') {
|
|
group = 'GT Buildscript'
|
|
description = 'Updates the build script to the latest version'
|
|
|
|
if (gradle.gradleVersion != buildscriptGradleVersion && !Boolean.getBoolean('DISABLE_BUILDSCRIPT_GRADLE_UPDATE')) {
|
|
dependsOn('wrapper')
|
|
}
|
|
|
|
doLast {
|
|
if (performBuildScriptUpdate()) return
|
|
print('Build script already up to date!')
|
|
}
|
|
}
|
|
|
|
if (!project.getGradle().startParameter.isOffline() && !Boolean.getBoolean('DISABLE_BUILDSCRIPT_UPDATE_CHECK') && isNewBuildScriptVersionAvailable()) {
|
|
if (autoUpdateBuildScript.toBoolean()) {
|
|
performBuildScriptUpdate()
|
|
} else {
|
|
out.style(Style.SuccessHeader).println("Build script update available! Run 'gradle updateBuildScript'")
|
|
if (gradle.gradleVersion != buildscriptGradleVersion) {
|
|
out.style(Style.SuccessHeader).println("updateBuildScript can update gradle from ${gradle.gradleVersion} to ${buildscriptGradleVersion}\n")
|
|
}
|
|
}
|
|
}
|
|
|
|
static URL availableBuildScriptUrl() {
|
|
new URL("https://raw.githubusercontent.com/GregTechCEu/Buildscripts/master/build.gradle")
|
|
}
|
|
|
|
static URL exampleSettingsGradleUrl() {
|
|
new URL("https://raw.githubusercontent.com/GregTechCEu/Buildscripts/master/settings.gradle")
|
|
}
|
|
|
|
boolean verifySettingsGradle() {
|
|
def settingsFile = getFile("settings.gradle")
|
|
if (!settingsFile.exists()) {
|
|
println("Downloading default settings.gradle")
|
|
exampleSettingsGradleUrl().withInputStream { i -> settingsFile.withOutputStream { it << i } }
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
boolean performBuildScriptUpdate() {
|
|
if (isNewBuildScriptVersionAvailable()) {
|
|
def buildscriptFile = getFile("build.gradle")
|
|
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
|
|
def out = services.get(StyledTextOutputFactory).create('buildscript-update-output')
|
|
out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
|
|
if (verifySettingsGradle()) {
|
|
throw new GradleException("Settings has been updated, please re-run task.")
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
boolean isNewBuildScriptVersionAvailable() {
|
|
Map parameters = ["connectTimeout": 10000, "readTimeout": 10000]
|
|
|
|
String currentBuildScript = getFile("build.gradle").getText()
|
|
String currentBuildScriptHash = getVersionHash(currentBuildScript)
|
|
String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText()
|
|
String availableBuildScriptHash = getVersionHash(availableBuildScript)
|
|
|
|
boolean isUpToDate = currentBuildScriptHash.empty || availableBuildScriptHash.empty || currentBuildScriptHash == availableBuildScriptHash
|
|
return !isUpToDate
|
|
}
|
|
|
|
static String getVersionHash(String buildScriptContent) {
|
|
String versionLine = buildScriptContent.find("^//version: [a-z0-9]*")
|
|
if (versionLine != null) {
|
|
return versionLine.split(": ").last()
|
|
}
|
|
return ""
|
|
}
|
|
|
|
|
|
// Faq
|
|
|
|
tasks.register('faq') {
|
|
group = 'GT Buildscript'
|
|
description = 'Prints frequently asked questions about building a project'
|
|
doLast {
|
|
print("\nTo update this buildscript to the latest version, run 'gradlew updateBuildScript' or run the generated run configuration if you are using IDEA.\n" +
|
|
"To set up the project, run the 'setupDecompWorkspace' task, which you can run as './gradlew setupDecompWorkspace' in a terminal, or find in the 'modded minecraft' gradle category.\n\n" +
|
|
"To add new dependencies to your project, place them in 'dependencies.gradle', NOT in 'build.gradle' as they would be replaced when the script updates.\n" +
|
|
"To add new repositories to your project, place them in 'repositories.gradle'.\n" +
|
|
"If you need additional gradle code to run, you can place it in a file named 'addon.gradle' (or either of the above, up to you for organization).\n\n" +
|
|
"If your build fails to recognize the syntax of newer Java versions, enable Jabel in your 'gradle.properties' under the option name 'enableModernJavaSyntax'.\n" +
|
|
"To see information on how to configure your IDE properly for Java 17, see https://github.com/GregTechCEu/Buildscripts/blob/master/docs/jabel.md\n\n" +
|
|
"Report any issues or feature requests you have for this build script to https://github.com/GregTechCEu/Buildscripts/issues\n")
|
|
}
|
|
}
|
|
|
|
|
|
// Helpers
|
|
|
|
def getFile(String relativePath) {
|
|
return new File(projectDir, relativePath)
|
|
}
|
|
|
|
def checkPropertyExists(String propertyName) {
|
|
if (!project.hasProperty(propertyName)) {
|
|
throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/GregTechCEu/Buildscripts/blob/main/gradle.properties")
|
|
}
|
|
}
|
|
|
|
def propertyDefaultIfUnset(String propertyName, defaultValue) {
|
|
if (!project.hasProperty(propertyName) || project.property(propertyName) == "") {
|
|
project.ext.setProperty(propertyName, defaultValue)
|
|
}
|
|
}
|
|
|
|
def propertyDefaultIfUnsetWithEnvVar(String propertyName, defaultValue, String envVarName) {
|
|
def envVar = providers.environmentVariable(envVarName)
|
|
if (envVar.isPresent()) {
|
|
project.ext.setProperty(propertyName, envVar.get())
|
|
} else {
|
|
propertyDefaultIfUnset(propertyName, defaultValue)
|
|
}
|
|
}
|
|
|
|
static runShell(command) {
|
|
def process = command.execute()
|
|
def outputStream = new StringBuffer()
|
|
def errorStream = new StringBuffer()
|
|
process.waitForProcessOutput(outputStream, errorStream)
|
|
|
|
errorStream.toString().with {
|
|
if (it) {
|
|
throw new GradleException("Error executing ${command}:\n> ${it}")
|
|
}
|
|
}
|
|
return outputStream.toString().trim()
|
|
}
|
|
|
|
def getLastTag() {
|
|
def githubTag = providers.environmentVariable('GITHUB_TAG')
|
|
return runShell('git describe --abbrev=0 --tags ' +
|
|
(githubTag.isPresent() ? runShell('git rev-list --tags --skip=1 --max-count=1') : ''))
|
|
} |