mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-04-28 21:53:11 +00:00

I've no motivation for modding right now, but always got time for build system busywork! CC:T (and CC before that) has always published its API docs. However, they're not always the most helpful — they're useful if you know what you're looking for, but aren't a good getting-started guide. Part of the issue here is there's no examples, and everything is described pretty abstractly. I have occasionally tried to improve this (e.g. the peripheral docs in bdffabc08e2eb9895f966c949acc8334a2bf4475), but it's a long road. This commit adds a new example mod, which registers peripherals, an API and a turtle upgrade. While the mod itself isn't exported as part of the docs, we reference blocks of it using Java's new {@snippet} tag. - Switch the Forge project to use NeoForge's new Legacy MDG plugin. We don't *need* to do this, but it means the build logic for Forge and NeoForge is more closely aligned. - Add a new SnippetTaglet, which is a partial backport of Java 18+'s {@snippet}. - Add an example mod. This is a working multi-loader mod, complete with datagen (albeit with no good multi-loader abstractions). - Move our existing <pre>{@code ...}</pre> blocks into the example mod, replacing them with {@snippet}s. - Add a new overview page to the docs, providing some getting-started information. We had this already in the dan200.computercraft.api package docs, but it's not especially visible there.
249 lines
7.6 KiB
Plaintext
249 lines
7.6 KiB
Plaintext
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
|
|
//
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
import cc.tweaked.gradle.*
|
|
import net.neoforged.moddevgradle.dsl.RunModel
|
|
|
|
plugins {
|
|
id("cc-tweaked.forge")
|
|
id("cc-tweaked.mod")
|
|
id("cc-tweaked.mod-publishing")
|
|
}
|
|
|
|
val modVersion: String by extra
|
|
|
|
val allProjects = listOf(":core-api", ":core", ":forge-api").map { evaluationDependsOn(it) }
|
|
cct {
|
|
inlineProject(":common")
|
|
allProjects.forEach { externalSources(it) }
|
|
}
|
|
|
|
legacyForge {
|
|
val computercraft by mods.registering {
|
|
cct.sourceDirectories.get().forEach {
|
|
if (it.classes) sourceSet(it.sourceSet)
|
|
}
|
|
}
|
|
|
|
val computercraftDatagen by mods.registering {
|
|
cct.sourceDirectories.get().forEach {
|
|
if (it.classes) sourceSet(it.sourceSet)
|
|
}
|
|
sourceSet(sourceSets.datagen.get())
|
|
}
|
|
|
|
val testMod by mods.registering {
|
|
sourceSet(sourceSets.testMod.get())
|
|
sourceSet(sourceSets.testFixtures.get())
|
|
sourceSet(project(":core").sourceSets["testFixtures"])
|
|
}
|
|
|
|
val exampleMod by mods.registering {
|
|
sourceSet(sourceSets.examples.get())
|
|
}
|
|
|
|
runs {
|
|
configureEach {
|
|
ideName = "Forge - ${name.capitalise()}"
|
|
systemProperty("forge.logging.markers", "REGISTRIES")
|
|
systemProperty("forge.logging.console.level", "debug")
|
|
loadedMods.add(computercraft)
|
|
}
|
|
|
|
register("client") {
|
|
client()
|
|
}
|
|
|
|
register("server") {
|
|
server()
|
|
gameDirectory = file("run/server")
|
|
programArgument("--nogui")
|
|
}
|
|
|
|
fun RunModel.configureForData(mod: String, sourceSet: SourceSet) {
|
|
data()
|
|
gameDirectory = file("run/run${name.capitalise()}")
|
|
programArguments.addAll(
|
|
"--mod", mod, "--all",
|
|
"--output",
|
|
layout.buildDirectory.dir(sourceSet.getTaskName("generateResources", null))
|
|
.getAbsolutePath(),
|
|
"--existing", project.project(":common").file("src/${sourceSet.name}/resources/").absolutePath,
|
|
"--existing", project.file("src/${sourceSet.name}/resources/").absolutePath,
|
|
)
|
|
}
|
|
|
|
register("data") {
|
|
configureForData("computercraft", sourceSets.main.get())
|
|
loadedMods = listOf(computercraftDatagen.get())
|
|
}
|
|
|
|
fun RunModel.configureForGameTest() {
|
|
systemProperty(
|
|
"cctest.sources",
|
|
project.project(":common").file("src/testMod/resources/data/cctest").absolutePath,
|
|
)
|
|
|
|
programArgument("--mixin.config=computercraft-gametest.mixins.json")
|
|
loadedMods.add(testMod)
|
|
|
|
jvmArgument("-ea")
|
|
}
|
|
|
|
register("testClient") {
|
|
client()
|
|
gameDirectory = file("run/testClient")
|
|
configureForGameTest()
|
|
|
|
systemProperty("cctest.tags", "client,common")
|
|
}
|
|
|
|
register("gametest") {
|
|
type = "gameTestServer"
|
|
configureForGameTest()
|
|
|
|
systemProperty("forge.logging.console.level", "info")
|
|
systemProperty(
|
|
"cctest.gametest-report",
|
|
layout.buildDirectory.dir("test-results/runGametest.xml").getAbsolutePath(),
|
|
)
|
|
gameDirectory = file("run/gametest")
|
|
}
|
|
|
|
register("exampleClient") {
|
|
client()
|
|
loadedMods.add(exampleMod.get())
|
|
}
|
|
|
|
register("exampleData") {
|
|
configureForData("examplemod", sourceSets.examples.get())
|
|
loadedMods.add(exampleMod.get())
|
|
}
|
|
}
|
|
}
|
|
|
|
configurations {
|
|
additionalRuntimeClasspath { extendsFrom(jarJar.get()) }
|
|
|
|
val testAdditionalRuntimeClasspath by registering {
|
|
isCanBeResolved = true
|
|
isCanBeConsumed = false
|
|
// Prevent ending up with multiple versions of libraries on the classpath.
|
|
shouldResolveConsistentlyWith(additionalRuntimeClasspath.get())
|
|
}
|
|
|
|
for (testConfig in listOf("testClientAdditionalRuntimeClasspath", "gametestAdditionalRuntimeClasspath")) {
|
|
named(testConfig) { extendsFrom(testAdditionalRuntimeClasspath.get()) }
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
compileOnly(libs.jetbrainsAnnotations)
|
|
annotationProcessorEverywhere(libs.autoService)
|
|
|
|
clientCompileOnly(variantOf(libs.emi) { classifier("api") })
|
|
modCompileOnly(libs.bundles.externalMods.forge.compile)
|
|
modRuntimeOnly(libs.bundles.externalMods.forge.runtime)
|
|
modCompileOnly(variantOf(libs.create.forge) { classifier("slim") })
|
|
|
|
// Depend on our other projects.
|
|
api(commonClasses(project(":forge-api"))) { cct.exclude(this) }
|
|
clientApi(clientClasses(project(":forge-api"))) { cct.exclude(this) }
|
|
implementation(project(":core")) { cct.exclude(this) }
|
|
|
|
jarJar(libs.cobalt)
|
|
jarJar(libs.jzlib)
|
|
// We don't jar-in-jar our additional netty dependencies (see the tasks.jarJar configuration), but still want them
|
|
// on the legacy classpath.
|
|
additionalRuntimeClasspath(libs.netty.http) { isTransitive = false }
|
|
additionalRuntimeClasspath(libs.netty.socks) { isTransitive = false }
|
|
additionalRuntimeClasspath(libs.netty.proxy) { isTransitive = false }
|
|
|
|
testFixturesApi(libs.bundles.test)
|
|
testFixturesApi(libs.bundles.kotlin)
|
|
|
|
testImplementation(testFixtures(project(":core")))
|
|
testImplementation(libs.bundles.test)
|
|
testRuntimeOnly(libs.bundles.testRuntime)
|
|
|
|
testModImplementation(testFixtures(project(":core")))
|
|
testModImplementation(testFixtures(project(":forge")))
|
|
|
|
// Ensure our test fixture dependencies are on the classpath
|
|
"testAdditionalRuntimeClasspath"(libs.bundles.kotlin)
|
|
"testAdditionalRuntimeClasspath"(libs.bundles.test)
|
|
|
|
testFixturesImplementation(testFixtures(project(":core")))
|
|
}
|
|
|
|
// Compile tasks
|
|
|
|
tasks.processResources {
|
|
inputs.property("modVersion", modVersion)
|
|
inputs.property("forgeVersion", libs.versions.forge.get())
|
|
|
|
filesMatching("META-INF/mods.toml") {
|
|
expand(mapOf("forgeVersion" to libs.versions.forge.get(), "file" to mapOf("jarVersion" to modVersion)))
|
|
}
|
|
}
|
|
|
|
tasks.jar {
|
|
// Include all classes from other projects except core.
|
|
val coreSources = project(":core").sourceSets["main"]
|
|
for (source in cct.sourceDirectories.get()) {
|
|
if (source.classes && source.sourceSet != coreSources) from(source.sourceSet.output)
|
|
}
|
|
|
|
// Include core separately, along with the relocated netty classes.
|
|
from(zipTree(project(":core").tasks.named("shadowJar", AbstractArchiveTask::class).map { it.archiveFile })) {
|
|
exclude("META-INF/**")
|
|
}
|
|
}
|
|
|
|
tasks.sourcesJar {
|
|
for (source in cct.sourceDirectories.get()) from(source.sourceSet.allSource)
|
|
}
|
|
|
|
// Check tasks
|
|
|
|
tasks.test {
|
|
systemProperty("cct.test-files", layout.buildDirectory.dir("tmp/testFiles").getAbsolutePath())
|
|
}
|
|
|
|
val runGametest = tasks.named<JavaExec>("runGametest") {
|
|
usesService(MinecraftRunnerService.get(gradle))
|
|
}
|
|
cct.jacoco(runGametest)
|
|
tasks.check { dependsOn(runGametest) }
|
|
|
|
val runGametestClient by tasks.registering(ClientJavaExec::class) {
|
|
description = "Runs client-side gametests with no mods"
|
|
copyFromForge("runTestClient")
|
|
tags("client")
|
|
}
|
|
cct.jacoco(runGametestClient)
|
|
|
|
tasks.register("checkClient") {
|
|
group = LifecycleBasePlugin.VERIFICATION_GROUP
|
|
description = "Runs all client-only checks."
|
|
dependsOn(runGametestClient)
|
|
}
|
|
|
|
// Upload tasks
|
|
|
|
modPublishing {
|
|
output.set(tasks.reobfJar)
|
|
}
|
|
|
|
publishing {
|
|
publications {
|
|
named("maven", MavenPublication::class) {
|
|
mavenDependencies {
|
|
cct.configureExcludes(this)
|
|
exclude(libs.jei.forge.get())
|
|
}
|
|
}
|
|
}
|
|
}
|