From 1b543bbdfe4cf5f8a14da88b6c2b28a401110aaa Mon Sep 17 00:00:00 2001 From: Chrys Chrysanthemum Date: Mon, 6 Jul 2026 21:24:19 +1000 Subject: [PATCH] build: Reimplement API JAR and build script refactors. --- .forgejo/workflows/publish-all.yml | 5 - README.md | 11 +- .../greenhouse/config/gradle/Properties.kt | 2 +- .../config/gradle/base/api.gradle.kts | 49 ++- .../config/gradle/base/java.gradle.kts | 9 +- .../config/gradle/base/merge.gradle.kts | 284 +++++++++++------- .../config/gradle/base/publish.gradle.kts | 33 ++ .../config/gradle/base/root.gradle.kts | 2 +- .../config/gradle/platform/fabric.gradle.kts | 22 +- .../config/gradle/platform/loader.gradle.kts | 12 +- .../gradle/platform/neoforge.gradle.kts | 2 + .../config/gradle/platform/xplat.gradle.kts | 2 +- fabric/build.gradle.kts | 20 +- .../greenhouse_config_testmod.classtweaker | 0 neoforge/build.gradle.kts | 11 +- 15 files changed, 306 insertions(+), 158 deletions(-) rename {xplat => fabric}/src/testmod/resources/greenhouse_config_testmod.classtweaker (100%) diff --git a/.forgejo/workflows/publish-all.yml b/.forgejo/workflows/publish-all.yml index c17046f..87b3cfb 100644 --- a/.forgejo/workflows/publish-all.yml +++ b/.forgejo/workflows/publish-all.yml @@ -31,11 +31,6 @@ jobs: - name: Build with Gradle run: ./gradlew build - - name: Publish to CurseForge - env: - CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} - run: ./gradlew publishCurseforge - - name: Publish to Modrinth env: MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} diff --git a/README.md b/README.md index 4eae437..20fd7eb 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ users have to download a separate dependency just to play with your mod. The below is for Kotlin DSL, you will need to adjust this for Groovy DSL. ```kotlin +val greenhouseModdingApiAttribute = Attribute.of("lgbt.greenhouse.modding.api", String::class.java) + repositories { maven("https://maven.greenhouse.lgbt/releases") { name = "Greenhouse Maven" @@ -32,11 +34,16 @@ repositories { dependencies { // Depend on the Cross-Platform/Loader Independent API. - compileOnly("lgbt.greenhouse.config:greenhouse-config-api:${greenhouse_config_version}") + compileOnly("lgbt.greenhouse.config:greenhouse-config:${greenhouse_config_version}") { + attributes { + attribute(greenhouseModdingApiAttribute, "") // The value must remain empty. + } + } // Depend on the Fabric project, for Loom. runtimeOnly("lgbt.greenhouse.config:greenhouse-config-fabric:${greenhouse_config_version}") - include("lgbt.greenhouse.config:greenhouse-config-fabric:${greenhouse_config_version}") + + include("lgbt.greenhouse.config:greenhouse-config:${greenhouse_config_version}") // Depend on the NeoForge project, for ModDevGradle. runtimeOnly("lgbt.greenhouse.config:greenhouse-config-neoforge:${greenhouse_config_version}") diff --git a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/Properties.kt b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/Properties.kt index a8ddb75..f92ae01 100644 --- a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/Properties.kt +++ b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/Properties.kt @@ -8,7 +8,7 @@ object Properties { const val GROUP = "lgbt.greenhouse.config" const val MOD_NAME = "Greenhouse Config" const val MOD_ID = "greenhouse_config" - const val ARCHIVES_MOD_ID = "greenhouse-config" + val ARCHIVES_BASE_NAME = MOD_ID.replace("_", "-") const val MOD_AUTHOR = "Greenhouse Modding" val MOD_CONTRIBUTORS = listOf("ChrysanthCow", "Kneelawk") const val DESCRIPTION = "Powerful codec oriented config library made for my own use case." diff --git a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/api.gradle.kts b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/api.gradle.kts index ac80ee1..f2211fb 100644 --- a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/api.gradle.kts +++ b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/api.gradle.kts @@ -1,31 +1,37 @@ package lgbt.greenhouse.config.gradle.base +import lgbt.greenhouse.config.gradle.ModPlatform import lgbt.greenhouse.config.gradle.Properties import org.gradle.jvm.component.internal.DefaultJvmSoftwareComponent -import org.gradle.jvm.component.internal.JvmSoftwareComponentInternal import org.gradle.jvm.tasks.Jar plugins { id("lgbt.greenhouse.config.gradle.base.java") - id("lgbt.greenhouse.config.gradle.base.publish") } -val greenhouseModdingPlatformAttribute = Attribute.of("lgbt.greenhouse.modding.platform", String::class.java) -val apiComponent = components.create("api") as DefaultJvmSoftwareComponent +val javaComponent = components.getByName("java") +val platform = ModPlatform.getProjectPlatform(project.name) + +val greenhouseModdingApiAttribute = Attribute.of("lgbt.greenhouse.modding.api", String::class.java) configurations { - register("apiCompileElements") + register("apiApiElements") { + isCanBeConsumed = true + isCanBeResolved = false + } } tasks { register("apiJar") { - archiveBaseName.set(Properties.ARCHIVES_MOD_ID) - archiveClassifier = "api" + description = "Assembles a jar archive containing only the API classes of the 'main' feature." + archiveBaseName.set(Properties.ARCHIVES_BASE_NAME) + archiveClassifier = "api-${platform.platformName}" dependsOn(named("jar")) - from(zipTree(getByName("jar").archiveFile)) - includes.add("lgbt/greenhouse/config/api/v3/**") + + var platform = if (!platform.isXplat()) "/${platform.platformName}" else "" + includes.add("lgbt/greenhouse/config${platform}/api/v3/**") } } @@ -34,7 +40,7 @@ tasks.getByName("assemble").dependsOn("apiJar") project.afterEvaluate { val main = sourceSets["main"] - configurations.getByName("apiCompileElements") { + configurations.getByName("apiApiElements") { extendsFrom(configurations[main.apiConfigurationName]) attributes { attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category::class, Category.LIBRARY)) @@ -48,35 +54,18 @@ project.afterEvaluate { if (languageVersion.isPresent) { attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, languageVersion.get().asInt()) } - attribute(greenhouseModdingPlatformAttribute, "api") + attribute(greenhouseModdingApiAttribute, "") } } artifacts.add( - "apiCompileElements", + "apiApiElements", tasks.getByName("apiJar") ) { classifier = "api" } - - apiComponent.addVariantsFromConfiguration(configurations["apiCompileElements"]) { + javaComponent.addVariantsFromConfiguration(configurations["apiApiElements"]) { mapToMavenScope("compile") mapToOptional() } - - apiComponent.addVariantsFromConfiguration(configurations[main.sourcesElementsConfigurationName]) { - mapToOptional() - } - apiComponent.addVariantsFromConfiguration(configurations[main.javadocElementsConfigurationName]) { - mapToOptional() - } -} - -publishing { - publications { - create("mavenJavaApi") { - artifactId = Properties.ARCHIVES_MOD_ID + "-api" - from(components["api"]) - } - } } diff --git a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/java.gradle.kts b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/java.gradle.kts index 89637b7..db1aee8 100644 --- a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/java.gradle.kts +++ b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/java.gradle.kts @@ -39,17 +39,12 @@ configurations { named("testmodCompileClasspath") { extendsFrom(configurations["compileClasspath"]) } - register("testmodOutput") { - isCanBeResolved = false + register("platformApi") { + isCanBeResolved = true isCanBeConsumed = true } } -artifacts { - add("testmodOutput", sourceSets["testmod"].output.classesDirs.singleFile) - add("testmodOutput", sourceSets["testmod"].output.resourcesDir!!) -} - tasks { named("jar") { from(rootProject.file("LICENSE")) { diff --git a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/merge.gradle.kts b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/merge.gradle.kts index 205b7ee..3232bf0 100644 --- a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/merge.gradle.kts +++ b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/merge.gradle.kts @@ -5,25 +5,27 @@ package lgbt.greenhouse.config.gradle.base import lgbt.greenhouse.config.gradle.ModPlatform import lgbt.greenhouse.config.gradle.Properties import org.gradle.accessors.dm.LibrariesForLibs +import org.gradle.api.internal.tasks.JvmConstants +import org.gradle.api.publish.internal.component.DefaultAdhocSoftwareComponent import org.gradle.jvm.component.internal.DefaultJvmSoftwareComponent +import org.gradle.kotlin.dsl.get +import org.gradle.kotlin.dsl.invoke plugins { id("lgbt.greenhouse.config.gradle.base.java") } -val excludedSourceSets = setOf("generated") - // https://github.com/gradle/gradle/issues/15383#issuecomment-779893192 val libs = the() val platform = ModPlatform.getProjectPlatform(project.name) -val xplatProject = ":xplat" -val fabricProject = ":fabric" -val neoforgeProject = ":neoforge" val greenhouseModdingPlatformAttribute = Attribute.of("lgbt.greenhouse.modding.platform", String::class.java) +val greenhouseModdingApiAttribute = Attribute.of("lgbt.greenhouse.modding.api", String::class.java) val mcGradleConventionsAttribute = Attribute.of("io.github.mcgradleconventions.loader", String::class.java) +val hasApi = configurations.findByName("apiApiElements") != null + configurations { val xplatClasspath = setOf( "compileClasspath", @@ -36,14 +38,10 @@ configurations { } outgoing { capabilities.clear() - capability("${group}:${Properties.ARCHIVES_MOD_ID}-xplat:${version}") + capability("${group}:${Properties.ARCHIVES_BASE_NAME}-xplat:${version}") } } - createPlatformOutput(ModPlatform.XPLAT) - createPlatformOutput(ModPlatform.FABRIC) - createPlatformOutput(ModPlatform.NEOFORGE) - createPlatformClasspaths(ModPlatform.FABRIC) createPlatformClasspaths(ModPlatform.NEOFORGE) @@ -51,57 +49,54 @@ configurations { createPlatformElements(ModPlatform.FABRIC) createPlatformElements(ModPlatform.NEOFORGE) - register("interfaceInjectionDataElements") { - isCanBeConsumed = true - isCanBeResolved = false + if (neoforgeInterfaceInjectionsFile().exists()) { + register("interfaceInjectionDataElements") { + isCanBeConsumed = true + isCanBeResolved = false - attributes { - attribute( - Category.CATEGORY_ATTRIBUTE, - project.objects.named(Category.CATEGORY_ATTRIBUTE.getType(), "interfaceinjection") - ) + attributes { + attribute( + Category.CATEGORY_ATTRIBUTE, + project.objects.named(Category.CATEGORY_ATTRIBUTE.getType(), "interfaceinjection") + ) + } } - } - register("neoforgeInterfaceInjectionDataElements") { - isCanBeConsumed = true - isCanBeResolved = false + register("neoforgeInterfaceInjectionDataElements") { + isCanBeConsumed = true + isCanBeResolved = false - attributes { - attribute(greenhouseModdingPlatformAttribute, "neoforge") - attribute(mcGradleConventionsAttribute, "neoforge") + attributes { + attribute(greenhouseModdingPlatformAttribute, "neoforge") + attribute(mcGradleConventionsAttribute, "neoforge") - attribute( - Category.CATEGORY_ATTRIBUTE, - project.objects.named(Category.CATEGORY_ATTRIBUTE.getType(), "interfaceinjection") - ) + attribute( + Category.CATEGORY_ATTRIBUTE, + project.objects.named(Category.CATEGORY_ATTRIBUTE.getType(), "interfaceinjection") + ) + } } } } dependencies { - "fabricCompileClasspath"(project(fabricProject, "compileClasspath")) - "neoforgeCompileClasspath"(project(neoforgeProject, "compileClasspath")) - - "fabricApiElements"(project(fabricProject, "apiElements")) - "neoforgeApiElements"(project(neoforgeProject, "apiElements")) - - "fabricRuntimeElements"(project(fabricProject, "runtimeElements")) - "neoforgeRuntimeElements"(project(neoforgeProject, "runtimeElements")) - - "fabricJavadocElements"(project(fabricProject, "javadocElements")) - "neoforgeJavadocElements"(project(neoforgeProject, "javadocElements")) + "fabricCompileClasspath"(project(":fabric", "compileClasspath")) + "neoforgeCompileClasspath"(project(":neoforge", "compileClasspath")) - "fabricSourcesElements"(project(fabricProject, "sourcesElements")) - "neoforgeSourcesElements"(project(neoforgeProject, "sourcesElements")) + "xplatApiElements"(project(":xplat", "platformApi")) + "fabricApiElements"(project(":fabric", "platformApi")) + "neoforgeApiElements"(project(":neoforge", "platformApi")) - "interfaceInjectionDataElements"(project(neoforgeProject, "interfaceInjectionDataElements")) - "neoforgeInterfaceInjectionDataElements"(project(neoforgeProject, "interfaceInjectionDataElements")) + if (hasApi) { + "xplatApiApiElements"(project(":xplat", "apiApiElements")) + "fabricApiApiElements"(project(":fabric", "apiApiElements")) + "neoforgeApiApiElements"(project(":neoforge", "apiApiElements")) + } } val mergeJar = tasks.register("mergeJar") { description = "Assembles a jar archive containing the classes of the 'main' feature from all submodules." - archiveBaseName.set(Properties.ARCHIVES_MOD_ID) + archiveBaseName.set(Properties.ARCHIVES_BASE_NAME) destinationDirectory.set(project.rootDir.resolve("build/libs")) duplicatesStrategy = DuplicatesStrategy.EXCLUDE @@ -110,19 +105,17 @@ val mergeJar = tasks.register("mergeJar") { val mergeJavadocJar = tasks.register("mergeJavadocJar") { description = "Assembles a jar archive containing the main javadocs from all submodules." - archiveBaseName.set(Properties.ARCHIVES_MOD_ID) + archiveBaseName.set(Properties.ARCHIVES_BASE_NAME) archiveClassifier.set("javadoc") destinationDirectory.set(project.rootDir.resolve("build/libs")) - // Idk how to avoid this ngl. duplicatesStrategy = DuplicatesStrategy.EXCLUDE } val mergeSourcesJar = tasks.register("mergeSourcesJar") { description = "Assembles a jar archive containing the main javadocs from all sources." - - archiveBaseName.set(Properties.ARCHIVES_MOD_ID) + archiveBaseName.set(Properties.ARCHIVES_BASE_NAME) archiveClassifier.set("sources") destinationDirectory.set(project.rootDir.resolve("build/libs")) @@ -138,10 +131,10 @@ tasks.named("assemble") { } afterEvaluate { - val apiElementsName = sourceSets["main"].apiElementsConfigurationName - val runtimeElementsName = sourceSets["main"].runtimeElementsConfigurationName - val javadocElementsName = sourceSets["main"].javadocElementsConfigurationName - val sourcesElementsName = sourceSets["main"].sourcesElementsConfigurationName + val apiElementsName = JvmConstants.API_ELEMENTS_CONFIGURATION_NAME + val runtimeElementsName = JvmConstants.RUNTIME_ELEMENTS_CONFIGURATION_NAME + val javadocElementsName = JvmConstants.JAVADOC_ELEMENTS_CONFIGURATION_NAME + val sourcesElementsName = JvmConstants.SOURCES_ELEMENTS_CONFIGURATION_NAME configurations[apiElementsName].artifacts.clear() artifacts.add(apiElementsName, mergeJar.get().archiveFile) @@ -156,49 +149,66 @@ afterEvaluate { artifacts.add(sourcesElementsName, mergeSourcesJar.get().archiveFile) artifacts { - add("xplatApiElements", jarPath("xplat", "")) { + addApiArtifact(ModPlatform.XPLAT) + addApiArtifact(ModPlatform.FABRIC) + addApiArtifact(ModPlatform.NEOFORGE) + + add("xplatApiElements", jarFile("xplat", "")) { classifier = "xplat" } add("xplatRuntimeElements", mergeJar.get().archiveFile) { builtBy(mergeJar.get()) } - add("xplatJavadocElements", jarPath("xplat", "javadoc")) { - classifier = "xplat-javadoc" + add("xplatJavadocElements", jarFile("xplat", "javadoc")) { + classifier = "javadoc-xplat" } - add("xplatSourcesElements", jarPath("xplat", "sources")) { - classifier = "xplat-sources" + add("xplatSourcesElements", jarFile("xplat", "sources")) { + classifier = "sources-xplat" } - add("fabricApiElements", jarPath("fabric", "")) { + add("fabricApiElements", jarFile("fabric", "")) { classifier = "fabric" } add("fabricRuntimeElements", mergeJar.get().archiveFile) { builtBy(mergeJar.get()) } - add("fabricJavadocElements", jarPath("fabric", "javadoc")) { - classifier = "fabric-javadoc" + add("fabricJavadocElements", jarFile("fabric", "javadoc")) { + classifier = "javadoc-fabric" } - add("fabricSourcesElements", jarPath("fabric", "sources")) { - classifier = "fabric-sources" + add("fabricSourcesElements", jarFile("fabric", "sources")) { + classifier = "sources-fabric" } - add("neoforgeApiElements", jarPath("neoforge", "")) { + add("neoforgeApiElements", jarFile("neoforge", "")) { classifier = "neoforge" } add("neoforgeRuntimeElements", mergeJar.get().archiveFile) { builtBy(mergeJar.get()) } - add("neoforgeJavadocElements", jarPath("neoforge", "javadoc")) { - classifier = "neoforge-javadoc" + add("neoforgeJavadocElements", jarFile("neoforge", "javadoc")) { + classifier = "javadoc-neoforge" } - add("neoforgeSourcesElements", jarPath("neoforge", "sources")) { - classifier = "neoforge-sources" + add("neoforgeSourcesElements", jarFile("neoforge", "sources")) { + classifier = "sources-neoforge" + } + + if (neoforgeInterfaceInjectionsFile().exists()) { + add("interfaceInjectionDataElements", neoforgeInterfaceInjectionsFile()) { + classifier = "interfaceinjection" + } + add("neoforgeInterfaceInjectionDataElements", neoforgeInterfaceInjectionsFile()) { + classifier = "neoforge-interfaceinjection" + } } } @Suppress("UnstableApiUsage") components { named("java") { + addVariantsFromApiConfiguration(ModPlatform.XPLAT) + addVariantsFromApiConfiguration(ModPlatform.FABRIC) + addVariantsFromApiConfiguration(ModPlatform.NEOFORGE) + addVariantsFromConfiguration(configurations["fabricApiElements"]) { mapToMavenScope("compile") mapToOptional() @@ -241,12 +251,22 @@ afterEvaluate { addVariantsFromConfiguration(configurations["xplatSourcesElements"]) { mapToOptional() } - addVariantsFromConfiguration(configurations["neoforgeInterfaceInjectionDataElements"]) { - mapToOptional() - if (configurationVariant.artifacts.isEmpty()) { - skip() + + if (neoforgeInterfaceInjectionsFile().exists()) { + addVariantsFromConfiguration(configurations["interfaceInjectionDataElements"]) { + mapToOptional() + if (configurationVariant.artifacts.isEmpty()) { + skip() + } + } + addVariantsFromConfiguration(configurations["neoforgeInterfaceInjectionDataElements"]) { + mapToOptional() + if (configurationVariant.artifacts.isEmpty()) { + skip() + } } } + withVariantsFromConfiguration(configurations[apiElementsName]) { mapToOptional() } @@ -263,19 +283,12 @@ afterEvaluate { } } -fun ConfigurationContainer.createPlatformOutput(modPlatform: ModPlatform) { - register("${modPlatform.platformName}Output") { - isCanBeConsumed = false - isCanBeResolved = true - } -} - fun ConfigurationContainer.createPlatformClasspaths(modPlatform: ModPlatform) { - val compileClasspathConfigurationName = sourceSets["main"].compileClasspathConfigurationName + val compileClasspathConfigurationName = JvmConstants.COMPILE_CLASSPATH_CONFIGURATION_NAME register(modPlatform.mapConfigurationName(compileClasspathConfigurationName)) { isCanBeConsumed = true isCanBeResolved = false - extendsFrom(configurations[compileClasspathConfigurationName]) + attributes { attribute(greenhouseModdingPlatformAttribute, modPlatform.platformName) attribute(mcGradleConventionsAttribute, modPlatform.mcGradleConventionsName) @@ -295,15 +308,15 @@ fun ConfigurationContainer.createPlatformClasspaths(modPlatform: ModPlatform) { } outgoing { capabilities.clear() - capability("${group}:${Properties.ARCHIVES_MOD_ID}-${modPlatform.platformName}:${version}") + capability("${group}:${Properties.ARCHIVES_BASE_NAME}-${modPlatform.platformName}:${version}") } } - val runtimeClasspathConfigurationName = sourceSets["main"].runtimeClasspathConfigurationName + val runtimeClasspathConfigurationName = JvmConstants.RUNTIME_CLASSPATH_CONFIGURATION_NAME register(modPlatform.mapConfigurationName(runtimeClasspathConfigurationName)) { isCanBeConsumed = true isCanBeResolved = false - extendsFrom(configurations[runtimeClasspathConfigurationName]) + attributes { attribute(greenhouseModdingPlatformAttribute, modPlatform.platformName) attribute(mcGradleConventionsAttribute, modPlatform.mcGradleConventionsName) @@ -323,22 +336,46 @@ fun ConfigurationContainer.createPlatformClasspaths(modPlatform: ModPlatform) { } outgoing { capabilities.clear() - capability("${group}:${Properties.ARCHIVES_MOD_ID}-${modPlatform.platformName}:${version}") + capability("${group}:${Properties.ARCHIVES_BASE_NAME}-${modPlatform.platformName}:${version}") } } } fun ConfigurationContainer.createPlatformElements(modPlatform: ModPlatform) { - val apiElementsConfigurationName = sourceSets["main"].apiElementsConfigurationName - val runtimeElementsConfigurationName = sourceSets["main"].runtimeElementsConfigurationName - val javadocElementsConfigurationName = sourceSets["main"].javadocElementsConfigurationName - val sourcesElementsConfigurationName = sourceSets["main"].sourcesElementsConfigurationName + val apiElementsConfigurationName = JvmConstants.API_ELEMENTS_CONFIGURATION_NAME + val runtimeElementsConfigurationName = JvmConstants.RUNTIME_ELEMENTS_CONFIGURATION_NAME + val javadocElementsConfigurationName = JvmConstants.JAVADOC_ELEMENTS_CONFIGURATION_NAME + val sourcesElementsConfigurationName = JvmConstants.SOURCES_ELEMENTS_CONFIGURATION_NAME + + if (hasApi) { + register(modPlatform.mapConfigurationName("apiApiElements")) { + isCanBeConsumed = true + isCanBeResolved = false + + attributes { + attribute(greenhouseModdingPlatformAttribute, modPlatform.platformName) + attribute(mcGradleConventionsAttribute, modPlatform.mcGradleConventionsName) + + attribute(greenhouseModdingApiAttribute, "") + + attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category::class, Category.LIBRARY)) + attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class, Usage.JAVA_API)) + attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling::class, Bundling.EXTERNAL)) + attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements::class, LibraryElements.JAR)) + attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, java.toolchain.languageVersion.get().asInt()) + } + outgoing { + capabilities.clear() + capability("${group}:${Properties.ARCHIVES_BASE_NAME}-${modPlatform.platformName}:${version}") + } + } + } if (configurations.findByName(apiElementsConfigurationName) != null) { register(modPlatform.mapConfigurationName(apiElementsConfigurationName)) { - isCanBeConsumed = false - isCanBeResolved = true - extendsFrom(configurations[apiElementsConfigurationName]) + isCanBeConsumed = true + isCanBeResolved = false + attributes { attribute(greenhouseModdingPlatformAttribute, modPlatform.platformName) attribute(mcGradleConventionsAttribute, modPlatform.mcGradleConventionsName) @@ -351,14 +388,17 @@ fun ConfigurationContainer.createPlatformElements(modPlatform: ModPlatform) { } outgoing { capabilities.clear() - capability("${group}:${Properties.ARCHIVES_MOD_ID}-${modPlatform.platformName}:${version}") + capability("${group}:${Properties.ARCHIVES_BASE_NAME}-${modPlatform.platformName}:${version}") } } } if (configurations.findByName(runtimeElementsConfigurationName) != null) { register(modPlatform.mapConfigurationName(runtimeElementsConfigurationName)) { + isCanBeConsumed = false isCanBeResolved = true - extendsFrom(configurations[runtimeElementsConfigurationName]) + + extendsFrom(configurations.getByName("api")) + attributes { attribute(greenhouseModdingPlatformAttribute, modPlatform.platformName) attribute(mcGradleConventionsAttribute, modPlatform.mcGradleConventionsName) @@ -371,14 +411,15 @@ fun ConfigurationContainer.createPlatformElements(modPlatform: ModPlatform) { } outgoing { capabilities.clear() - capability("${group}:${Properties.ARCHIVES_MOD_ID}-${modPlatform.platformName}:${version}") + capability("${group}:${Properties.ARCHIVES_BASE_NAME}-${modPlatform.platformName}:${version}") } } } if (configurations.findByName(javadocElementsConfigurationName) != null) { register(modPlatform.mapConfigurationName(javadocElementsConfigurationName)) { + isCanBeConsumed = false isCanBeResolved = true - extendsFrom(configurations[javadocElementsConfigurationName]) + attributes { attribute(greenhouseModdingPlatformAttribute, modPlatform.platformName) attribute(mcGradleConventionsAttribute, modPlatform.mcGradleConventionsName) @@ -390,14 +431,15 @@ fun ConfigurationContainer.createPlatformElements(modPlatform: ModPlatform) { } outgoing { capabilities.clear() - capability("${group}:${Properties.ARCHIVES_MOD_ID}-${modPlatform.platformName}:${version}") + capability("${group}:${Properties.ARCHIVES_BASE_NAME}-${modPlatform.platformName}:${version}") } } } if (configurations.findByName(sourcesElementsConfigurationName) != null) { register(modPlatform.mapConfigurationName(sourcesElementsConfigurationName)) { + isCanBeConsumed = false isCanBeResolved = true - extendsFrom(configurations[sourcesElementsConfigurationName]) + attributes { attribute(greenhouseModdingPlatformAttribute, modPlatform.platformName) attribute(mcGradleConventionsAttribute, modPlatform.mcGradleConventionsName) @@ -409,14 +451,54 @@ fun ConfigurationContainer.createPlatformElements(modPlatform: ModPlatform) { } outgoing { capabilities.clear() - capability("${group}:${Properties.ARCHIVES_MOD_ID}-${modPlatform.platformName}:${version}") + capability("${group}:${Properties.ARCHIVES_BASE_NAME}-${modPlatform.platformName}:${version}") } } } } -fun jarPath(projectName: String, classifier: String): File { +fun jarFile(projectName: String, classifier: String): File { val finalClassifier: String = if (!classifier.isBlank()) "-${classifier}" else classifier - return rootProject.file("${projectName}/build/libs/${Properties.ARCHIVES_MOD_ID}-${Properties.MOD_VERSION}+${Properties.FRIENDLY_MINECRAFT_VERSION}${finalClassifier}-${projectName}.jar") + return rootProject.file("${projectName}/build/libs/${Properties.ARCHIVES_BASE_NAME}-${Properties.MOD_VERSION}+${Properties.FRIENDLY_MINECRAFT_VERSION}${finalClassifier}-${projectName}.jar") +} + +fun neoforgeInterfaceInjectionsFile(): File { + return rootProject.file("neoforge/interfaces.json") +} + +fun ArtifactHandler.addApiArtifact(modPlatform: ModPlatform) { + if (!hasApi) return + + val apiJar = jarFile(modPlatform.platformName, "api") + if (apiJar.exists()) { + add("${modPlatform.platformName}ApiApiElements", apiJar) { + classifier = "${modPlatform.platformName}-api" + } + } + + val xplatApiJar = jarFile("xplat", "api") + if (xplatApiJar.exists()) { + add("${modPlatform.platformName}ApiApiElements", xplatApiJar) { + classifier = "xplat-api" + } + } } +fun DefaultAdhocSoftwareComponent.addVariantsFromApiConfiguration(modPlatform: ModPlatform) { + if (!hasApi) + return + + addVariantsFromConfiguration(configurations[modPlatform.mapConfigurationName("apiApiElements")]) { + mapToMavenScope("compile") + mapToOptional() + if (configurationVariant.artifacts.isEmpty()) { + skip() + } + } + addVariantsFromConfiguration(configurations[modPlatform.mapConfigurationName(JvmConstants.JAVADOC_ELEMENTS_CONFIGURATION_NAME)]) { + mapToOptional() + } + addVariantsFromConfiguration(configurations[modPlatform.mapConfigurationName(JvmConstants.SOURCES_ELEMENTS_CONFIGURATION_NAME)]) { + mapToOptional() + } +} diff --git a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/publish.gradle.kts b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/publish.gradle.kts index 623b812..680a9e5 100644 --- a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/publish.gradle.kts +++ b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/publish.gradle.kts @@ -10,11 +10,21 @@ plugins { val fabricProject = project(":fabric") val neoforgeProject = project(":neoforge") +val hasApi = components.findByName("api") != null + publishing { publications { create("mavenJava") { artifactId = base.archivesName.get() from(components["java"]) + suppressAllPomMetadataWarnings() + } + if (hasApi) { + create("mavenJavaApi") { + artifactId = base.archivesName.get() + from(components["api"]) + suppressAllPomMetadataWarnings() + } } } repositories { @@ -40,5 +50,28 @@ afterEvaluate { dependsOn(neoforgeProject.tasks["jar"]) dependsOn(neoforgeProject.tasks["javadocJar"]) dependsOn(neoforgeProject.tasks["sourcesJar"]) + + if (hasApi) { + val fabricApiJar = fabricProject.tasks.findByName("apiJar") + val neoforgeApiJar = neoforgeProject.tasks.findByName("apiJar") + + dependsOn(tasks["apiJar"]) + + if (fabricApiJar != null) { + dependsOn(fabricApiJar) + } + if (neoforgeApiJar != null) { + dependsOn(neoforgeApiJar) + } + + dependsOn(tasks["javadocJar"]) + dependsOn(tasks["sourcesJar"]) + + dependsOn(fabricProject.tasks["javadocJar"]) + dependsOn(fabricProject.tasks["sourcesJar"]) + + dependsOn(neoforgeProject.tasks["javadocJar"]) + dependsOn(neoforgeProject.tasks["sourcesJar"]) + } } } diff --git a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/root.gradle.kts b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/root.gradle.kts index 3fcd865..3157b1f 100644 --- a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/root.gradle.kts +++ b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/base/root.gradle.kts @@ -19,7 +19,7 @@ val platformAttribute = Attribute.of("lgbt.greenhouse.modding.platform", String: // Cursed but it works! plugins.apply(libs.plugins.yumi.licenser.get().pluginId) -base.archivesName.set(Properties.MOD_ID) +base.archivesName.set(Properties.ARCHIVES_BASE_NAME) group = Properties.GROUP version = "${Properties.MOD_VERSION}+${Properties.FRIENDLY_MINECRAFT_VERSION}" diff --git a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/fabric.gradle.kts b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/fabric.gradle.kts index eb6e1ff..777f74c 100644 --- a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/fabric.gradle.kts +++ b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/fabric.gradle.kts @@ -11,15 +11,31 @@ plugins { // https://github.com/gradle/gradle/issues/15383#issuecomment-779893192 val libs = the() + val xplatProject = project(":xplat") -val platformAttribute = Attribute.of("lgbt.greenhouse.modding.platform", String::class.java) // Cursed but it works! plugins.apply(libs.plugins.loom.get().pluginId) +sourceSets { + getByName("testmod") { + // Loom seems to only like it when I do this, annoying but reasonable for it to do the bare minimum within the 'mods' block. + runtimeClasspath += sourceSets["main"].output + } +} + xplatProject.tasks { named("mergeJar") { - dependsOn(tasks["processIncludeJars"]) + dependsOn(tasks["jar"]) + from(zipTree(tasks.getByName("jar").archiveFile.get())) + } + named("mergeJavadocJar") { + dependsOn(tasks["javadocJar"]) + from(zipTree(tasks.getByName("javadocJar").archiveFile.get())) + } + named("mergeSourcesJar") { + dependsOn(tasks["sourcesJar"]) + from(zipTree(tasks.getByName("sourcesJar").archiveFile.get())) } } @@ -44,7 +60,7 @@ dependencies { } extensions.configure("loom") { - val ct = xplatProject.file("src/main/resources/${Properties.MOD_ID}.classtweaker") + val ct = file("src/testmod/resources/${Properties.MOD_ID}.classtweaker") if (ct.exists()) accessWidenerPath.set(ct) } diff --git a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/loader.gradle.kts b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/loader.gradle.kts index 117a18b..191c0ab 100644 --- a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/loader.gradle.kts +++ b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/loader.gradle.kts @@ -25,7 +25,6 @@ sourceSets { runtimeClasspath += xplatProject.sourceSets["testmod"].output // Loom seems to only like it when I do this, annoying but reasonable for it to do the bare minimum within the 'mods' block. - runtimeClasspath += sourceSets["main"].output runtimeClasspath += xplatProject.sourceSets["main"].output } } @@ -52,6 +51,17 @@ configurations { } dependencies { + compileOnlyApi(project(":xplat")) { + attributes { + attribute(platformAttribute, ":xplat") + } + } + "platformApi"(project(":xplat")) { + attributes { + attribute(platformAttribute, ":xplat") + } + } + api(libs.yumi.mc.foundation) api(libs.polyamory) { diff --git a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/neoforge.gradle.kts b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/neoforge.gradle.kts index 841a7ab..af5c443 100644 --- a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/neoforge.gradle.kts +++ b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/neoforge.gradle.kts @@ -44,6 +44,7 @@ dependencies { "include"(libs.polyamory.lang.jsonc) } + tasks { getByName("processResources") { dependsOn(xplatProject.tasks.getByName("processResources")) @@ -53,6 +54,7 @@ tasks { } } + extensions.configure("neoForge") { version = libs.versions.neoforge.get() diff --git a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/xplat.gradle.kts b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/xplat.gradle.kts index 0b5fefb..c62323e 100644 --- a/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/xplat.gradle.kts +++ b/build_logic/src/main/kotlin/lgbt/greenhouse/config/gradle/platform/xplat.gradle.kts @@ -61,7 +61,7 @@ dependencies { } extensions.configure("loom") { - val ct = file("src/main/resources/${Properties.MOD_ID}.classtweaker") + val ct = rootProject.file("fabric/src/testmod/resources/${Properties.MOD_ID}.classtweaker") if (ct.exists()) accessWidenerPath.set(ct) } diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index b473e13..e479dc7 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -1,18 +1,21 @@ import lgbt.greenhouse.config.gradle.Properties +import org.gradle.kotlin.dsl.support.uppercaseFirstChar plugins { id("lgbt.greenhouse.config.gradle.platform.fabric") } +val xplatProject = project(":xplat") + loom { mods { register(Properties.MOD_ID) { - sourceSet("main", ":xplat") - sourceSet("main") + sourceSet(xplatProject.sourceSets["main"]) + sourceSet(sourceSets["main"]) } register("${Properties.MOD_ID}_testmod") { - sourceSet("testmod", ":xplat") - sourceSet("testmod") + sourceSet(xplatProject.sourceSets["testmod"]) + sourceSet(sourceSets["testmod"]) } } @@ -43,3 +46,12 @@ loom { } } } + +val runTasks = loom.runs.map { "run${it.name.uppercaseFirstChar()}" }.toSet() +tasks.named { runTasks.contains(it) }.configureEach { + dependsOn(xplatProject.tasks.getByName("compileTestmodJava")) + dependsOn(tasks.getByName("compileTestmodJava")) + + dependsOn(xplatProject.tasks.getByName("processTestmodResources")) + dependsOn(tasks.getByName("processTestmodResources")) +} diff --git a/xplat/src/testmod/resources/greenhouse_config_testmod.classtweaker b/fabric/src/testmod/resources/greenhouse_config_testmod.classtweaker similarity index 100% rename from xplat/src/testmod/resources/greenhouse_config_testmod.classtweaker rename to fabric/src/testmod/resources/greenhouse_config_testmod.classtweaker diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts index aae39ce..9d7f462 100644 --- a/neoforge/build.gradle.kts +++ b/neoforge/build.gradle.kts @@ -4,6 +4,8 @@ plugins { id("lgbt.greenhouse.config.gradle.platform.neoforge") } +val xplatProject = project(":xplat") + neoForge { val at = file("src/testmod/resources/${Properties.MOD_ID}_testmod.cfg") if (at.exists()) @@ -11,18 +13,23 @@ neoForge { mods { register(Properties.MOD_ID) { - sourceSet(project(":xplat").sourceSets["main"]) + sourceSet(xplatProject.sourceSets["main"]) sourceSet(sourceSets["main"]) } register("${Properties.MOD_ID}_testmod") { - sourceSet(project(":xplat").sourceSets["testmod"]) + sourceSet(xplatProject.sourceSets["testmod"]) sourceSet(sourceSets["testmod"]) } } runs { configureEach { + tasksBefore.add(xplatProject.tasks.named("compileTestmodJava")) + tasksBefore.add(xplatProject.tasks.named("processTestmodResources")) + tasksBefore.add(tasks.named("compileTestmodJava")) + tasksBefore.add(tasks.named("processTestmodResources")) + systemProperty("forge.logging.markers", "REGISTRIES") systemProperty("forge.logging.console.level", "debug") } -- 2.51.2