diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle deleted file mode 100644 index 7e9c4587b..000000000 --- a/buildSrc/build.gradle +++ /dev/null @@ -1,39 +0,0 @@ -plugins { - id 'groovy-gradle-plugin' -} - -repositories { - gradlePluginPortal() - mavenCentral() - maven { - name = 'MinecraftForge' - url = 'https://maven.minecraftforge.net/' - } - maven { - name = 'Architectury' - url = 'https://maven.architectury.dev/' - } - maven { url = 'https://repo.spongepowered.org/repository/maven-public' } - maven { url = 'https://maven.parchmentmc.org' } -} - -gradlePlugin { - plugins { - platformPlugin { PluginDeclaration plugin -> - plugin.id = 'flywheel.platform' - plugin.implementationClass = 'com.jozufozu.gradle.PlatformPlugin' - } - jarSetPlugin { PluginDeclaration plugin -> - plugin.id = 'flywheel.jar-sets' - plugin.implementationClass = 'com.jozufozu.gradle.JarSetPlugin' - } - packageInfosPlugin { PluginDeclaration plugin -> - plugin.id = 'flywheel.package-infos' - plugin.implementationClass = 'com.jozufozu.gradle.PackageInfosPlugin' - } - } -} - -dependencies { - implementation 'dev.architectury.loom:dev.architectury.loom.gradle.plugin:1.6-SNAPSHOT' -} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 000000000..0c9716767 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("groovy-gradle-plugin") + id("java-gradle-plugin") + kotlin("jvm") version "1.9.20" + `kotlin-dsl` +} + +repositories { + gradlePluginPortal() + mavenCentral() + maven("https://maven.minecraftforge.net/") { + name = "MinecraftForge" + } + maven("https://maven.architectury.dev/") { + name = "Architectury" + } + maven("https://repo.spongepowered.org/repository/maven-public") + maven("https://maven.parchmentmc.org") +} + +gradlePlugin { + plugins { + create("platformPlugin") { + id = "flywheel.platform" + implementationClass = "com.jozufozu.gradle.PlatformPlugin" + } + create("jarSetPlugin") { + id = "flywheel.jar-sets" + implementationClass = "com.jozufozu.gradle.JarSetPlugin" + } + create("packageInfosPlugin") { + id = "flywheel.package-infos" + implementationClass = "com.jozufozu.gradle.PackageInfosPlugin" + } + create("transitiveSourceSetsPlugin") { + id = "flywheel.transitive-source-sets" + implementationClass = "com.jozufozu.gradle.TransitiveSourceSetsPlugin" + } + } +} + +dependencies { + implementation("dev.architectury.loom:dev.architectury.loom.gradle.plugin:1.6-SNAPSHOT") +} diff --git a/buildSrc/src/main/groovy/com/jozufozu/gradle/PlatformPlugin.groovy b/buildSrc/src/main/groovy/com/jozufozu/gradle/PlatformPlugin.groovy index 055b2ba4b..280df3024 100644 --- a/buildSrc/src/main/groovy/com/jozufozu/gradle/PlatformPlugin.groovy +++ b/buildSrc/src/main/groovy/com/jozufozu/gradle/PlatformPlugin.groovy @@ -30,27 +30,10 @@ class PlatformPlugin implements Plugin { def loom = project.getExtensions().getByType(LoomGradleExtensionAPI) def publishing = project.getExtensions().getByType(PublishingExtension) - // Loom only populates mc stuff to the main source set, - // so grab that here and use it for the others. - // Note that the `+` operator does NOT perform a deep copy - // of a FileCollection, so this object is shared between - // the source sets and we should avoid mutating it. SourceSet platformImpl = sourceSets.named('main').get() - FileCollection mcCompileClassPath = platformImpl.compileClasspath - SourceSet platformApi = sourceSets.create('api') - platformApi.compileClasspath = mcCompileClassPath - SourceSet platformLib = sourceSets.create('lib') - platformLib.compileClasspath = mcCompileClassPath + platformApi.output - SourceSet platformBackend = sourceSets.create('backend') - platformBackend.compileClasspath = mcCompileClassPath + platformApi.output + platformLib.output - - // Assign here rather than concatenate to avoid modifying the mcCompileClassPath FileCollection - platformImpl.compileClasspath = mcCompileClassPath + platformApi.output + platformLib.output + platformBackend.output - // This isn't necessary for forge but fabric needs to recognize each classpath entry from ModSettings. - platformImpl.runtimeClasspath += platformApi.output + platformLib.output + platformBackend.output // This is needed for both platforms. def mainMod = loom.mods.maybeCreate('main') @@ -59,16 +42,6 @@ class PlatformPlugin implements Plugin { mainMod.sourceSet(platformBackend) mainMod.sourceSet(platformImpl) - def forApi = newConfiguration(project, 'forApi').get() - def forLib = newConfiguration(project, 'forLib').get() - def forBackend = newConfiguration(project, 'forBackend').get() - def forImpl = newConfiguration(project, 'forImpl').get() - - extendsFrom(project, platformApi.compileOnlyConfigurationName, forApi) - extendsFrom(project, platformLib.compileOnlyConfigurationName, forApi, forLib) - extendsFrom(project, platformBackend.compileOnlyConfigurationName, forApi, forLib, forBackend) - extendsFrom(project, platformImpl.compileOnlyConfigurationName, forApi, forLib, forBackend, forImpl) - SourceSet commonApi = commonSourceSets.named('api').get() SourceSet commonLib = commonSourceSets.named('lib').get() SourceSet commonBackend = commonSourceSets.named('backend').get() diff --git a/buildSrc/src/main/kotlin/com/jozufozu/gradle/TransitiveSourceSetConfigurator.kt b/buildSrc/src/main/kotlin/com/jozufozu/gradle/TransitiveSourceSetConfigurator.kt new file mode 100644 index 000000000..f105246da --- /dev/null +++ b/buildSrc/src/main/kotlin/com/jozufozu/gradle/TransitiveSourceSetConfigurator.kt @@ -0,0 +1,40 @@ +package com.jozufozu.gradle + +import org.gradle.api.tasks.SourceSet + +class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsExtension, private val sourceSet: SourceSet) { + internal val compileSourceSets = mutableSetOf() + internal val runtimeSourceSets = mutableSetOf() + + fun rootCompile() { + parent.compileClasspath?.let { sourceSet.compileClasspath = it } + } + + fun rootRuntime() { + parent.runtimeClasspath?.let { sourceSet.runtimeClasspath = it } + } + + fun rootImplementation() { + rootCompile() + rootRuntime() + } + + fun compile(vararg sourceSets: SourceSet) { + compileSourceSets += sourceSets + for (sourceSet in sourceSets) { + this.sourceSet.compileClasspath += sourceSet.output + } + } + + fun runtime(vararg sourceSets: SourceSet) { + runtimeSourceSets += sourceSets + for (sourceSet in sourceSets) { + this.sourceSet.runtimeClasspath += sourceSet.output + } + } + + fun implementation(vararg sourceSets: SourceSet) { + compile(*sourceSets) + runtime(*sourceSets) + } +} diff --git a/buildSrc/src/main/kotlin/com/jozufozu/gradle/TransitiveSourceSetsExtension.kt b/buildSrc/src/main/kotlin/com/jozufozu/gradle/TransitiveSourceSetsExtension.kt new file mode 100644 index 000000000..817c9d93b --- /dev/null +++ b/buildSrc/src/main/kotlin/com/jozufozu/gradle/TransitiveSourceSetsExtension.kt @@ -0,0 +1,79 @@ +package com.jozufozu.gradle + +import org.gradle.api.Action +import org.gradle.api.Project +import org.gradle.api.file.FileCollection +import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.SourceSetContainer +import org.gradle.kotlin.dsl.the + +open class TransitiveSourceSetsExtension(private val project: Project) { + var compileClasspath: FileCollection? = null + var runtimeClasspath: FileCollection? = null + + private val transitives = mutableMapOf() + + fun create(name: String) { + sourceSet(project.the().maybeCreate(name)) + } + + fun create(name: String, action: Action) { + sourceSet(project.the().maybeCreate(name), action) + } + + fun sourceSet(name: String) { + sourceSet(project.the().getByName(name)) + } + + fun sourceSet(name: String, action: Action) { + sourceSet(project.the().getByName(name), action) + } + + fun sourceSet(sourceSet: SourceSet) { + registerSourceSet(sourceSet) + } + + fun sourceSet(sourceSet: SourceSet, action: Action) { + action.execute(registerSourceSet(sourceSet)) + } + + private fun registerSourceSet(sourceSet: SourceSet): TransitiveSourceSetConfigurator { + return transitives.computeIfAbsent(sourceSet) { TransitiveSourceSetConfigurator(this, it) } + } + + fun createCompileConfigurations() { + val configs = transitives.mapValues { (sourceSet, _) -> + project.configurations.create("for${sourceSet.name.capitalize()}") { + isCanBeConsumed = true + isCanBeResolved = false + } + } + + transitives.forEach { (sourceSet, configurator) -> + project.configurations.named(sourceSet.compileOnlyConfigurationName).configure { + extendsFrom(configs[sourceSet]) + configurator.compileSourceSets.forEach { + extendsFrom(configs[it]) + } + } + } + } + + fun createRuntimeConfigurations() { + val configs = transitives.mapValues { (sourceSet, _) -> + project.configurations.create("run${sourceSet.name.capitalize()}") { + isCanBeConsumed = true + isCanBeResolved = false + } + } + + transitives.forEach { (sourceSet, configurator) -> + project.configurations.named(sourceSet.runtimeOnlyConfigurationName).configure { + extendsFrom(configs[sourceSet]) + configurator.runtimeSourceSets.forEach { + extendsFrom(configs[it]) + } + } + } + } +} diff --git a/buildSrc/src/main/kotlin/com/jozufozu/gradle/TransitiveSourceSetsPlugin.kt b/buildSrc/src/main/kotlin/com/jozufozu/gradle/TransitiveSourceSetsPlugin.kt new file mode 100644 index 000000000..2f00416a8 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/jozufozu/gradle/TransitiveSourceSetsPlugin.kt @@ -0,0 +1,10 @@ +package com.jozufozu.gradle + +import org.gradle.api.Plugin +import org.gradle.api.Project + +class TransitiveSourceSetsPlugin: Plugin { + override fun apply(target: Project) { + target.extensions.create("transitiveSourceSets", TransitiveSourceSetsExtension::class.java, target) + } +} diff --git a/common/build.gradle b/common/build.gradle index 0181025c8..b407c7258 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -7,36 +7,28 @@ plugins { id 'flywheel.package-infos' id 'flywheel.subproject' id 'flywheel.jar-sets' + id 'flywheel.transitive-source-sets' } -sourceSets { - // Loom only populates mc stuff to the main source set, - // so grab that here and use it for the others. - // Note that the `+` operator does NOT perform a deep copy - // of a FileCollection, so this object is shared between - // the source sets and we should avoid mutating it. - FileCollection mcCompileClassPath = main.compileClasspath +transitiveSourceSets { + compileClasspath = sourceSets.main.compileClasspath - SourceSet api = api { - compileClasspath = mcCompileClassPath + create('api') { + rootCompile() } - SourceSet lib = lib { - compileClasspath = mcCompileClassPath + api.output + create('lib') { + rootCompile() + compile sourceSets.api } - SourceSet backend = backend { - compileClasspath = mcCompileClassPath + api.output + lib.output + create('backend') { + rootCompile() + compile sourceSets.api, sourceSets.lib } - - main { - // Assign here rather than concatenate to avoid modifying the mcCompileClassPath FileCollection - compileClasspath = mcCompileClassPath + api.output + lib.output + backend.output + sourceSet(sourceSets.main) { + compile sourceSets.api, sourceSets.lib, sourceSets.backend } - - test { - // Only test needs runtimeClasspath filled since the game shouldn't run from common alone. - // Fine to concatenate here. - compileClasspath += api.output + lib.output + backend.output - runtimeClasspath += api.output + lib.output + backend.output + sourceSet(sourceSets.test) { + implementation sourceSets.api, sourceSets.lib, sourceSets.backend } } diff --git a/fabric/build.gradle b/fabric/build.gradle index e975b7754..53483d51f 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -7,10 +7,32 @@ plugins { id 'flywheel.package-infos' id 'flywheel.subproject' id 'flywheel.platform' + id 'flywheel.transitive-source-sets' } evaluationDependsOn(':common') +transitiveSourceSets { + compileClasspath = sourceSets.main.compileClasspath + + create('api') { + rootCompile() + } + create('lib') { + rootCompile() + compile sourceSets.api + } + create('backend') { + rootCompile() + compile sourceSets.api, sourceSets.lib + } + sourceSet(sourceSets.main) { + implementation sourceSets.api, sourceSets.lib, sourceSets.backend + } + + createCompileConfigurations() +} + defaultPackageInfos { forSourceSets sourceSets.api, sourceSets.lib, sourceSets.backend, sourceSets.main } @@ -50,5 +72,5 @@ dependencies { forApi project(path: ':common', configuration: 'commonApiOnly') forLib project(path: ':common', configuration: 'commonLib') forBackend project(path: ':common', configuration: 'commonBackend') - forImpl project(path: ':common', configuration: 'commonImpl') + forMain project(path: ':common', configuration: 'commonImpl') } diff --git a/forge/build.gradle b/forge/build.gradle index 97a812da3..995477e64 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -7,10 +7,32 @@ plugins { id 'flywheel.package-infos' id 'flywheel.subproject' id 'flywheel.platform' + id 'flywheel.transitive-source-sets' } evaluationDependsOn(':common') +transitiveSourceSets { + compileClasspath = sourceSets.main.compileClasspath + + create('api') { + rootCompile() + } + create('lib') { + rootCompile() + compile sourceSets.api + } + create('backend') { + rootCompile() + compile sourceSets.api, sourceSets.lib + } + sourceSet(sourceSets.main) { + compile sourceSets.api, sourceSets.lib, sourceSets.backend + } + + createCompileConfigurations() +} + defaultPackageInfos { forSourceSets sourceSets.api, sourceSets.lib, sourceSets.backend, sourceSets.main } @@ -60,5 +82,5 @@ dependencies { forApi project(path: ':common', configuration: 'commonApiOnly') forLib project(path: ':common', configuration: 'commonLib') forBackend project(path: ':common', configuration: 'commonBackend') - forImpl project(path: ':common', configuration: 'commonImpl') + forMain project(path: ':common', configuration: 'commonImpl') }