Skip to content

Commit fcec49c

Browse files
cdsaprenovate[bot]
andauthored
Adding di parameter (#237)
* initial di test * adding di parameter * adding latest Metro versions * chore(deps): update dependency com.google.dagger:hilt-android to v2.59.1 (#236) * chore(deps): update dependency com.google.dagger:hilt-android to v2.59.1 * using latest agp version --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Inaki Villar <inaki.seri@gmail.com> * initial di test * fixing tests --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
1 parent c503593 commit fcec49c

24 files changed

Lines changed: 450 additions & 149 deletions

File tree

.github/renovate.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@
8888
"depNameTemplate": "androidx.hilt:hilt-navigation-compose",
8989
"datasourceTemplate": "maven"
9090
},
91+
{
92+
"fileMatch": ["^.*Versions\\.kt$"],
93+
"matchStrings": ["val metro: String = \"(?<currentValue>\\d+\\.\\d+\\.\\d+)\""],
94+
"depNameTemplate": "dev.zacsweers.metro:dev.zacsweers.metro.gradle.plugin",
95+
"datasourceTemplate": "maven"
96+
},
9197
{
9298
"fileMatch": ["^.*Versions\\.kt$"],
9399
"matchStrings": ["val composeBom: String = \"(?<currentValue>\\d+\\.\\d+\\.\\d+)\""],

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Then, you can use the versions.yaml in the `generate-project` command:
4040
- `--layers`: Number of layers (default: 5)
4141
- `--language`: kts (default), groovy, both
4242
- `--type`: android (default), jvm
43+
- `--di`: hilt (default), metro, none
4344
- `--classes-module`: Number of classes per module (default: 5)
4445
- `--classes-module-type`: fixed (default), random
4546
- `--type-of-string-resources`: normal (default), large
@@ -66,7 +67,7 @@ ProjectGenerator(
6667
language = Language.KTS,
6768
typeOfProjectRequested = TypeProjectRequested.ANDROID,
6869
classesPerModule = ClassesPerModule(ClassesPerModuleType.FIXED, 20),
69-
versions = Versions(project = Project(jdk = "17")),
70+
versions = Versions(project = Project(jdk = "17"), di = DependencyInjection.HILT),
7071
typeOfStringResources = TypeOfStringResources.LARGE,
7172
layers = 5,
7273
generateUnitTest = true,

build.gradle.kts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ plugins {
55
alias(libs.plugins.ktlint)
66
}
77

8-
98
project.extensions.getByType(KotlinJvmProjectExtension::class.java).apply {
109
jvmToolchain(23)
1110
}
12-

cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/GenerateVersionsYaml.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class GenerateVersionsYaml {
1313
| develocity: ${versions.project.develocity}
1414
| develocityUrl: ${versions.project.develocityUrl}
1515
| jdk: ${versions.project.jdk}
16+
|di: ${versions.di}
1617
|kotlin:
1718
| kgp: ${versions.kotlin.kgp}
1819
| ksp: ${versions.kotlin.ksp}
@@ -31,6 +32,8 @@ class GenerateVersionsYaml {
3132
| work: ${versions.android.work}
3233
| hilt: ${versions.android.hilt}
3334
| hiltAandroidx: ${versions.android.hiltAandroidx}
35+
| metro: ${versions.android.metro}
36+
| metroPlugin: ${versions.android.metroPlugin}
3437
| composeBom: ${versions.android.composeBom}
3538
|testing:
3639
| junit4: ${versions.testing.junit4}

cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/Main.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class GenerateProjects : CliktCommand(name = "generate-project") {
3838
private val modules by option().int().required()
3939
.check("max number of projects 4000") { it in (layers + 1)..4000 }
4040
private val type by option().choice("android", "jvm").default("android")
41+
private val di: String by option().choice("hilt", "metro", "none").default("hilt")
4142
private val classesModule by option().int().default(5)
4243
private val classesModuleType: String by option().choice("fixed", "random").default("fixed")
4344
private val typeOfStringResources: String by option().choice("large", "normal").default("normal")
@@ -62,7 +63,8 @@ class GenerateProjects : CliktCommand(name = "generate-project") {
6263
override fun run() {
6364
val typeOfProjectRequested = TypeProjectRequested.valueOf(type.uppercase())
6465
val shape = Shape.valueOf(shape.uppercase())
65-
val versions = getVersions(versionsFile, develocityUrl, agp9)
66+
val dependencyInjection = DependencyInjection.valueOf(di.uppercase())
67+
val versions = getVersions(versionsFile, develocityUrl, agp9).copy(di = dependencyInjection)
6668
val develocityEnabled = getDevelocityEnabled(develocity, develocityUrl)
6769
ProjectGenerator(
6870
modules,
Lines changed: 98 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
package io.github.cdsap.projectgenerator.generator.android
22

3+
import io.github.cdsap.projectgenerator.model.DependencyInjection
34
import io.github.cdsap.projectgenerator.model.LanguageAttributes
45
import io.github.cdsap.projectgenerator.model.ProjectGraph
56
import io.github.cdsap.projectgenerator.NameMappings
7+
import io.github.cdsap.projectgenerator.generator.classes.GenerateDictionaryAndroid
8+
import io.github.cdsap.projectgenerator.model.ClassTypeAndroid
69
import java.io.File
10+
import java.util.concurrent.CopyOnWriteArrayList
711

812
class AndroidApplication {
9-
fun createApplicationClass(node: ProjectGraph, lang: LanguageAttributes) {
13+
fun createApplicationClass(
14+
node: ProjectGraph,
15+
lang: LanguageAttributes,
16+
di: DependencyInjection,
17+
dictionary: MutableMap<String, CopyOnWriteArrayList<GenerateDictionaryAndroid>>
18+
) {
1019
val layerDir = NameMappings.layerName(node.layer)
1120
val moduleDir = NameMappings.moduleName(node.id)
1221
val packageDir = NameMappings.modulePackageName(node.id)
@@ -15,60 +24,94 @@ class AndroidApplication {
1524
appDir.mkdirs()
1625
val appFile = File(appDir, "MainApplication.kt")
1726

18-
// Create a more robust Application class that properly initializes Hilt
19-
val appContent = """
20-
|package com.awesomeapp.$packageDir
21-
|
22-
|import android.app.Application
23-
|import android.content.Context
24-
|import androidx.hilt.work.HiltWorkerFactory
25-
|import androidx.work.Configuration
26-
|import dagger.hilt.android.HiltAndroidApp
27-
|import dagger.hilt.android.qualifiers.ApplicationContext
28-
|import javax.inject.Inject
29-
|
30-
|/**
31-
| * Main application class with Hilt support
32-
| */
33-
|@HiltAndroidApp
34-
|class MainApplication : Application(){
35-
|
36-
| override fun onCreate() {
37-
| super.onCreate()
38-
| // Application initialization here
39-
| }
40-
|
41-
| companion object {
42-
| /**
43-
| * Gets an entry point from the Hilt component
44-
| */
45-
| @JvmStatic
46-
| fun getEntryPoint(@ApplicationContext context: Context, entryPoint: Class<*>): Any {
47-
| return try {
48-
| val entryPointAccessors = Class.forName("dagger.hilt.android.EntryPointAccessors")
49-
| val getMethod = entryPointAccessors.getDeclaredMethod("fromApplication", Context::class.java, Class::class.java)
50-
| getMethod.invoke(null, context.applicationContext, entryPoint)
51-
| } catch (e: Exception) {
52-
| throw RuntimeException("Error accessing Hilt entry point", e)
53-
| }
54-
| }
55-
|
56-
| /**
57-
| * Gets a specific implementation from an entry point
58-
| */
59-
| @JvmStatic
60-
| inline fun <reified T> getImplementation(@ApplicationContext context: Context, entryPoint: Class<*>): T {
61-
| val ep = getEntryPoint(context, entryPoint)
62-
| // Find method that returns T
63-
| val method = entryPoint.methods.find {
64-
| it.returnType == T::class.java
65-
| } ?: throw RuntimeException("No method found returning")
66-
|
67-
| return method.invoke(ep) as T
68-
| }
69-
| }
70-
|}
71-
""".trimMargin()
27+
val appContent = when (di) {
28+
DependencyInjection.HILT -> """
29+
|package com.awesomeapp.$packageDir
30+
|
31+
|import android.app.Application
32+
|import android.content.Context
33+
|import androidx.hilt.work.HiltWorkerFactory
34+
|import androidx.work.Configuration
35+
|import dagger.hilt.android.HiltAndroidApp
36+
|import dagger.hilt.android.qualifiers.ApplicationContext
37+
|import javax.inject.Inject
38+
|
39+
|/**
40+
| * Main application class with Hilt support
41+
| */
42+
|@HiltAndroidApp
43+
|class MainApplication : Application(){
44+
|
45+
| override fun onCreate() {
46+
| super.onCreate()
47+
| // Application initialization here
48+
| }
49+
|
50+
| companion object {
51+
| /**
52+
| * Gets an entry point from the Hilt component
53+
| */
54+
| @JvmStatic
55+
| fun getEntryPoint(@ApplicationContext context: Context, entryPoint: Class<*>): Any {
56+
| return try {
57+
| val entryPointAccessors = Class.forName("dagger.hilt.android.EntryPointAccessors")
58+
| val getMethod = entryPointAccessors.getDeclaredMethod("fromApplication", Context::class.java, Class::class.java)
59+
| getMethod.invoke(null, context.applicationContext, entryPoint)
60+
| } catch (e: Exception) {
61+
| throw RuntimeException("Error accessing Hilt entry point", e)
62+
| }
63+
| }
64+
|
65+
| /**
66+
| * Gets a specific implementation from an entry point
67+
| */
68+
| @JvmStatic
69+
| inline fun <reified T> getImplementation(@ApplicationContext context: Context, entryPoint: Class<*>): T {
70+
| val ep = getEntryPoint(context, entryPoint)
71+
| // Find method that returns T
72+
| val method = entryPoint.methods.find {
73+
| it.returnType == T::class.java
74+
| } ?: throw RuntimeException("No method found returning")
75+
|
76+
| return method.invoke(ep) as T
77+
| }
78+
| }
79+
|}
80+
""".trimMargin()
81+
82+
DependencyInjection.METRO -> {
83+
val moduleId = NameMappings.moduleName(node.id)
84+
val moduleNumber = node.id.split("_").last().toInt()
85+
val viewModel = dictionary[moduleId]
86+
?.firstOrNull { it.type == ClassTypeAndroid.VIEWMODEL }
87+
?.className
88+
?: "Viewmodel${moduleNumber}_1"
89+
"""
90+
|package com.awesomeapp.$packageDir
91+
|
92+
|import android.app.Application
93+
|import dev.zacsweers.metro.DependencyGraph
94+
|import dev.zacsweers.metro.createGraph
95+
|
96+
|@DependencyGraph
97+
|interface AppGraph {
98+
| val viewModel: $viewModel
99+
|}
100+
|
101+
|class MainApplication : Application() {
102+
| val graph: AppGraph by lazy { createGraph() }
103+
|}
104+
""".trimMargin()
105+
}
106+
107+
DependencyInjection.NONE -> """
108+
|package com.awesomeapp.$packageDir
109+
|
110+
|import android.app.Application
111+
|
112+
|class MainApplication : Application()
113+
""".trimMargin()
114+
}
72115
appFile.writeText(appContent)
73116
}
74117
}

project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/buildfiles/BuildFilesGeneratorAndroid.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ import io.github.cdsap.projectgenerator.model.LanguageAttributes
66
import io.github.cdsap.projectgenerator.model.ProjectGraph
77
import io.github.cdsap.projectgenerator.model.TypeProject
88
import io.github.cdsap.projectgenerator.model.Versions
9+
import io.github.cdsap.projectgenerator.model.DependencyInjection
910
import io.github.cdsap.projectgenerator.NameMappings
1011
import java.io.File
1112

12-
class BuildFilesGeneratorAndroid(val versions: Versions) : BuildFilesGenerator {
13+
class BuildFilesGeneratorAndroid(
14+
private val versions: Versions,
15+
private val di: DependencyInjection
16+
) : BuildFilesGenerator {
1317
override fun generateBuildFiles(
1418
node: ProjectGraph,
1519
lang: LanguageAttributes,
@@ -37,7 +41,7 @@ class BuildFilesGeneratorAndroid(val versions: Versions) : BuildFilesGenerator {
3741
}
3842
}
3943

40-
val deps = AndroidToml().tomlImplementations(versions)
44+
val deps = AndroidToml().tomlImplementations(versions, di)
4145
return """
4246
|plugins {
4347
| id("awesome.androidapp.plugin")
@@ -55,7 +59,7 @@ ${testImplementations.joinToString("\n").prependIndent(" ")}
5559
private fun createAndroidLibBuildFile(node: ProjectGraph, generateUnitTests: Boolean): String {
5660
val implementations = mutableSetOf<String>()
5761
val testImplementations = mutableSetOf<String>()
58-
val deps = AndroidToml().tomlImplementations(versions)
62+
val deps = AndroidToml().tomlImplementations(versions, di)
5963
// Add direct dependencies first (only from different layers)
6064
node.nodes.forEach { dependency ->
6165
if (dependency.layer != node.layer) {

0 commit comments

Comments
 (0)