Skip to content

Commit 3567ef4

Browse files
authored
Added Koin to plugin in project template. (#40)
1 parent 7b2d66e commit 3567ef4

26 files changed

+344
-87
lines changed

cli/src/main/kotlin/com/mitteloupe/cag/cli/AppArgumentProcessor.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class AppArgumentProcessor(
127127
.parsePrimaryWithSecondaries(arguments = arguments, primaryFlag = NewArchitecturePrimary)
128128
.map { secondaries ->
129129
ArchitectureRequest(
130+
appModuleDirectory = null,
130131
dependencyInjection = DependencyInjection.Hilt,
131132
enableCompose = !secondaries.containsKey(SecondaryFlagConstants.NO_COMPOSE),
132133
enableKtlint = secondaries.containsKey(SecondaryFlagConstants.KTLINT),

cli/src/main/kotlin/com/mitteloupe/cag/cli/Main.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ fun main(arguments: Array<String>) {
116116
val architecturePackageName = basePackage?.let { "$it.architecture" } ?: "com.unknown.app.architecture"
117117
val architectureRequest =
118118
GenerateArchitectureRequest(
119+
projectNamespace = projectNamespace,
119120
destinationRootDirectory = destinationRootDirectory,
121+
appModuleDirectory = request.appModuleDirectory,
120122
architecturePackageName = architecturePackageName,
121123
dependencyInjection = request.dependencyInjection,
122124
enableCompose = request.enableCompose,

cli/src/main/kotlin/com/mitteloupe/cag/cli/request/ArchitectureRequest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.mitteloupe.cag.cli.request
22

33
import com.mitteloupe.cag.core.option.DependencyInjection
4+
import java.io.File
45

56
data class ArchitectureRequest(
7+
val appModuleDirectory: File?,
68
val dependencyInjection: DependencyInjection,
79
val enableCompose: Boolean,
810
val enableKtlint: Boolean,

core/src/main/kotlin/com/mitteloupe/cag/core/Generator.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class Generator(
3030
projectNamespace = request.projectNamespace,
3131
destinationRootDirectory = request.destinationRootDirectory,
3232
appModuleDirectory = request.appModuleDirectory,
33+
dependencyInjection = request.dependencyInjection,
3334
enableCompose = request.enableCompose,
3435
enableKtlint = request.enableKtlint,
3536
enableDetekt = request.enableDetekt
@@ -81,7 +82,9 @@ class Generator(
8182

8283
fun generateArchitecture(request: GenerateArchitectureRequest) {
8384
architectureFilesGenerator.generateArchitecture(
85+
projectNamespace = request.projectNamespace,
8486
destinationRootDirectory = request.destinationRootDirectory,
87+
appModuleDirectory = request.appModuleDirectory,
8588
architecturePackageName = request.architecturePackageName,
8689
dependencyInjection = request.dependencyInjection,
8790
enableCompose = request.enableCompose,

core/src/main/kotlin/com/mitteloupe/cag/core/GeneratorFactory.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ class GeneratorFactory(
6464
architectureModulesContentGenerator,
6565
settingsFileUpdater,
6666
buildSrcContentCreator,
67-
configurationFileCreator
67+
configurationFileCreator,
68+
appModuleContentGenerator
6869
)
6970
val featureFilesGenerator =
7071
FeatureFilesGenerator(

core/src/main/kotlin/com/mitteloupe/cag/core/content/AppFeatureModuleKotlinFileBuilder.kt renamed to core/src/main/kotlin/com/mitteloupe/cag/core/content/AppFeatureDependencyInjectionModuleKotlinFileBuilder.kt

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,41 @@
11
package com.mitteloupe.cag.core.content
22

33
import com.mitteloupe.cag.core.generation.format.optimizeImports
4+
import com.mitteloupe.cag.core.option.DependencyInjection
45

5-
fun buildAppFeatureModuleKotlinFile(
6+
fun buildAppFeatureDependencyInjectionModuleKotlinFile(
67
projectNamespace: String,
78
featurePackageName: String,
8-
featureName: String
9+
featureName: String,
10+
dependencyInjection: DependencyInjection
911
): String {
1012
val className = featureName.capitalized
1113
val variableName = className.replaceFirstChar { it.lowercase() }
12-
return """package $projectNamespace.di
13-
14-
${
15-
"""
16-
import dagger.Module
17-
import dagger.Provides
18-
import dagger.hilt.InstallIn
19-
import dagger.hilt.components.SingletonComponent
20-
import $featurePackageName.data.repository.${className}Repository
14+
val providedImports = """import $featurePackageName.data.repository.${className}Repository
2115
import $featurePackageName.domain.repository.PerformActionRepository
2216
import $featurePackageName.domain.usecase.PerformActionUseCase
2317
import $featurePackageName.presentation.mapper.StubDomainMapper
2418
import $featurePackageName.presentation.mapper.StubPresentationMapper
2519
import $featurePackageName.presentation.viewmodel.${className}ViewModel
26-
import $featurePackageName.presentation.navigation.${className}PresentationNavigationEvent
2720
import $featurePackageName.ui.di.${className}Dependencies
2821
import $featurePackageName.ui.mapper.StubUiMapper
22+
"""
23+
return when (dependencyInjection) {
24+
DependencyInjection.Hilt -> {
25+
"""package $projectNamespace.di
26+
27+
${
28+
"""import dagger.Module
29+
import dagger.Provides
30+
import dagger.hilt.InstallIn
31+
import dagger.hilt.components.SingletonComponent
2932
import $projectNamespace.architecture.domain.UseCaseExecutor
3033
import $projectNamespace.architecture.presentation.notification.PresentationNotification
3134
import $projectNamespace.architecture.ui.navigation.mapper.NavigationEventDestinationMapper
3235
import $projectNamespace.architecture.ui.notification.mapper.NotificationUiMapper
33-
""".optimizeImports()
34-
}
36+
import $featurePackageName.presentation.navigation.${className}PresentationNavigationEvent
37+
$providedImports""".optimizeImports()
38+
}
3539
@Module
3640
@InstallIn(SingletonComponent::class)
3741
object ${className}Module {
@@ -75,4 +79,26 @@ object ${className}Module {
7579
)
7680
}
7781
"""
82+
}
83+
DependencyInjection.Koin -> {
84+
"""package $projectNamespace.di
85+
86+
${
87+
"""import org.koin.core.module.dsl.factoryOf
88+
import org.koin.dsl.module
89+
$providedImports""".optimizeImports()
90+
}
91+
val ${className.first().lowercase() + className.substring(1)}Module = module {
92+
factory { StubDomainMapper() }
93+
factory { StubPresentationMapper() }
94+
factory<PerformActionRepository> { ${className}Repository() }
95+
factoryOf(::PerformActionUseCase)
96+
factoryOf(::${className}ViewModel)
97+
factory { StubUiMapper() }
98+
factoryOf(::${className}Dependencies)
99+
}
100+
"""
101+
}
102+
DependencyInjection.None -> error("Unexpected dependency injection option: $dependencyInjection")
103+
}
78104
}

core/src/main/kotlin/com/mitteloupe/cag/core/content/ApplicationKotlinFileBuilder.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ fun buildApplicationKotlinFile(
2424
DependencyInjection.Koin -> {
2525
val optimizedImports =
2626
"""import $projectNamespace.di.architectureModule
27+
import $projectNamespace.di.sampleFeatureModule
2728
import android.app.Application
2829
import org.koin.android.ext.koin.androidContext
2930
import org.koin.android.ext.koin.androidLogger
@@ -40,7 +41,7 @@ class ${appName}Application : Application() {
4041
private fun initKoin(config : KoinAppDeclaration? = null){
4142
startKoin {
4243
includes(config)
43-
modules(architectureModule)
44+
modules(architectureModule, sampleFeatureModule)
4445
}
4546
}
4647
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.mitteloupe.cag.core.content
2+
3+
import com.mitteloupe.cag.core.generation.format.optimizeImports
4+
import com.mitteloupe.cag.core.option.DependencyInjection
5+
6+
fun buildArchitectureDependencyInjectionModuleKotlinFile(
7+
projectNamespace: String,
8+
dependencyInjection: DependencyInjection
9+
): String {
10+
val commonImports =
11+
"""import $projectNamespace.architecture.domain.UseCaseExecutor
12+
"""
13+
return when (dependencyInjection) {
14+
DependencyInjection.Hilt -> {
15+
"""package $projectNamespace.di
16+
17+
${
18+
"""
19+
import dagger.Module
20+
import dagger.Provides
21+
import dagger.hilt.InstallIn
22+
import dagger.hilt.components.SingletonComponent
23+
$commonImports
24+
""".optimizeImports()
25+
}
26+
@Module
27+
@InstallIn(SingletonComponent::class)
28+
object ArchitectureModule {
29+
@Provides
30+
fun providesUseCaseExecutor(): UseCaseExecutor = UseCaseExecutor()
31+
}
32+
"""
33+
}
34+
DependencyInjection.Koin -> {
35+
"""package $projectNamespace.di
36+
37+
${
38+
"""import org.koin.dsl.module
39+
$commonImports
40+
""".optimizeImports()
41+
}
42+
val architectureModule = module {
43+
single { UseCaseExecutor() }
44+
}
45+
"""
46+
}
47+
DependencyInjection.None -> error("Unexpected dependency injection option: $dependencyInjection")
48+
}
49+
}

core/src/main/kotlin/com/mitteloupe/cag/core/generation/app/AppModuleContentGenerator.kt

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ package com.mitteloupe.cag.core.generation.app
33
import com.mitteloupe.cag.core.AppModuleDirectoryFinder
44
import com.mitteloupe.cag.core.DirectoryFinder
55
import com.mitteloupe.cag.core.content.buildAndroidManifest
6-
import com.mitteloupe.cag.core.content.buildAppFeatureModuleKotlinFile
6+
import com.mitteloupe.cag.core.content.buildAppFeatureDependencyInjectionModuleKotlinFile
77
import com.mitteloupe.cag.core.content.buildApplicationKotlinFile
8+
import com.mitteloupe.cag.core.content.buildArchitectureDependencyInjectionModuleKotlinFile
89
import com.mitteloupe.cag.core.content.buildBackupRulesXml
910
import com.mitteloupe.cag.core.content.buildColorsKt
1011
import com.mitteloupe.cag.core.content.buildDataExtractionRulesXml
@@ -26,13 +27,50 @@ class AppModuleContentGenerator(
2627
private val fileCreator: FileCreator,
2728
private val directoryFinder: DirectoryFinder
2829
) {
29-
fun writeFeatureModuleIfPossible(
30+
fun writeArchitectureDependencyInjectionModuleIfPossible(
31+
startDirectory: File,
32+
projectNamespace: String,
33+
appModuleDirectory: File?,
34+
dependencyInjection: DependencyInjection
35+
) {
36+
if (dependencyInjection is DependencyInjection.None) {
37+
return
38+
}
39+
40+
val rootDirectory =
41+
appModuleDirectory ?: run {
42+
val projectRoot = findGradleProjectRoot(startDirectory, directoryFinder) ?: startDirectory
43+
val appModuleDirectories =
44+
AppModuleDirectoryFinder(directoryFinder).findAndroidAppModuleDirectories(projectRoot)
45+
if (appModuleDirectories.isEmpty()) {
46+
return
47+
} else {
48+
appModuleDirectories.first()
49+
}
50+
}
51+
val sourceRoot = File(rootDirectory, "src/main/java")
52+
val basePackageDirectory = buildPackageDirectory(sourceRoot, projectNamespace.toSegments())
53+
val dependencyInjectionDirectory = createDirectoryIfNotExists(basePackageDirectory, "di")
54+
createFileIfNotExists(dependencyInjectionDirectory, "ArchitectureModule.kt") {
55+
buildArchitectureDependencyInjectionModuleKotlinFile(
56+
projectNamespace = projectNamespace,
57+
dependencyInjection = dependencyInjection
58+
)
59+
}
60+
}
61+
62+
fun writeFeatureDependencyInjectionModuleIfPossible(
3063
startDirectory: File,
3164
projectNamespace: String,
3265
featureName: String,
3366
featurePackageName: String,
34-
appModuleDirectory: File?
67+
appModuleDirectory: File?,
68+
dependencyInjection: DependencyInjection
3569
) {
70+
if (dependencyInjection is DependencyInjection.None) {
71+
return
72+
}
73+
3674
val rootDirectory =
3775
appModuleDirectory ?: run {
3876
val projectRoot = findGradleProjectRoot(startDirectory, directoryFinder) ?: startDirectory
@@ -48,7 +86,12 @@ class AppModuleContentGenerator(
4886
val basePackageDirectory = buildPackageDirectory(sourceRoot, projectNamespace.toSegments())
4987
val dependencyInjectionDirectory = createDirectoryIfNotExists(basePackageDirectory, "di")
5088
createFileIfNotExists(dependencyInjectionDirectory, "${featureName.capitalized}Module.kt") {
51-
buildAppFeatureModuleKotlinFile(projectNamespace, featurePackageName, featureName)
89+
buildAppFeatureDependencyInjectionModuleKotlinFile(
90+
projectNamespace = projectNamespace,
91+
featurePackageName = featurePackageName,
92+
featureName = featureName,
93+
dependencyInjection = dependencyInjection
94+
)
5295
}
5396
}
5497

core/src/main/kotlin/com/mitteloupe/cag/core/generation/architecture/ArchitectureModulesContentGenerator.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class ArchitectureModulesContentGenerator(
6767
)
6868
if (dependencyInjection == DependencyInjection.Hilt) {
6969
addAll(LibraryConstants.HILT_LIBRARIES)
70+
add(LibraryConstants.TEST_ANDROID_HILT)
7071
}
7172
addAll(
7273
if (enableCompose) {

0 commit comments

Comments
 (0)