Do not autoconfigure jfmod subprojects, do not use properties
ci/woodpecker/push/gradle Pipeline was successful Details
ci/woodpecker/push/pages Pipeline was successful Details

This commit is contained in:
Johannes Frohnmeyer 2023-07-09 16:47:13 +02:00
parent 6d0036bad9
commit d4d5a0f42d
Signed by: Johannes
GPG Key ID: E76429612C2929F4
12 changed files with 267 additions and 135 deletions

View File

@ -1,2 +1,2 @@
group = "io.gitlab.jfronny"
version = "1.4-SNAPSHOT"
version = "1.5-SNAPSHOT"

View File

@ -4,6 +4,9 @@ import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.kotlin.dsl.extra
fun Project.earlyAfterEvaluate(action: Action<Project>) {
(extra["earlyAfterEvaluates"] as MutableList<Action<Project>>).add(action)
}
fun Project.earlyAfterEvaluate(action: Action<Project>) = earlyAfterEvaluates!!.add(action)
fun Project.insertEarlyAfterEvaluate(action: Action<Project>) = earlyAfterEvaluates!!.add(0, action)
var Project.earlyAfterEvaluates
get() = extra["earlyAfterEvaluates"] as MutableList<Action<Project>>?
set(value) { extra["earlyAfterEvaluates"] = value }

View File

@ -1,12 +1,10 @@
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.kotlin.dsl.extra
import io.gitlab.jfronny.scripts.*
extra["earlyAfterEvaluates"] = ArrayList<Action<Project>>()
earlyAfterEvaluates = ArrayList()
afterEvaluate {
(extra["earlyAfterEvaluates"] as List<Action<Project>>).forEach {
earlyAfterEvaluates!!.forEach {
it.execute(this)
}
extra["earlyAfterEvaluates"] = null
earlyAfterEvaluates = null
}

View File

@ -0,0 +1,57 @@
package io.gitlab.jfronny.scripts
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Nested
interface JfModExtension: LomExtension {
val libJfVersion: Property<String>
@get:Nested val curseforge: CurseForge
@get:Nested val modrinth: Modrinth
override fun check(proj: Project) {
super.check(proj)
libJfVersion.finalizeValue()
val p = proj.allprojects
modrinth.check(proj)
curseforge.check(proj)
}
fun isMod(proj: Project) = proj.extensions.findByName("jfModule") != null
fun curseforge(closure: Action<CurseForge>) = closure.execute(curseforge)
fun modrinth(closure: Action<Modrinth>) = closure.execute(modrinth)
interface CurseForge {
val projectId: Property<String>
val requiredDependencies: ListProperty<String>
val optionalDependencies: ListProperty<String>
fun check(proj: Project) {
projectId.finalizeValue()
requiredDependencies.finalizeValue()
optionalDependencies.finalizeValue()
if (!projectId.isPresent) {
require(requiredDependencies.map { it.isEmpty() }.getOrElse(true)) { "curseforge is not configured for a project id but has dependencies" }
require(optionalDependencies.map { it.isEmpty() }.getOrElse(true)) { "curseforge is not configured for a project id but has dependencies" }
}
}
}
interface Modrinth {
val projectId: Property<String>
val requiredDependencies: ListProperty<String>
val optionalDependencies: ListProperty<String>
fun check(proj: Project) {
projectId.finalizeValue()
requiredDependencies.finalizeValue()
optionalDependencies.finalizeValue()
if (!projectId.isPresent) {
require(requiredDependencies.map { it.isEmpty() }.getOrElse(true)) { "modrinth is not configured for a project id but has dependencies" }
require(optionalDependencies.map { it.isEmpty() }.getOrElse(true)) { "modrinth is not configured for a project id but has dependencies" }
}
}
}
}

View File

@ -0,0 +1,64 @@
package io.gitlab.jfronny.scripts
import org.gradle.api.Project
import org.gradle.api.plugins.BasePluginExtension
fun Project.legacyCheck(jfMod: JfModExtension) {
val splitRegex = Regex(", ?")
fun String.splitByComma() = splitRegex.split(this).filter { it.isNotBlank() }
if (hasProperty("maven_group")) {
logger.warn("Using maven_group is deprecated, please use group on rootProject")
group = prop("maven_group")
}
if (hasProperty("archives_base_name")) {
logger.warn("Using archives_base_name is deprecated, please use base.archivesName on allprojects")
allprojects {
extensions.configure<BasePluginExtension>("base") {
archivesName.set(prop("archives_base_name"))
}
}
}
if (hasProperty("dev_only_module")) {
logger.error("Using dev_only_module is deprecated, please use the DSL")
}
if (hasProperty("non_mod_project")) {
logger.error("Using non_mod_project is deprecated, please use the DSL")
}
if (hasProperty("minecraft_version")) {
logger.warn("Using minecraft_version is deprecated, please use the DSL")
jfMod.minecraftVersion.set(prop("minecraft_version"))
}
if (hasProperty("loader_version")) {
logger.warn("Using loader_version is deprecated, please use the DSL")
jfMod.loaderVersion.set(prop("loader_version"))
}
if (hasProperty("yarn_mappings")) {
logger.warn("Using yarn_mappings is deprecated, please use the DSL")
jfMod.yarn(prop("yarn_mappings"))
}
if (hasProperty("curseforge_id")) {
logger.warn("Using curseforge_id is deprecated, please use the DSL")
jfMod.curseforge.projectId.set(prop("curseforge_id"))
}
if (hasProperty("curseforge_required_dependencies")) {
logger.warn("Using curseforge_required_dependencies is deprecated, please use the DSL")
jfMod.curseforge.requiredDependencies.addAll(prop("curseforge_required_dependencies").splitByComma())
}
if (hasProperty("curseforge_optional_dependencies")) {
logger.warn("Using curseforge_optional_dependencies is deprecated, please use the DSL")
jfMod.curseforge.optionalDependencies.addAll(prop("curseforge_optional_dependencies").splitByComma())
}
if (hasProperty("modrinth_id")) {
logger.warn("Using modrinth_id is deprecated, please use the DSL")
jfMod.curseforge.projectId.set(prop("modrinth_id"))
}
if (hasProperty("modrinth_required_dependencies")) {
logger.warn("Using modrinth_required_dependencies is deprecated, please use the DSL")
jfMod.modrinth.requiredDependencies.addAll(prop("modrinth_required_dependencies").splitByComma())
}
if (hasProperty("modrinth_optional_dependencies")) {
logger.warn("Using modrinth_optional_dependencies is deprecated, please use the DSL")
jfMod.modrinth.optionalDependencies.addAll(prop("modrinth_optional_dependencies").splitByComma())
}
}

View File

@ -0,0 +1,13 @@
package io.gitlab.jfronny.scripts
import org.gradle.api.Project
import org.gradle.api.provider.Property
interface JfModuleExtension {
val devOnly: Property<Boolean>
fun check(proj: Project) {
devOnly.finalizeValue()
require(proj != proj.rootProject || !devOnly.getOrElse(false)) { "Root project may not be devOnly" }
}
}

View File

@ -5,11 +5,13 @@ plugins {
id("com.matthewprenger.cursegradle")
}
val args = extensions.getByName("jfMod") as JfModExtension
curseforge {
if (System.getenv().containsKey("CURSEFORGE_API_TOKEN")) apiKey = System.getenv()["CURSEFORGE_API_TOKEN"]
else println("No CURSEFORGE_API_TOKEN specified")
project {
id = prop("curseforge_id")
id = args.curseforge.projectId.get()
releaseType = versionType.curseforgeName
addGameVersion("Fabric")
addGameVersion(lom.minecraftVersion.get())
@ -18,14 +20,8 @@ curseforge {
displayName = "[${lom.minecraftVersion.get()}] $versionS"
}
relations {
prop("curseforge_required_dependencies", "")
.split(", ", ",")
.filter { it.isNotBlank() }
.forEach { requiredDependency(it) }
prop("curseforge_optional_dependencies", "")
.split(", ", ",")
.filter { it.isNotBlank() }
.forEach { optionalDependency(it) }
args.curseforge.requiredDependencies.getOrElse(listOf()).forEach { requiredDependency(it) }
args.curseforge.optionalDependencies.getOrElse(listOf()).forEach { optionalDependency(it) }
}
}
options {

View File

@ -2,98 +2,16 @@ import io.gitlab.jfronny.scripts.*
plugins {
id("jf.autoversion")
id("jf.maven-publish")
id("lom")
id("jfmod.module")
}
val splitRegex = Regex(", ?")
fun String.splitByComma() = splitRegex.split(this).filter { it.isNotBlank() }
val args = extensions.create<JfModExtension>("jfMod")
legacyCheck(args)
val devOnlyModules by extra(prop("dev_only_module", "").splitByComma())
val nonModSubprojects by extra(prop("non_mod_project", "").splitByComma())
val self = project
if (hasProperty("maven_group")) group = prop("maven_group")
allprojects {
if (name in nonModSubprojects) return@allprojects
group = self.group
version = self.version
apply(plugin = "jf.maven-publish")
apply(plugin = "lom")
base {
archivesName.set(prop("archives_base_name", archivesName.get()))
}
lom {
minecraftVersion.set(prop("minecraft_version"))
loaderVersion.set(prop("loader_version"))
if (hasProperty("yarn_mappings")) yarn(prop("yarn_mappings"))
else mojmap()
}
if (hasProperty("libjf_version")) {
dependencies {
clientAnnotationProcessor(annotationProcessor("io.gitlab.jfronny.libjf:libjf-config-compiler-plugin-v2:${prop("libjf_version")}")!!)
}
tasks.withType<JavaCompile> {
options.compilerArgs.add("-AmodId=" + base.archivesName.get())
}
}
afterEvaluate {
self.allprojects.forEach { sub ->
if (sub != this && sub.name !in nonModSubprojects) {
loom {
mods {
register(sub.name) {
sourceSet(sub.sourceSets.main.get())
sourceSet(sub.sourceSets.client.get())
}
if (!sourceSets.testmod.get().resources.isEmpty) {
register("${sub.name}-testmod") {
sourceSet(sub.sourceSets.testmod.get())
}
}
}
}
}
}
}
}
subprojects {
if (name in nonModSubprojects) return@subprojects
self.tasks.deployDebug.dependsOn(tasks.deployDebug)
self.tasks.deployRelease.dependsOn(tasks.deployRelease)
tasks.named("javadoc") { enabled = false }
if (name !in devOnlyModules && !sourceSets.testmod.get().resources.isEmpty) {
//TODO register testmods of subprojects as testmodInclude automatically
// val configuration = configurations.create("testmodJar").name
// val testmodJarTask = tasks.named<Jar>("testmodJar").get()
// artifacts.add(configuration, testmodJarTask.archiveFile.get().asFile) {
// type = "jar"
// builtBy(testmodJarTask)
// }
//
// self.dependencies {
// testmodInclude(project(mapOf("path" to path, "configuration" to configuration)))
// }
}
self.dependencies {
api(project(mapOf("path" to project.path, "configuration" to "shadow")))
clientImplementation(sourceSets.client.get().output)
testmodImplementation(sourceSets.testmod.get().output)
if (name !in devOnlyModules) include(project)
}
earlyAfterEvaluate {
args.check(project)
if (args.curseforge.projectId.isPresent) apply(plugin = "jfmod.curseforge")
if (args.modrinth.projectId.isPresent) apply(plugin = "jfmod.modrinth")
}
val moveArtifacts by tasks.registering(Copy::class) {
@ -112,6 +30,3 @@ val moveArtifacts by tasks.registering(Copy::class) {
}
tasks.deployDebug.dependsOn(moveArtifacts)
if (hasProperty("curseforge_id")) apply(plugin = "jfmod.curseforge")
if (hasProperty("modrinth_id")) apply(plugin = "jfmod.modrinth")

View File

@ -5,25 +5,21 @@ plugins {
id("com.modrinth.minotaur")
}
val args = extensions.getByName("jfMod") as JfModExtension
val readmeFile = file("README.md")
modrinth {
token.set(System.getenv()["MODRINTH_API_TOKEN"])
projectId.set(prop("modrinth_id"))
projectId.set(args.modrinth.projectId)
versionName.set("[${lom.minecraftVersion.get()}] $versionS")
versionType.set(project.versionType.modrinthName)
changelog.set(project.changelog)
uploadFile.set(tasks.remapJar as Any)
gameVersions.add(lom.minecraftVersion.get())
loaders.add("fabric")
prop("modrinth_required_dependencies", "")
.split(", ", ",")
.filter { it.isNotBlank() }
.forEach { required.project(it) }
prop("modrinth_optional_dependencies", "")
.split(", ", ",")
.filter { it.isNotBlank() }
.forEach { optional.project(it) }
args.modrinth.requiredDependencies.getOrElse(listOf()).forEach { required.project(it) }
args.modrinth.optionalDependencies.getOrElse(listOf()).forEach { optional.project(it) }
if (readmeFile.exists()) {
syncBodyFrom.set(
"""${readmeFile.readText()}

View File

@ -0,0 +1,84 @@
import io.gitlab.jfronny.scripts.*
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.withType
plugins {
id("jf.maven-publish")
id("lom")
}
val args = extensions.create<JfModuleExtension>("jfModule")
val isRoot = project == rootProject
val rootArgs get() = rootProject.extensions.getByName<JfModExtension>("jfMod");
insertEarlyAfterEvaluate {
args.check(project)
if (!isRoot) versionS = rootProject.versionS
lom {
copyFrom(rootArgs)
}
if (rootArgs.libJfVersion.isPresent) {
dependencies {
clientAnnotationProcessor(annotationProcessor("io.gitlab.jfronny.libjf:libjf-config-compiler-plugin-v2:${rootArgs.libJfVersion.get()}")!!)
}
tasks.withType<JavaCompile> {
options.compilerArgs.add("-AmodId=" + base.archivesName.get())
}
}
}
afterEvaluate {
rootProject.allprojects.forEach { sub ->
if (sub != this && rootArgs.isMod(sub)) {
loom {
mods {
register(sub.name) {
sourceSet(sub.sourceSets.main.get())
sourceSet(sub.sourceSets.client.get())
}
if (!sourceSets.testmod.get().resources.isEmpty) {
register("${sub.name}-testmod") {
sourceSet(sub.sourceSets.testmod.get())
}
}
}
}
}
}
val devOnly = args.devOnly.getOrElse(false)
if (!isRoot && !devOnly && !sourceSets.testmod.get().resources.isEmpty) {
//TODO register testmods of subprojects as testmodInclude automatically
// val configuration = configurations.create("testmodJar").name
// val testmodJarTask = tasks.named<Jar>("testmodJar").get()
// artifacts.add(configuration, testmodJarTask.archiveFile.get().asFile) {
// type = "jar"
// builtBy(testmodJarTask)
// }
//
// self.dependencies {
// testmodInclude(project(mapOf("path" to path, "configuration" to configuration)))
// }
}
if (!isRoot) rootProject.dependencies {
api(project(mapOf("path" to project.path, "configuration" to "shadow")))
clientImplementation(sourceSets.client.get().output)
testmodImplementation(sourceSets.testmod.get().output)
if (!devOnly) include(project)
}
}
if (!isRoot) {
rootProject.tasks.deployDebug.dependsOn(tasks.deployDebug)
rootProject.tasks.deployRelease.dependsOn(tasks.deployRelease)
tasks.named("javadoc") { enabled = false }
}

View File

@ -1,27 +1,32 @@
package io.gitlab.jfronny.scripts
import net.fabricmc.loom.LoomGradleExtension
import org.gradle.api.Project
import org.gradle.api.provider.Property
import java.util.*
interface LomExtension {
var yarnBuild: String?
val yarnBuild: Property<String>
fun yarn(yarnBuild: String) {
this.yarnBuild = Objects.requireNonNull(yarnBuild)
this.yarnBuild.set(Objects.requireNonNull(yarnBuild))
}
fun mojmap() {
yarnBuild = null
yarnBuild.set(null)
}
val minecraftVersion: Property<String>
val loaderVersion: Property<String>
companion object {
operator fun get(project: Project): LoomGradleExtension {
return project.extensions.getByName("lom") as LoomGradleExtension
}
fun check(proj: Project) {
yarnBuild.finalizeValue()
minecraftVersion.finalizeValue()
loaderVersion.finalizeValue()
}
fun copyFrom(ext: LomExtension) {
yarnBuild.set(ext.yarnBuild)
minecraftVersion.set(ext.minecraftVersion)
loaderVersion.set(ext.loaderVersion)
}
}

View File

@ -86,9 +86,10 @@ repositories {
// Register common dependencies
val args = extensions.create<LomExtension>("lom")
earlyAfterEvaluate {
args.check(this)
dependencies {
minecraft("com.mojang:minecraft:${args.minecraftVersion.get()}")
if (args.yarnBuild != null) mappings("net.fabricmc:yarn:${args.minecraftVersion.get()}+${args.yarnBuild}:v2")
if (args.yarnBuild.isPresent) mappings("net.fabricmc:yarn:${args.minecraftVersion.get()}+${args.yarnBuild.get()}:v2")
else loom.officialMojangMappings()
modImplementation("net.fabricmc:fabric-loader:${args.loaderVersion.get()}")
testImplementation("net.fabricmc:fabric-loader-junit:${args.loaderVersion.get()}")
@ -105,12 +106,6 @@ tasks.test {
// Mark normal jars as -dev
tasks.jar.get().archiveClassifier.set("dev")
// Used for referencing the unremapped jars of other projects
artifacts.add(configurations.create("dev").name, tasks.jar) {
type = "jar"
builtBy(tasks.jar)
}
// configure the shadow task to not shadow by default and output to builds/devlibs
tasks.shadowJar {
// get injectCompiledConfig task if present (-> LibJF) or use normal jar task
@ -122,6 +117,12 @@ tasks.shadowJar {
destinationDirectory.set(devlibs)
}
// Used for referencing the unremapped jars of other projects
artifacts.add(configurations.create("dev").name, tasks.shadowJar) {
type = "jar"
builtBy(tasks.shadowJar)
}
// generate sources jar to publish for better debugging with dependents
java {
withSourcesJar()