diff options
| -rw-r--r-- | .gitattributes | 44 | ||||
| -rw-r--r-- | build.gradle | 1270 | ||||
| -rw-r--r-- | gradle/wrapper/gradle-wrapper.jar | bin | 55616 -> 61608 bytes | |||
| -rw-r--r-- | gradle/wrapper/gradle-wrapper.properties | 3 | ||||
| -rwxr-xr-x | gradlew | 272 | ||||
| -rw-r--r-- | gradlew.bat | 38 | ||||
| -rw-r--r-- | settings.gradle | 28 |
7 files changed, 1197 insertions, 458 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..fd2792b6cb --- /dev/null +++ b/.gitattributes @@ -0,0 +1,44 @@ +* text eol=lf + +*.[jJ][aA][rR] binary + +*.[pP][nN][gG] binary +*.[jJ][pP][gG] binary +*.[jJ][pP][eE][gG] binary +*.[gG][iI][fF] binary +*.[tT][iI][fF] binary +*.[tT][iI][fF][fF] binary +*.[iI][cC][oO] binary +*.[sS][vV][gG] text +*.[eE][pP][sS] binary +*.[xX][cC][fF] binary + +*.[kK][aA][rR] binary +*.[mM]4[aA] binary +*.[mM][iI][dD] binary +*.[mM][iI][dD][iI] binary +*.[mM][pP]3 binary +*.[oO][gG][gG] binary +*.[rR][aA] binary + +*.7[zZ] binary +*.[gG][zZ] binary +*.[tT][aA][rR] binary +*.[tT][gG][zZ] binary +*.[zZ][iI][pP] binary + +*.[tT][cC][nN] binary +*.[sS][oO] binary +*.[dD][lL][lL] binary +*.[dD][yY][lL][iI][bB] binary +*.[pP][sS][dD] binary +*.[tT][tT][fF] binary +*.[oO][tT][fF] binary + +*.[pP][aA][tT][cC][hH] -text + +*.[bB][aA][tT] text eol=crlf +*.[cC][mM][dD] text eol=crlf +*.[pP][sS]1 text eol=crlf + +*[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary diff --git a/build.gradle b/build.gradle index c9bb6ce785..18afe431e9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,71 +1,87 @@ -//version: 1642484596 +//version: 1675013090 /* -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/GTNewHorizons/ExampleMod1.7.10/blob/main/build.gradle for updates. + 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/GTNewHorizons/ExampleMod1.7.10/blob/master/build.gradle for updates. */ +import com.diffplug.blowdryer.Blowdryer import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - +import com.gtnewhorizons.retrofuturagradle.mcp.ReobfuscatedJar +import com.matthewprenger.cursegradle.CurseArtifact +import com.matthewprenger.cursegradle.CurseRelation +import com.modrinth.minotaur.dependencies.ModDependency +import com.modrinth.minotaur.dependencies.VersionDependency +import org.gradle.internal.logging.text.StyledTextOutput.Style +import org.gradle.internal.logging.text.StyledTextOutputFactory +import org.jetbrains.gradle.ext.* + +import java.nio.file.Files +import java.nio.file.Paths import java.util.concurrent.TimeUnit +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream buildscript { repositories { + mavenLocal() + mavenCentral() + maven { - name = "forge" - url = "https://maven.minecraftforge.net" + name 'forge' + url 'https://maven.minecraftforge.net' } maven { - name = "sonatype" - url = "https://oss.sonatype.org/content/repositories/snapshots/" + // GTNH RetroFuturaGradle and ASM Fork + name "GTNH Maven" + url "http://jenkins.usrv.eu:8081/nexus/content/groups/public/" + allowInsecureProtocol = true } maven { - name = "Scala CI dependencies" - url = "https://repo1.maven.org/maven2/" + name 'sonatype' + url 'https://oss.sonatype.org/content/repositories/snapshots/' } maven { - name = "jitpack" - url = "https://jitpack.io" + name 'Scala CI dependencies' + url 'https://repo1.maven.org/maven2/' } } - dependencies { - classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.7' - } } - plugins { - id 'idea' + id 'java-library' + id "org.jetbrains.gradle.plugin.idea-ext" version "1.1.7" + id 'eclipse' id 'scala' - id("org.ajoberstar.grgit") version("3.1.1") - id("com.github.johnrengelman.shadow") version("4.0.4") - id("com.palantir.git-version") version("0.12.3") - id("maven-publish") + id 'maven-publish' + id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false + id 'org.jetbrains.kotlin.kapt' version '1.5.30' apply false + id 'com.google.devtools.ksp' version '1.5.30-1.0.0' apply false + id 'org.ajoberstar.grgit' version '4.1.1' // 4.1.1 is the last jvm8 supporting version ,unused, available for addon.gradle + id 'com.github.johnrengelman.shadow' version '7.1.2' apply false + id 'com.palantir.git-version' version '0.13.0' apply false // 0.13.0 is the last jvm8 supporting version + id 'de.undercouch.download' version '5.3.0' + id 'com.github.gmazzo.buildconfig' version '3.1.0' apply false // Unused, available for addon.gradle + id 'com.diffplug.spotless' version '6.7.2' apply false + id 'com.modrinth.minotaur' version '2.+' apply false + id 'com.matthewprenger.cursegradle' version '1.4.0' apply false + id 'com.gtnewhorizons.retrofuturagradle' version '1.0.18' } +boolean settingsupdated = verifySettingsGradle() +settingsupdated = verifyGitAttributes() || settingsupdated +if (settingsupdated) + throw new GradleException("Settings has been updated, please re-run task.") -apply plugin: 'forge' - -def projectJavaVersion = JavaLanguageVersion.of(8) - -java { - toolchain { - languageVersion.set(projectJavaVersion) - } +if (project.file('.git/HEAD').isFile()) { + apply plugin: 'com.palantir.git-version' } -idea { - module { - inheritOutputDirs = true - downloadJavadoc = true - downloadSources = true - } -} +def out = services.get(StyledTextOutputFactory).create('an-output') -if(JavaVersion.current() != JavaVersion.VERSION_1_8) { - throw new GradleException("This project requires Java 8, but it's running on " + JavaVersion.current()) -} +def projectJavaVersion = JavaLanguageVersion.of(8) + +boolean disableSpotless = project.hasProperty("disableSpotless") ? project.disableSpotless.toBoolean() : false checkPropertyExists("modName") checkPropertyExists("modId") @@ -74,10 +90,7 @@ checkPropertyExists("autoUpdateBuildScript") checkPropertyExists("minecraftVersion") checkPropertyExists("forgeVersion") checkPropertyExists("replaceGradleTokenInFile") -checkPropertyExists("gradleTokenModId") -checkPropertyExists("gradleTokenModName") checkPropertyExists("gradleTokenVersion") -checkPropertyExists("gradleTokenGroupName") checkPropertyExists("apiPackage") checkPropertyExists("accessTransformersFile") checkPropertyExists("usesMixins") @@ -88,61 +101,175 @@ checkPropertyExists("containsMixinsAndOrCoreModOnly") checkPropertyExists("usesShadowedDependencies") checkPropertyExists("developmentEnvironmentUserName") -boolean noPublishedSources = project.findProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false +propertyDefaultIfUnset("generateGradleTokenClass", "") +propertyDefaultIfUnset("includeWellKnownRepositories", true) +propertyDefaultIfUnset("noPublishedSources", false) +propertyDefaultIfUnset("usesMixinDebug", project.usesMixins) +propertyDefaultIfUnset("forceEnableMixins", false) +propertyDefaultIfUnset("channel", "stable") +propertyDefaultIfUnset("mappingsVersion", "12") +propertyDefaultIfUnset("modrinthProjectId", "") +propertyDefaultIfUnset("modrinthRelations", "") +propertyDefaultIfUnset("curseForgeProjectId", "") +propertyDefaultIfUnset("curseForgeRelations", "") +propertyDefaultIfUnset("minimizeShadowedDependencies", true) +// Deprecated properties (kept for backwards compat) +propertyDefaultIfUnset("gradleTokenModId", "") +propertyDefaultIfUnset("gradleTokenModName", "") +propertyDefaultIfUnset("gradleTokenGroupName", "") + +propertyDefaultIfUnset("enableModernJavaSyntax", false) // On by default for new projects only +propertyDefaultIfUnset("enableGenericInjection", false) // On by default for new projects only + +project.extensions.add(Blowdryer, "Blowdryer", Blowdryer) // Make blowdryer available in "apply from:" scripts +if (!disableSpotless) { + apply plugin: 'com.diffplug.spotless' + apply from: Blowdryer.file('spotless.gradle') +} String javaSourceDir = "src/main/java/" String scalaSourceDir = "src/main/scala/" +String kotlinSourceDir = "src/main/kotlin/" + +if (usesShadowedDependencies.toBoolean()) { + apply plugin: "com.github.johnrengelman.shadow" +} + +java { + toolchain { + if (enableModernJavaSyntax.toBoolean()) { + languageVersion.set(JavaLanguageVersion.of(17)) + } else { + languageVersion.set(projectJavaVersion) + } + vendor.set(JvmVendorSpec.ADOPTIUM) + } + if (!noPublishedSources) { + withSourcesJar() + } +} + +configurations { + create("runtimeOnlyNonPublishable") { + description = "Runtime only dependencies that are not published alongside the jar" + canBeConsumed = false + canBeResolved = false + } +} + +if (enableModernJavaSyntax.toBoolean()) { + dependencies { + annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0' + compileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') { + transitive = false // We only care about the 1 annotation class + } + } + + tasks.withType(JavaCompile).configureEach { + if (it.name in ["compileMcLauncherJava", "compilePatchedMcJava"]) { + return + } + sourceCompatibility = 17 // for the IDE support + options.release.set(8) -String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") -String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") -if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) { - throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala) + javaCompiler.set(javaToolchains.compilerFor { + languageVersion.set(JavaLanguageVersion.of(17)) + vendor.set(JvmVendorSpec.ADOPTIUM) + }) + } } -if(apiPackage) { - targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") - targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") - if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) { - throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala) +eclipse { + classpath { + downloadSources = true + downloadJavadoc = true } } -if(accessTransformersFile) { +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 +String targetPackageKotlin = kotlinSourceDir + modGroupPath +if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) { + throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin) +} + +if (apiPackage) { + targetPackageJava = javaSourceDir + modGroupPath + "/" + apiPackagePath + targetPackageScala = scalaSourceDir + modGroupPath + "/" + apiPackagePath + targetPackageKotlin = kotlinSourceDir + modGroupPath + "/" + apiPackagePath + if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) { + throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin) + } +} + +if (accessTransformersFile) { String targetFile = "src/main/resources/META-INF/" + accessTransformersFile - if(getFile(targetFile).exists() == false) { + 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) +} else { + boolean atsFound = false + for (File at : sourceSets.getByName("main").resources.files) { + if (at.name.toLowerCase().endsWith("_at.cfg")) { + atsFound = true + tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(at) + tasks.srgifyBinpatchedJar.accessTransformerFiles.from(at) + } + } + for (File at : sourceSets.getByName("api").resources.files) { + if (at.name.toLowerCase().endsWith("_at.cfg")) { + atsFound = true + tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(at) + tasks.srgifyBinpatchedJar.accessTransformerFiles.from(at) + } + } + if (atsFound) { + logger.warn("Found and added access transformers in the resources folder, please configure gradle.properties to explicitly mention them by name") + } } -if(usesMixins.toBoolean()) { - if(mixinsPackage.isEmpty() || mixinPlugin.isEmpty()) { - throw new GradleException("\"mixinPlugin\" requires \"mixinsPackage\" and \"mixinPlugin\" to be set!") +if (usesMixins.toBoolean()) { + if (mixinsPackage.isEmpty()) { + throw new GradleException("\"usesMixins\" requires \"mixinsPackage\" to be set!") } - - targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/") - targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/") - if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) { - throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala) + final String mixinPackagePath = mixinsPackage.toString().replaceAll("\\.", "/") + final String mixinPluginPath = mixinPlugin.toString().replaceAll("\\.", "/") + + targetPackageJava = javaSourceDir + modGroupPath + "/" + mixinPackagePath + targetPackageScala = scalaSourceDir + modGroupPath + "/" + mixinPackagePath + targetPackageKotlin = kotlinSourceDir + modGroupPath + "/" + mixinPackagePath + if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) { + throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin) } - String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java" - String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".scala" - String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java" - if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) { - throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava) + if (!mixinPlugin.isEmpty()) { + String targetFileJava = javaSourceDir + modGroupPath + "/" + mixinPluginPath + ".java" + String targetFileScala = scalaSourceDir + modGroupPath + "/" + mixinPluginPath + ".scala" + String targetFileScalaJava = scalaSourceDir + modGroupPath + "/" + mixinPluginPath + ".java" + String targetFileKotlin = kotlinSourceDir + modGroupPath + "/" + mixinPluginPath + ".kt" + if (!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) { + throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin) + } } } -if(coreModClass) { - String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java" - String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".scala" - String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java" - if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) { - throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava) +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" + String targetFileKotlin = kotlinSourceDir + modGroupPath + "/" + coreModPath + ".kt" + if (!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) { + throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin) } } -configurations.all { +configurations.configureEach { resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS) // Make sure GregTech build won't time out @@ -151,333 +278,402 @@ configurations.all { } // Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version -'git config core.fileMode false'.execute() +try { + 'git config core.fileMode false'.execute() +} +catch (Exception ignored) { + out.style(Style.Failure).println("git isn't installed at all") +} // Pulls version first from the VERSION env and then git tag String identifiedVersion +String versionOverride = System.getenv("VERSION") ?: null try { - String versionOverride = System.getenv("VERSION") ?: null identifiedVersion = versionOverride == null ? gitVersion() : versionOverride - version = minecraftVersion + "-" + identifiedVersion } -catch (Exception e) { - throw new IllegalStateException("This mod must be version controlled by Git AND the repository must provide at least one tag, or the VERSION override must be set!"); +catch (Exception ignored) { + out.style(Style.Failure).text( + 'This mod must be version controlled by Git AND the repository must provide at least one tag,\n' + + 'or the VERSION override must be set! ').style(Style.SuccessHeader).text('(Do NOT download from GitHub using the ZIP option, instead\n' + + 'clone the repository, see ').style(Style.Info).text('https://gtnh.miraheze.org/wiki/Development').style(Style.SuccessHeader).println(' for details.)' + ) + versionOverride = 'NO-GIT-TAG-SET' + identifiedVersion = versionOverride +} +version = identifiedVersion +ext { + modVersion = identifiedVersion +} + +if (identifiedVersion == versionOverride) { + out.style(Style.Failure).text('Override version to ').style(Style.Identifier).text(modVersion).style(Style.Failure).println('!\7') } group = modGroup -if(project.hasProperty("customArchiveBaseName") && customArchiveBaseName) { +if (project.hasProperty("customArchiveBaseName") && customArchiveBaseName) { archivesBaseName = customArchiveBaseName -} -else { +} else { archivesBaseName = modId } -minecraft { - version = minecraftVersion + "-" + forgeVersion + "-" + minecraftVersion - runDir = "run" +minecraft { if (replaceGradleTokenInFile) { - replaceIn replaceGradleTokenInFile - if(gradleTokenModId) { - replace gradleTokenModId, modId + for (f in replaceGradleTokenInFile.split(',')) { + tagReplacementFiles.add f } - if(gradleTokenModName) { - replace gradleTokenModName, modName - } - if(gradleTokenVersion) { - replace gradleTokenVersion, versionDetails().lastTag - } - if(gradleTokenGroupName) { - replace gradleTokenGroupName, modGroup + } + if (gradleTokenModId) { + injectedTags.put gradleTokenModId, modId + } + if (gradleTokenModName) { + injectedTags.put gradleTokenModName, modName + } + if (gradleTokenVersion) { + injectedTags.put gradleTokenVersion, modVersion + } + if (gradleTokenGroupName) { + injectedTags.put gradleTokenGroupName, modGroup + } + if (enableGenericInjection.toBoolean()) { + injectMissingGenerics.set(true) + } + + // Enable assertions in the current mod + extraRunJvmArguments.add("-ea:${modGroup}") + + if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) { + extraTweakClasses.add("org.spongepowered.asm.launch.MixinTweaker") + + if (usesMixinDebug.toBoolean()) { + extraRunJvmArguments.addAll([ + "-Dmixin.debug.countInjections=true", + "-Dmixin.debug.verbose=true", + "-Dmixin.debug.export=true" + ]) } } -} -if(file("addon.gradle").exists()) { - apply from: "addon.gradle" + // Blowdryer is present in some old mod builds, do not propagate it further as a dependency + // IC2 has no reobf jars in its Maven + groupsToExcludeFromAutoReobfMapping.addAll(["com.diffplug", "com.diffplug.durian", "net.industrial-craft"]) } -apply from: 'repositories.gradle' - -configurations { - implementation.extendsFrom(shadowImplementation) // TODO: remove after all uses are refactored - implementation.extendsFrom(shadowCompile) - implementation.extendsFrom(shadeCompile) +if (generateGradleTokenClass) { + tasks.injectTags.outputClassName.set(generateGradleTokenClass) } -repositories { - maven { - name = "Overmind forge repo mirror" - url = "https://gregtech.overminddl1.com/" - } - if(usesMixins.toBoolean()) { - maven { - name = "sponge" - url = "https://repo.spongepowered.org/repository/maven-public" - } - maven { - url = "https://jitpack.io" +// Custom reobf auto-mappings +configurations.configureEach { + dependencies.configureEach { dep -> + if (dep instanceof org.gradle.api.artifacts.ExternalModuleDependency) { + if (dep.group == "net.industrial-craft" && dep.name == "industrialcraft-2") { + // https://www.curseforge.com/minecraft/mc-mods/industrial-craft/files/2353971 + project.dependencies.reobfJarConfiguration("curse.maven:ic2-242638:2353971") + } } } } -dependencies { - if(usesMixins.toBoolean()) { - annotationProcessor("org.ow2.asm:asm-debug-all:5.0.3") - annotationProcessor("com.google.guava:guava:24.1.1-jre") - annotationProcessor("com.google.code.gson:gson:2.8.6") - annotationProcessor("org.spongepowered:mixin:0.8-SNAPSHOT") - // using 0.8 to workaround a issue in 0.7 which fails mixin application - compile("com.github.GTNewHorizons:SpongePoweredMixin:0.7.12-GTNH") { - // Mixin includes a lot of dependencies that are too up-to-date - exclude module: "launchwrapper" - exclude module: "guava" - exclude module: "gson" - exclude module: "commons-io" - exclude module: "log4j-core" +// Ensure tests have access to minecraft classes +sourceSets { + test { + java { + compileClasspath += sourceSets.patchedMc.output + sourceSets.mcLauncher.output + runtimeClasspath += sourceSets.patchedMc.output + sourceSets.mcLauncher.output } - compile("com.github.GTNewHorizons:SpongeMixins:1.5.0") } } -apply from: 'dependencies.gradle' - -def mixingConfigRefMap = "mixins." + modId + ".refmap.json" -def refMap = "${tasks.compileJava.temporaryDir}" + File.separator + mixingConfigRefMap -def mixinSrg = "${tasks.reobf.temporaryDir}" + File.separator + "mixins.srg" - -task generateAssets { - if(usesMixins.toBoolean()) { - getFile("/src/main/resources/mixins." + modId + ".json").text = """{ - "required": true, - "minVersion": "0.7.11", - "package": "${modGroup}.${mixinsPackage}", - "plugin": "${modGroup}.${mixinPlugin}", - "refmap": "${mixingConfigRefMap}", - "target": "@env(DEFAULT)", - "compatibilityLevel": "JAVA_8" +if (file('addon.gradle').exists()) { + apply from: 'addon.gradle' } -""" +// Allow unsafe repos but warn +repositories.configureEach { repo -> + if (repo instanceof org.gradle.api.artifacts.repositories.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 + } } } -task relocateShadowJar(type: ConfigureShadowRelocation) { - target = tasks.shadowJar - prefix = modGroup + ".shadow" -} +apply from: 'repositories.gradle' -shadowJar { - project.configurations.shadeCompile.each { dep -> - from(project.zipTree(dep)) { - exclude 'META-INF', 'META-INF/**' +configurations { + for (config in [compileClasspath, runtimeClasspath, testCompileClasspath, testRuntimeClasspath]) { + config.extendsFrom(runtimeOnlyNonPublishable) + if (usesShadowedDependencies.toBoolean()) { + config.extendsFrom(shadowImplementation) + // TODO: remove Compile after all uses are refactored to Implementation + config.extendsFrom(shadeCompile) + config.extendsFrom(shadowCompile) } } - - manifest { - attributes(getManifestAttributes()) + // A "bag-of-dependencies"-style configuration for backwards compatibility, gets put in "api" + create("compile") { + description = "Deprecated: use api or implementation instead, gets put in api" + canBeConsumed = false + canBeResolved = false + visible = false + } + create("testCompile") { + description = "Deprecated: use testImplementation instead" + canBeConsumed = false + canBeResolved = false + visible = false } + api.extendsFrom(compile) + testImplementation.extendsFrom(testCompile) +} - minimize() // This will only allow shading for actually used classes - configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile] - dependsOn(relocateShadowJar) +afterEvaluate { + if (!configurations.compile.allDependencies.empty || !configurations.testCompile.allDependencies.empty) { + logger.warn("This project uses deprecated `compile` dependencies, please migrate to using `api` and `implementation`") + logger.warn("For more details, see https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/master/dependencies.gradle") + } } -jar { - project.configurations.shadeCompile.each { dep -> - from(project.zipTree(dep)) { - exclude 'META-INF', 'META-INF/**' +repositories { + maven { + name 'Overmind forge repo mirror' + url 'https://gregtech.overminddl1.com/' + mavenContent { + excludeGroup("net.minecraftforge") // missing the `universal` artefact } } - - manifest { - attributes(getManifestAttributes()) + maven { + name = "GTNH Maven" + url = "http://jenkins.usrv.eu:8081/nexus/content/groups/public/" + allowInsecureProtocol = true } - - if(usesShadowedDependencies.toBoolean()) { - dependsOn(shadowJar) - enabled = false + if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) { + if (usesMixinDebug.toBoolean()) { + maven { + name = "Fabric Maven" + url = "https://maven.fabricmc.net/" + } + } } -} - -reobf { - if(usesMixins.toBoolean()) { - addExtraSrgFile mixinSrg + if (includeWellKnownRepositories.toBoolean()) { + maven { + name "CurseMaven" + url "https://cursemaven.com" + content { + includeGroup "curse.maven" + } + } + maven { + name = "ic2" + url = "https://maven.ic2.player.to/" + metadataSources { + mavenPom() + artifact() + } + } + maven { + name = "ic2-mirror" + url = "https://maven2.ic2.player.to/" + metadataSources { + mavenPom() + artifact() + } + } + maven { + name "MMD Maven" + url "https://maven.mcmoddev.com/" + } } } -afterEvaluate { - if(usesMixins.toBoolean()) { - tasks.compileJava { - options.compilerArgs += [ - "-AreobfSrgFile=${tasks.reobf.srg}", - "-AoutSrgFile=${mixinSrg}", - "-AoutRefMapFile=${refMap}", - // Elan: from what I understand they are just some linter configs so you get some warning on how to properly code - "-XDenableSunApiLintControl", - "-XDignore.symbol.file" - ] +dependencies { + if (usesMixins.toBoolean()) { + annotationProcessor('org.ow2.asm:asm-debug-all:5.0.3') + annotationProcessor('com.google.guava:guava:24.1.1-jre') + annotationProcessor('com.google.code.gson:gson:2.8.6') + annotationProcessor('com.gtnewhorizon:gtnhmixins:2.1.10:processor') + if (usesMixinDebug.toBoolean()) { + runtimeOnlyNonPublishable('org.jetbrains:intellij-fernflower:1.2.1.16') } } + if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) { + implementation('com.gtnewhorizon:gtnhmixins:2.1.10') + } } -runClient { - def arguments = [] +apply from: 'dependencies.gradle' - if(usesMixins.toBoolean()) { - arguments += [ - "--mods=../build/libs/$modId-${version}.jar", - "--tweakClass org.spongepowered.asm.launch.MixinTweaker" - ] - } +def mixingConfigRefMap = 'mixins.' + modId + '.refmap.json' +def mixinTmpDir = buildDir.path + File.separator + 'tmp' + File.separator + 'mixins' +def refMap = "${mixinTmpDir}" + File.separator + mixingConfigRefMap +def mixinSrg = "${mixinTmpDir}" + File.separator + "mixins.srg" - if(developmentEnvironmentUserName) { - arguments += [ - "--username", - developmentEnvironmentUserName - ] - } +tasks.register('generateAssets') { + group = "GTNH Buildscript" + description = "Generates a mixin config file at /src/main/resources/mixins.modid.json if needed" + onlyIf { usesMixins.toBoolean() } + doLast { + def mixinConfigFile = getFile("/src/main/resources/mixins." + modId + ".json") + if (!mixinConfigFile.exists()) { + def mixinPluginLine = "" + if (!mixinPlugin.isEmpty()) { + // We might not have a mixin plugin if we're using early/late mixins + mixinPluginLine += """\n "plugin": "${modGroup}.${mixinPlugin}", """ + } - args(arguments) + mixinConfigFile.text = """{ + "required": true, + "minVersion": "0.8.5-GTNH", + "package": "${modGroup}.${mixinsPackage}",${mixinPluginLine} + "refmap": "${mixingConfigRefMap}", + "target": "@env(DEFAULT)", + "compatibilityLevel": "JAVA_8", + "mixins": [], + "client": [], + "server": [] } - -runServer { - def arguments = [] - - if (usesMixins.toBoolean()) { - arguments += [ - "--mods=../build/libs/$modId-${version}.jar", - "--tweakClass org.spongepowered.asm.launch.MixinTweaker" - ] +""" + } } +} - args(arguments) +if (usesMixins.toBoolean()) { + tasks.named("reobfJar", ReobfuscatedJar).configure { + extraSrgFiles.from(mixinSrg) + } } -tasks.withType(JavaExec).configureEach { - javaLauncher.set( - javaToolchains.launcherFor { - languageVersion = projectJavaVersion - } - ) +if (usesMixins.toBoolean()) { + tasks.named("compileJava", JavaCompile).configure { + doFirst { + new File(mixinTmpDir).mkdirs() + } + options.compilerArgs += [ + "-AreobfSrgFile=${tasks.reobfJar.srg.get().asFile}", + "-AoutSrgFile=${mixinSrg}", + "-AoutRefMapFile=${refMap}", + // Elan: from what I understand they are just some linter configs so you get some warning on how to properly code + "-XDenableSunApiLintControl", + "-XDignore.symbol.file" + ] + } } -processResources -{ +tasks.named("processResources", ProcessResources).configure { // this will ensure that this task is redone when the versions change. inputs.property "version", project.version - inputs.property "mcversion", project.minecraft.version - - // replace stuff in mcmod.info, nothing else - from(sourceSets.main.resources.srcDirs) { - include 'mcmod.info' - - // replace version and mcversion - expand "minecraftVersion": project.minecraft.version, - "modVersion": versionDetails().lastTag, - "modId": modId, - "modName": modName + inputs.property "mcversion", project.minecraft.mcVersion + exclude("spotless.gradle") + + // replace stuff in mcmod.info, nothing else. replaces ${key} with value in text + filesMatching("mcmod.info") { + expand "minecraftVersion": project.minecraft.mcVersion, + "modVersion": modVersion, + "modId": modId, + "modName": modName } - if(usesMixins.toBoolean()) { + if (usesMixins.toBoolean()) { from refMap } - - // copy everything else, thats not the mcmod.info - from(sourceSets.main.resources.srcDirs) { - exclude 'mcmod.info' - } } def getManifestAttributes() { def manifestAttributes = [:] - if(containsMixinsAndOrCoreModOnly.toBoolean() == false && (usesMixins.toBoolean() || coreModClass)) { + if (!containsMixinsAndOrCoreModOnly.toBoolean() && (usesMixins.toBoolean() || coreModClass)) { manifestAttributes += ["FMLCorePluginContainsFMLMod": true] } - if(accessTransformersFile) { - manifestAttributes += ["FMLAT" : accessTransformersFile.toString()] + if (accessTransformersFile) { + manifestAttributes += ["FMLAT": accessTransformersFile.toString()] } - if(coreModClass) { + if (coreModClass) { manifestAttributes += ["FMLCorePlugin": modGroup + "." + coreModClass] } - if(usesMixins.toBoolean()) { + if (usesMixins.toBoolean()) { manifestAttributes += [ - "TweakClass" : "org.spongepowered.asm.launch.MixinTweaker", - "MixinConfigs" : "mixins." + modId + ".json", - "ForceLoadAsMod" : containsMixinsAndOrCoreModOnly.toBoolean() == false + "TweakClass" : "org.spongepowered.asm.launch.MixinTweaker", + "MixinConfigs" : "mixins." + modId + ".json", + "ForceLoadAsMod": !containsMixinsAndOrCoreModOnly.toBoolean() ] } return manifestAttributes } -task sourcesJar(type: Jar) { - from (sourceSets.main.allJava) - from (file("$projectDir/LICENSE")) - getArchiveClassifier().set('sources') -} - -task shadowDevJar(type: ShadowJar) { - project.configurations.shadeCompile.each { dep -> - from(project.zipTree(dep)) { - exclude 'META-INF', 'META-INF/**' - } - } - - from sourceSets.main.output - getArchiveClassifier().set("dev") - +tasks.named("jar", Jar).configure { manifest { attributes(getManifestAttributes()) } - - minimize() // This will only allow shading for actually used classes - configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile] } -task relocateShadowDevJar(type: ConfigureShadowRelocation) { - target = tasks.shadowDevJar - prefix = modGroup + ".shadow" -} - -task circularResolverJar(type: Jar) { - dependsOn(relocateShadowDevJar) - dependsOn(shadowDevJar) - enabled = false -} +if (usesShadowedDependencies.toBoolean()) { + tasks.register('relocateShadowJar', ConfigureShadowRelocation) { + |
