import io.papermc.paperweight.checkstyle.JavadocTag import paper.libs.com.google.gson.Gson plugins { `java-library` `maven-publish` // Infstar:API 模块基于 Paper API 源码生成。 idea // Paper Checkstyle 依赖上游复合构建中的 paper-checkstyle 模块,衍生核心暂不启用。 // id("io.papermc.paperweight.paper-checkstyle") } java { withSourcesJar() withJavadocJar() } val projectCustomJavadocTags = setOf( JavadocTag("apiNote", "a", "API Note:"), ) /* paperCheckstyle { customJavadocTags = projectCustomJavadocTags directoriesToSkipFile = layout.projectDirectory.file(".checkstyle/ignored_directories.txt") } */ val annotationsVersion = "26.1.0" val adventureVersion = "5.2.0" val bungeeCordChatVersion = "1.21-R0.2-deprecated+build.21" val slf4jVersion = "2.0.17" val log4jVersion = "2.26.0" val apiAndDocs: Configuration = configurations.create("apiAndDocs") configurations.api { extendsFrom(apiAndDocs) } val javadocSourcepath: Configuration = configurations.create("javadocSourcepath") { attributes { attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION)) attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named(DocsType.SOURCES)) attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) } } // Configure mockito agent that is needed in newer Java versions val mockitoAgent = configurations.register("mockitoAgent") abstract class MockitoAgentProvider : CommandLineArgumentProvider { @get:CompileClasspath abstract val fileCollection: ConfigurableFileCollection override fun asArguments(): Iterable { return listOf("-javaagent:" + fileCollection.files.single().absolutePath) } } dependencies { // api dependencies are listed transitively to API consumers api("com.google.guava:guava:33.6.0-jre") api("com.google.code.gson:gson:2.14.0") api("org.yaml:snakeyaml:2.2") api("org.joml:joml:1.10.9") api("it.unimi.dsi:fastutil:8.5.18") api("org.apache.logging.log4j:log4j-api:$log4jVersion") api("org.slf4j:slf4j-api:$slf4jVersion") api("com.mojang:brigadier:1.3.11") // Deprecate bungeecord-chat in favor of adventure api("net.md-5:bungeecord-chat:$bungeeCordChatVersion") { exclude("com.google.guava", "guava") } apiAndDocs(platform("net.kyori:adventure-bom:$adventureVersion")) apiAndDocs("net.kyori:adventure-api") apiAndDocs("net.kyori:adventure-key") apiAndDocs("net.kyori:adventure-text-minimessage") apiAndDocs("net.kyori:adventure-text-serializer-gson") apiAndDocs("net.kyori:adventure-text-serializer-legacy") apiAndDocs("net.kyori:adventure-text-serializer-plain") apiAndDocs("net.kyori:adventure-text-logger-slf4j") api("org.apache.maven:maven-resolver-provider:3.9.6") // make API dependency for Paper Plugins implementation("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18") implementation("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18") // Annotations - Slowly migrate to jspecify val annotations = "org.jetbrains:annotations:$annotationsVersion" compileOnly(annotations) testCompileOnly(annotations) javadocSourcepath(annotations) // For adventure-api module requirements val checkerQual = "org.checkerframework:checker-qual:4.2.3" compileOnlyApi(checkerQual) testCompileOnly(checkerQual) apiAndDocs("org.jspecify:jspecify:1.0.0") // Test dependencies testImplementation("org.apache.commons:commons-lang3:3.20.0") testImplementation("org.junit.jupiter:junit-jupiter:6.0.3") testImplementation("org.hamcrest:hamcrest:2.2") testImplementation("org.mockito:mockito-core:5.22.0") testImplementation("org.ow2.asm:asm-tree:9.9.1") mockitoAgent("org.mockito:mockito-core:5.22.0") { isTransitive = false } // configure mockito agent that is needed in newer java versions testRuntimeOnly("org.junit.platform:junit-platform-launcher:6.0.3") // checkstyle // checkstyle(project(":paper-checkstyle")) } val generatedDir: java.nio.file.Path = rootProject.layout.projectDirectory.dir("paper-api/src/generated/java").asFile.toPath() idea { module { generatedSourceDirs.add(generatedDir.toFile()) } } sourceSets { main { java { srcDir(generatedDir) srcDir(file("../paper-api/src/main/java")) } resources { srcDir(file("../paper-api/src/main/resources")) } } test { java { srcDir(file("../paper-api/src/test/java")) } resources { srcDir(file("../paper-api/src/test/resources")) } } } val outgoingVariants = arrayOf("runtimeElements", "apiElements", "sourcesElements", "javadocElements") val mainCapability = "${project.group}:${project.name}:${project.version}" configurations { val outgoing = outgoingVariants.map { named(it) } for (config in outgoing) { config { attributes { attribute(io.papermc.paperweight.util.mainCapabilityAttribute, mainCapability) } outgoing { capability(mainCapability) // Paper-MojangAPI has been merged into Paper-API capability("io.papermc.paper:paper-mojangapi:${project.version}") capability("com.destroystokyo.paper:paper-mojangapi:${project.version}") // Conflict with old coordinates capability("com.destroystokyo.paper:paper-api:${project.version}") capability("org.spigotmc:spigot-api:${project.version}") capability("org.bukkit:bukkit:${project.version}") } } } } configure { publications.create("maven") { // For Brigadier API outgoingVariants.forEach { suppressPomMetadataWarningsFor(it) } from(components["java"]) } } abstract class GenerateApiVersioningFile : DefaultTask() { @get:OutputFile abstract val outputFile: RegularFileProperty @get:Input abstract val projectVersion: Property @get:Input abstract val apiVersion: Property @TaskAction fun generate() { val file = outputFile.get().asFile file.parentFile.mkdirs() val map = mapOf( "version" to projectVersion.get(), "currentApiVersion" to apiVersion.get() ) file.writeText(Gson().toJson(map)) } } val generateApiVersioningFile = tasks.register("generateApiVersioningFile") { outputFile.set(layout.buildDirectory.file("apiVersioning.json")) projectVersion.set(project.version.toString()) apiVersion.set(rootProject.providers.gradleProperty("apiVersion")) } tasks.jar { from(generateApiVersioningFile.flatMap { it.outputFile }) manifest { attributes( "Automatic-Module-Name" to "org.bukkit" ) } } abstract class Services { @get:Inject abstract val fileSystemOperations: FileSystemOperations } val services = objects.newInstance() tasks.withType().configureEach { val options = options as StandardJavadocDocletOptions options.overview = "src/main/javadoc/overview.html" options.use() options.isDocFilesSubDirs = true options.links( "https://guava.dev/releases/33.6.0-jre/api/docs/", "https://www.javadocs.dev/org.yaml/snakeyaml/2.2/", "https://www.javadocs.dev/org.jetbrains/annotations/$annotationsVersion/", "https://www.javadocs.dev/org.joml/joml/1.10.9/", "https://www.javadocs.dev/com.google.code.gson/gson/2.14.0", "https://jspecify.dev/docs/api/", "https://jd.papermc.io/adventure/$adventureVersion/", "https://www.javadocs.dev/org.slf4j/slf4j-api/$slf4jVersion/", "https://logging.apache.org/log4j/2.x/javadoc/log4j-api/", "https://www.javadocs.dev/org.apache.maven.resolver/maven-resolver-api/1.7.3", ) options.tags(projectCustomJavadocTags.map { it.toOptionString() }) inputs.files(javadocSourcepath).ignoreEmptyDirectories().withPropertyName(javadocSourcepath.name + "-configuration") val javadocSourcepathElements = javadocSourcepath.elements doFirst { options.addStringOption( "sourcepath", javadocSourcepathElements.get().map { it.asFile }.joinToString(separator = File.pathSeparator, transform = File::getPath) ) } // workaround for https://github.com/gradle/gradle/issues/4046 inputs.dir("src/main/javadoc").withPropertyName("javadoc-sourceset") val fsOps = services.fileSystemOperations doLast { fsOps.copy { from("src/main/javadoc") { include("**/doc-files/**") } into("build/docs/javadoc") } } } tasks.test { useJUnitPlatform() // configure mockito agent that is needed in newer java versions val provider = objects.newInstance() provider.fileCollection.from(mockitoAgent) jvmArgumentProviders.add(provider) } // Compile tests with -parameters for better junit parameterized test names tasks.compileTestJava { options.compilerArgs.add("-parameters") } val scanJarForBadCalls = tasks.register("scanJarForBadCalls") { badAnnotations.add("Lio/papermc/paper/annotation/DoNotUse;") jarToScan.set(tasks.jar.flatMap { it.archiveFile }) classpath.from(configurations.compileClasspath) } tasks.check { dependsOn(scanJarForBadCalls) }