ru.pocketbyte.locolaser.kotlinmpp.KotlinMultiplatformResourcesConfigBuilder.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of resource-kotlin-mpp Show documentation
Show all versions of resource-kotlin-mpp Show documentation
Implementation of platform for LocoLaser tool to work with Kotlin MPP projects.
The newest version!
package ru.pocketbyte.locolaser.kotlinmpp
import groovy.lang.Closure
import org.gradle.api.Project
import ru.pocketbyte.locolaser.config.resources.ResourcesConfig
import ru.pocketbyte.locolaser.config.resources.ResourcesConfigBuilder
import ru.pocketbyte.locolaser.config.resources.ResourcesSetConfig
import ru.pocketbyte.locolaser.config.resources.filter.RegExResourcesFilter
import ru.pocketbyte.locolaser.config.resources.filter.ResourcesFilter
import ru.pocketbyte.locolaser.kotlinmpp.builder.BaseKmpBuilder
import ru.pocketbyte.locolaser.kotlinmpp.builder.BaseKmpClassBuilder
import ru.pocketbyte.locolaser.kotlinmpp.builder.CustomFormattingClassBuilderFactory
import ru.pocketbyte.locolaser.kotlinmpp.builder.FixedFormattingClassBuilderFactory
import ru.pocketbyte.locolaser.kotlinmpp.builder.KmpClassCustomFormattingBuilder
import ru.pocketbyte.locolaser.kotlinmpp.builder.KmpClassFixedFormattingBuilder
import ru.pocketbyte.locolaser.kotlinmpp.builder.KmpInterfaceBuilder
import ru.pocketbyte.locolaser.kotlinmpp.extension.kotlin
import ru.pocketbyte.locolaser.utils.callWithDelegate
import java.io.File
class KotlinMultiplatformResourcesConfigBuilder(
private val project: Project?
) : ResourcesConfigBuilder {
/**
* Package of the Repository that should be used in interface and class names.
* Package will be ignored if interface name or class name contains canonical name.
* By default package will taken from project.group if it provided.
*/
var repositoryPackage: String? = null
get() = if (field == null) {
project?.group?.toString()
} else {
field
}
/**
* Canonical or Simple name of the Repository interface that
* should be implemented by generated classes.
* If empty there will no interfaces implemented by generated Repository classes.
*/
var repositoryInterface: String? = null
/**
* Canonical or Simple name of the Repository class that
* should be generated for each platform.
*/
var repositoryClass: String? = null
/**
* Source dir path.
*/
var srcDir: String = "./build/generated/locolaser/"
/**
* Filter function.
* If defined, only strings that suits the filter will be added as Repository fields.
*/
@Deprecated(
"Lambda function for filter is deprecated and will be replaced with ResourcesFilter" +
" in future builds. Please, use filter(filter: ResourcesFilter?) or" +
" filter(regExp: String) instead."
)
var filter: ((key: String) -> Boolean)? = null
/**
* Filter function.
* If defined, only strings that suits the filter will be added as Repository fields.
*/
var resourcesFilter: ResourcesFilter? = null
set(value) {
field = value
filter = null
}
private val platformCommon: KmpInterfaceBuilder = KmpInterfaceBuilder()
private val platformMap = mutableMapOf>()
init {
project?.afterEvaluate {
it.kotlin {
sourceSets.apply {
commonMain {
val sourcesDir = platformCommon.sourcesDir
?: BaseKmpBuilder.defaultSourcesDir(srcDir, platformCommon)
kotlin.srcDir(sourcesDir)
}
platformMap.values.forEach { builder ->
val sourcesDir = builder.sourcesDir
?: BaseKmpBuilder.defaultSourcesDir(srcDir, builder)
val sourceSet = findByName(builder.sourceSet)
?: throw IllegalArgumentException(
"Missing sourceSet `${builder.sourceSet}`"
)
sourceSet.kotlin.srcDir(sourcesDir)
}
}
}
}
}
/**
* If defined, only strings with keys that matches filter will be added as Repository fields.
* @param filter Only strings with keys that matches filter will be added as Repository fields.
*/
fun filter(filter: ResourcesFilter?) {
this.resourcesFilter = filter
this.filter = null
}
/**
* If defined, only strings with keys that matches RegExp will be added as Repository fields.
* @param regExp RegExp String. Only strings with keys that matches RegExp will be added as Repository fields.
*/
fun filter(regExp: String) {
resourcesFilter = RegExResourcesFilter(regExp)
this.filter = null
}
/**
* Configure Repository interface in common module.
*/
fun common(action: KmpInterfaceBuilder.() -> Unit) {
action.invoke(platformCommon)
}
/**
* Configure Repository interface in common module.
*/
fun common(action: Closure) {
common { action.callWithDelegate(this) }
}
/**
* Configure Repository implementation for Android platform.
* There is no Android implementation will be generated if Android platform wasn't be configured.
*/
fun android() {
android(null)
}
/**
* Configure Repository implementation for Android platform.
* There is no Android implementation will be generated if Android platform wasn't be configured.
*/
fun android(action: (KmpClassFixedFormattingBuilder.() -> Unit)?) {
platform("android", KotlinAndroidResourcesConfig, action ?: {})
}
/**
* Configure Repository implementation for Android platform.
* There is no Android implementation will be generated if Android platform wasn't be configured.
*/
fun android(action: Closure) {
android { action.callWithDelegate(this) }
}
/**
* Configure Repository implementation for iOS platform.
* There is no iOS implementation will be generated if iOS platform wasn't be configured.
*/
fun ios() {
ios(null)
}
/**
* Configure Repository implementation for iOS platform.
* There is no iOS implementation will be generated if iOS platform wasn't be configured.
*/
fun ios(action: (KmpClassFixedFormattingBuilder.() -> Unit)?) {
platform("ios", KotlinIosResourcesConfig, action ?: {})
}
/**
* Configure Repository implementation for iOS platform.
* There is no iOS implementation will be generated if iOS platform wasn't be configured.
*/
fun ios(action: Closure) {
ios { action.callWithDelegate(this) }
}
/**
* Configure Repository implementation for JS platform.
* There is no JS implementation will be generated if JS platform wasn't be configured.
*/
fun js() {
js(null)
}
/**
* Configure Repository implementation for JS platform.
* There is no JS implementation will be generated if JS platform wasn't be configured.
*/
fun js(action: (KmpClassFixedFormattingBuilder.() -> Unit)?) {
platform("js", KotlinJsResourcesConfig, action ?: {})
}
/**
* Configure Repository implementation for JS platform.
* There is no JS implementation will be generated if JS platform wasn't be configured.
*/
fun js(action: Closure) {
js { action.callWithDelegate(this) }
}
/**
* Configure abstract KeyValue Repository implementation for provided platform name.
* This config generates abstract strings Repository implementation, that can be used in any target.
*/
fun absKeyValue(
name: String,
action: (KmpClassCustomFormattingBuilder.() -> Unit)?
) {
platformWithFormat(name, KotlinAbsKeyValueResourcesConfig, action ?: {})
}
/**
* Configure abstract KeyValue Repository implementation for provided platform name.
* This config generates abstract strings Repository implementation, that can be used in any target.
*/
fun absKeyValue(
name: String,
action: Closure
) {
absKeyValue(name) { action.callWithDelegate(this) }
}
/**
* Configure abstract Static Repository implementation for provided platform name.
* This config generates abstract strings Repository implementation, that can be used in any target.
*/
fun absStatic(
name: String,
action: (KmpClassCustomFormattingBuilder.() -> Unit)?
) {
platformWithFormat(name, KotlinAbsStaticResourcesConfig, action ?: {})
}
/**
* Configure abstract Static Repository implementation for provided platform name.
* This config generates abstract strings Repository implementation, that can be used in any target.
*/
fun absStatic(
name: String,
action: Closure
) {
absStatic(name) { action.callWithDelegate(this) }
}
/**
* Configure abstract Proxy Repository implementation for provided platform name.
* This config generates abstract strings Repository implementation, that can be used in any target.
*/
fun absProxy(
name: String,
action: (KmpClassFixedFormattingBuilder.() -> Unit)?
) {
platform(name, KotlinAbsProxyResourcesConfig, action ?: {})
}
/**
* Configure abstract Proxy Repository implementation for provided platform name.
* This config generates abstract strings Repository implementation, that can be used in any target.
*/
fun absProxy(
name: String,
action: Closure
) {
absProxy(name) { action.callWithDelegate(this) }
}
/**
* Configure Repository implementation for provided platform type.
* @param name Name of platform.
* @param config Platform Configuration instance.
* Class should not be abstract and should have a constructor without parameters.
* @param action Configure action.
*/
fun platform (
name: String,
builderFactory: FixedFormattingClassBuilderFactory,
action: (KmpClassFixedFormattingBuilder.() -> Unit)
) {
val platformBuilder = platformMap[name] as? KmpClassFixedFormattingBuilder
?: KmpClassFixedFormattingBuilder(name, builderFactory).apply {
sourceSet = "${name}Main"
platformMap[name] = this
}
action(platformBuilder)
}
/**
* Configure Repository implementation for provided platform type.
* @param name Name of platform.
* @param config Platform Configuration instance.
* Class should not be abstract and should have a constructor without parameters.
* @param action Configure action.
*/
fun platform (
name: String,
builderFactory: FixedFormattingClassBuilderFactory,
action: Closure
) {
platform(name, builderFactory) {
action.callWithDelegate(this)
}
}
/**
* Configure Repository implementation for provided platform type.
* @param name Name of platform.
* @param config Platform Configuration instance.
* Class should not be abstract and should have a constructor without parameters.
* @param action Configure action.
*/
private fun platformWithFormat (
name: String,
builderFactory: CustomFormattingClassBuilderFactory,
action: (KmpClassCustomFormattingBuilder.() -> Unit)
) {
val platformBuilder = platformMap[name] as? KmpClassCustomFormattingBuilder
?: KmpClassCustomFormattingBuilder(name, builderFactory).apply {
sourceSet = "${name}Main"
platformMap[name] = this
}
action(platformBuilder)
}
override fun build(workDir: File?): ResourcesConfig {
val resultSet = LinkedHashSet()
val commonConfig = platformCommon.build(workDir, this)
resultSet.add(commonConfig)
platformMap.values.forEach { builder ->
builder.build(workDir, this) {
this.implements = commonConfig.resourceName
}.let {
resultSet.add(it)
}
}
return ResourcesSetConfig(resultSet)
}
}