Kafkatorio/modules/factorio-events-data-model/build.gradle.kts

362 lines
9.9 KiB
Text
Raw Normal View History

2021-10-30 07:26:12 +02:00
import java.util.function.Supplier
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.provider.Property
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.property
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
2021-10-30 07:26:12 +02:00
import org.gradle.nativeplatform.platform.internal.DefaultOperatingSystem
import org.gradle.plugins.ide.idea.model.IdeaModel
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
2021-10-30 07:26:12 +02:00
import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs
plugins {
id("dev.adamko.factoriowebmap.archetype.kotlin-jvm")
`kotlin-dsl`
}
2021-10-25 23:35:18 +02:00
val projectId: String by project.extra
val buildDir: Directory = layout.buildDirectory.dir(projectId).get()
2021-10-25 23:35:18 +02:00
2021-10-30 07:26:12 +02:00
dependencies {
}
2021-10-25 23:35:18 +02:00
2021-10-30 11:29:07 +02:00
open class ProtocPlugin : Plugin<Project> {
override fun apply(project: Project) {
configureIntelliJ(project)
val protocConfig =
project.extensions.create("protocPluginConfig", ProtocPluginConfig::class, project)
2021-10-30 11:29:07 +02:00
val protobufCompiler: Configuration = project.configurations.create("protobufCompiler") {
isVisible = false
isCanBeConsumed = false
isCanBeResolved = true
isTransitive = false
2021-10-30 11:29:07 +02:00
defaultDependencies {
add(protocConfig.dependency.get())
}
}
val protobufLib: Configuration = project.configurations.create("protobufLib") {
2021-10-30 11:29:07 +02:00
isVisible = true
isCanBeConsumed = false
isCanBeResolved = true
isTransitive = false
}
project.dependencies {
protobufLib("com.google.protobuf:protobuf-javalite:3.19.1")
2021-10-30 11:29:07 +02:00
}
/** Download protobuf libs */
val protoLibsTask = project.tasks.register<Sync>("protobufLibs") {
2021-10-30 11:29:07 +02:00
group = "protobuf"
description = "Download and extract protobuf libs"
2021-10-30 11:29:07 +02:00
includeEmptyDirs = false
dependsOn(protobufLib)
2021-10-30 11:29:07 +02:00
val protoLibDir by project.objects.directoryProperty()
.convention(project.layout.buildDirectory.dir("protobuf/libs"))
into(protoLibDir)
2021-10-30 11:29:07 +02:00
protobufLib
2021-10-30 11:29:07 +02:00
.map { project.zipTree(it) }
.forEach {
logger.lifecycle("protoc lib - $it")
from(it) {
include("**/*.proto")
}
}
}
// TODO investigate builtBy and sourceDirectorySet?
// project.objects.fileCollection().builtBy()
// val pbSrcSet = project.objects.sourceDirectorySet("protobuf", "protobuf")
2021-10-30 11:29:07 +02:00
/** Convert `.proto` files to Kotlin */
val pbCompileTask = project.tasks.register<Exec>("protobufCompile") {
group = "protobuf"
dependsOn(protobufCompiler, protoLibsTask)
2021-10-30 11:29:07 +02:00
standardOutput = System.out
executable(protobufCompiler.singleFile)
workingDir(temporaryDirFactory)
val outDir = project.layout.buildDirectory.dir("protobuf/generated-sources")
2021-10-30 11:54:46 +02:00
outputs.dir(outDir)
val protoLibsDir: Provider<File> = protoLibsTask.map { it.destinationDir }
val javaOut = workingDir.resolve("java")
val kotlinOut = workingDir.resolve("kotlin")
2021-10-30 11:54:46 +02:00
val protoFile by project.objects.fileProperty()
.convention(project.layout.projectDirectory.file("src/main/proto/FactorioServerLogRecord.proto"))
2021-10-30 11:54:46 +02:00
val protoFileParent = project.provider { protoFile.asFile.parentFile }
2021-10-30 11:29:07 +02:00
val isLiteEnabled: Boolean by project.objects.property<Boolean>().convention(true)
2021-10-30 11:33:40 +02:00
doFirst {
2021-10-30 11:54:46 +02:00
project.delete(workingDir)
project.mkdir(outDir)
2021-10-30 11:54:46 +02:00
project.mkdir(javaOut)
project.mkdir(kotlinOut)
val liteOpt: String = when (isLiteEnabled) {
true -> "lite:"
false -> ""
}
args(
parseSpaceSeparatedArgs(
"""
--proto_path=${protoLibsDir.get()}
--proto_path=${protoFileParent.get()}
--java_out=$liteOpt$javaOut
--kotlin_out=$liteOpt$kotlinOut
$protoFile
"""
)
)
2021-10-30 11:54:46 +02:00
}
doLast {
project.sync {
from(workingDir)
into(outDir)
}
project.delete(workingDir)
2021-10-30 11:33:40 +02:00
}
}
project.tasks.assemble { dependsOn(pbCompileTask) }
}
/** Setup source dirs */
private fun configureIntelliJ(project: Project) {
val genSrcDir = project.layout.buildDirectory.dir("protobuf/generated-sources")
val ktGenSrc = genSrcDir.map { it.dir("kotlin") }
project.mkdir(ktGenSrc)
project.extensions.findByType<KotlinJvmProjectExtension>()?.apply {
project.logger.lifecycle("-------\nadding generated sources $ktGenSrc\n-------")
project.sourceSets.named("main") {
this.java.srcDir(ktGenSrc)
}
// sourceSets.main.get().kotlin.srcDir(ktGenSrc)
2021-10-30 11:33:40 +02:00
// sourceSets.main.configure {
// this.kotlin.srcDir(ktGenSrc)
// }
}
project.plugins.withType<IdeaPlugin> {
project.extensions.configure<IdeaModel> {
this.module.generatedSourceDirs.add(ktGenSrc.get().asFile)
}
}
/**
* IntelliJ requires source dirs are configured first.
*
* https://github.com/google/protobuf-gradle-plugin/blob/master/src/main/groovy/com/google/protobuf/gradle/Utils.groovy#L128
*/
project.tasks.withType<GenerateIdeaModule> {
doFirst {
project.mkdir(ktGenSrc)
}
2021-10-30 11:29:07 +02:00
}
}
}
abstract class ProtocPluginConfig(private val project: Project) {
2021-10-30 07:26:12 +02:00
val protocWorkingDir: DirectoryProperty =
project.objects.directoryProperty()
.convention(project.rootProject.layout.projectDirectory.dir(".gradle/protoc"))
val protocVersion: Property<String> =
2021-10-30 11:29:07 +02:00
project.objects.property(String::class).convention("3.19.1")
val protocGroup: Property<String> =
project.objects.property(String::class).convention("com.google.protobuf")
val protocArtifactName: Property<String> =
project.objects.property(String::class).convention("protoc")
val protocArtifactExtension: Property<String> =
project.objects.property(String::class).convention("exe")
2021-10-30 07:26:12 +02:00
val operatingSystemProvider: Property<Supplier<DefaultOperatingSystem>> =
project.objects.property<Supplier<DefaultOperatingSystem>>()
.convention { DefaultNativePlatform.getCurrentOperatingSystem() }
/**
* Should return one of
*
* * `linux`
* * `osx`
* * `windows`
*/
2021-10-30 07:26:12 +02:00
val operatingSystemName: Property<String> =
project.objects
.property<String>()
.convention(operatingSystemProvider.map { it.get().toFamilyName() })
private val architectureProvider: Provider<Architecture> =
project.provider { DefaultNativePlatform.getCurrentArchitecture() }
/**
* Should return one of
*
* * `aarch_64`
* * `ppcle_64`
* * `x86_32`
* * `x86_64`
*/
2021-10-30 07:26:12 +02:00
val architectureName: Property<String> =
project.objects
.property<String>()
.convention(architectureProvider.map { it.name.replace("-", "_") })
private val classifierProvider: Provider<String> =
project.provider { "${operatingSystemName.get()}-${architectureName.get()}" }
/**
* Default: concatenate [osFamilyNameProvider] and [architectureProvider]
*
* Should return one of:
*
* * `linux-aarch_64`
* * `linux-ppcle_64`
* * `linux-x86_64`
* * `osx-x86_32`
* * `osx-x86_64`
* * `windows-x86_32`
*/
2021-10-30 07:26:12 +02:00
val classifier: Property<String> =
project.objects
.property<String>()
.convention(classifierProvider)
private val dependencyProvider: Provider<ExternalModuleDependency> =
project.provider {
project.dependencies.create(
group = protocGroup.get(),
name = protocArtifactName.get(),
version = protocVersion.get(),
classifier = classifierProvider.get(),
ext = protocArtifactExtension.get(),
)
}
2021-10-30 07:26:12 +02:00
val dependency: Property<ExternalModuleDependency> =
project.objects
.property<ExternalModuleDependency>()
.convention(dependencyProvider)
}
abstract class ProtocPrepareTask : DefaultTask() {
@Internal
val protocPluginConfig: Provider<ProtocPluginConfig> = project.provider {
project.extensions.getByType<ProtocPluginConfig>()
}
2021-10-30 07:26:12 +02:00
@get:OutputDirectory
val outputDirectory: DirectoryProperty = project.objects.directoryProperty()
.convention(protocPluginConfig.flatMap { it.protocWorkingDir })
@Internal
2021-10-30 07:26:12 +02:00
val protocOutput: RegularFileProperty = project.objects.fileProperty()
@Internal
val protocDependency: Provider<ExternalModuleDependency> =
protocPluginConfig.flatMap { it.dependency }
init {
2021-10-30 11:29:07 +02:00
super.setGroup("protobuf")
outputs.dir(outputDirectory)
2021-10-30 07:26:12 +02:00
}
@TaskAction
2021-10-30 11:29:07 +02:00
fun action() {
val protocDep: Configuration = project.configurations.create("protoc") {
isVisible = false
isCanBeConsumed = false
isCanBeResolved = true
isTransitive = false
defaultDependencies {
add(protocDependency.get())
}
}
2021-10-30 07:26:12 +02:00
logger.lifecycle("Downloading protoc")
val resolvedProtocDep = protocDep.singleFile
logger.lifecycle("Downloaded $resolvedProtocDep")
project.sync {
from(resolvedProtocDep)
into(outputDirectory)
2021-10-30 11:29:07 +02:00
logger.lifecycle("Syncing from $resolvedProtocDep to ${outputDirectory.asFile.get().canonicalPath}")
protocOutput.set(outputDirectory.asFileTree.singleFile)
}
}
}
abstract class ProtocGenerationTask : DefaultTask() {
@TaskAction
fun generate() {
logger.lifecycle("generating protoc...")
}
}
apply<ProtocPlugin>()
configure<ProtocPluginConfig> {
}
val logSS = tasks.create("logSourceSets") {
group = "protobuf"
doLast {
sourceSets.forEach { set ->
logger.lifecycle("SourceSet name: ${set.name}")
set.allSource.forEach { src ->
logger.lifecycle("location: ${src.toRelativeString(rootProject.projectDir)}")
}
}
logger.lifecycle("-------\nIdeaModel generated source dirs: ${project.idea.module.generatedSourceDirs.joinToString()}\n-------")
}
}
tasks.named("protobufCompile") { finalizedBy(logSS) }