mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-11-19 08:14:52 +00:00
1e703f1b07
We now fuzz UploadFileMessage, generating random files and checking they round-trip correctly. The joy of having a long-lasting refactor branch with an absolutely massive diff, is that you end up spotting bugs, and then it's a massive pain to merge the fix back into trunk!
626 lines
19 KiB
Groovy
626 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.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'
|
|
|
|
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'
|
|
|
|
testCompileOnly(libs.autoService)
|
|
testAnnotationProcessor(libs.autoService)
|
|
|
|
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).
|
|
JavaExec exec = tasks.getByName("runTestServer")
|
|
dependsOn(exec.getDependsOn())
|
|
exec.copyTo(it)
|
|
setClasspath(exec.getClasspath())
|
|
mainClass = exec.mainClass
|
|
javaLauncher = exec.javaLauncher
|
|
setArgs(exec.getArgs())
|
|
|
|
// 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)
|
|
}
|