mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-11-19 00:04:53 +00:00
9db3e6d2a0
This is a little odd (it's more complex for one!), but means we can reuse the internal API interface in other classes, which is useful for the data provider refactor I'm about to do. This is much nicer in Java 17 :D (records, ServiceLoader.stream()), but such is the perils of still targetting 1.16.
621 lines
19 KiB
Groovy
621 lines
19 KiB
Groovy
plugins {
|
|
id "checkstyle"
|
|
id "jacoco"
|
|
id "maven-publish"
|
|
id "org.cadixdev.licenser" version "0.6.1"
|
|
id "com.matthewprenger.cursegradle" version "1.4.0"
|
|
id "com.github.breadmoirai.github-release" version "2.2.12"
|
|
id "org.jetbrains.kotlin.jvm" version "1.7.0"
|
|
id "com.modrinth.minotaur" version "2.+"
|
|
id "net.minecraftforge.gradle" version "5.1.+"
|
|
id "org.spongepowered.mixin" version "0.7.+"
|
|
id "org.parchmentmc.librarian.forgegradle" version "1.+"
|
|
id "com.github.johnrengelman.shadow" version "7.1.2"
|
|
id "cc-tweaked.illuaminate"
|
|
}
|
|
|
|
|
|
import cc.tweaked.gradle.ExtensionsKt
|
|
import cc.tweaked.gradle.IlluaminateExec
|
|
import cc.tweaked.gradle.IlluaminateExecToDir
|
|
import org.apache.tools.ant.taskdefs.condition.Os
|
|
|
|
version = mod_version
|
|
|
|
group = "org.squiddev"
|
|
archivesBaseName = "cc-tweaked-${mc_version}"
|
|
|
|
def javaVersion = JavaLanguageVersion.of(8)
|
|
java {
|
|
toolchain {
|
|
languageVersion = javaVersion
|
|
}
|
|
|
|
withSourcesJar()
|
|
withJavadocJar()
|
|
registerFeature("extraMods") { usingSourceSet(sourceSets.main) }
|
|
}
|
|
|
|
sourceSets {
|
|
main.resources {
|
|
srcDir 'src/generated/resources'
|
|
}
|
|
|
|
testMod {}
|
|
}
|
|
|
|
minecraft {
|
|
runs {
|
|
all {
|
|
property 'forge.logging.markers', 'REGISTRIES'
|
|
property 'forge.logging.console.level', 'debug'
|
|
forceExit = false
|
|
|
|
mods {
|
|
computercraft {
|
|
source sourceSets.main
|
|
}
|
|
}
|
|
|
|
arg "-mixin.config=computercraft.mixins.json"
|
|
}
|
|
|
|
client {
|
|
workingDirectory project.file('run')
|
|
}
|
|
|
|
server {
|
|
workingDirectory project.file("run/server")
|
|
arg "--nogui"
|
|
}
|
|
|
|
data {
|
|
workingDirectory project.file('run')
|
|
args '--mod', 'computercraft', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
|
|
}
|
|
|
|
testClient {
|
|
workingDirectory project.file('test-files/client')
|
|
parent runs.client
|
|
|
|
mods {
|
|
cctest {
|
|
source sourceSets.testMod
|
|
}
|
|
}
|
|
}
|
|
|
|
testServer {
|
|
workingDirectory project.file('test-files/server')
|
|
parent runs.server
|
|
|
|
property("cctest.run", "true")
|
|
property("forge.logging.console.level", "info")
|
|
|
|
mods {
|
|
cctest {
|
|
source sourceSets.testMod
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
mappings channel: 'parchment', version: "${mapping_version}-${mc_version}"
|
|
|
|
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
|
|
accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg')
|
|
}
|
|
|
|
mixin {
|
|
add sourceSets.main, 'computercraft.mixins.refmap.json'
|
|
}
|
|
|
|
reobf {
|
|
shadowJar {}
|
|
}
|
|
|
|
repositories {
|
|
mavenCentral()
|
|
maven {
|
|
name "SquidDev"
|
|
url "https://squiddev.cc/maven"
|
|
}
|
|
}
|
|
|
|
configurations {
|
|
shade { transitive = false }
|
|
implementation.extendsFrom shade
|
|
cctJavadoc
|
|
|
|
testModImplementation.extendsFrom(implementation)
|
|
testModImplementation.extendsFrom(testImplementation)
|
|
}
|
|
|
|
dependencies {
|
|
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
|
|
|
|
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
|
|
annotationProcessor 'org.spongepowered:mixin:0.8.4:processor'
|
|
|
|
compileOnly(libs.jetbrainsAnnotations)
|
|
ExtensionsKt.annotationProcessorEverywhere(dependencies, libs.autoService)
|
|
|
|
extraModsCompileOnly fg.deobf("mezz.jei:jei-1.16.5:7.7.0.104:api")
|
|
extraModsRuntimeOnly fg.deobf("mezz.jei:jei-1.16.5:7.7.0.104")
|
|
|
|
extraModsCompileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.16.5:7.1.0.313")
|
|
extraModsCompileOnly fg.deobf("commoble.morered:morered-1.16.5:2.1.1.0")
|
|
|
|
shade 'org.squiddev:Cobalt:0.5.7'
|
|
|
|
testImplementation(libs.bundles.test)
|
|
testImplementation(libs.bundles.kotlin)
|
|
testRuntimeOnly(libs.bundles.testRuntime)
|
|
|
|
testModImplementation sourceSets.main.output
|
|
|
|
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.7'
|
|
}
|
|
|
|
illuaminate {
|
|
version.set("0.1.0-3-g0f40379")
|
|
}
|
|
|
|
// Compile tasks
|
|
|
|
javadoc {
|
|
include "dan200/computercraft/api/**/*.java"
|
|
}
|
|
|
|
def apiJar = tasks.register("apiJar", Jar.class) {
|
|
archiveClassifier.set("api")
|
|
from(sourceSets.main.output) {
|
|
include "dan200/computercraft/api/**/*"
|
|
}
|
|
}
|
|
assemble.dependsOn(apiJar)
|
|
|
|
def luaJavadoc = tasks.register("luaJavadoc", Javadoc.class) {
|
|
description "Generates documentation for Java-side Lua functions."
|
|
group "documentation"
|
|
|
|
source = sourceSets.main.allJava
|
|
destinationDir = file("${project.docsDir}/luaJavadoc")
|
|
classpath = sourceSets.main.compileClasspath
|
|
|
|
options.docletpath = configurations.cctJavadoc.files as List
|
|
options.doclet = "cc.tweaked.javadoc.LuaDoclet"
|
|
options.noTimestamp = false
|
|
|
|
javadocTool = javaToolchains.javadocToolFor {
|
|
languageVersion = JavaLanguageVersion.of(11)
|
|
}
|
|
}
|
|
|
|
jar {
|
|
finalizedBy("reobfJar")
|
|
|
|
archiveClassifier.set("slim")
|
|
manifest {
|
|
attributes([
|
|
"Specification-Title" : "computercraft",
|
|
"Specification-Vendor" : "SquidDev",
|
|
"Specification-Version" : "1",
|
|
"Implementation-Title" : "CC: Tweaked",
|
|
"Implementation-Version" : "${mod_version}",
|
|
"Implementation-Vendor" : "SquidDev",
|
|
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
|
|
"MixinConfigs" : "computercraft.mixins.json",
|
|
])
|
|
}
|
|
}
|
|
|
|
shadowJar {
|
|
finalizedBy("reobfShadowJar")
|
|
|
|
archiveClassifier.set("")
|
|
configurations = [project.configurations.shade]
|
|
relocate("org.squiddev.cobalt", "cc.tweaked.internal.cobalt")
|
|
minimize()
|
|
}
|
|
|
|
assemble.dependsOn("shadowJar")
|
|
|
|
[
|
|
tasks.named("compileJava", JavaCompile.class),
|
|
tasks.named("compileTestJava", JavaCompile.class),
|
|
tasks.named("compileTestModJava", JavaCompile.class)
|
|
].forEach {
|
|
it.configure {
|
|
options.compilerArgs << "-Xlint" << "-Xlint:-processing"
|
|
}
|
|
}
|
|
|
|
processResources {
|
|
inputs.property "version", mod_version
|
|
inputs.property "mcversion", mc_version
|
|
|
|
def hash = 'none'
|
|
Set<String> contributors = []
|
|
try {
|
|
hash = ["git", "-C", projectDir, "rev-parse", "HEAD"].execute().text.trim()
|
|
|
|
def blacklist = ['GitHub', 'Daniel Ratcliffe', 'Weblate']
|
|
|
|
// Extract all authors, commiters and co-authors from the git log.
|
|
def authors = ["git", "-C", projectDir, "log", "--format=tformat:%an <%ae>%n%cn <%ce>%n%(trailers:key=Co-authored-by,valueonly)"]
|
|
.execute().text.readLines().unique()
|
|
|
|
// We now pass this through git's mailmap to de-duplicate some authors.
|
|
def remapAuthors = ["git", "check-mailmap", "--stdin"].execute()
|
|
remapAuthors.withWriter { stdin ->
|
|
if (stdin !instanceof BufferedWriter) stdin = new BufferedWriter(stdin)
|
|
|
|
authors.forEach {
|
|
if (it == "") return
|
|
if (!it.endsWith(">")) it += ">" // Some commits have broken Co-Authored-By lines!
|
|
stdin.writeLine(it)
|
|
}
|
|
stdin.close()
|
|
}
|
|
|
|
// And finally extract out the actual name.
|
|
def emailRegex = ~/^([^<]+) <.+>$/
|
|
remapAuthors.text.readLines().forEach {
|
|
def matcher = it =~ emailRegex
|
|
matcher.find()
|
|
def name = matcher.group(1)
|
|
if (!blacklist.contains(name)) contributors.add(name)
|
|
}
|
|
} catch (Exception e) {
|
|
e.printStackTrace()
|
|
}
|
|
inputs.property "commithash", hash
|
|
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
|
|
|
from(sourceSets.main.resources.srcDirs) {
|
|
include 'META-INF/mods.toml'
|
|
include 'data/computercraft/lua/rom/help/credits.txt'
|
|
|
|
expand 'version': mod_version,
|
|
'mcversion': mc_version,
|
|
'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
|
|
}
|
|
|
|
from(sourceSets.main.resources.srcDirs) {
|
|
exclude 'META-INF/mods.toml'
|
|
exclude 'data/computercraft/lua/rom/help/credits.txt'
|
|
}
|
|
}
|
|
|
|
sourcesJar {
|
|
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
|
}
|
|
|
|
// Web tasks
|
|
|
|
List<String> mkCommand(String command) {
|
|
return Os.isFamily(Os.FAMILY_WINDOWS) ? ["cmd", "/c", command] : ["sh", "-c", command]
|
|
}
|
|
|
|
def rollup = tasks.register("rollup", Exec.class) {
|
|
group = "build"
|
|
description = "Bundles JS into rollup"
|
|
|
|
inputs.files(fileTree("src/web")).withPropertyName("sources")
|
|
inputs.file("package-lock.json").withPropertyName("package-lock.json")
|
|
inputs.file("tsconfig.json").withPropertyName("Typescript config")
|
|
inputs.file("rollup.config.js").withPropertyName("Rollup config")
|
|
outputs.file("$buildDir/rollup/index.js").withPropertyName("output")
|
|
|
|
commandLine mkCommand('"node_modules/.bin/rollup" --config rollup.config.js')
|
|
}
|
|
|
|
def illuaminateDocs = tasks.register("illuaminateDocs", IlluaminateExecToDir.class) {
|
|
group = "documentation"
|
|
description = "Generates docs using Illuaminate"
|
|
dependsOn(rollup)
|
|
|
|
// Config files
|
|
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
|
|
// Sources
|
|
inputs.files(fileTree("doc")).withPropertyName("docs")
|
|
inputs.files(fileTree("src/main/resources/data/computercraft/lua")).withPropertyName("lua rom")
|
|
inputs.files(luaJavadoc)
|
|
// Additional assets
|
|
inputs.file("$buildDir/rollup/index.js").withPropertyName("scripts")
|
|
inputs.file("src/web/styles.css").withPropertyName("styles")
|
|
|
|
// Output directory. Also defined in illuaminate.sexp and transform.tsx
|
|
output.set(new File(buildDir, "docs/lua"))
|
|
|
|
args = ["doc-gen"]
|
|
}
|
|
|
|
def jsxDocs = tasks.register("jsxDocs", Exec) {
|
|
group = "documentation"
|
|
description = "Post-processes documentation to statically render some dynamic content."
|
|
|
|
inputs.files(fileTree("src/web")).withPropertyName("sources")
|
|
inputs.file("src/generated/export/index.json").withPropertyName("export")
|
|
inputs.file("package-lock.json").withPropertyName("package-lock.json")
|
|
inputs.file("tsconfig.json").withPropertyName("Typescript config")
|
|
inputs.files(illuaminateDocs)
|
|
outputs.dir("$buildDir/docs/site")
|
|
|
|
commandLine mkCommand('"node_modules/.bin/ts-node" -T --esm src/web/transform.tsx')
|
|
}
|
|
|
|
def docWebsite = tasks.register("docWebsite", Copy.class) {
|
|
group = "documentation"
|
|
description = "Copy additional assets to the website directory."
|
|
dependsOn(jsxDocs)
|
|
|
|
from('doc') {
|
|
include 'logo.png'
|
|
include 'images/**'
|
|
}
|
|
from("$buildDir/rollup") {
|
|
exclude 'index.js'
|
|
}
|
|
from("$buildDir/docs/lua") {
|
|
exclude '**/*.html'
|
|
}
|
|
from("src/generated/export/items") {
|
|
into("images/items")
|
|
}
|
|
|
|
into "${project.docsDir}/site"
|
|
}
|
|
|
|
// Check tasks
|
|
|
|
test {
|
|
useJUnitPlatform()
|
|
testLogging {
|
|
events "skipped", "failed"
|
|
}
|
|
}
|
|
|
|
jacocoTestReport {
|
|
dependsOn('test')
|
|
reports {
|
|
xml.required = true
|
|
html.required = true
|
|
}
|
|
}
|
|
|
|
test.finalizedBy("jacocoTestReport")
|
|
|
|
license {
|
|
header = file('config/license/main.txt')
|
|
lineEnding = '\n'
|
|
newLine = false
|
|
|
|
properties {
|
|
year = Calendar.getInstance().get(Calendar.YEAR)
|
|
}
|
|
|
|
include("**/*.java") // We could apply to Kotlin, but for now let's not
|
|
matching("dan200/computercraft/api/**") {
|
|
header = file('config/license/api.txt')
|
|
}
|
|
}
|
|
|
|
check.dependsOn("licenseCheck")
|
|
|
|
def lintLua = tasks.register("lintLua", IlluaminateExec.class) {
|
|
group = JavaBasePlugin.VERIFICATION_GROUP
|
|
description = "Lint Lua (and Lua docs) with illuaminate"
|
|
|
|
// Config files
|
|
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
|
|
// Sources
|
|
inputs.files(fileTree("doc")).withPropertyName("docs")
|
|
inputs.files(fileTree("src/main/resources/data/computercraft/lua")).withPropertyName("lua rom")
|
|
inputs.files(luaJavadoc)
|
|
|
|
args = ["lint"]
|
|
|
|
doFirst { if (System.getenv("GITHUB_ACTIONS") != null) println("::add-matcher::.github/matchers/illuaminate.json") }
|
|
doLast { if (System.getenv("GITHUB_ACTIONS") != null) println("::remove-matcher owner=illuaminate::") }
|
|
}
|
|
|
|
|
|
def setupServer = tasks.register("setupServer", Copy.class) {
|
|
group "test server"
|
|
description "Sets up the environment for the test server."
|
|
|
|
from("src/testMod/server-files") {
|
|
include "eula.txt"
|
|
include "server.properties"
|
|
}
|
|
into "test-files/server"
|
|
}
|
|
|
|
def testServerClassDumpDir = new File(buildDir, "jacocoClassDump/runTestServer")
|
|
|
|
def testServer = tasks.register("testServer", JavaExec.class) {
|
|
group("In-game tests")
|
|
description("Runs tests on a temporary Minecraft instance.")
|
|
dependsOn(setupServer, "cleanTestServer")
|
|
finalizedBy("jacocoTestServerReport")
|
|
|
|
// Copy from runTestServer. We do it in this slightly odd way as runTestServer
|
|
// isn't created until the task is configured (which is no good for us).
|
|
ExtensionsKt.copyToFull(tasks.getByName("runTestServer"), it)
|
|
|
|
// Jacoco and modlauncher don't play well together as the classes loaded in-game don't
|
|
// match up with those written to disk. We get Jacoco to dump all classes to disk, and
|
|
// use that when generating the report.
|
|
jacoco.applyTo(it)
|
|
it.jacoco.setIncludes(["dan200.computercraft.*"])
|
|
it.jacoco.setClassDumpDir(testServerClassDumpDir)
|
|
outputs.dir(testServerClassDumpDir)
|
|
// Older versions of modlauncher don't include a protection domain (and thus no code
|
|
// source). Jacoco skips such classes by default, so we need to explicitly include them.
|
|
it.jacoco.setIncludeNoLocationClasses(true)
|
|
}
|
|
|
|
tasks.register("jacocoTestServerReport", JacocoReport.class) {
|
|
group("In-game tests")
|
|
description("Generate coverage reports for testServer")
|
|
dependsOn(testServer)
|
|
|
|
executionData(new File(buildDir, "jacoco/testServer.exec"))
|
|
sourceDirectories.from(sourceSets.main.allJava.srcDirs)
|
|
classDirectories.from(testServerClassDumpDir)
|
|
|
|
reports {
|
|
xml.enabled true
|
|
html.enabled true
|
|
}
|
|
}
|
|
|
|
check.dependsOn(testServer)
|
|
|
|
// Upload tasks
|
|
|
|
def checkRelease = tasks.register("checkRelease") {
|
|
group "upload"
|
|
description "Verifies that everything is ready for a release"
|
|
|
|
inputs.property "version", mod_version
|
|
inputs.file("src/main/resources/data/computercraft/lua/rom/help/changelog.md")
|
|
inputs.file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
|
|
|
|
doLast {
|
|
def ok = true
|
|
|
|
// Check we're targetting the current version
|
|
def whatsnew = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.md").readLines()
|
|
if (whatsnew[0] != "New features in CC: Tweaked $mod_version") {
|
|
ok = false
|
|
project.logger.error("Expected `whatsnew.md' to target $mod_version.")
|
|
}
|
|
|
|
// Check "read more" exists and trim it
|
|
def idx = whatsnew.findIndexOf { it == 'Type "help changelog" to see the full version history.' }
|
|
if (idx == -1) {
|
|
ok = false
|
|
project.logger.error("Must mention the changelog in whatsnew.md")
|
|
} else {
|
|
whatsnew = whatsnew.getAt(0..<idx)
|
|
}
|
|
|
|
// Check whatsnew and changelog match.
|
|
def versionChangelog = "# " + whatsnew.join("\n")
|
|
def changelog = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/changelog.md").getText()
|
|
if (!changelog.startsWith(versionChangelog)) {
|
|
ok = false
|
|
project.logger.error("whatsnew and changelog are not in sync")
|
|
}
|
|
|
|
if (!ok) throw new IllegalStateException("Could not check release")
|
|
}
|
|
}
|
|
check.dependsOn(checkRelease)
|
|
|
|
def isStable = true
|
|
|
|
curseforge {
|
|
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
|
|
project {
|
|
id = '282001'
|
|
releaseType = isStable ? 'release' : 'alpha'
|
|
changelog = "Release notes can be found on the GitHub repository (https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
|
|
mainArtifact(shadowJar)
|
|
|
|
addGameVersion "${mc_version}"
|
|
}
|
|
}
|
|
|
|
modrinth {
|
|
token = project.hasProperty('modrinthApiKey') ? project.getProperty('modrinthApiKey') : ''
|
|
projectId = 'gu7yAYhd'
|
|
versionNumber = "${project.mc_version}-${project.mod_version}"
|
|
versionName = "${project.mod_version}"
|
|
versionType = isStable ? 'release' : 'alpha'
|
|
uploadFile = shadowJar
|
|
gameVersions = [project.mc_version]
|
|
changelog = "Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
|
|
}
|
|
|
|
publishing {
|
|
publications {
|
|
maven(MavenPublication) {
|
|
from components.java
|
|
artifact(apiJar)
|
|
fg.component(it)
|
|
|
|
pom {
|
|
name = 'CC: Tweaked'
|
|
description = 'CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft.'
|
|
url = 'https://github.com/cc-tweaked/CC-Tweaked'
|
|
|
|
scm {
|
|
url = 'https://github.com/cc-tweaked/CC-Tweaked.git'
|
|
}
|
|
|
|
issueManagement {
|
|
system = 'github'
|
|
url = 'https://github.com/cc-tweaked/CC-Tweaked/issues'
|
|
}
|
|
|
|
licenses {
|
|
license {
|
|
name = 'ComputerCraft Public License, Version 1.0'
|
|
url = 'https://github.com/cc-tweaked/CC-Tweaked/blob/mc-1.16.x/LICENSE'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
repositories {
|
|
if (project.hasProperty("mavenUser")) {
|
|
maven {
|
|
name = "SquidDev"
|
|
url = "https://squiddev.cc/maven"
|
|
credentials {
|
|
username = project.property("mavenUser") as String
|
|
password = project.property("mavenPass") as String
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
githubRelease {
|
|
token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
|
|
owner 'cc-tweaked'
|
|
repo 'CC-Tweaked'
|
|
targetCommitish.set(project.provider({
|
|
try {
|
|
return ["git", "-C", projectDir, "rev-parse", "--abbrev-ref", "HEAD"].execute().text.trim()
|
|
} catch (Exception e) {
|
|
e.printStackTrace()
|
|
}
|
|
return "master"
|
|
}))
|
|
|
|
tagName "v${mc_version}-${mod_version}"
|
|
releaseName "[${mc_version}] ${mod_version}"
|
|
body.set(project.provider({
|
|
"## " + new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
|
|
.readLines()
|
|
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
|
|
.join("\n").trim()
|
|
}))
|
|
prerelease !isStable
|
|
}
|
|
|
|
def uploadTasks = ["publish", "curseforge", "modrinth", "githubRelease"]
|
|
uploadTasks.forEach { tasks.named(it) { dependsOn(checkRelease) } }
|
|
|
|
tasks.register("uploadAll") {
|
|
group = "upload"
|
|
description = "Uploads to all repositories (Maven, Curse, Modrinth, GitHub release)"
|
|
dependsOn(uploadTasks)
|
|
}
|