1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-07-03 02:23:20 +00:00
CC-Tweaked/projects/web/build.gradle.kts
Jonathan Coates c0643fadca
Build a web-based emulator for the documentation site (#1597)
Historically we've used copy-cat to provide a web-based emulator for
running example code on our documentation site. However, copy-cat is
often out-of-date with CC:T, which means example snippets fail when you
try to run them!

This commit vendors in copy-cat (or rather an updated version of it)
into CC:T itself, allowing us to ensure the emulator is always in sync
with the mod.

While the ARCHITECTURE.md documentation goes into a little bit more
detail here, the general implementation is as follows

 - In project/src/main we implement the core of the emulator. This
   includes a basic reimplementation of some of CC's classes to work on
   the web (mostly the HTTP API and ComputerThread), and some additional
   code to expose the computers to Javascript.

 - This is all then compiled to Javascript using [TeaVM][1] (we actually
   use a [personal fork of it][2] as there's a couple of changes I've
   not upstreamed yet).

 - The Javascript side then pulls in the these compiled classes (and
   the CC ROM) and hooks them up to [cc-web-term][3] to display the
   actual computer.

 - As we're no longer pulling in copy-cat, we can simplify our bundling
   system a little - we now just compile to ESM modules directly.

[1]: https://github.com/konsoletyper/teavm
[2]: https://github.com/SquidDev/teavm/tree/squid-patches
[3]: https://github.com/squiddev-cc/cc-web-term
2023-10-03 09:19:19 +01:00

157 lines
5.1 KiB
Plaintext

// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
import cc.tweaked.gradle.getAbsolutePath
plugins {
id("cc-tweaked.java-convention")
id("cc-tweaked.node")
id("cc-tweaked.illuaminate")
}
val modVersion: String by extra
node {
projectRoot.set(rootProject.projectDir)
}
illuaminate {
version.set(libs.versions.illuaminate)
}
sourceSets.register("builder")
dependencies {
implementation(project(":core"))
implementation(libs.bundles.teavm.api)
implementation(libs.asm)
implementation(libs.guava)
implementation(libs.netty.http)
implementation(libs.slf4j)
"builderCompileOnly"(libs.bundles.annotations)
"builderImplementation"(libs.bundles.teavm.tooling)
"builderImplementation"(libs.asm)
"builderImplementation"(libs.asm.commons)
}
val compileTeaVM by tasks.registering(JavaExec::class) {
group = LifecycleBasePlugin.BUILD_GROUP
description = "Generate our classes and resources files"
val output = layout.buildDirectory.dir("teaVM")
val minify = !project.hasProperty("noMinify")
inputs.property("version", modVersion)
inputs.property("minify", minify)
inputs.files(sourceSets.main.get().runtimeClasspath).withPropertyName("inputClasspath")
outputs.dir(output).withPropertyName("output")
classpath = sourceSets["builder"].runtimeClasspath
jvmArguments.addAll(
provider {
val main = sourceSets.main.get()
listOf(
"-Dcct.input=${main.output.classesDirs.asPath}",
"-Dcct.version=$modVersion",
"-Dcct.classpath=${main.runtimeClasspath.asPath}",
"-Dcct.output=${output.getAbsolutePath()}",
"-Dcct.minify=$minify",
)
},
)
mainClass.set("cc.tweaked.web.builder.Builder")
javaLauncher.set(project.javaToolchains.launcherFor { languageVersion.set(java.toolchain.languageVersion) })
}
val rollup by tasks.registering(cc.tweaked.gradle.NpxExecToDir::class) {
group = LifecycleBasePlugin.BUILD_GROUP
description = "Bundles JS into rollup"
val minify = !project.hasProperty("noMinify")
inputs.property("minify", minify)
// Sources
inputs.files(fileTree("src/frontend")).withPropertyName("sources")
inputs.files(compileTeaVM)
// Config files
inputs.file("tsconfig.json").withPropertyName("Typescript config")
inputs.file("rollup.config.js").withPropertyName("Rollup config")
// Output directory. Also defined in illuaminate.sexp and rollup.config.js
output.set(layout.buildDirectory.dir("rollup"))
args = listOf("rollup", "--config", "rollup.config.js") + if (minify) emptyList() else listOf("--configDebug")
}
val illuaminateDocs by tasks.registering(cc.tweaked.gradle.IlluaminateExecToDir::class) {
group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Generates docs using Illuaminate"
// Config files
inputs.file(rootProject.file("illuaminate.sexp")).withPropertyName("illuaminate config")
// Sources
inputs.files(rootProject.fileTree("doc")).withPropertyName("docs")
inputs.files(project(":core").fileTree("src/main/resources/data/computercraft/lua")).withPropertyName("lua rom")
inputs.files(project(":forge").tasks.named("luaJavadoc"))
// Assets
inputs.files(rollup)
// Output directory. Also defined in illuaminate.sexp.
output.set(layout.buildDirectory.dir("illuaminate"))
args = listOf("doc-gen")
workingDir = rootProject.projectDir
}
val htmlTransform by tasks.registering(cc.tweaked.gradle.NpxExecToDir::class) {
group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Post-processes documentation to statically render some dynamic content."
val sources = fileTree("src/htmlTransform")
// Config files
inputs.file("tsconfig.json").withPropertyName("Typescript config")
// Sources
inputs.files(sources).withPropertyName("sources")
inputs.files(illuaminateDocs)
// Output directory.
output.set(layout.buildDirectory.dir(name))
argumentProviders.add {
listOf(
"tsx",
sources.dir.resolve("index.tsx").absolutePath,
illuaminateDocs.get().output.getAbsolutePath(),
sources.dir.resolve("export/index.json").absolutePath,
output.getAbsolutePath(),
)
}
}
val docWebsite by tasks.registering(Copy::class) {
group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Assemble docs and assets together into the documentation website."
duplicatesStrategy = DuplicatesStrategy.FAIL
from(htmlTransform)
// Pick up assets from the /docs folder
from(rootProject.file("doc")) {
include("logo.png")
include("images/**")
}
// index.js is provided by illuaminate, but rollup outputs some other chunks
from(rollup) { exclude("index.js") }
// Grab illuaminate's assets. HTML files are provided by jsxDocs
from(illuaminateDocs) { exclude("**/*.html") }
// And item/block images from the data export
from(file("src/htmlTransform/export/items")) { into("images/items") }
into(layout.buildDirectory.dir("site"))
}
tasks.assemble { dependsOn(docWebsite) }