From a7e6b8baffcfec8062b00926269134b3496ea7cb Mon Sep 17 00:00:00 2001 From: bombcar Date: Sat, 12 Feb 2022 15:11:06 -0600 Subject: [PATCH] Maven (#1) * include new build and test workflow * Update for maven build --- .github/scripts/test-no-error-reports.sh | 33 + .github/workflows/build-and-test.yml | 45 ++ .github/workflows/release-tags.yml | 51 ++ .gitignore | 44 +- CODEOWNERS | 3 + build.gradle | 724 +++++++++++++++++- build.properties | 3 - dependencies.gradle | 5 + gradle.properties | 67 ++ gradle/wrapper/gradle-wrapper.jar | Bin 55627 -> 55616 bytes gradle/wrapper/gradle-wrapper.properties | 5 +- gradlew | 98 ++- gradlew.bat | 30 +- jitpack.yml | 2 + repositories.gradle | 5 + .../torohealthmod/ToroHealthMod.java | 2 +- src/main/resources/mcmod.info | 14 +- 17 files changed, 1024 insertions(+), 107 deletions(-) create mode 100755 .github/scripts/test-no-error-reports.sh create mode 100644 .github/workflows/build-and-test.yml create mode 100644 .github/workflows/release-tags.yml create mode 100644 CODEOWNERS delete mode 100644 build.properties create mode 100644 dependencies.gradle create mode 100644 gradle.properties mode change 100644 => 100755 gradlew create mode 100644 jitpack.yml create mode 100644 repositories.gradle diff --git a/.github/scripts/test-no-error-reports.sh b/.github/scripts/test-no-error-reports.sh new file mode 100755 index 0000000..84c1e5d --- /dev/null +++ b/.github/scripts/test-no-error-reports.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +RUNDIR="run" +CRASH="crash-reports" +SERVERLOG="server.log" + +if [[ -d $RUNDIR/$CRASH ]]; then + echo "Crash reports detected:" + cat $RUNDIR/$CRASH/crash*.txt + exit 1 +fi + +if grep --quiet "Fatal errors were detected" $SERVERLOG; then + echo "Fatal errors detected:" + cat server.log + exit 1 +fi + +if grep --quiet "The state engine was in incorrect state ERRORED and forced into state SERVER_STOPPED" $SERVERLOG; then + echo "Server force stopped:" + cat server.log + exit 1 +fi + +if ! grep --quiet -Po '.+Done \(.+\)\! For help, type "help" or "\?"' $SERVERLOG; then + echo "Server didn't finish startup:" + cat server.log + exit 1 +fi + +echo "No crash reports detected" +exit 0 + diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 0000000..2a74327 --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,45 @@ +# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Build and test + +on: + pull_request: + branches: [ master, main ] + push: + branches: [ master, main ] + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up JDK 8 + uses: actions/setup-java@v2 + with: + java-version: '8' + distribution: 'adopt' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Setup the workspace + run: ./gradlew setupCIWorkspace + + - name: Build the mod + run: ./gradlew build + + - name: Run server for 1.5 minutes + run: | + mkdir run + echo "eula=true" > run/eula.txt + timeout 90 ./gradlew runServer 2>&1 | tee -a server.log || true + + - name: Test no errors reported during server run + run: | + chmod +x .github/scripts/test-no-error-reports.sh + .github/scripts/test-no-error-reports.sh diff --git a/.github/workflows/release-tags.yml b/.github/workflows/release-tags.yml new file mode 100644 index 0000000..c86d888 --- /dev/null +++ b/.github/workflows/release-tags.yml @@ -0,0 +1,51 @@ +# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Release tagged build + +on: + push: + tags: + - '*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set release version + run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV + + - name: Set up JDK 8 + uses: actions/setup-java@v2 + with: + java-version: '8' + distribution: 'adopt' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Setup the workspace + run: ./gradlew setupCIWorkspace + + - name: Build the mod + run: ./gradlew build + + - name: Release under current tag + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: "${{ env.RELEASE_VERSION }}" + prerelease: false + title: "${{ env.RELEASE_VERSION }}" + files: build/libs/*.jar + + - name: Publish to Maven + run: ./gradlew publish + env: + MAVEN_USER: ${{ secrets.MAVEN_USER }} + MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} diff --git a/.gitignore b/.gitignore index 2c770e0..48c525b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,32 @@ -# eclipse -bin -*.launch +.gradle .settings -.metadata +/.idea/ +/.vscode/ +/run/ +/build/ +/eclipse/ .classpath .project - -# idea -out +/bin/ +/config/ +/crash-reports/ +/logs/ +options.txt +/saves/ +usernamecache.json +banned-ips.json +banned-players.json +eula.txt +ops.json +server.properties +servers.dat +usercache.json +whitelist.json +/out/ +*.iml *.ipr *.iws -*.iml -.idea - -# gradle -build -.gradle - -# other -eclipse -run +src/main/resources/mixins.*.json +*.bat +*.DS_Store +!gradlew.bat diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..a6b5f68 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,3 @@ +# Any Github changes require admin approval +/.github/** @GTNewHorizons/admin + diff --git a/build.gradle b/build.gradle index afc52b1..5ea36f3 100644 --- a/build.gradle +++ b/build.gradle @@ -1,49 +1,417 @@ +//version: 1644612407 +/* +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. +*/ + +import org.gradle.internal.logging.text.StyledTextOutput +import org.gradle.internal.logging.text.StyledTextOutputFactory +import org.gradle.internal.logging.text.StyledTextOutput.Style + +import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +import java.util.concurrent.TimeUnit + buildscript { repositories { - mavenCentral() maven { - name = "forge" - url = "http://files.minecraftforge.net/maven" + name 'forge' + url 'https://maven.minecraftforge.net' + } + maven { + name 'sonatype' + url 'https://oss.sonatype.org/content/repositories/snapshots/' } maven { - name = "sonatype" - url = "https://oss.sonatype.org/content/repositories/snapshots/" + name 'Scala CI dependencies' + url 'https://repo1.maven.org/maven2/' + } + maven { + name 'jitpack' + url 'https://jitpack.io' } } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' + classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.7' } } +plugins { + id 'java-library' + id 'idea' + id 'eclipse' + id 'scala' + 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 'org.ajoberstar.grgit' version '4.1.1' + id 'com.github.johnrengelman.shadow' version '4.0.4' + id 'com.palantir.git-version' version '0.13.0' apply false + id 'de.undercouch.download' version '5.0.1' + id 'com.github.gmazzo.buildconfig' version '3.0.3' apply false +} + +if (project.file('.git/HEAD').isFile()) { + apply plugin: 'com.palantir.git-version' +} + +def out = services.get(StyledTextOutputFactory).create('an-output') + apply plugin: 'forge' -ext.configFile = file "build.properties" -configFile.withReader { - // Load config. It shall from now be referenced as simply config or project.config - def prop = new Properties() - prop.load(it) - project.ext.config = new ConfigSlurper().parse prop +def projectJavaVersion = JavaLanguageVersion.of(8) + +java { + toolchain { + languageVersion.set(projectJavaVersion) + } +} + +idea { + module { + inheritOutputDirs = true + downloadJavadoc = true + downloadSources = true + } } -version = config.minecraft_version + "-" + config.mod_version -group= "net.torocraft.torohealth" // http://maven.apache.org/guides/mini/guide-naming-conventions.html -archivesBaseName = "torohealth" +if(JavaVersion.current() != JavaVersion.VERSION_1_8) { + throw new GradleException("This project requires Java 8, but it's running on " + JavaVersion.current()) +} + +checkPropertyExists("modName") +checkPropertyExists("modId") +checkPropertyExists("modGroup") +checkPropertyExists("autoUpdateBuildScript") +checkPropertyExists("minecraftVersion") +checkPropertyExists("forgeVersion") +checkPropertyExists("replaceGradleTokenInFile") +checkPropertyExists("gradleTokenModId") +checkPropertyExists("gradleTokenModName") +checkPropertyExists("gradleTokenVersion") +checkPropertyExists("gradleTokenGroupName") +checkPropertyExists("apiPackage") +checkPropertyExists("accessTransformersFile") +checkPropertyExists("usesMixins") +checkPropertyExists("mixinPlugin") +checkPropertyExists("mixinsPackage") +checkPropertyExists("coreModClass") +checkPropertyExists("containsMixinsAndOrCoreModOnly") +checkPropertyExists("usesShadowedDependencies") +checkPropertyExists("developmentEnvironmentUserName") + +boolean noPublishedSources = project.findProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false + +String javaSourceDir = "src/main/java/" +String scalaSourceDir = "src/main/scala/" +String kotlinSourceDir = "src/main/kotlin/" + +String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") +String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") +String targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") +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 + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + 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()) { + throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile) + } +} + +if(usesMixins.toBoolean()) { + if(mixinsPackage.isEmpty() || mixinPlugin.isEmpty()) { + throw new GradleException("\"mixinPlugin\" requires \"mixinsPackage\" and \"mixinPlugin\" to be set!") + } + + targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/") + targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/") + targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/") + 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" + String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".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" + String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".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 { + resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS) + + // Make sure GregTech build won't time out + System.setProperty("org.gradle.internal.http.connectionTimeout", 120000 as String) + System.setProperty("org.gradle.internal.http.socketTimeout", 120000 as String) +} + +// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version +try { + 'git config core.fileMode false'.execute() +} +catch (Exception e) { + 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 { + identifiedVersion = versionOverride == null ? gitVersion() : versionOverride +} +catch (Exception e) { + 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 = minecraftVersion + '-' + identifiedVersion +ext { + modVersion = identifiedVersion +} + +if( identifiedVersion.equals(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) { + archivesBaseName = customArchiveBaseName +} +else { + archivesBaseName = modId +} + +def arguments = [] +def jvmArguments = [] + +if(usesMixins.toBoolean()) { + arguments += [ + "--tweakClass org.spongepowered.asm.launch.MixinTweaker" + ] + jvmArguments += [ + "-Dmixin.debug.countInjections=true", "-Dmixin.debug.verbose=true", "-Dmixin.debug.export=true" + ] +} minecraft { - version = config.minecraft_version + "-" + config.forge_version - runDir = "run" + version = minecraftVersion + '-' + forgeVersion + '-' + minecraftVersion + runDir = 'run' - replace "\${version}", project.version - replace "\${mcversion}", version - replace "(gradle_replace_mcversion,)", "[" + version + "]" - replace "(gradle_replace_forgeversion,)", "[" + config.forge_version + ",)" + if (replaceGradleTokenInFile) { + replaceIn replaceGradleTokenInFile + if(gradleTokenModId) { + replace gradleTokenModId, modId + } + if(gradleTokenModName) { + replace gradleTokenModName, modName + } + if(gradleTokenVersion) { + replace gradleTokenVersion, modVersion + } + if(gradleTokenGroupName) { + replace gradleTokenGroupName, modGroup + } + } + + clientIntellijRun { + args(arguments) + jvmArgs(jvmArguments) + + if(developmentEnvironmentUserName) { + args("--username", developmentEnvironmentUserName) + } + } + + serverIntellijRun { + args(arguments) + jvmArgs(jvmArguments) + } +} + +if(file('addon.gradle').exists()) { + apply from: 'addon.gradle' +} + +apply from: 'repositories.gradle' + +configurations { + implementation.extendsFrom(shadowImplementation) // TODO: remove after all uses are refactored + implementation.extendsFrom(shadowCompile) + implementation.extendsFrom(shadeCompile) +} + +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' + } + } } 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' + } + 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" +} + +""" + } } -processResources -{ +task relocateShadowJar(type: ConfigureShadowRelocation) { + target = tasks.shadowJar + prefix = modGroup + ".shadow" +} + +shadowJar { + project.configurations.shadeCompile.each { dep -> + from(project.zipTree(dep)) { + exclude 'META-INF', 'META-INF/**' + } + } + + manifest { + attributes(getManifestAttributes()) + } + + minimize() // This will only allow shading for actually used classes + configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile] + dependsOn(relocateShadowJar) +} + +jar { + project.configurations.shadeCompile.each { dep -> + from(project.zipTree(dep)) { + exclude 'META-INF', 'META-INF/**' + } + } + + manifest { + attributes(getManifestAttributes()) + } + + if(usesShadowedDependencies.toBoolean()) { + dependsOn(shadowJar) + enabled = false + } +} + +reobf { + if(usesMixins.toBoolean()) { + addExtraSrgFile mixinSrg + } +} + +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" + ] + } + } +} + +runClient { + if(developmentEnvironmentUserName) { + arguments += [ + "--username", + developmentEnvironmentUserName + ] + } + + args(arguments) + jvmArgs(jvmArguments) +} + +runServer { + args(arguments) + jvmArgs(jvmArguments) +} + +tasks.withType(JavaExec).configureEach { + javaLauncher.set( + javaToolchains.launcherFor { + languageVersion = projectJavaVersion + } + ) +} + +processResources { // this will ensure that this task is redone when the versions change. inputs.property "version", project.version inputs.property "mcversion", project.minecraft.version @@ -51,13 +419,313 @@ processResources // replace stuff in mcmod.info, nothing else from(sourceSets.main.resources.srcDirs) { include 'mcmod.info' - - // replace version and mcversion - expand 'version':project.version, 'mcversion':project.minecraft.version + + // replace modVersion and minecraftVersion + expand "minecraftVersion": project.minecraft.version, + "modVersion": modVersion, + "modId": modId, + "modName": modName } - - // copy everything else, thats not the mcmod.info + + if(usesMixins.toBoolean()) { + from refMap + } + + // copy everything else that's not the mcmod.info from(sourceSets.main.resources.srcDirs) { exclude 'mcmod.info' } } + +def getManifestAttributes() { + def manifestAttributes = [:] + if(containsMixinsAndOrCoreModOnly.toBoolean() == false && (usesMixins.toBoolean() || coreModClass)) { + manifestAttributes += ["FMLCorePluginContainsFMLMod": true] + } + + if(accessTransformersFile) { + manifestAttributes += ["FMLAT" : accessTransformersFile.toString()] + } + + if(coreModClass) { + manifestAttributes += ["FMLCorePlugin": modGroup + "." + coreModClass] + } + + if(usesMixins.toBoolean()) { + manifestAttributes += [ + "TweakClass" : "org.spongepowered.asm.launch.MixinTweaker", + "MixinConfigs" : "mixins." + modId + ".json", + "ForceLoadAsMod" : containsMixinsAndOrCoreModOnly.toBoolean() == false + ] + } + 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") + + 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 +} + +task devJar(type: Jar) { + project.configurations.shadeCompile.each { dep -> + from(project.zipTree(dep)) { + exclude 'META-INF', 'META-INF/**' + } + } + + from sourceSets.main.output + getArchiveClassifier().set("dev") + + manifest { + attributes(getManifestAttributes()) + } + + if(usesShadowedDependencies.toBoolean()) { + dependsOn(circularResolverJar) + enabled = false + } +} + +task apiJar(type: Jar) { + from (sourceSets.main.allJava) { + include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**' + } + + from (sourceSets.main.output) { + include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**' + } + + from (sourceSets.main.resources.srcDirs) { + include("LICENSE") + } + + getArchiveClassifier().set('api') +} + +artifacts { + if(!noPublishedSources) { + archives sourcesJar + } + archives devJar + if(apiPackage) { + archives apiJar + } +} + +// The gradle metadata includes all of the additional deps that we disabled from POM generation (including forgeBin with no groupID), +// and isn't strictly needed with the POM so just disable it. +tasks.withType(GenerateModuleMetadata) { + enabled = false +} + +publishing { + publications { + maven(MavenPublication) { + from components.java + if(usesShadowedDependencies.toBoolean()) { + artifact source: shadowJar, classifier: "" + } + if(!noPublishedSources) { + artifact source: sourcesJar, classifier: "src" + } + artifact source: usesShadowedDependencies.toBoolean() ? shadowDevJar : devJar, classifier: "dev" + if (apiPackage) { + artifact source: apiJar, classifier: "api" + } + + groupId = System.getenv("ARTIFACT_GROUP_ID") ?: "com.github.GTNewHorizons" + artifactId = System.getenv("ARTIFACT_ID") ?: project.name + // Using the identified version, not project.version as it has the prepended 1.7.10 + version = System.getenv("RELEASE_VERSION") ?: identifiedVersion + + // remove extra garbage from who knows where + pom.withXml { + def badPomGroup = ['net.minecraft', 'com.google.code.findbugs', 'org.ow2.asm', 'com.typesafe.akka', 'com.typesafe', 'org.scala-lang', + 'org.scala-lang.plugins', 'net.sf.jopt-simple', 'lzma', 'com.mojang', 'org.apache.commons', 'org.apache.httpcomponents', + 'commons-logging', 'java3d', 'net.sf.trove4j', 'com.ibm.icu', 'com.paulscode', 'io.netty', 'com.google.guava', + 'commons-io', 'commons-codec', 'net.java.jinput', 'net.java.jutils', 'com.google.code.gson', 'org.apache.logging.log4j', + 'org.lwjgl.lwjgl', 'tv.twitch', 'org.jetbrains.kotlin', ''] + Node pomNode = asNode() + pomNode.dependencies.'*'.findAll() { + badPomGroup.contains(it.groupId.text()) + }.each() { + it.parent().remove(it) + } + } + } + } + + repositories { + maven { + url = "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases" + credentials { + username = System.getenv("MAVEN_USER") ?: "NONE" + password = System.getenv("MAVEN_PASSWORD") ?: "NONE" + } + } + } +} + +// Updating +task updateBuildScript { + doLast { + if (performBuildScriptUpdate(projectDir.toString())) return + + print("Build script already up-to-date!") + } +} + +if (isNewBuildScriptVersionAvailable(projectDir.toString())) { + if (autoUpdateBuildScript.toBoolean()) { + performBuildScriptUpdate(projectDir.toString()) + } else { + out.style(Style.SuccessHeader).println("Build script update available! Run 'gradle updateBuildScript'") + } +} + +static URL availableBuildScriptUrl() { + new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/main/build.gradle") +} + +boolean performBuildScriptUpdate(String projectDir) { + if (isNewBuildScriptVersionAvailable(projectDir)) { + def buildscriptFile = getFile("build.gradle") + availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } } + out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!") + return true + } + return false +} + +boolean isNewBuildScriptVersionAvailable(String projectDir) { + Map parameters = ["connectTimeout": 2000, "readTimeout": 2000] + + 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 "" +} + +configure(updateBuildScript) { + group = 'forgegradle' + description = 'Updates the build script to the latest version' +} + +// Deobfuscation + +def deobf(String sourceURL) { + try { + URL url = new URL(sourceURL) + String fileName = url.getFile() + + //get rid of directories: + int lastSlash = fileName.lastIndexOf("/") + if(lastSlash > 0) { + fileName = fileName.substring(lastSlash + 1) + } + //get rid of extension: + if(fileName.endsWith(".jar")) { + fileName = fileName.substring(0, fileName.lastIndexOf(".")) + } + + String hostName = url.getHost() + if(hostName.startsWith("www.")) { + hostName = hostName.substring(4) + } + List parts = Arrays.asList(hostName.split("\\.")) + Collections.reverse(parts) + hostName = String.join(".", parts) + + return deobf(sourceURL, hostName + "/" + fileName) + } catch(Exception e) { + return deobf(sourceURL, "deobf/" + String.valueOf(sourceURL.hashCode())) + } +} + +// The method above is to be preferred. Use this method if the filename is not at the end of the URL. +def deobf(String sourceURL, String fileName) { + String cacheDir = System.getProperty("user.home") + "/.gradle/caches/" + String bon2Dir = cacheDir + "forge_gradle/deobf" + String bon2File = bon2Dir + "/BON2-2.5.0.jar" + String obfFile = cacheDir + "modules-2/files-2.1/" + fileName + ".jar" + String deobfFile = cacheDir + "modules-2/files-2.1/" + fileName + "-deobf.jar" + + if(file(deobfFile).exists()) { + return files(deobfFile) + } + + download.run { + src 'https://github.com/GTNewHorizons/BON2/releases/download/2.5.0/BON2-2.5.0.CUSTOM-all.jar' + dest bon2File + quiet true + overwrite false + } + + download.run { + src sourceURL + dest obfFile + quiet true + overwrite false + } + + exec { + commandLine 'java', '-jar', bon2File, '--inputJar', obfFile, '--outputJar', deobfFile, '--mcVer', '1.7.10', '--mappingsVer', 'stable_12', '--notch' + workingDir bon2Dir + standardOutput = new ByteArrayOutputStream() + } + + return files(deobfFile) +} + +// Helper methods + +def checkPropertyExists(String propertyName) { + if (project.hasProperty(propertyName) == false) { + 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/GTNewHorizons/ExampleMod1.7.10/blob/main/gradle.properties") + } +} + +def getFile(String relativePath) { + return new File(projectDir, relativePath) +} diff --git a/build.properties b/build.properties deleted file mode 100644 index 8a807ec..0000000 --- a/build.properties +++ /dev/null @@ -1,3 +0,0 @@ -mod_version=1.0.0 -minecraft_version=1.7.10 -forge_version=10.13.4.1614-1.7.10 \ No newline at end of file diff --git a/dependencies.gradle b/dependencies.gradle new file mode 100644 index 0000000..b6456d0 --- /dev/null +++ b/dependencies.gradle @@ -0,0 +1,5 @@ +// Add your dependencies here + +dependencies { + +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..7c480a4 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,67 @@ +modName = ToroHealth Damage Indicators + +# This is a case-sensitive string to identify your mod. Convention is to use lower case. +modId = torohealthmod + +modGroup = net.torocraft + +# WHY is there no version field? +# The build script relies on git to provide a version via tags. It is super easy and will enable you to always know the +# code base or your binary. Check out this tutorial: https://blog.mattclemente.com/2017/10/13/versioning-with-git-tags/ + +# Will update your build.gradle automatically whenever an update is available +autoUpdateBuildScript = false + +minecraftVersion = 1.7.10 +forgeVersion = 10.13.4.1614 + +# Select a username for testing your mod with breakpoints. You may leave this empty for a random username each time you +# restart Minecraft in development. Choose this dependent on your mod: +# Do you need consistent player progressing (for example Thaumcraft)? -> Select a name +# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty +developmentEnvironmentUserName = Developer + +# Define a source file of your project with: +# public static final String VERSION = "GRADLETOKEN_VERSION"; +# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's +# version in @Mod([...], version = VERSION, [...]) +# Leave these properties empty to skip individual token replacements +replaceGradleTokenInFile = ToroHealthMod.java +gradleTokenModId = +gradleTokenModName = +gradleTokenVersion = GRADLETOKEN_VERSION +gradleTokenGroupName = + +# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can +# leave this property empty. +# Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api +apiPackage = + +# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/META-INF/ +# Example value: mymodid_at.cfg +accessTransformersFile = + +# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled! +usesMixins = false +# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise. +mixinPlugin = +# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail! +mixinsPackage = +# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin! +# This parameter is for legacy compatibility only +# Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin +coreModClass = +# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class +# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false! +containsMixinsAndOrCoreModOnly = false + +# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your +# responsibility check the licence and request permission for distribution, if required. +usesShadowedDependencies = false + +# Optional parameter to customize the produced artifacts. Use this to preserver artifact naming when migrating older +# projects. New projects should not use this parameter. +customArchiveBaseName = torohealth + +# Optional parameter to prevent the source code from being published +# noPublishedSources = diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a1347e58afd717f8b5ec6f158a91325210d46ccb..5c2d1cf016b3885f6930543d57b744ea8c220a1a 100644 GIT binary patch delta 17603 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 delta 17598 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5ebe727..3ab0b72 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Tue Mar 17 17:23:30 CET 2020 -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 index 91a7e26..83f2acf --- a/gradlew +++ b/gradlew @@ -1,4 +1,20 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## ## @@ -6,20 +22,38 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +64,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,31 +75,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -90,7 +105,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -110,10 +125,11 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -154,11 +170,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282..9618d8d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -8,14 +24,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +62,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +75,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..09bbb51 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,2 @@ +before_install: + - ./gradlew setupCIWorkspace \ No newline at end of file diff --git a/repositories.gradle b/repositories.gradle new file mode 100644 index 0000000..c884390 --- /dev/null +++ b/repositories.gradle @@ -0,0 +1,5 @@ +// Add any additional repositories for your dependencies here + +repositories { + +} diff --git a/src/main/java/net/torocraft/torohealthmod/ToroHealthMod.java b/src/main/java/net/torocraft/torohealthmod/ToroHealthMod.java index ee9a869..cabd424 100644 --- a/src/main/java/net/torocraft/torohealthmod/ToroHealthMod.java +++ b/src/main/java/net/torocraft/torohealthmod/ToroHealthMod.java @@ -13,7 +13,7 @@ public class ToroHealthMod { public static final String MODID = "torohealthmod"; - public static final String VERSION = "${version}"; + public static final String VERSION = "GRADLETOKEN_VERSION"; public static final String MODNAME = "ToroHealthMod"; public static final String GUI_FACTORY_CLASS = "net.torocraft.torohealthmod.configuration.gui.GuiFactory"; diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index d8f8155..064242f 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -1,10 +1,9 @@ -[ -{ - "modid": "torohealthmod", - "name": "ToroHealth Damage Indicators", +[{ + "modid": "${modId}", + "name": "${modName}", "description": "Displays damage indicators and health bars for all entities.", - "version": "${version}", - "mcversion": "${mcversion}", + "version": "${modVersion}", + "mcversion": "${minecraftVersion}", "url": "http://torocraft.net/", "updateUrl": "", "authorList": ["torocraft"], @@ -12,5 +11,4 @@ "logoFile": "", "screenshots": [], "dependencies": [] -} -] +}]