mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-12 11:10:29 +00:00
331031be45
Name a more iconic duo than @SquidDev and over-engineered test frameworks. This uses Minecraft's test core[1] plus a home-grown framework to run tests against computers in-world. The general idea is: - Build a structure in game. - Save the structure to a file. This will be spawned in every time the test is run. - Write some code which asserts the structure behaves in a particular way. This is done in Kotlin (shock, horror), as coroutines give us a nice way to run asynchronous code while still running on the main thread. As with all my testing efforts, I still haven't actually written any tests! It'd be good to go through some of the historic ones and write some tests though. Turtle block placing and computer redstone interactions are probably a good place to start. [1]: https://www.youtube.com/watch?v=vXaWOJTCYNg
584 lines
18 KiB
Groovy
584 lines
18 KiB
Groovy
buildscript {
|
|
repositories {
|
|
jcenter()
|
|
mavenCentral()
|
|
maven {
|
|
name = "forge"
|
|
url = "https://files.minecraftforge.net/maven"
|
|
}
|
|
}
|
|
dependencies {
|
|
classpath 'com.google.code.gson:gson:2.8.1'
|
|
classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.190'
|
|
classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2'
|
|
classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
|
|
}
|
|
}
|
|
|
|
plugins {
|
|
id "checkstyle"
|
|
id "jacoco"
|
|
id "com.github.hierynomus.license" version "0.15.0"
|
|
id "com.matthewprenger.cursegradle" version "1.3.0"
|
|
id "com.github.breadmoirai.github-release" version "2.2.4"
|
|
id "org.jetbrains.kotlin.jvm" version "1.3.72"
|
|
}
|
|
|
|
apply plugin: 'net.minecraftforge.gradle'
|
|
apply plugin: 'org.ajoberstar.grgit'
|
|
apply plugin: 'maven-publish'
|
|
apply plugin: 'maven'
|
|
|
|
version = mod_version
|
|
|
|
group = "org.squiddev"
|
|
archivesBaseName = "cc-tweaked-${mc_version}"
|
|
|
|
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
|
|
|
|
minecraft {
|
|
runs {
|
|
client {
|
|
workingDirectory project.file('run')
|
|
property 'forge.logging.markers', 'REGISTRIES'
|
|
property 'forge.logging.console.level', 'debug'
|
|
|
|
mods {
|
|
computercraft {
|
|
source sourceSets.main
|
|
}
|
|
}
|
|
}
|
|
|
|
server {
|
|
workingDirectory project.file("run/server")
|
|
property 'forge.logging.markers', 'REGISTRIES'
|
|
property 'forge.logging.console.level', 'debug'
|
|
arg "--nogui"
|
|
|
|
mods {
|
|
computercraft {
|
|
source sourceSets.main
|
|
}
|
|
}
|
|
}
|
|
|
|
data {
|
|
workingDirectory project.file('run')
|
|
property 'forge.logging.markers', 'REGISTRIES'
|
|
property 'forge.logging.console.level', 'debug'
|
|
|
|
args '--mod', 'computercraft', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
|
|
mods {
|
|
computercraft {
|
|
source sourceSets.main
|
|
}
|
|
}
|
|
}
|
|
|
|
testServer {
|
|
workingDirectory project.file('test-files/server')
|
|
parent runs.server
|
|
|
|
mods {
|
|
cctest {
|
|
source sourceSets.test
|
|
}
|
|
}
|
|
}
|
|
|
|
testServerRun {
|
|
parent runs.testServer
|
|
property 'forge.logging.console.level', 'info'
|
|
property 'cctest.run', 'true'
|
|
forceExit false
|
|
}
|
|
}
|
|
|
|
mappings channel: 'official', version: project.mc_version
|
|
|
|
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
|
|
}
|
|
|
|
sourceSets {
|
|
main.resources {
|
|
srcDir 'src/generated/resources'
|
|
}
|
|
}
|
|
|
|
repositories {
|
|
mavenCentral()
|
|
maven {
|
|
name "SquidDev"
|
|
url "https://squiddev.cc/maven"
|
|
}
|
|
}
|
|
|
|
configurations {
|
|
shade
|
|
compile.extendsFrom shade
|
|
deployerJars
|
|
cctJavadoc
|
|
}
|
|
|
|
dependencies {
|
|
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
|
|
|
|
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
|
|
|
|
compileOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3:api")
|
|
compileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.15.2:6.0.0.9")
|
|
|
|
runtimeOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3")
|
|
|
|
compileOnly 'com.google.auto.service:auto-service:1.0-rc7'
|
|
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7'
|
|
|
|
shade 'org.squiddev:Cobalt:0.5.1-SNAPSHOT'
|
|
|
|
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
|
|
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
|
|
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
|
|
testImplementation 'org.hamcrest:hamcrest:2.2'
|
|
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72'
|
|
testImplementation 'org.jetbrains.kotlin:kotlin-reflect:1.3.72'
|
|
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
|
|
|
|
deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
|
|
|
|
cctJavadoc 'cc.tweaked:cct-javadoc:1.3.0'
|
|
}
|
|
|
|
// Compile tasks
|
|
|
|
javadoc {
|
|
include "dan200/computercraft/api/**/*.java"
|
|
}
|
|
|
|
task luaJavadoc(type: Javadoc) {
|
|
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"
|
|
|
|
// Attempt to run under Java 11 (any Java >= 9 will work though).
|
|
if(System.getProperty("java.version").startsWith("1.")
|
|
&& (System.getenv("JAVA_HOME_11_X64") != null || project.hasProperty("java11Home"))) {
|
|
executable = "${System.getenv("JAVA_HOME_11_X64") ?: project.property("java11Home")}/bin/javadoc"
|
|
}
|
|
}
|
|
|
|
jar {
|
|
dependsOn javadoc
|
|
|
|
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")])
|
|
}
|
|
|
|
from (sourceSets.main.allSource) {
|
|
include "dan200/computercraft/api/**/*.java"
|
|
}
|
|
|
|
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
|
|
}
|
|
|
|
[compileJava, compileTestJava].forEach {
|
|
it.configure {
|
|
options.compilerArgs << "-Xlint" << "-Xlint:-processing"
|
|
}
|
|
}
|
|
|
|
import java.nio.charset.StandardCharsets
|
|
import java.nio.file.*
|
|
import java.util.zip.*
|
|
|
|
import com.google.gson.GsonBuilder
|
|
import com.google.gson.JsonElement
|
|
import com.hierynomus.gradle.license.tasks.LicenseCheck
|
|
import com.hierynomus.gradle.license.tasks.LicenseFormat
|
|
import org.ajoberstar.grgit.Grgit
|
|
import proguard.gradle.ProGuardTask
|
|
|
|
task proguard(type: ProGuardTask, dependsOn: jar) {
|
|
description "Removes unused shadowed classes from the jar"
|
|
group "compact"
|
|
|
|
injars jar.archivePath
|
|
outjars "${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar"
|
|
|
|
// Add the main runtime jar and all non-shadowed dependencies
|
|
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
|
|
libraryjars "${System.getProperty('java.home')}/lib/jce.jar"
|
|
doFirst {
|
|
sourceSets.main.compileClasspath
|
|
.filter { !it.name.contains("Cobalt") }
|
|
.each { libraryjars it }
|
|
}
|
|
|
|
// We want to avoid as much obfuscation as possible. We're only doing this to shrink code size.
|
|
dontobfuscate; dontoptimize; keepattributes; keepparameternames
|
|
|
|
// Proguard will remove directories by default, but that breaks JarMount.
|
|
keepdirectories 'data/computercraft/lua**'
|
|
|
|
// Preserve ComputerCraft classes - we only want to strip shadowed files.
|
|
keep 'class dan200.computercraft.** { *; }'
|
|
|
|
// LWJGL and Apache bundle Java 9 versions, which is great, but rather breaks Proguard
|
|
dontwarn 'module-info'
|
|
dontwarn 'org.apache.**,org.lwjgl.**'
|
|
}
|
|
|
|
task proguardMove(dependsOn: proguard) {
|
|
description "Replace the original jar with the minified version"
|
|
group "compact"
|
|
|
|
doLast {
|
|
Files.move(
|
|
file("${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar").toPath(),
|
|
file(jar.archivePath).toPath(),
|
|
StandardCopyOption.REPLACE_EXISTING
|
|
)
|
|
}
|
|
}
|
|
|
|
processResources {
|
|
inputs.property "version", mod_version
|
|
inputs.property "mcversion", mc_version
|
|
|
|
def hash = 'none'
|
|
Set<String> contributors = []
|
|
try {
|
|
def grgit = Grgit.open(dir: '.')
|
|
hash = grgit.head().id
|
|
|
|
def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
|
|
grgit.log().each {
|
|
if (!blacklist.contains(it.author.name)) contributors.add(it.author.name)
|
|
if (!blacklist.contains(it.committer.name)) contributors.add(it.committer.name)
|
|
}
|
|
} catch(Exception ignored) { }
|
|
|
|
inputs.property "commithash", hash
|
|
|
|
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'
|
|
}
|
|
}
|
|
|
|
task compressJson(dependsOn: jar) {
|
|
group "compact"
|
|
description "Minifies all JSON files, stripping whitespace"
|
|
|
|
def jarPath = file(jar.archivePath)
|
|
|
|
def tempPath = File.createTempFile("input", ".jar", temporaryDir)
|
|
tempPath.deleteOnExit()
|
|
|
|
def gson = new GsonBuilder().create()
|
|
|
|
doLast {
|
|
// Copy over all files in the current jar to the new one, running json files from GSON. As pretty printing
|
|
// is turned off, they should be minified.
|
|
new ZipFile(jarPath).withCloseable { inJar ->
|
|
tempPath.getParentFile().mkdirs()
|
|
new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tempPath))).withCloseable { outJar ->
|
|
inJar.entries().each { entry ->
|
|
if(entry.directory) {
|
|
outJar.putNextEntry(entry)
|
|
} else if(!entry.name.endsWith(".json")) {
|
|
outJar.putNextEntry(entry)
|
|
inJar.getInputStream(entry).withCloseable { outJar << it }
|
|
} else {
|
|
ZipEntry newEntry = new ZipEntry(entry.name)
|
|
newEntry.setTime(entry.time)
|
|
outJar.putNextEntry(newEntry)
|
|
|
|
def element = inJar.getInputStream(entry).withCloseable { gson.fromJson(it.newReader("UTF8"), JsonElement.class) }
|
|
outJar.write(gson.toJson(element).getBytes(StandardCharsets.UTF_8))
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// And replace the original jar again
|
|
Files.move(tempPath.toPath(), jarPath.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
|
}
|
|
}
|
|
|
|
assemble.dependsOn compressJson
|
|
|
|
// Web tasks
|
|
|
|
import org.apache.tools.ant.taskdefs.condition.Os
|
|
|
|
List<String> mkCommand(String command) {
|
|
return Os.isFamily(Os.FAMILY_WINDOWS) ? ["cmd", "/c", command] : ["sh", "-c", command]
|
|
}
|
|
|
|
task rollup(type: Exec) {
|
|
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')
|
|
}
|
|
|
|
task minifyWeb(type: Exec, dependsOn: rollup) {
|
|
group = "build"
|
|
description = "Bundles JS into rollup"
|
|
|
|
inputs.file("$buildDir/rollup/index.js").withPropertyName("sources")
|
|
inputs.file("package-lock.json").withPropertyName("package-lock.json")
|
|
outputs.file("$buildDir/rollup/index.min.js").withPropertyName("output")
|
|
|
|
commandLine mkCommand('"node_modules/.bin/terser"' + " -o '$buildDir/rollup/index.min.js' '$buildDir/rollup/index.js'")
|
|
}
|
|
|
|
task illuaminateDocs(type: Exec, dependsOn: [minifyWeb, luaJavadoc]) {
|
|
group = "build"
|
|
description = "Bundles JS into rollup"
|
|
|
|
inputs.files(fileTree("doc")).withPropertyName("docs")
|
|
inputs.files(fileTree("src/main/resources/data/computercraft/lua/rom")).withPropertyName("lua rom")
|
|
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
|
|
inputs.dir("$buildDir/docs/luaJavadoc")
|
|
inputs.file("$buildDir/rollup/index.min.js").withPropertyName("scripts")
|
|
inputs.file("src/web/styles.css").withPropertyName("styles")
|
|
outputs.dir("$buildDir/docs/lua")
|
|
|
|
commandLine mkCommand('"bin/illuaminate" doc-gen')
|
|
}
|
|
|
|
task docWebsite(type: Copy, dependsOn: [illuaminateDocs]) {
|
|
from 'doc/logo.png'
|
|
into "${project.docsDir}/lua"
|
|
}
|
|
|
|
// Check tasks
|
|
|
|
test {
|
|
useJUnitPlatform()
|
|
testLogging {
|
|
events "skipped", "failed"
|
|
}
|
|
}
|
|
|
|
jacocoTestReport {
|
|
reports {
|
|
xml.enabled true
|
|
html.enabled true
|
|
}
|
|
}
|
|
|
|
check.dependsOn jacocoTestReport
|
|
|
|
license {
|
|
mapping("java", "SLASHSTAR_STYLE")
|
|
strictCheck true
|
|
|
|
ext.year = Calendar.getInstance().get(Calendar.YEAR)
|
|
}
|
|
|
|
[licenseMain, licenseFormatMain].forEach {
|
|
it.configure {
|
|
include("**/*.java")
|
|
exclude("dan200/computercraft/api/**")
|
|
header file('config/license/main.txt')
|
|
}
|
|
}
|
|
|
|
[licenseTest, licenseFormatTest].forEach {
|
|
it.configure {
|
|
include("**/*.java")
|
|
header file('config/license/main.txt')
|
|
}
|
|
}
|
|
|
|
gradle.projectsEvaluated {
|
|
tasks.withType(LicenseFormat) {
|
|
outputs.upToDateWhen { false }
|
|
}
|
|
}
|
|
|
|
|
|
task licenseAPI(type: LicenseCheck);
|
|
task licenseFormatAPI(type: LicenseFormat);
|
|
[licenseAPI, licenseFormatAPI].forEach {
|
|
it.configure {
|
|
source = sourceSets.main.java
|
|
include("dan200/computercraft/api/**")
|
|
header file('config/license/api.txt')
|
|
}
|
|
}
|
|
|
|
task setupServer(type: Copy) {
|
|
from("src/test/server-files") {
|
|
include "eula.txt"
|
|
include "server.properties"
|
|
}
|
|
into "test-files/server"
|
|
}
|
|
|
|
// Upload tasks
|
|
|
|
task 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.txt")
|
|
inputs.file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
|
|
|
|
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.txt").readLines()
|
|
if (whatsnew[0] != "New features in CC: Tweaked $mod_version") {
|
|
ok = false
|
|
project.logger.error("Expected `whatsnew.txt' 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.txt")
|
|
} 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.txt").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
|
|
|
|
curseforge {
|
|
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
|
|
project {
|
|
id = '282001'
|
|
releaseType = 'release'
|
|
changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
|
|
|
|
relations {
|
|
incompatible "computercraft"
|
|
}
|
|
}
|
|
}
|
|
|
|
publishing {
|
|
publications {
|
|
mavenJava(MavenPublication) {
|
|
from components.java
|
|
// artifact sourceJar
|
|
}
|
|
}
|
|
}
|
|
|
|
uploadArchives {
|
|
repositories {
|
|
if(project.hasProperty('mavenUploadUrl')) {
|
|
mavenDeployer {
|
|
configuration = configurations.deployerJars
|
|
|
|
repository(url: project.property('mavenUploadUrl')) {
|
|
authentication(
|
|
userName: project.property('mavenUploadUser'),
|
|
privateKey: project.property('mavenUploadKey'))
|
|
}
|
|
|
|
pom.project {
|
|
name 'CC: Tweaked'
|
|
packaging 'jar'
|
|
description 'CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft.'
|
|
url 'https://github.com/SquidDev-CC/CC-Tweaked'
|
|
|
|
scm {
|
|
url 'https://github.com/SquidDev-CC/CC-Tweaked.git'
|
|
}
|
|
|
|
issueManagement {
|
|
system 'github'
|
|
url 'https://github.com/SquidDev-CC/CC-Tweaked/issues'
|
|
}
|
|
|
|
licenses {
|
|
license {
|
|
name 'ComputerCraft Public License, Version 1.0'
|
|
url 'https://github.com/SquidDev-CC/CC-Tweaked/blob/master/LICENSE'
|
|
distribution 'repo'
|
|
}
|
|
}
|
|
}
|
|
|
|
pom.whenConfigured { pom ->
|
|
pom.dependencies.clear()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
githubRelease {
|
|
token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
|
|
owner 'SquidDev-CC'
|
|
repo 'CC-Tweaked'
|
|
try {
|
|
targetCommitish = Grgit.open(dir: '.').branch.current().name
|
|
} catch(Exception ignored) { }
|
|
|
|
tagName "v${mc_version}-${mod_version}"
|
|
releaseName "[${mc_version}] ${mod_version}"
|
|
body {
|
|
"## " + new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
|
|
.readLines()
|
|
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
|
|
.join("\n").trim()
|
|
}
|
|
prerelease false
|
|
}
|
|
|
|
def uploadTasks = ["uploadArchives", "curseforge", "githubRelease"]
|
|
uploadTasks.forEach { tasks.getByName(it).dependsOn checkRelease }
|
|
|
|
task uploadAll(dependsOn: uploadTasks) {
|
|
group "upload"
|
|
description "Uploads to all repositories (Maven, Curse, GitHub release)"
|
|
}
|