Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
name: Build
on: [ pull_request, push ]
on:
push:
branches:
- main
pull_request:
jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -19,3 +23,28 @@ jobs:
run: ./gradlew build
- name: Test with Gradle
run: ./gradlew test
platform-compat:
name: Check ${{ matrix.platform }} compatibility modules
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- platform: Fabric
task: checkFabricPlatformCompat
- platform: NeoForge
task: checkNeoForgePlatformCompat
steps:
- name: Checkout sources
uses: actions/checkout@v7.0.0
- name: Setup Java
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v6
with:
cache-read-only: ${{ github.ref != 'refs/heads/main' }}
- name: Check compatibility modules
run: ./gradlew ${{ matrix.task }}
2 changes: 1 addition & 1 deletion .github/workflows/maven-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ jobs:
env:
REPOSITORY_USER: ${{ secrets.REPOSITORY_USER }}
REPOSITORY_TOKEN: ${{ secrets.REPOSITORY_TOKEN }}
run: ./gradlew publish
run: ./gradlew publish publishPlatformCompat
28 changes: 23 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Documentation: https://docs.faststats.dev/java

## Building

Run Gradle from the repository root. The library modules use the standard Java lifecycle, while deployable example plugins and mods use the packaging task expected by their platform.
Run Gradle from the repository root. The library modules use the standard Java lifecycle, while deployable example
plugins and mods use the packaging task expected by their platform.

### Libraries

Expand All @@ -15,19 +16,27 @@ Use `build` for the reusable FastStats libraries:
./gradlew :config:build
./gradlew :bukkit:build
./gradlew :bungeecord:build
./gradlew :fabric:build
./gradlew :hytale:build
./gradlew :minestom:build
./gradlew :nukkit:build
./gradlew :sponge:build
./gradlew :velocity:build
```

Library jars are written to each module's `build/libs` directory. Fabric also produces a remapped jar through Fabric Loom as part of its build output.
Library jars are written to each module's `build/libs` directory. Fabric and NeoForge compatibility artifacts are
published under stable Maven artifact IDs with Minecraft range suffixes:

```text
dev.faststats.metrics:fabric:<sdk-version>+mc26.1-26.2
dev.faststats.metrics:neoforge:<sdk-version>+mc26.1-26.2
```

Use `checkPlatformCompat` to compile all Fabric and NeoForge compatibility modules.

### Bukkit, BungeeCord, Hytale, Minestom, Nukkit, Sponge, and Velocity examples

These examples use Shadow so FastStats is bundled into the deployable plugin or server jar. Build the `shadowJar` task directly when you want the artifact to install or run:
These examples use Shadow so FastStats is bundled into the deployable plugin or server jar. Build the `shadowJar` task
directly when you want the artifact to install or run:

```sh
./gradlew :bukkit:example-plugin:shadowJar
Expand All @@ -49,7 +58,8 @@ Fabric mods should be packaged by Fabric Loom, not Shadow. Build the mod jar wit
./gradlew :fabric:example-mod:jar
```

Use `fabric/example-mod/build/libs/example-mod-<version>.jar`. Do not use a Shadow `*-all.jar` for Fabric; it can bundle Minecraft and loader internals into the mod.
Use `fabric/example-mod/build/libs/example-mod-<version>.jar`. Do not use a Shadow `*-all.jar` for Fabric; it can bundle
Minecraft and loader internals into the mod.

### Building everything

Expand All @@ -60,3 +70,11 @@ To compile and test all modules with the standard lifecycle, run:
```

For deployable example artifacts, run the platform-specific commands above after `build` or instead of it.

### Platform compatibility checks

Compile all published platform compatibility modules with:

```sh
./gradlew checkPlatformCompat
```
98 changes: 57 additions & 41 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,25 @@ plugins {
kotlin("jvm") version "2.4.20-Beta1" apply false
}

val javaVersionsOverride = mapOf(
":bukkit" to 21,
":bukkit:example-plugin" to 21,
":fabric" to 25,
":fabric:example-mod" to 25,
":hytale" to 25,
":hytale:example-plugin" to 25,
":minestom" to 25,
":minestom:example-server" to 25,
":neoforge" to 25,
":neoforge:example-mod" to 25,
":velocity" to 21,
":velocity:example-plugin" to 21
)
val defaultJavaVersion = 17

subprojects {
apply {
plugin("java")
plugin("java-library")
}

val example = project.name.startsWith("example")
if (example) {
apply { plugin("org.jetbrains.kotlin.jvm") }
if (project.path != ":fabric:example-mod" && project.path != ":neoforge:example-mod") {
apply { plugin("com.gradleup.shadow") }
}
} else {
apply { plugin("maven-publish") }
}

group = "dev.faststats.metrics"

repositories {
mavenCentral()
}

val javaVersion = javaVersionsOverride[project.path] ?: defaultJavaVersion

extensions.configure<JavaPluginExtension> {
toolchain.languageVersion = JavaLanguageVersion.of(javaVersion)
withSourcesJar()
withJavadocJar()
}

tasks.compileJava {
options.release.set(javaVersion)
}

val generateFastStatsProperties by tasks.registering {
val generateFastStatsProperties = tasks.register("generateFastStatsProperties") {
description = "Generates the META-INF/faststats.properties file"
val outputDir = layout.buildDirectory.dir("generated/resources/faststats")
outputs.dir(outputDir)
doLast {
Expand All @@ -76,20 +44,24 @@ subprojects {
}
}

fun ownProperty(name: String): String? {
return if (extensions.extraProperties.has(name)) extensions.extraProperties.get(name).toString() else null
}

tasks.withType<JavaCompile>().configureEach {
project.findProperty("moduleName")?.let { moduleName ->
ownProperty("moduleName")?.let { moduleName ->
options.compilerArgs.addAll(listOf("--add-reads", "$moduleName=ALL-UNNAMED"))
}
}

tasks.withType<Test>().configureEach {
project.findProperty("moduleName")?.let { moduleName ->
ownProperty("moduleName")?.let { moduleName ->
jvmArgs("--add-reads", "$moduleName=ALL-UNNAMED")
}
}

tasks.withType<JavaExec>().configureEach {
project.findProperty("moduleName")?.let { moduleName ->
ownProperty("moduleName")?.let { moduleName ->
jvmArgs("--add-reads", "$moduleName=ALL-UNNAMED")
}
}
Expand All @@ -101,20 +73,33 @@ subprojects {
"implSpec:a:Implementation Requirements:",
"implNote:a:Implementation Note:"
)
project.findProperty("moduleName")?.let { moduleName ->
ownProperty("moduleName")?.let { moduleName ->
options.addStringOption("-add-reads", "$moduleName=ALL-UNNAMED")
}
}

afterEvaluate {
if (example) return@afterEvaluate
val publishArtifactId = ownProperty("publishArtifactId")
if (!plugins.hasPlugin("maven-publish") && publishArtifactId == null) return@afterEvaluate
if (!plugins.hasPlugin("maven-publish") || publishArtifactId == null) throw IllegalStateException(
"Invalid publishing setup for project \"${project.path}\", " +
"maven-publish: ${plugins.hasPlugin("maven-publish")}, publishArtifactId: $publishArtifactId"
)

ownProperty("publishVersionSuffix")?.let { suffix ->
version = "${rootProject.version}+$suffix"
}

extensions.configure<PublishingExtension> {
publications.create<MavenPublication>("maven") {
artifactId = project.name
artifactId = publishArtifactId
groupId = "dev.faststats.metrics"

pom {
url.set("https://faststats.dev/docs")
url.set(
ownProperty("publishDocsUrl")
?: throw IllegalStateException("No docs URL provided by \"${project.path}\"")
)
scm {
val repository = "faststats-dev/faststats-java"
url.set("https://github.com/$repository")
Expand All @@ -139,3 +124,34 @@ subprojects {
}
}
}

fun platformCompatProjects(platform: String) = subprojects.filter { project ->
project.path.startsWith(":$platform:versions:")
}

tasks.register("checkFabricPlatformCompat") {
group = "verification"
description = "Compiles all Fabric platform compatibility modules."
dependsOn(platformCompatProjects("fabric").map { "${it.path}:compileJava" })
}

tasks.register("checkNeoForgePlatformCompat") {
group = "verification"
description = "Compiles all NeoForge platform compatibility modules."
dependsOn(platformCompatProjects("neoforge").map { "${it.path}:compileJava" })
}

tasks.register("checkPlatformCompat") {
group = "verification"
description = "Compiles all platform compatibility modules."
dependsOn(tasks.named("checkFabricPlatformCompat"), tasks.named("checkNeoForgePlatformCompat"))
}

tasks.register("publishPlatformCompat") {
group = "publishing"
description = "Publishes all platform compatibility modules."
dependsOn(
platformCompatProjects("fabric").map { "${it.path}:publish" } +
platformCompatProjects("neoforge").map { "${it.path}:publish" }
)
}
17 changes: 12 additions & 5 deletions bukkit/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
extra.set("publishArtifactId", "bukkit")
extra.set("publishDocsUrl", "https://docs.faststats.dev/java/platform/bukkit")

plugins {
id("maven-publish")
}

java.toolchain.languageVersion = JavaLanguageVersion.of(25)

tasks.compileJava {
options.release.set(17)
}

configurations.compileClasspath {
attributes {
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
}
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 25)
}

repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}

dependencies {
Expand Down
13 changes: 12 additions & 1 deletion bukkit/example-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
plugins {
id("com.gradleup.shadow")
kotlin("jvm")
}

java.toolchain.languageVersion = JavaLanguageVersion.of(25)

tasks.compileJava {
options.release.set(25)
}

repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}

dependencies {
compileOnly("io.papermc.paper:paper-api:1.21.11-R0.1-SNAPSHOT")
compileOnly("io.papermc.paper:paper-api:26.2.build.+")
implementation(project(":bukkit"))
}

Expand Down
14 changes: 13 additions & 1 deletion bungeecord/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
val moduleName by extra("dev.faststats.bungee")
extra.set("moduleName", "dev.faststats.bungee")
extra.set("publishArtifactId", "bungeecord")
extra.set("publishDocsUrl", "https://docs.faststats.dev/java/platform/bungeecord")

plugins {
id("maven-publish")
}

java.toolchain.languageVersion = JavaLanguageVersion.of(17)

tasks.compileJava {
options.release.set(17)
}

repositories {
maven("https://repo.papermc.io/repository/maven-public/")
Expand Down
11 changes: 11 additions & 0 deletions bungeecord/example-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
plugins {
id("com.gradleup.shadow")
kotlin("jvm")
}

java.toolchain.languageVersion = JavaLanguageVersion.of(17)

tasks.compileJava {
options.release.set(17)
}

repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
Expand Down
13 changes: 13 additions & 0 deletions config/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
extra.set("publishArtifactId", "config")
extra.set("publishDocsUrl", "https://docs.faststats.dev/java") // todo: add dedicated docs

plugins {
id("maven-publish")
}

java.toolchain.languageVersion = JavaLanguageVersion.of(17)

tasks.compileJava {
options.release.set(17)
}

dependencies {
compileOnly(project(":core"))
}
13 changes: 13 additions & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
extra.set("publishArtifactId", "core")
extra.set("publishDocsUrl", "https://docs.faststats.dev/java") // todo: add dedicated docs

plugins {
id("maven-publish")
}

java.toolchain.languageVersion = JavaLanguageVersion.of(17)

tasks.compileJava {
options.release.set(17)
}

dependencies {
compileOnlyApi("com.google.code.gson:gson:2.14.0")
compileOnlyApi("org.jetbrains:annotations:26.1.0")
Expand Down
Loading
Loading