From 74ec823bae5c6d145f0e768f4b65eeba77099cac Mon Sep 17 00:00:00 2001 From: Inaki Villar Date: Mon, 21 Sep 2026 10:14:03 -0700 Subject: [PATCH] fix: refactor generate-project resolution to use a cohesive options obje --- .../cli/GenerateProjectRequest.kt | 79 ++++----- .../github/cdsap/projectgenerator/cli/Main.kt | 44 ++--- .../cli/GenerateProjectsCliTest.kt | 156 ++++++++---------- 3 files changed, 133 insertions(+), 146 deletions(-) diff --git a/cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/GenerateProjectRequest.kt b/cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/GenerateProjectRequest.kt index 26ca223b..954c0cd0 100644 --- a/cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/GenerateProjectRequest.kt +++ b/cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/GenerateProjectRequest.kt @@ -11,6 +11,23 @@ import io.github.cdsap.projectgenerator.model.Versions import io.github.cdsap.projectgenerator.model.VersionsFile import io.github.cdsap.projectgenerator.writer.GradleWrapper +data class GenerateProjectOptions( + val modules: Int, + val shape: Shape, + val language: Language, + val typeOfProjectRequested: TypeProjectRequested, + val classesPerModule: ClassesPerModule, + val typeOfStringResources: TypeOfStringResources, + val layers: Int, + val generateUnitTest: Boolean, + val cliGradle: String?, + val develocityFlag: Boolean, + val versionsFile: VersionsFile?, + val outputDir: String?, + val projectName: String?, + val versionsOverrides: VersionsOverrides +) + data class GenerateProjectRequest( val modules: Int, val shape: Shape, @@ -43,53 +60,41 @@ data class GenerateProjectRequest( ) companion object { - fun resolve( - modules: Int, - shape: Shape, - language: Language, - typeOfProjectRequested: TypeProjectRequested, - classesPerModule: ClassesPerModule, - typeOfStringResources: TypeOfStringResources, - layers: Int, - generateUnitTest: Boolean, - cliGradle: String?, - develocityFlag: Boolean, - versionsFile: VersionsFile?, - outputDir: String?, - projectName: String?, - versionsOverrides: VersionsOverrides - ): GenerateProjectRequest { + fun resolve(options: GenerateProjectOptions): GenerateProjectRequest { validateAndroidOnlyFeatures( - typeOfProjectRequested = typeOfProjectRequested, - roomDatabase = versionsOverrides.roomDatabase, - kotlinMultiplatformLibrary = versionsOverrides.kotlinMultiplatformLibrary + typeOfProjectRequested = options.typeOfProjectRequested, + roomDatabase = options.versionsOverrides.roomDatabase, + kotlinMultiplatformLibrary = options.versionsOverrides.kotlinMultiplatformLibrary ) val resolvedProjectName = resolveProjectName( - projectName, - typeOfProjectRequested, - shape, - modules + options.projectName, + options.typeOfProjectRequested, + options.shape, + options.modules ) return GenerateProjectRequest( - modules = modules, - shape = shape, - language = language, - typeOfProjectRequested = typeOfProjectRequested, - classesPerModule = classesPerModule, + modules = options.modules, + shape = options.shape, + language = options.language, + typeOfProjectRequested = options.typeOfProjectRequested, + classesPerModule = options.classesPerModule, versions = VersionsResolver.resolve( - fileVersions = versionsFile, - overrides = versionsOverrides + fileVersions = options.versionsFile, + overrides = options.versionsOverrides ), - typeOfStringResources = typeOfStringResources, - layers = layers, - generateUnitTest = generateUnitTest, - gradle = VersionsResolver.resolveGradle(cliGradle, versionsFile), + typeOfStringResources = options.typeOfStringResources, + layers = options.layers, + generateUnitTest = options.generateUnitTest, + gradle = VersionsResolver.resolveGradle(options.cliGradle, options.versionsFile), projectRootPath = ProjectOutputPathResolver.defaultRootPath( - outputDir, - language, + options.outputDir, + options.language, resolvedProjectName ), - develocity = resolveDevelocityEnabled(develocityFlag, versionsOverrides.develocityUrl), + develocity = resolveDevelocityEnabled( + options.develocityFlag, + options.versionsOverrides.develocityUrl + ), projectName = resolvedProjectName ) } diff --git a/cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/Main.kt b/cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/Main.kt index 6dbb04a9..08f15074 100644 --- a/cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/Main.kt +++ b/cli/src/main/kotlin/io/github/cdsap/projectgenerator/cli/Main.kt @@ -59,27 +59,29 @@ class GenerateProjects : CliktCommand(name = "generate-project") { override fun run() { try { GenerateProjectRequest.resolve( - modules = modules, - shape = Shape.valueOf(shape.uppercase()), - language = Language.valueOf(language.uppercase()), - typeOfProjectRequested = TypeProjectRequested.valueOf(type.uppercase()), - classesPerModule = ClassesPerModule( - ClassesPerModuleType.valueOf(classesModuleType.uppercase()), - classesModule - ), - typeOfStringResources = TypeOfStringResources.valueOf(typeOfStringResources.uppercase()), - layers = layers, - generateUnitTest = generateUnitTest, - cliGradle = gradle, - develocityFlag = develocity, - versionsFile = versionsFile?.let(VersionsParser::fromFile), - outputDir = outputDir, - projectName = projectName, - versionsOverrides = VersionsOverrides( - dependencyInjection = DependencyInjection.valueOf(di.uppercase()), - develocityUrl = develocityUrl, - roomDatabase = roomDatabase, - kotlinMultiplatformLibrary = kotlinMultiplatformLibrary + GenerateProjectOptions( + modules = modules, + shape = Shape.valueOf(shape.uppercase()), + language = Language.valueOf(language.uppercase()), + typeOfProjectRequested = TypeProjectRequested.valueOf(type.uppercase()), + classesPerModule = ClassesPerModule( + ClassesPerModuleType.valueOf(classesModuleType.uppercase()), + classesModule + ), + typeOfStringResources = TypeOfStringResources.valueOf(typeOfStringResources.uppercase()), + layers = layers, + generateUnitTest = generateUnitTest, + cliGradle = gradle, + develocityFlag = develocity, + versionsFile = versionsFile?.let(VersionsParser::fromFile), + outputDir = outputDir, + projectName = projectName, + versionsOverrides = VersionsOverrides( + dependencyInjection = DependencyInjection.valueOf(di.uppercase()), + develocityUrl = develocityUrl, + roomDatabase = roomDatabase, + kotlinMultiplatformLibrary = kotlinMultiplatformLibrary + ) ) ).toProjectGenerator().write() } catch (e: GenerateProjectRequestValidationException) { diff --git a/cli/src/test/kotlin/io/github/cdsap/projectgenerator/cli/GenerateProjectsCliTest.kt b/cli/src/test/kotlin/io/github/cdsap/projectgenerator/cli/GenerateProjectsCliTest.kt index c52c38de..7652d938 100644 --- a/cli/src/test/kotlin/io/github/cdsap/projectgenerator/cli/GenerateProjectsCliTest.kt +++ b/cli/src/test/kotlin/io/github/cdsap/projectgenerator/cli/GenerateProjectsCliTest.kt @@ -10,6 +10,7 @@ import io.github.cdsap.projectgenerator.model.Language import io.github.cdsap.projectgenerator.model.Shape import io.github.cdsap.projectgenerator.model.TypeOfStringResources import io.github.cdsap.projectgenerator.model.TypeProjectRequested +import io.github.cdsap.projectgenerator.model.VersionsFile import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertTrue @@ -52,24 +53,14 @@ class GenerateProjectsCliTest { fun `resolve rejects room database for jvm type`() { val error = assertThrows { GenerateProjectRequest.resolve( - modules = 6, - shape = Shape.RECTANGLE, - language = Language.KTS, - typeOfProjectRequested = TypeProjectRequested.JVM, - classesPerModule = ClassesPerModule(ClassesPerModuleType.FIXED, 10), - typeOfStringResources = TypeOfStringResources.NORMAL, - layers = 5, - generateUnitTest = false, - cliGradle = null, - develocityFlag = false, - versionsFile = null, - outputDir = null, - projectName = null, - versionsOverrides = VersionsOverrides( - dependencyInjection = DependencyInjection.HILT, - develocityUrl = null, - roomDatabase = true, - kotlinMultiplatformLibrary = false + options( + typeOfProjectRequested = TypeProjectRequested.JVM, + versionsOverrides = VersionsOverrides( + dependencyInjection = DependencyInjection.HILT, + develocityUrl = null, + roomDatabase = true, + kotlinMultiplatformLibrary = false + ) ) ) } @@ -80,24 +71,14 @@ class GenerateProjectsCliTest { fun `resolve rejects android kotlin multiplatform library for jvm type`() { val error = assertThrows { GenerateProjectRequest.resolve( - modules = 6, - shape = Shape.RECTANGLE, - language = Language.KTS, - typeOfProjectRequested = TypeProjectRequested.JVM, - classesPerModule = ClassesPerModule(ClassesPerModuleType.FIXED, 10), - typeOfStringResources = TypeOfStringResources.NORMAL, - layers = 5, - generateUnitTest = false, - cliGradle = null, - develocityFlag = false, - versionsFile = null, - outputDir = null, - projectName = null, - versionsOverrides = VersionsOverrides( - dependencyInjection = DependencyInjection.HILT, - develocityUrl = null, - roomDatabase = false, - kotlinMultiplatformLibrary = true + options( + typeOfProjectRequested = TypeProjectRequested.JVM, + versionsOverrides = VersionsOverrides( + dependencyInjection = DependencyInjection.HILT, + develocityUrl = null, + roomDatabase = false, + kotlinMultiplatformLibrary = true + ) ) ) } @@ -179,24 +160,15 @@ class GenerateProjectsCliTest { @Test fun `develocity url enables develocity when develocity flag is absent`() { val request = GenerateProjectRequest.resolve( - modules = 6, - shape = Shape.RECTANGLE, - language = Language.KTS, - typeOfProjectRequested = TypeProjectRequested.ANDROID, - classesPerModule = ClassesPerModule(ClassesPerModuleType.FIXED, 10), - typeOfStringResources = TypeOfStringResources.NORMAL, - layers = 5, - generateUnitTest = false, - cliGradle = null, - develocityFlag = false, - versionsFile = null, - outputDir = null, - projectName = "named", - versionsOverrides = VersionsOverrides( - dependencyInjection = DependencyInjection.HILT, - develocityUrl = "https://develocity.example", - roomDatabase = false, - kotlinMultiplatformLibrary = false + options( + typeOfProjectRequested = TypeProjectRequested.ANDROID, + projectName = "named", + versionsOverrides = VersionsOverrides( + dependencyInjection = DependencyInjection.HILT, + develocityUrl = "https://develocity.example", + roomDatabase = false, + kotlinMultiplatformLibrary = false + ) ) ) @@ -212,24 +184,11 @@ class GenerateProjectsCliTest { @Test fun `resolve builds default project name and nested root path`() { val request = GenerateProjectRequest.resolve( - modules = 12, - shape = Shape.TRIANGLE, - language = Language.KTS, - typeOfProjectRequested = TypeProjectRequested.JVM, - classesPerModule = ClassesPerModule(ClassesPerModuleType.FIXED, 10), - typeOfStringResources = TypeOfStringResources.NORMAL, - layers = 5, - generateUnitTest = false, - cliGradle = null, - develocityFlag = false, - versionsFile = null, - outputDir = null, - projectName = null, - versionsOverrides = VersionsOverrides( - dependencyInjection = DependencyInjection.HILT, - develocityUrl = null, - roomDatabase = false, - kotlinMultiplatformLibrary = false + options( + modules = 12, + shape = Shape.TRIANGLE, + typeOfProjectRequested = TypeProjectRequested.JVM, + projectName = null ) ) @@ -264,25 +223,46 @@ class GenerateProjectsCliTest { projectName: String? ): GenerateProjectRequest { return GenerateProjectRequest.resolve( - modules = 6, - shape = Shape.RECTANGLE, + options(language = language, outputDir = outputDir, projectName = projectName) + ) + } + + private fun options( + modules: Int = 6, + shape: Shape = Shape.RECTANGLE, + language: Language = Language.KTS, + typeOfProjectRequested: TypeProjectRequested = TypeProjectRequested.JVM, + classesPerModule: ClassesPerModule = ClassesPerModule(ClassesPerModuleType.FIXED, 10), + typeOfStringResources: TypeOfStringResources = TypeOfStringResources.NORMAL, + layers: Int = 5, + generateUnitTest: Boolean = false, + cliGradle: String? = null, + develocityFlag: Boolean = false, + versionsFile: VersionsFile? = null, + outputDir: String? = null, + projectName: String? = null, + versionsOverrides: VersionsOverrides = VersionsOverrides( + dependencyInjection = DependencyInjection.HILT, + develocityUrl = null, + roomDatabase = false, + kotlinMultiplatformLibrary = false + ) + ): GenerateProjectOptions { + return GenerateProjectOptions( + modules = modules, + shape = shape, language = language, - typeOfProjectRequested = TypeProjectRequested.JVM, - classesPerModule = ClassesPerModule(ClassesPerModuleType.FIXED, 10), - typeOfStringResources = TypeOfStringResources.NORMAL, - layers = 5, - generateUnitTest = false, - cliGradle = null, - develocityFlag = false, - versionsFile = null, + typeOfProjectRequested = typeOfProjectRequested, + classesPerModule = classesPerModule, + typeOfStringResources = typeOfStringResources, + layers = layers, + generateUnitTest = generateUnitTest, + cliGradle = cliGradle, + develocityFlag = develocityFlag, + versionsFile = versionsFile, outputDir = outputDir, projectName = projectName, - versionsOverrides = VersionsOverrides( - dependencyInjection = DependencyInjection.HILT, - develocityUrl = null, - roomDatabase = false, - kotlinMultiplatformLibrary = false - ) + versionsOverrides = versionsOverrides ) } }