From d4d5a0f42dda83643fe397d56f8422a45c73dae7 Mon Sep 17 00:00:00 2001 From: JFronny Date: Sun, 9 Jul 2023 16:47:13 +0200 Subject: [PATCH] Do not autoconfigure jfmod subprojects, do not use properties --- build.gradle.kts | 2 +- .../jfronny/scripts/EarlyAfterEvaluateExt.kt | 9 +- .../kotlin/jf.earlyafterevaluate.gradle.kts | 10 +- .../gitlab/jfronny/scripts/JfModExtension.kt | 57 +++++++++++ .../jfronny/scripts/JfModLegacyChecker.kt | 64 ++++++++++++ .../jfronny/scripts/JfModuleExtension.kt | 13 +++ .../main/kotlin/jfmod.curseforge.gradle.kts | 14 +-- jfmod/src/main/kotlin/jfmod.gradle.kts | 99 ++----------------- .../src/main/kotlin/jfmod.modrinth.gradle.kts | 14 +-- jfmod/src/main/kotlin/jfmod.module.gradle.kts | 84 ++++++++++++++++ .../io/gitlab/jfronny/scripts/LomExtension.kt | 21 ++-- lom/src/main/kotlin/lom.gradle.kts | 15 +-- 12 files changed, 267 insertions(+), 135 deletions(-) create mode 100644 jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModExtension.kt create mode 100644 jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModLegacyChecker.kt create mode 100644 jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModuleExtension.kt create mode 100644 jfmod/src/main/kotlin/jfmod.module.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts index bc960e5..f14b59e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,2 +1,2 @@ group = "io.gitlab.jfronny" -version = "1.4-SNAPSHOT" +version = "1.5-SNAPSHOT" diff --git a/convention/src/main/kotlin/io/gitlab/jfronny/scripts/EarlyAfterEvaluateExt.kt b/convention/src/main/kotlin/io/gitlab/jfronny/scripts/EarlyAfterEvaluateExt.kt index 280db92..fe236a1 100644 --- a/convention/src/main/kotlin/io/gitlab/jfronny/scripts/EarlyAfterEvaluateExt.kt +++ b/convention/src/main/kotlin/io/gitlab/jfronny/scripts/EarlyAfterEvaluateExt.kt @@ -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) { - (extra["earlyAfterEvaluates"] as MutableList>).add(action) -} \ No newline at end of file +fun Project.earlyAfterEvaluate(action: Action) = earlyAfterEvaluates!!.add(action) +fun Project.insertEarlyAfterEvaluate(action: Action) = earlyAfterEvaluates!!.add(0, action) + +var Project.earlyAfterEvaluates + get() = extra["earlyAfterEvaluates"] as MutableList>? + set(value) { extra["earlyAfterEvaluates"] = value } \ No newline at end of file diff --git a/convention/src/main/kotlin/jf.earlyafterevaluate.gradle.kts b/convention/src/main/kotlin/jf.earlyafterevaluate.gradle.kts index c4044a5..1d2161b 100644 --- a/convention/src/main/kotlin/jf.earlyafterevaluate.gradle.kts +++ b/convention/src/main/kotlin/jf.earlyafterevaluate.gradle.kts @@ -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>() +earlyAfterEvaluates = ArrayList() afterEvaluate { - (extra["earlyAfterEvaluates"] as List>).forEach { + earlyAfterEvaluates!!.forEach { it.execute(this) } - extra["earlyAfterEvaluates"] = null + earlyAfterEvaluates = null } \ No newline at end of file diff --git a/jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModExtension.kt b/jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModExtension.kt new file mode 100644 index 0000000..5ad5c0c --- /dev/null +++ b/jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModExtension.kt @@ -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 + @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) = closure.execute(curseforge) + fun modrinth(closure: Action) = closure.execute(modrinth) + + interface CurseForge { + val projectId: Property + val requiredDependencies: ListProperty + val optionalDependencies: ListProperty + + 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 + val requiredDependencies: ListProperty + val optionalDependencies: ListProperty + + 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" } + } + } + } +} \ No newline at end of file diff --git a/jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModLegacyChecker.kt b/jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModLegacyChecker.kt new file mode 100644 index 0000000..69667ab --- /dev/null +++ b/jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModLegacyChecker.kt @@ -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("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()) + } +} \ No newline at end of file diff --git a/jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModuleExtension.kt b/jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModuleExtension.kt new file mode 100644 index 0000000..e6b4c2c --- /dev/null +++ b/jfmod/src/main/kotlin/io/gitlab/jfronny/scripts/JfModuleExtension.kt @@ -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 + + fun check(proj: Project) { + devOnly.finalizeValue() + require(proj != proj.rootProject || !devOnly.getOrElse(false)) { "Root project may not be devOnly" } + } +} \ No newline at end of file diff --git a/jfmod/src/main/kotlin/jfmod.curseforge.gradle.kts b/jfmod/src/main/kotlin/jfmod.curseforge.gradle.kts index 4e3db13..3acbf81 100644 --- a/jfmod/src/main/kotlin/jfmod.curseforge.gradle.kts +++ b/jfmod/src/main/kotlin/jfmod.curseforge.gradle.kts @@ -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 { diff --git a/jfmod/src/main/kotlin/jfmod.gradle.kts b/jfmod/src/main/kotlin/jfmod.gradle.kts index 4a38b6a..83da826 100644 --- a/jfmod/src/main/kotlin/jfmod.gradle.kts +++ b/jfmod/src/main/kotlin/jfmod.gradle.kts @@ -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("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 { - 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("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") diff --git a/jfmod/src/main/kotlin/jfmod.modrinth.gradle.kts b/jfmod/src/main/kotlin/jfmod.modrinth.gradle.kts index b793d13..3d8bef6 100644 --- a/jfmod/src/main/kotlin/jfmod.modrinth.gradle.kts +++ b/jfmod/src/main/kotlin/jfmod.modrinth.gradle.kts @@ -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()} diff --git a/jfmod/src/main/kotlin/jfmod.module.gradle.kts b/jfmod/src/main/kotlin/jfmod.module.gradle.kts new file mode 100644 index 0000000..6cfd779 --- /dev/null +++ b/jfmod/src/main/kotlin/jfmod.module.gradle.kts @@ -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("jfModule") + +val isRoot = project == rootProject +val rootArgs get() = rootProject.extensions.getByName("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 { + 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("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 } +} diff --git a/lom/src/main/kotlin/io/gitlab/jfronny/scripts/LomExtension.kt b/lom/src/main/kotlin/io/gitlab/jfronny/scripts/LomExtension.kt index 22f77ac..f5f93b6 100644 --- a/lom/src/main/kotlin/io/gitlab/jfronny/scripts/LomExtension.kt +++ b/lom/src/main/kotlin/io/gitlab/jfronny/scripts/LomExtension.kt @@ -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 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 val loaderVersion: Property - 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) } } \ No newline at end of file diff --git a/lom/src/main/kotlin/lom.gradle.kts b/lom/src/main/kotlin/lom.gradle.kts index 23d7474..12976fa 100644 --- a/lom/src/main/kotlin/lom.gradle.kts +++ b/lom/src/main/kotlin/lom.gradle.kts @@ -86,9 +86,10 @@ repositories { // Register common dependencies val args = extensions.create("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()