mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-11-23 02:28:47 +00:00
commit
0d825cf424
@ -1,5 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## 0.16.12
|
||||
|
||||
* `Repos`:
|
||||
* `Exposed`:
|
||||
* `CommonExposedRepo.selectByIds` uses `foldRight` by default instead of raw foreach
|
||||
* `Koin`:
|
||||
* `Generator`:
|
||||
* Module has been created
|
||||
|
||||
## 0.16.11
|
||||
|
||||
* `LanguageCodes`:
|
||||
|
@ -9,6 +9,7 @@ buildscript {
|
||||
dependencies {
|
||||
classpath libs.buildscript.kt.gradle
|
||||
classpath libs.buildscript.kt.serialization
|
||||
classpath libs.buildscript.kt.ksp
|
||||
classpath libs.buildscript.jb.dokka
|
||||
classpath libs.buildscript.gh.release
|
||||
classpath libs.buildscript.android.gradle
|
||||
|
@ -29,6 +29,6 @@ allprojects {
|
||||
defaultAndroidSettingsPresetPath = "${rootProject.projectDir.absolutePath}/defaultAndroidSettings.gradle"
|
||||
|
||||
publishGradlePath = "${rootProject.projectDir.absolutePath}/publish.gradle"
|
||||
publishMavenPath = "${rootProject.projectDir.absolutePath}/maven.publish.gradle"
|
||||
publishJvmOnlyPath = "${rootProject.projectDir.absolutePath}/jvm.publish.gradle"
|
||||
}
|
||||
}
|
||||
|
@ -14,5 +14,5 @@ crypto_js_version=4.1.1
|
||||
# Project data
|
||||
|
||||
group=dev.inmo
|
||||
version=0.16.11
|
||||
android_code_version=179
|
||||
version=0.16.12
|
||||
android_code_version=180
|
||||
|
@ -19,6 +19,9 @@ gh-release = "2.4.1"
|
||||
|
||||
koin = "3.3.2"
|
||||
|
||||
ksp = "1.7.20-1.0.8"
|
||||
kotlin-poet = "1.12.0"
|
||||
|
||||
android-gradle = "7.3.0"
|
||||
dexcount = "3.1.0"
|
||||
|
||||
@ -83,9 +86,16 @@ android-test-junit = { module = "androidx.test.ext:junit", version.ref = "androi
|
||||
kt-test-js = { module = "org.jetbrains.kotlin:kotlin-test-js", version.ref = "kt" }
|
||||
kt-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kt" }
|
||||
|
||||
# ksp dependencies
|
||||
|
||||
kotlin-poet = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlin-poet" }
|
||||
ksp = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" }
|
||||
|
||||
# Buildscript
|
||||
|
||||
buildscript-kt-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kt" }
|
||||
buildscript-kt-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kt" }
|
||||
buildscript-kt-ksp = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "ksp" }
|
||||
buildscript-jb-dokka = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "jb-dokka" }
|
||||
buildscript-gh-release = { module = "com.github.breadmoirai:github-release", version.ref = "gh-release" }
|
||||
buildscript-android-gradle = { module = "com.android.tools.build:gradle", version.ref = "android-gradle" }
|
||||
|
118
jvm.publish.gradle
Normal file
118
jvm.publish.gradle
Normal file
@ -0,0 +1,118 @@
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
task javadocJar(type: Jar) {
|
||||
from javadoc
|
||||
classifier = 'javadoc'
|
||||
}
|
||||
task sourcesJar(type: Jar) {
|
||||
from sourceSets.main.allSource
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
maven(MavenPublication) {
|
||||
from components.java
|
||||
|
||||
artifact javadocJar
|
||||
artifact sourcesJar
|
||||
|
||||
pom {
|
||||
resolveStrategy = Closure.DELEGATE_FIRST
|
||||
|
||||
description = "It is set of projects with micro tools for avoiding of routines coding"
|
||||
name = "${project.name}"
|
||||
url = "https://github.com/InsanusMokrassar/MicroUtils/"
|
||||
|
||||
scm {
|
||||
developerConnection = "scm:git:[fetch=]https://github.com/InsanusMokrassar/MicroUtils.git[push=]https://github.com/InsanusMokrassar/MicroUtils.git"
|
||||
url = "https://github.com/InsanusMokrassar/MicroUtils.git"
|
||||
}
|
||||
|
||||
developers {
|
||||
|
||||
developer {
|
||||
id = "InsanusMokrassar"
|
||||
name = "Aleksei Ovsiannikov"
|
||||
email = "ovsyannikov.alexey95@gmail.com"
|
||||
}
|
||||
|
||||
|
||||
developer {
|
||||
id = "000Sanya"
|
||||
name = "Syrov Aleksandr"
|
||||
email = "000sanya.000sanya@gmail.com"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
licenses {
|
||||
|
||||
license {
|
||||
name = "Apache Software License 2.0"
|
||||
url = "https://github.com/InsanusMokrassar/MicroUtils/blob/master/LICENSE"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
if ((project.hasProperty('GITHUBPACKAGES_USER') || System.getenv('GITHUBPACKAGES_USER') != null) && (project.hasProperty('GITHUBPACKAGES_PASSWORD') || System.getenv('GITHUBPACKAGES_PASSWORD') != null)) {
|
||||
maven {
|
||||
name = "GithubPackages"
|
||||
url = uri("https://maven.pkg.github.com/InsanusMokrassar/MicroUtils")
|
||||
|
||||
credentials {
|
||||
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
|
||||
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (project.hasProperty('GITEA_TOKEN') || System.getenv('GITEA_TOKEN') != null) {
|
||||
maven {
|
||||
name = "Gitea"
|
||||
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven")
|
||||
|
||||
credentials(HttpHeaderCredentials) {
|
||||
name = "Authorization"
|
||||
value = project.hasProperty('GITEA_TOKEN') ? project.property('GITEA_TOKEN') : System.getenv('GITEA_TOKEN')
|
||||
}
|
||||
|
||||
authentication {
|
||||
header(HttpHeaderAuthentication)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
|
||||
maven {
|
||||
name = "sonatype"
|
||||
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
|
||||
|
||||
credentials {
|
||||
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
|
||||
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (project.hasProperty("signing.gnupg.keyName")) {
|
||||
apply plugin: 'signing'
|
||||
|
||||
signing {
|
||||
useGpgCmd()
|
||||
|
||||
sign publishing.publications
|
||||
}
|
||||
|
||||
task signAll {
|
||||
tasks.withType(Sign).forEach {
|
||||
dependsOn(it)
|
||||
}
|
||||
}
|
||||
}
|
1
jvm.publish.kpsb
Normal file
1
jvm.publish.kpsb
Normal file
@ -0,0 +1 @@
|
||||
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/MicroUtils/blob/master/LICENSE"}],"mavenConfig":{"name":"${project.name}","description":"It is set of projects with micro tools for avoiding of routines coding","url":"https://github.com/InsanusMokrassar/MicroUtils/","vcsUrl":"https://github.com/InsanusMokrassar/MicroUtils.git","developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"},{"id":"000Sanya","name":"Syrov Aleksandr","eMail":"000sanya.000sanya@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/MicroUtils"},{"name":"Gitea","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven","credsType":{"type":"dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository.CredentialsType.HttpHeaderCredentials","headerName":"Authorization","headerValueProperty":"GITEA_TOKEN"}},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}},"type":"JVM"}
|
100
koin/generator/README.md
Normal file
100
koin/generator/README.md
Normal file
@ -0,0 +1,100 @@
|
||||
# Koin generator
|
||||
|
||||
It is Kotlin Symbol Processing generator for `Koin` module in `MicroUtils`.
|
||||
|
||||
1. [What may do this generator](#what-may-do-this-generator)
|
||||
2. [How to add generator](#how-to-add-generator)
|
||||
|
||||
## What may do this generator
|
||||
|
||||
Let's imagine you want to have shortcuts in koin, to get something easily:
|
||||
|
||||
```kotlin
|
||||
val koin: Koin// some initialization
|
||||
|
||||
val someUrl = koin.serverUrl
|
||||
```
|
||||
|
||||
So, in that case you may mark containing file with next annotation (in the beginning of file):
|
||||
|
||||
```kotlin
|
||||
@file:GenerateKoinDefinition("serverUrl", String::class, nullable = false)
|
||||
```
|
||||
|
||||
If file is called like `Sample.kt`, will be generated file `GeneratedDefinitionsSample.kt` with next content:
|
||||
|
||||
```kotlin
|
||||
public val Scope.serverUrl: String
|
||||
get() = get(named("serverUrl"))
|
||||
|
||||
public val Koin.serverUrl: String
|
||||
get() = get(named("serverUrl"))
|
||||
|
||||
public fun Module.serverUrlSingle(createdAtStart: Boolean = false,
|
||||
definition: Definition<String>): KoinDefinition<String> =
|
||||
single(named("serverUrl"), createdAtStart = createdAtStart, definition = definition)
|
||||
|
||||
public fun Module.serverUrlFactory(definition: Definition<String>):
|
||||
KoinDefinition<String> = factory(named("serverUrl"), definition = definition)
|
||||
```
|
||||
|
||||
Besides, you may use the generics:
|
||||
|
||||
```kotlin
|
||||
@file:GenerateKoinDefinition("sampleInfo", Sample::class, G1::class, G2::class, nullable = false)
|
||||
```
|
||||
|
||||
Will generate:
|
||||
|
||||
```kotlin
|
||||
public val Scope.sampleInfo: Sample<G1, G2>
|
||||
get() = get(named("sampleInfo"))
|
||||
|
||||
public val Koin.sampleInfo: Sample<G1, G2>
|
||||
get() = get(named("sampleInfo"))
|
||||
|
||||
public fun Module.sampleInfoSingle(createdAtStart: Boolean = false,
|
||||
definition: Definition<Sample<G1, G2>>): KoinDefinition<Sample<G1, G2>> =
|
||||
single(named("sampleInfo"), createdAtStart = createdAtStart, definition = definition)
|
||||
|
||||
public fun Module.sampleInfoFactory(definition: Definition<Sample<G1, G2>>):
|
||||
KoinDefinition<Sample<G1, G2>> = factory(named("sampleInfo"), definition = definition)
|
||||
```
|
||||
|
||||
In case you wish not to generate single:
|
||||
|
||||
```kotlin
|
||||
@file:GenerateKoinDefinition("sampleInfo", Sample::class, G1::class, G2::class, nullable = false, generateSingle = false)
|
||||
```
|
||||
|
||||
And you will take next code:
|
||||
|
||||
```kotlin
|
||||
public val Scope.sampleInfo: Sample<G1, G2>
|
||||
get() = get(named("sampleInfo"))
|
||||
|
||||
public val Koin.sampleInfo: Sample<G1, G2>
|
||||
get() = get(named("sampleInfo"))
|
||||
|
||||
public fun Module.sampleInfoFactory(definition: Definition<Sample<G1, G2>>):
|
||||
KoinDefinition<Sample<G1, G2>> = factory(named("sampleInfo"), definition = definition)
|
||||
```
|
||||
|
||||
## How to add generator
|
||||
|
||||
**Note: $ksp_version in the samples above is equal to supported `ksp` version presented in `/gradle/libs.versions.toml` of project**
|
||||
|
||||
**Note: $microutils_version in the version of MicroUtils library in your project**
|
||||
|
||||
1. Add `classpath` in `build.gradle` (`classpath "com.google.devtools.ksp:symbol-processing-gradle-plugin:$ksp_version"`)
|
||||
2. Add plugin to the plugins list of your module: `id "com.google.devtools.ksp"`
|
||||
3. In `dependencies` block add to the required target/compile the dependency `dev.inmo:micro_utils.koin.generator:$microutils_version`:
|
||||
```groovy
|
||||
dependencies {
|
||||
add("kspCommonMainMetadata", "dev.inmo:micro_utils.koin.generator:$microutils_version") // will work in commonMain of your multiplatform module
|
||||
add("kspJvm", "dev.inmo:micro_utils.koin.generator:$microutils_version") // will work in main of your JVM module
|
||||
}
|
||||
|
||||
ksp { // this generator do not require any arguments and we should left `ksp` empty
|
||||
}
|
||||
```
|
15
koin/generator/build.gradle
Normal file
15
koin/generator/build.gradle
Normal file
@ -0,0 +1,15 @@
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.jvm"
|
||||
}
|
||||
|
||||
apply from: "$publishJvmOnlyPath"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api project(":micro_utils.koin")
|
||||
api libs.kotlin.poet
|
||||
api libs.ksp
|
||||
}
|
178
koin/generator/src/main/kotlin/Processor.kt
Normal file
178
koin/generator/src/main/kotlin/Processor.kt
Normal file
@ -0,0 +1,178 @@
|
||||
package dev.inmo.micro_utils.koin.generator
|
||||
|
||||
import com.google.devtools.ksp.KSTypeNotPresentException
|
||||
import com.google.devtools.ksp.KSTypesNotPresentException
|
||||
import com.google.devtools.ksp.KspExperimental
|
||||
import com.google.devtools.ksp.getAnnotationsByType
|
||||
import com.google.devtools.ksp.processing.CodeGenerator
|
||||
import com.google.devtools.ksp.processing.Resolver
|
||||
import com.google.devtools.ksp.processing.SymbolProcessor
|
||||
import com.google.devtools.ksp.symbol.KSAnnotated
|
||||
import com.google.devtools.ksp.symbol.KSFile
|
||||
import com.squareup.kotlinpoet.ClassName
|
||||
import com.squareup.kotlinpoet.FileSpec
|
||||
import com.squareup.kotlinpoet.FunSpec
|
||||
import com.squareup.kotlinpoet.ParameterSpec
|
||||
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
|
||||
import com.squareup.kotlinpoet.PropertySpec
|
||||
import com.squareup.kotlinpoet.asTypeName
|
||||
import com.squareup.kotlinpoet.ksp.toClassName
|
||||
import com.squareup.kotlinpoet.ksp.toTypeName
|
||||
import com.squareup.kotlinpoet.ksp.writeTo
|
||||
import dev.inmo.micro_utils.koin.annotations.GenerateKoinDefinition
|
||||
import org.koin.core.Koin
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.core.scope.Scope
|
||||
import java.io.File
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class Processor(
|
||||
private val codeGenerator: CodeGenerator
|
||||
) : SymbolProcessor {
|
||||
private val definitionClassName = ClassName("org.koin.core.definition", "Definition")
|
||||
private val koinDefinitionClassName = ClassName("org.koin.core.definition", "KoinDefinition")
|
||||
|
||||
@OptIn(KspExperimental::class)
|
||||
override fun process(resolver: Resolver): List<KSAnnotated> {
|
||||
resolver.getSymbolsWithAnnotation(
|
||||
GenerateKoinDefinition::class.qualifiedName!!
|
||||
).filterIsInstance<KSFile>().forEach { ksFile ->
|
||||
FileSpec.builder(
|
||||
ksFile.packageName.asString(),
|
||||
"GeneratedDefinitions${ksFile.fileName.removeSuffix(".kt")}"
|
||||
).apply {
|
||||
addFileComment(
|
||||
"""
|
||||
THIS CODE HAVE BEEN GENERATED AUTOMATICALLY
|
||||
TO REGENERATE IT JUST DELETE FILE
|
||||
ORIGINAL FILE: ${ksFile.fileName}
|
||||
""".trimIndent()
|
||||
)
|
||||
ksFile.getAnnotationsByType(GenerateKoinDefinition::class).forEach {
|
||||
val type = runCatching {
|
||||
it.type.asTypeName()
|
||||
}.getOrElse { e ->
|
||||
if (e is KSTypeNotPresentException) {
|
||||
e.ksType.toClassName()
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
val targetType = runCatching {
|
||||
type.parameterizedBy(*(it.typeArgs.takeIf { it.isNotEmpty() } ?.map { it.asTypeName() } ?.toTypedArray() ?: return@runCatching type))
|
||||
}.getOrElse { e ->
|
||||
when (e) {
|
||||
is KSTypeNotPresentException -> e.ksType.toClassName()
|
||||
}
|
||||
if (e is KSTypesNotPresentException) {
|
||||
type.parameterizedBy(*e.ksTypes.map { it.toTypeName() }.toTypedArray())
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}.copy(
|
||||
nullable = it.nullable
|
||||
)
|
||||
fun addGetterProperty(
|
||||
receiver: KClass<*>
|
||||
) {
|
||||
addProperty(
|
||||
PropertySpec.builder(
|
||||
it.name,
|
||||
targetType,
|
||||
).apply {
|
||||
addKdoc(
|
||||
"""
|
||||
@return Definition by key "${it.name}"
|
||||
""".trimIndent()
|
||||
)
|
||||
getter(
|
||||
FunSpec.getterBuilder().apply {
|
||||
addCode(
|
||||
"return " + (if (it.nullable) {
|
||||
"getOrNull"
|
||||
} else {
|
||||
"get"
|
||||
}) + "(named(\"${it.name}\"))"
|
||||
)
|
||||
}.build()
|
||||
)
|
||||
receiver(receiver)
|
||||
}.build()
|
||||
)
|
||||
}
|
||||
|
||||
addGetterProperty(Scope::class)
|
||||
addGetterProperty(Koin::class)
|
||||
|
||||
if (it.generateSingle) {
|
||||
addFunction(
|
||||
FunSpec.builder("${it.name}Single").apply {
|
||||
addKdoc(
|
||||
"""
|
||||
Will register [definition] with [org.koin.core.module.Module.single] and key "${it.name}"
|
||||
""".trimIndent()
|
||||
)
|
||||
receiver(Module::class)
|
||||
addParameter(
|
||||
ParameterSpec.builder(
|
||||
"createdAtStart",
|
||||
Boolean::class
|
||||
).apply {
|
||||
defaultValue("false")
|
||||
}.build()
|
||||
)
|
||||
addParameter(
|
||||
ParameterSpec.builder(
|
||||
"definition",
|
||||
definitionClassName.parameterizedBy(targetType.copy(nullable = false))
|
||||
).build()
|
||||
)
|
||||
returns(koinDefinitionClassName.parameterizedBy(targetType.copy(nullable = false)))
|
||||
addCode(
|
||||
"return single(named(\"${it.name}\"), createdAtStart = createdAtStart, definition = definition)"
|
||||
)
|
||||
}.build()
|
||||
)
|
||||
}
|
||||
|
||||
if (it.generateFactory) {
|
||||
addFunction(
|
||||
FunSpec.builder("${it.name}Factory").apply {
|
||||
addKdoc(
|
||||
"""
|
||||
Will register [definition] with [org.koin.core.module.Module.factory] and key "${it.name}"
|
||||
""".trimIndent()
|
||||
)
|
||||
receiver(Module::class)
|
||||
addParameter(
|
||||
ParameterSpec.builder(
|
||||
"definition",
|
||||
definitionClassName.parameterizedBy(targetType.copy(nullable = false))
|
||||
).build()
|
||||
)
|
||||
returns(koinDefinitionClassName.parameterizedBy(targetType.copy(nullable = false)))
|
||||
addCode(
|
||||
"return factory(named(\"${it.name}\"), definition = definition)"
|
||||
)
|
||||
}.build()
|
||||
)
|
||||
}
|
||||
addImport("org.koin.core.qualifier", "named")
|
||||
}
|
||||
}.build().let {
|
||||
File(
|
||||
File(ksFile.filePath).parent,
|
||||
"GeneratedDefinitions${ksFile.fileName}"
|
||||
).takeIf { !it.exists() } ?.apply {
|
||||
parentFile.mkdirs()
|
||||
|
||||
writer().use { writer ->
|
||||
it.writeTo(writer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return emptyList()
|
||||
}
|
||||
}
|
11
koin/generator/src/main/kotlin/Provider.kt
Normal file
11
koin/generator/src/main/kotlin/Provider.kt
Normal file
@ -0,0 +1,11 @@
|
||||
package dev.inmo.micro_utils.koin.generator
|
||||
|
||||
import com.google.devtools.ksp.processing.SymbolProcessor
|
||||
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
|
||||
import com.google.devtools.ksp.processing.SymbolProcessorProvider
|
||||
|
||||
class Provider : SymbolProcessorProvider {
|
||||
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor = Processor(
|
||||
environment.codeGenerator
|
||||
)
|
||||
}
|
@ -0,0 +1 @@
|
||||
dev.inmo.micro_utils.koin.generator.Provider
|
27
koin/generator/test/build.gradle
Normal file
27
koin/generator/test/build.gradle
Normal file
@ -0,0 +1,27 @@
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
id "org.jetbrains.kotlin.plugin.serialization"
|
||||
id "com.android.library"
|
||||
id "com.google.devtools.ksp"
|
||||
}
|
||||
|
||||
apply from: "$mppProjectWithSerializationPresetPath"
|
||||
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api project(":micro_utils.koin")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
add("kspCommonMainMetadata", project(":micro_utils.koin.generator"))
|
||||
}
|
||||
|
||||
ksp {
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
// THIS CODE HAVE BEEN GENERATED AUTOMATICALLY
|
||||
// TO REGENERATE IT JUST DELETE FILE
|
||||
// ORIGINAL FILE: Test.kt
|
||||
package dev.inmo.micro_utils.koin.generator.test
|
||||
|
||||
import kotlin.Boolean
|
||||
import kotlin.String
|
||||
import org.koin.core.Koin
|
||||
import org.koin.core.definition.Definition
|
||||
import org.koin.core.definition.KoinDefinition
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koin.core.scope.Scope
|
||||
|
||||
/**
|
||||
* @return Definition by key "sampleInfo"
|
||||
*/
|
||||
public val Scope.sampleInfo: Test<String>
|
||||
get() = get(named("sampleInfo"))
|
||||
|
||||
/**
|
||||
* @return Definition by key "sampleInfo"
|
||||
*/
|
||||
public val Koin.sampleInfo: Test<String>
|
||||
get() = get(named("sampleInfo"))
|
||||
|
||||
/**
|
||||
* Will register [definition] with [org.koin.core.module.Module.single] and key "sampleInfo"
|
||||
*/
|
||||
public fun Module.sampleInfoSingle(createdAtStart: Boolean = false,
|
||||
definition: Definition<Test<String>>): KoinDefinition<Test<String>> =
|
||||
single(named("sampleInfo"), createdAtStart = createdAtStart, definition = definition)
|
||||
|
||||
/**
|
||||
* Will register [definition] with [org.koin.core.module.Module.factory] and key "sampleInfo"
|
||||
*/
|
||||
public fun Module.sampleInfoFactory(definition: Definition<Test<String>>):
|
||||
KoinDefinition<Test<String>> = factory(named("sampleInfo"), definition = definition)
|
13
koin/generator/test/src/commonMain/kotlin/Test.kt
Normal file
13
koin/generator/test/src/commonMain/kotlin/Test.kt
Normal file
@ -0,0 +1,13 @@
|
||||
@file:GenerateKoinDefinition("sampleInfo", Test::class, String::class, nullable = false)
|
||||
package dev.inmo.micro_utils.koin.generator.test
|
||||
|
||||
import dev.inmo.micro_utils.koin.annotations.GenerateKoinDefinition
|
||||
import org.koin.core.Koin
|
||||
|
||||
class Test<T>(
|
||||
koin: Koin
|
||||
) {
|
||||
init {
|
||||
koin.sampleInfo
|
||||
}
|
||||
}
|
1
koin/generator/test/src/main/AndroidManifest.xml
Normal file
1
koin/generator/test/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1 @@
|
||||
<manifest package="dev.inmo.micro_utils.koin.generator.test"/>
|
@ -0,0 +1,28 @@
|
||||
package dev.inmo.micro_utils.koin.annotations
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Use this annotation to mark files near to which generator should place generated extensions for koin [org.koin.core.scope.Scope]
|
||||
* and [org.koin.core.Koin]
|
||||
*
|
||||
* @param name Name for definitions. This name will be available as extension for [org.koin.core.scope.Scope] and [org.koin.core.Koin]
|
||||
* @param type Type of extensions. It is base star-typed class
|
||||
* @param typeArgs Generic types for [type]. For example, if [type] == `Something::class` and [typeArgs] == `G1::class,
|
||||
* G2::class`, the result type will be `Something<G1, G2>`
|
||||
* @param nullable In case when true, extension will not throw error when definition has not been registered in koin
|
||||
* @param generateSingle Generate definition factory with [org.koin.core.module.Module.single]. You will be able to use
|
||||
* the extension [org.koin.core.module.Module].[name]Single(createdAtStart/* default false */) { /* your definition */ }
|
||||
* @param generateFactory Generate definition factory with [org.koin.core.module.Module.factory]. You will be able to use
|
||||
* the extension [org.koin.core.module.Module].[name]Factory { /* your definition */ }
|
||||
*/
|
||||
@Target(AnnotationTarget.FILE)
|
||||
@Repeatable
|
||||
annotation class GenerateKoinDefinition(
|
||||
val name: String,
|
||||
val type: KClass<*>,
|
||||
vararg val typeArgs: KClass<*>,
|
||||
val nullable: Boolean = true,
|
||||
val generateSingle: Boolean = true,
|
||||
val generateFactory: Boolean = true
|
||||
)
|
@ -7,15 +7,9 @@ interface CommonExposedRepo<IdType, ObjectType> : ExposedRepo {
|
||||
val ResultRow.asId: IdType
|
||||
val selectById: ISqlExpressionBuilder.(IdType) -> Op<Boolean>
|
||||
val selectByIds: ISqlExpressionBuilder.(List<IdType>) -> Op<Boolean>
|
||||
get() = { list ->
|
||||
if (list.isEmpty()) {
|
||||
Op.FALSE
|
||||
} else {
|
||||
var op = selectById(list.first())
|
||||
(1 until list.size).forEach {
|
||||
op = op.or(selectById(list[it]))
|
||||
}
|
||||
op
|
||||
}
|
||||
get() = {
|
||||
it.foldRight<IdType, Op<Boolean>?>(null) { id, acc ->
|
||||
acc ?.or(selectById(id)) ?: selectById(id)
|
||||
} ?: Op.FALSE
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ String[] includes = [
|
||||
":safe_wrapper",
|
||||
":crypto",
|
||||
":koin",
|
||||
":koin:generator",
|
||||
":koin:generator:test",
|
||||
":selector:common",
|
||||
":pagination:common",
|
||||
":pagination:exposed",
|
||||
|
@ -39,14 +39,18 @@ object StartLauncherPlugin : StartPlugin {
|
||||
|
||||
includes(
|
||||
config.plugins.mapNotNull {
|
||||
val pluginName = it::class.simpleName ?: it.toString()
|
||||
runCatching {
|
||||
logger.i { "Start koin module registration for $pluginName" }
|
||||
module {
|
||||
with(it) {
|
||||
setupDI(rawJsonObject)
|
||||
}
|
||||
}
|
||||
}.onFailure { e ->
|
||||
logger.w("Unable to load DI part of $it", e)
|
||||
logger.w("Unable to register koin module of $pluginName", e)
|
||||
}.onSuccess {
|
||||
logger.i("Successfully registered koin module of $pluginName")
|
||||
}.getOrNull()
|
||||
}
|
||||
)
|
||||
@ -76,16 +80,17 @@ object StartLauncherPlugin : StartPlugin {
|
||||
logger.i("Start starting of subplugins")
|
||||
val scope = koin.get<CoroutineScope>()
|
||||
koin.get<Config>().plugins.map { plugin ->
|
||||
val pluginName = plugin::class.simpleName ?: plugin.toString()
|
||||
scope.launch {
|
||||
runCatchingSafely {
|
||||
logger.i("Start loading of $plugin")
|
||||
logger.i("Start loading of $pluginName")
|
||||
with(plugin) {
|
||||
startPlugin(koin)
|
||||
}
|
||||
}.onFailure { e ->
|
||||
logger.w("Unable to start plugin $plugin", e)
|
||||
logger.w("Unable to start plugin $pluginName", e)
|
||||
}.onSuccess {
|
||||
logger.i("Complete loading of $plugin")
|
||||
logger.i("Complete loading of $pluginName")
|
||||
}
|
||||
}
|
||||
}.joinAll()
|
||||
|
Loading…
Reference in New Issue
Block a user