Skip to content

Commit 7b1f0c1

Browse files
authored
Add output-dir flag and simplify generator output path API (#282)
1 parent 70effde commit 7b1f0c1

8 files changed

Lines changed: 107 additions & 30 deletions

File tree

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

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class GenerateProjects : CliktCommand(name = "generate-project") {
5252
)
5353
private val develocity by option().flag(default = false)
5454
private val versionsFile by option().file()
55+
private val outputDir by option("--output-dir")
5556
private val projectName by option()
5657
private val develocityUrl by option()
5758
// Kept for CLI backwards compatibility. AGP 9 is the default now.
@@ -75,24 +76,27 @@ class GenerateProjects : CliktCommand(name = "generate-project") {
7576
kotlinMultiplatformLibrary = kotlinMultiplatformLibrary
7677
).copy(di = dependencyInjection)
7778
val develocityEnabled = getDevelocityEnabled(develocity, develocityUrl)
79+
val language = Language.valueOf(language.uppercase())
80+
val resolvedProjectName = projectName ?: buildString {
81+
append(typeOfProjectRequested.name.lowercase())
82+
append(shape.name.lowercase().replaceFirstChar { it.uppercase() })
83+
append(modules)
84+
append("modules")
85+
}
7886
ProjectGenerator(
7987
modules,
8088
shape,
81-
Language.valueOf(language.uppercase()),
89+
language,
8290
typeOfProjectRequested,
8391
ClassesPerModule(ClassesPerModuleType.valueOf(classesModuleType.uppercase()), classesModule),
8492
versions = versions,
8593
TypeOfStringResources.valueOf(typeOfStringResources.uppercase()),
8694
layers,
8795
generateUnitTest,
8896
GradleWrapper(resolveGradle(gradle, versionsOverride)),
97+
projectRootPath = resolveProjectRootPath(outputDir, language, resolvedProjectName),
8998
develocity = develocityEnabled,
90-
projectName = projectName ?: buildString {
91-
append(typeOfProjectRequested.name.lowercase())
92-
append(shape.name.lowercase().replaceFirstChar { it.uppercase() })
93-
append(modules)
94-
append("modules")
95-
}
99+
projectName = resolvedProjectName
96100
).write()
97101
}
98102

@@ -132,6 +136,18 @@ class GenerateProjects : CliktCommand(name = "generate-project") {
132136
}
133137
}
134138

139+
internal fun resolveProjectRootPath(outputDir: String?, language: Language, projectName: String): String {
140+
return if (outputDir != null) {
141+
outputDir
142+
} else {
143+
when (language) {
144+
Language.KTS -> "projects_generated/$projectName/project_kts"
145+
Language.GROOVY -> "projects_generated/$projectName/project_groovy"
146+
Language.BOTH -> "projects_generated/$projectName"
147+
}
148+
}
149+
}
150+
135151
internal fun resolveGradle(cliGradle: String?, versionsFile: VersionsFile?): Gradle {
136152
return cliGradle?.let { Gradle.valueOf(it.uppercase()) }
137153
?: versionsFile?.gradle

cli/src/test/kotlin/io/github/cdsap/projectgenerator/cli/GenerateProjectsCliTest.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package io.github.cdsap.projectgenerator.cli
33
import com.github.ajalt.clikt.core.UsageError
44
import com.github.ajalt.clikt.core.parse
55
import io.github.cdsap.projectgenerator.model.Gradle
6+
import io.github.cdsap.projectgenerator.model.Language
67
import io.github.cdsap.projectgenerator.model.VersionsFile
78
import org.junit.jupiter.api.Assertions.assertEquals
89
import org.junit.jupiter.api.Assertions.assertTrue
@@ -60,4 +61,25 @@ class GenerateProjectsCliTest {
6061

6162
assertEquals(Gradle.GRADLE_9_4_0, resolved)
6263
}
64+
65+
@Test
66+
fun `default output path for kts nests project name and project_kts`() {
67+
val resolved = resolveProjectRootPath(null, Language.KTS, "sample")
68+
69+
assertEquals("projects_generated/sample/project_kts", resolved)
70+
}
71+
72+
@Test
73+
fun `output dir is used directly for single language projects`() {
74+
val resolved = resolveProjectRootPath(".", Language.KTS, "sample")
75+
76+
assertEquals(".", resolved)
77+
}
78+
79+
@Test
80+
fun `default output path for both languages nests project name only`() {
81+
val resolved = resolveProjectRootPath(null, Language.BOTH, "sample")
82+
83+
assertEquals("projects_generated/sample", resolved)
84+
}
6385
}

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

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class ProjectGenerator(
1616
private val layers: Int,
1717
private val generateUnitTest: Boolean = false,
1818
private val gradle: GradleWrapper = GradleWrapper(Gradle.GRADLE_9_4_0),
19-
private val path: String = "projects_generated",
19+
private val projectRootPath: String = "projects_generated/generated_project/project_kts",
2020
private val develocity: Boolean = false,
2121
private val layerNames: List<String> = DefaultNames.layerNames,
2222
private val moduleNameParts: List<String> = DefaultNames.moduleNames,
@@ -25,7 +25,7 @@ class ProjectGenerator(
2525

2626
fun write() {
2727

28-
println("Creating project $projectName in $path")
28+
println("Creating project $projectName in $projectRootPath")
2929
println("Calculating layer Distribution")
3030

3131
// Generate name mappings for layers and modules
@@ -56,8 +56,7 @@ class ProjectGenerator(
5656
}
5757
}.toMap()
5858

59-
val projectLanguageAttributes =
60-
getProjectLanguageAttributes(language, "$path/$projectName")
59+
val projectLanguageAttributes = getProjectLanguageAttributes()
6160
ProjectWriter(
6261
nodes,
6362
projectLanguageAttributes,
@@ -73,15 +72,21 @@ class ProjectGenerator(
7372
println("Project created in ${projectLanguageAttributes.first().projectName}")
7473
}
7574

76-
private fun getProjectLanguageAttributes(language: Language, labelProject: String) = when (language) {
77-
Language.KTS -> listOf(LanguageAttributes("gradle.kts", "$labelProject/project_kts"))
75+
private fun getProjectLanguageAttributes(): List<LanguageAttributes> {
76+
return when (language) {
77+
Language.KTS -> listOf(
78+
LanguageAttributes("gradle.kts", projectRootPath)
79+
)
7880

79-
Language.GROOVY -> listOf(LanguageAttributes("gradle", "$labelProject/project_groovy"))
81+
Language.GROOVY -> listOf(
82+
LanguageAttributes("gradle", projectRootPath)
83+
)
8084

81-
Language.BOTH -> listOf(
82-
LanguageAttributes("gradle", "$labelProject/project_groovy"),
83-
LanguageAttributes("gradle.kts", "$labelProject/project_kts")
84-
)
85+
Language.BOTH -> listOf(
86+
LanguageAttributes("gradle", "$projectRootPath/project_groovy"),
87+
LanguageAttributes("gradle.kts", "$projectRootPath/project_kts")
88+
)
89+
}
8590
}
8691

8792
private fun generateModuleName(index: Int): String {

project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/AndroidKotlinMultiplatformLibraryE2EValidationTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class AndroidKotlinMultiplatformLibraryE2EValidationTest {
4444
layers = 2,
4545
generateUnitTest = false,
4646
gradle = GradleWrapper(LATEST_GRADLE),
47-
path = tempDir.toFile().path,
47+
projectRootPath = "${tempDir.toFile().path}/$projectName/project_kts",
4848
projectName = projectName
4949
).write()
5050

@@ -75,7 +75,7 @@ class AndroidKotlinMultiplatformLibraryE2EValidationTest {
7575
layers = 2,
7676
generateUnitTest = false,
7777
gradle = GradleWrapper(LATEST_GRADLE),
78-
path = tempDir.toFile().path,
78+
projectRootPath = "${tempDir.toFile().path}/$projectName/project_kts",
7979
projectName = projectName
8080
).write()
8181

project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/ProjectGeneratorE2EJdk21Test.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ class ProjectGeneratorE2EJdk21Test {
3737
5,
3838
true,
3939
GradleWrapper(LATEST_GRADLE),
40-
path = tempDir.toFile().path,
41-
false,
40+
projectRootPath = "${tempDir.toFile().path}/${shape.name.lowercase().capitalize()}$modules/project_kts",
41+
develocity = false,
4242
projectName = "${shape.name.lowercase().capitalize()}$modules"
4343

4444
).write()

project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/ProjectGeneratorE2ETest.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ class ProjectGeneratorE2ETest {
4040
5,
4141
true,
4242
GradleWrapper(LATEST_GRADLE),
43-
path = tempDir.toFile().path,
44-
false,
43+
projectRootPath = "${tempDir.toFile().path}/${shape.name.lowercase().capitalize()}$modules/project_kts",
44+
develocity = false,
4545
projectName = "${shape.name.lowercase().capitalize()}$modules"
4646

4747
).write()
@@ -89,8 +89,8 @@ class ProjectGeneratorE2ETest {
8989
5,
9090
true,
9191
GradleWrapper(Gradle.GRADLE_8_14_3),
92-
path = tempDir.toFile().path,
93-
false,
92+
projectRootPath = "${tempDir.toFile().path}/${shape.name.lowercase().capitalize()}$modules/project_kts",
93+
develocity = false,
9494
projectName = "${shape.name.lowercase().capitalize()}$modules"
9595
).write()
9696

@@ -135,8 +135,8 @@ class ProjectGeneratorE2ETest {
135135
5,
136136
true,
137137
GradleWrapper(LATEST_GRADLE),
138-
path = tempDir.toFile().path,
139-
false,
138+
projectRootPath = "${tempDir.toFile().path}/${shape.name.lowercase().capitalize()}$modules/project_kts",
139+
develocity = false,
140140
projectName = "${shape.name.lowercase().capitalize()}$modules"
141141
).write()
142142
val toml = File(

project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/ProjectGeneratorTest.kt

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class ProjectGeneratorTest {
2525
shape = shape,
2626
classesPerModule = ClassesPerModule(ClassesPerModuleType.RANDOM, 10),
2727
layers = 5,
28-
path = tempDir.toString(),
28+
projectRootPath = "$tempDir/awesome_project${shape.name.capitalize()}/project_kts",
2929
projectName = "awesome_project${shape.name.capitalize()}",
3030
).write()
3131
assert(File("$tempDir/awesome_project${shape.name.capitalize()}/project_kts/build.gradle.kts").exists())
@@ -36,4 +36,38 @@ class ProjectGeneratorTest {
3636
)
3737
assert(File("$tempDir/awesome_project${shape.name.capitalize()}/project_kts/gradle.properties").exists())
3838
}
39+
40+
@Test
41+
fun `projectGenerator writes directly to output path for single language when requested`() {
42+
ProjectGenerator(
43+
modules = 6,
44+
shape = Shape.FLAT,
45+
language = Language.KTS,
46+
classesPerModule = ClassesPerModule(ClassesPerModuleType.FIXED, 10),
47+
layers = 2,
48+
projectRootPath = tempDir.toString(),
49+
projectName = "awesome_project"
50+
).write()
51+
52+
assert(File("$tempDir/build.gradle.kts").exists())
53+
assert(File("$tempDir/settings.gradle.kts").exists())
54+
assert(File("$tempDir/gradle.properties").exists())
55+
assert(!File("$tempDir/project_kts").exists())
56+
}
57+
58+
@Test
59+
fun `projectGenerator keeps language subdirectories for both language output path`() {
60+
ProjectGenerator(
61+
modules = 6,
62+
shape = Shape.FLAT,
63+
language = Language.BOTH,
64+
classesPerModule = ClassesPerModule(ClassesPerModuleType.FIXED, 10),
65+
layers = 2,
66+
projectRootPath = tempDir.toString(),
67+
projectName = "awesome_project"
68+
).write()
69+
70+
assert(File("$tempDir/project_kts/build.gradle.kts").exists())
71+
assert(File("$tempDir/project_groovy/build.gradle").exists())
72+
}
3973
}

project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/RoomDiVariantsAssembleE2EValidationTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class RoomDiVariantsAssembleE2EValidationTest {
4444
layers = 2,
4545
generateUnitTest = false,
4646
gradle = GradleWrapper(LATEST_GRADLE),
47-
path = tempDir.toFile().path,
47+
projectRootPath = "${tempDir.toFile().path}/$projectName/project_kts",
4848
projectName = projectName
4949
).write()
5050

0 commit comments

Comments
 (0)