From 569a8ca135996677d1f23cbd24c42e3c41fb9108 Mon Sep 17 00:00:00 2001 From: Inaki Villar Date: Tue, 22 Sep 2026 10:16:30 -0700 Subject: [PATCH] fix: refactor module layout generation to use explicit project name maps --- .../generator/GeneratedModuleLayout.kt | 46 +++--- .../classes/ClassGeneratorAndroid.kt | 7 +- .../generator/resources/ResourceGenerator.kt | 8 +- .../generator/test/TestGeneratorAndroid.kt | 7 +- .../writer/AndroidModulesWriter.kt | 16 ++- .../writer/JvmModulesWriter.kt | 5 +- .../projectgenerator/writer/ModulesWriter.kt | 5 +- .../projectgenerator/writer/ProjectWriter.kt | 13 +- .../projectgenerator/ProjectGeneratorTest.kt | 48 ++++--- .../generator/GeneratedModuleLayoutTest.kt | 131 +++++++++++++----- .../writer/ModulesWriterTest.kt | 41 +++++- 11 files changed, 236 insertions(+), 91 deletions(-) diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/GeneratedModuleLayout.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/GeneratedModuleLayout.kt index 51ea1447..1ced38e1 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/GeneratedModuleLayout.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/GeneratedModuleLayout.kt @@ -1,6 +1,6 @@ package io.github.cdsap.projectgenerator.generator -import io.github.cdsap.projectgenerator.NameMappings +import io.github.cdsap.projectgenerator.ProjectNameMaps import io.github.cdsap.projectgenerator.generator.android.AndroidSourceSetLayout import io.github.cdsap.projectgenerator.model.ModuleClassDefinitionAndroid import io.github.cdsap.projectgenerator.model.ProjectGraph @@ -9,17 +9,14 @@ import java.io.File class GeneratedModuleLayout private constructor( private val projectName: String, - private val layer: Int, - private val moduleId: String, + private val layerDir: String, + private val moduleDir: String, + private val packageDir: String, private val mainKotlinSourceDir: String, private val testKotlinSourceDir: String, private val resourcesSourceDir: String, private val manifestSourceDir: String ) { - private val layerDir: String = NameMappings.layerName(layer) - private val moduleDir: String = NameMappings.moduleName(moduleId) - private val packageDir: String = NameMappings.modulePackageName(moduleId) - fun mainKotlinPackageDir(): File = File("$projectName/$layerDir/$moduleDir/$mainKotlinSourceDir/com/awesomeapp/$packageDir/") @@ -39,27 +36,31 @@ class GeneratedModuleLayout private constructor( fun of( projectName: String, node: ProjectGraph, - kotlinMultiplatformLibrary: Boolean + kotlinMultiplatformLibrary: Boolean, + nameMaps: ProjectNameMaps ): GeneratedModuleLayout = of( projectName = projectName, layer = node.layer, moduleId = node.id, type = node.type, - kotlinMultiplatformLibrary = kotlinMultiplatformLibrary + kotlinMultiplatformLibrary = kotlinMultiplatformLibrary, + nameMaps = nameMaps ) fun of( projectName: String, moduleDefinition: ModuleClassDefinitionAndroid, - kotlinMultiplatformLibrary: Boolean + kotlinMultiplatformLibrary: Boolean, + nameMaps: ProjectNameMaps ): GeneratedModuleLayout = of( projectName = projectName, layer = moduleDefinition.layer, moduleId = moduleDefinition.moduleId, type = moduleDefinition.projectType ?: TypeProject.ANDROID_LIB, - kotlinMultiplatformLibrary = kotlinMultiplatformLibrary + kotlinMultiplatformLibrary = kotlinMultiplatformLibrary, + nameMaps = nameMaps ) fun of( @@ -67,12 +68,14 @@ class GeneratedModuleLayout private constructor( node: ProjectGraph, mainKotlinSourceDir: String, testKotlinSourceDir: String, + nameMaps: ProjectNameMaps, kotlinMultiplatformLibrary: Boolean = false ): GeneratedModuleLayout = GeneratedModuleLayout( projectName = projectName, - layer = node.layer, - moduleId = node.id, + layerDir = layerDir(nameMaps, node.layer), + moduleDir = moduleDir(nameMaps, node.id), + packageDir = packageDir(nameMaps, node.id), mainKotlinSourceDir = mainKotlinSourceDir, testKotlinSourceDir = testKotlinSourceDir, resourcesSourceDir = AndroidSourceSetLayout.resourcesSourceDir( @@ -90,12 +93,14 @@ class GeneratedModuleLayout private constructor( layer: Int, moduleId: String, type: TypeProject, - kotlinMultiplatformLibrary: Boolean + kotlinMultiplatformLibrary: Boolean, + nameMaps: ProjectNameMaps ): GeneratedModuleLayout = GeneratedModuleLayout( projectName = projectName, - layer = layer, - moduleId = moduleId, + layerDir = layerDir(nameMaps, layer), + moduleDir = moduleDir(nameMaps, moduleId), + packageDir = packageDir(nameMaps, moduleId), mainKotlinSourceDir = AndroidSourceSetLayout.kotlinMainSourceDir( type, kotlinMultiplatformLibrary @@ -113,5 +118,14 @@ class GeneratedModuleLayout private constructor( kotlinMultiplatformLibrary ) ) + + private fun layerDir(nameMaps: ProjectNameMaps, layer: Int): String = + nameMaps.layerNames[layer] ?: "layer_$layer" + + private fun moduleDir(nameMaps: ProjectNameMaps, moduleId: String): String = + nameMaps.moduleNames[moduleId] ?: moduleId + + private fun packageDir(nameMaps: ProjectNameMaps, moduleId: String): String = + moduleDir(nameMaps, moduleId).replace("-", "") } } diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/classes/ClassGeneratorAndroid.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/classes/ClassGeneratorAndroid.kt index c0ce43d5..93939d05 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/classes/ClassGeneratorAndroid.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/classes/ClassGeneratorAndroid.kt @@ -4,6 +4,7 @@ import io.github.cdsap.projectgenerator.generator.GeneratedModuleLayout import io.github.cdsap.projectgenerator.generator.android.AndroidSourceSetLayout import io.github.cdsap.projectgenerator.model.* import io.github.cdsap.projectgenerator.NameMappings +import io.github.cdsap.projectgenerator.ProjectNameMaps import io.github.cdsap.projectgenerator.generator.ClassGenerator import java.io.File import java.util.concurrent.CopyOnWriteArrayList @@ -21,7 +22,8 @@ data class GenerateDictionaryAndroid( class ClassGeneratorAndroid( private val di: DependencyInjection, - private val kotlinMultiplatformLibrary: Boolean = false + private val kotlinMultiplatformLibrary: Boolean = false, + private val nameMaps: ProjectNameMaps ) : ClassGenerator { @@ -753,7 +755,8 @@ class ClassGeneratorAndroid( val directory = GeneratedModuleLayout.of( projectName, moduleDefinition, - kotlinMultiplatformLibrary + kotlinMultiplatformLibrary, + nameMaps ).mainKotlinPackageDir() directory.mkdirs() diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/resources/ResourceGenerator.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/resources/ResourceGenerator.kt index a4e42633..a0970ef1 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/resources/ResourceGenerator.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/resources/ResourceGenerator.kt @@ -9,6 +9,7 @@ import io.github.cdsap.projectgenerator.generator.android.Manifest import io.github.cdsap.projectgenerator.generator.android.ValuesStrings import io.github.cdsap.projectgenerator.generator.ResourceGeneratorA import io.github.cdsap.projectgenerator.NameMappings +import io.github.cdsap.projectgenerator.ProjectNameMaps import io.github.cdsap.projectgenerator.generator.classes.GenerateDictionaryAndroid import io.github.cdsap.projectgenerator.model.DependencyInjection import io.github.cdsap.projectgenerator.model.LanguageAttributes @@ -21,7 +22,8 @@ import java.util.concurrent.CopyOnWriteArrayList class ResourceGenerator( private val di: DependencyInjection, private val roomDatabase: Boolean = false, - private val kotlinMultiplatformLibrary: Boolean = false + private val kotlinMultiplatformLibrary: Boolean = false, + private val nameMaps: ProjectNameMaps ) : ResourceGeneratorA { override fun generate( @@ -30,7 +32,7 @@ class ResourceGenerator( typeOfStringResources: TypeOfStringResources, classesDictionary: MutableMap> ) { - val layout = GeneratedModuleLayout.of(lang.projectName, node, kotlinMultiplatformLibrary) + val layout = GeneratedModuleLayout.of(lang.projectName, node, kotlinMultiplatformLibrary, nameMaps) layout.resourcesLayoutDir().mkdirs() layout.resourcesValuesDir().mkdirs() ClassTheme(kotlinMultiplatformLibrary).createThemeFile(node, lang) @@ -72,7 +74,7 @@ class ResourceGenerator( lang: LanguageAttributes, node: ProjectGraph ): Triple { - val layout = GeneratedModuleLayout.of(lang.projectName, node, kotlinMultiplatformLibrary) + val layout = GeneratedModuleLayout.of(lang.projectName, node, kotlinMultiplatformLibrary, nameMaps) return Triple(layout.resourcesLayoutDir(), layout.resourcesValuesDir(), layout.manifestDir()) } diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/test/TestGeneratorAndroid.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/test/TestGeneratorAndroid.kt index 51f24a07..835252c6 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/test/TestGeneratorAndroid.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/generator/test/TestGeneratorAndroid.kt @@ -8,12 +8,14 @@ import io.github.cdsap.projectgenerator.model.ClassDependencyAndroid import io.github.cdsap.projectgenerator.model.ClassTypeAndroid import io.github.cdsap.projectgenerator.model.ModuleClassDefinitionAndroid import io.github.cdsap.projectgenerator.NameMappings +import io.github.cdsap.projectgenerator.ProjectNameMaps import java.io.File import java.util.concurrent.CopyOnWriteArrayList class TestGeneratorAndroid( - private val kotlinMultiplatformLibrary: Boolean = false + private val kotlinMultiplatformLibrary: Boolean = false, + private val nameMaps: ProjectNameMaps ) : TestGenerator { @@ -25,7 +27,8 @@ class TestGeneratorAndroid( val testDir = GeneratedModuleLayout.of( projectName, moduleDefinition, - kotlinMultiplatformLibrary + kotlinMultiplatformLibrary, + nameMaps ).testKotlinPackageDir() testDir.mkdirs() diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/AndroidModulesWriter.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/AndroidModulesWriter.kt index 1395e1b7..518e9320 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/AndroidModulesWriter.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/AndroidModulesWriter.kt @@ -1,5 +1,6 @@ package io.github.cdsap.projectgenerator.writer +import io.github.cdsap.projectgenerator.ProjectNameMaps import io.github.cdsap.projectgenerator.generator.buildfiles.BuildFilesGeneratorAndroid import io.github.cdsap.projectgenerator.generator.classes.ClassGeneratorAndroid import io.github.cdsap.projectgenerator.generator.classes.ClassGeneratorAndroidLegacy @@ -17,24 +18,31 @@ class AndroidModulesWriter( typeOfStringResources: TypeOfStringResources, generateUnitTest: Boolean, versions: Versions, - di: DependencyInjection + di: DependencyInjection, + nameMaps: ProjectNameMaps ) : ModulesWrite( classGenerator = if (versions.android.roomDatabase) { - ClassGeneratorAndroid(di, versions.android.kotlinMultiplatformLibrary) + ClassGeneratorAndroid(di, versions.android.kotlinMultiplatformLibrary, nameMaps) } else { ClassGeneratorAndroidLegacy(di, versions.android.kotlinMultiplatformLibrary) }, classPlanner = if (versions.android.roomDatabase) ModuleClassPlannerAndroid() else ModuleClassPlannerAndroidLegacy(), testGenerator = if (versions.android.roomDatabase) { - TestGeneratorAndroid(versions.android.kotlinMultiplatformLibrary) + TestGeneratorAndroid(versions.android.kotlinMultiplatformLibrary, nameMaps) } else { TestGeneratorAndroidLegacy(versions.android.kotlinMultiplatformLibrary) }, - resourceGeneratorA = ResourceGenerator(di, versions.android.roomDatabase, versions.android.kotlinMultiplatformLibrary), + resourceGeneratorA = ResourceGenerator( + di, + versions.android.roomDatabase, + versions.android.kotlinMultiplatformLibrary, + nameMaps + ), generateUnitTest = generateUnitTest, buildFilesGenerator = BuildFilesGeneratorAndroid(versions, di), resources = typeOfStringResources, nodes = nodes, languages = languages, + nameMaps = nameMaps, sourceSetLayout = AndroidModuleSourceSetLayout(versions.android.kotlinMultiplatformLibrary) ) diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/JvmModulesWriter.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/JvmModulesWriter.kt index 4f310671..45a731d5 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/JvmModulesWriter.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/JvmModulesWriter.kt @@ -1,5 +1,6 @@ package io.github.cdsap.projectgenerator.writer +import io.github.cdsap.projectgenerator.ProjectNameMaps import io.github.cdsap.projectgenerator.generator.buildfiles.BuildFilesGeneratorJvm import io.github.cdsap.projectgenerator.generator.planner.ModuleClassPlannerJvm import io.github.cdsap.projectgenerator.generator.classes.ClassGeneratorJvm @@ -15,7 +16,8 @@ class JvmModulesWriter( nodes: List, languages: List, generateUnitTest: Boolean, - versions: Versions + versions: Versions, + nameMaps: ProjectNameMaps ) : ModulesWrite( classGenerator = ClassGeneratorJvm(), classPlanner = ModuleClassPlannerJvm(), @@ -24,5 +26,6 @@ class JvmModulesWriter( buildFilesGenerator = BuildFilesGeneratorJvm(), nodes = nodes, languages = languages, + nameMaps = nameMaps, sourceSetLayout = JvmModuleSourceSetLayout ) diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/ModulesWriter.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/ModulesWriter.kt index 425fcf0e..39b402dc 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/ModulesWriter.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/ModulesWriter.kt @@ -1,5 +1,6 @@ package io.github.cdsap.projectgenerator.writer +import io.github.cdsap.projectgenerator.ProjectNameMaps import io.github.cdsap.projectgenerator.generator.BuildFilesGenerator import io.github.cdsap.projectgenerator.generator.ClassGenerator import io.github.cdsap.projectgenerator.generator.GeneratedModuleLayout @@ -26,6 +27,7 @@ abstract class ModulesWrite( private val resources: TypeOfStringResources? = null, private val nodes: List, private val languages: List, + private val nameMaps: ProjectNameMaps, private val sourceSetLayout: ModuleSourceSetLayout = JvmModuleSourceSetLayout ) { suspend fun write() = coroutineScope { @@ -72,7 +74,8 @@ abstract class ModulesWrite( projectName = lang.projectName, node = node, mainKotlinSourceDir = sourceSetLayout.mainKotlinDir(node), - testKotlinSourceDir = sourceSetLayout.testKotlinDir(node) + testKotlinSourceDir = sourceSetLayout.testKotlinDir(node), + nameMaps = nameMaps ) layout.mainKotlinPackageDir().mkdirs() diff --git a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/ProjectWriter.kt b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/ProjectWriter.kt index e98aea86..754a14a8 100644 --- a/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/ProjectWriter.kt +++ b/project-generator/src/main/kotlin/io/github/cdsap/projectgenerator/writer/ProjectWriter.kt @@ -1,5 +1,6 @@ package io.github.cdsap.projectgenerator.writer +import io.github.cdsap.projectgenerator.NameMappings import io.github.cdsap.projectgenerator.ProjectNameMaps import io.github.cdsap.projectgenerator.generator.rootproject.BuildGradle import io.github.cdsap.projectgenerator.generator.rootproject.GradleProperties @@ -28,6 +29,7 @@ class ProjectWriter( private val nameMaps: ProjectNameMaps ) { fun write() { + NameMappings.configure(nameMaps) println("Creating Convention Plugin files") ConventionPluginWriter(languages, versions, typeOfProjectRequested).write() println("Creating Modules files") @@ -39,10 +41,17 @@ class ProjectWriter( typeOfStringResources, generateUnitTest, versions, - versions.di + versions.di, + nameMaps ).write() - TypeProjectRequested.JVM -> JvmModulesWriter(nodes, languages, generateUnitTest, versions).write() + TypeProjectRequested.JVM -> JvmModulesWriter( + nodes, + languages, + generateUnitTest, + versions, + nameMaps + ).write() } } diff --git a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/ProjectGeneratorTest.kt b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/ProjectGeneratorTest.kt index 2383328e..1fb1b36e 100644 --- a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/ProjectGeneratorTest.kt +++ b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/ProjectGeneratorTest.kt @@ -76,23 +76,37 @@ class ProjectGeneratorTest { @Test fun `projectGenerator configures NameMappings before writing project files`() { val layers = 2 - ProjectGenerator( - modules = 6, - shape = Shape.RECTANGLE, - language = Language.KTS, - classesPerModule = ClassesPerModule(ClassesPerModuleType.FIXED, 10), - layers = layers, - layerNames = listOf("platform"), - moduleNameParts = listOf("alpha", "beta"), - projectRootPath = tempDir.toString(), - projectName = "named_project" - ).write() + val previousLayers = NameMappings.layerNames + val previousModules = NameMappings.moduleNames + try { + ProjectGenerator( + modules = 6, + shape = Shape.RECTANGLE, + language = Language.KTS, + classesPerModule = ClassesPerModule(ClassesPerModuleType.FIXED, 10), + layers = layers, + layerNames = listOf("platform"), + moduleNameParts = listOf("alpha", "beta"), + projectRootPath = tempDir.toString(), + projectName = "named_project" + ).write() - assert(NameMappings.layerName(0) == "platform") - assert(NameMappings.layerName(1) == "layer_1") - assert(NameMappings.layerName(layers) == "app") - assert(NameMappings.moduleNames.values.contains("app")) - assert(NameMappings.moduleNames.values.any { it == "alpha" || it == "beta" || it.contains("-") }) - assert(File("$tempDir/settings.gradle.kts").readText().contains(":app:app")) + assert(NameMappings.layerName(0) == "platform") + assert(NameMappings.layerName(1) == "layer_1") + assert(NameMappings.layerName(layers) == "app") + assert(NameMappings.moduleNames.values.contains("app")) + assert(NameMappings.moduleNames.values.any { it == "alpha" || it == "beta" || it.contains("-") }) + assert(File("$tempDir/settings.gradle.kts").readText().contains(":app:app")) + assert(File("$tempDir/platform").isDirectory) + assert(File("$tempDir/app").isDirectory) + assert( + File("$tempDir").walkTopDown().any { + it.isDirectory && (it.name == "alpha" || it.name == "beta" || it.name.contains("-")) + } + ) + } finally { + NameMappings.layerNames = previousLayers + NameMappings.moduleNames = previousModules + } } } diff --git a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/generator/GeneratedModuleLayoutTest.kt b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/generator/GeneratedModuleLayoutTest.kt index f7e46f9e..edf23d40 100644 --- a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/generator/GeneratedModuleLayoutTest.kt +++ b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/generator/GeneratedModuleLayoutTest.kt @@ -1,60 +1,69 @@ package io.github.cdsap.projectgenerator.generator import io.github.cdsap.projectgenerator.NameMappings +import io.github.cdsap.projectgenerator.ProjectNameMaps import io.github.cdsap.projectgenerator.model.ModuleClassDefinitionAndroid import io.github.cdsap.projectgenerator.model.ProjectGraph import io.github.cdsap.projectgenerator.model.TypeProject import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotEquals import org.junit.jupiter.api.Test import java.io.File class GeneratedModuleLayoutTest { + private val emptyNameMaps = ProjectNameMaps(emptyMap(), emptyMap()) + @Test fun `android app uses standard main test resource and manifest paths`() { val node = ProjectGraph("module_1_1", 1, emptyList(), TypeProject.ANDROID_APP, 1) - val layout = GeneratedModuleLayout.of("projects_generated/demo", node, kotlinMultiplatformLibrary = false) + val layout = GeneratedModuleLayout.of( + "projects_generated/demo", + node, + kotlinMultiplatformLibrary = false, + nameMaps = emptyNameMaps + ) - assertEquals(expectedPackage("projects_generated/demo", node, "src/main/kotlin"), layout.mainKotlinPackageDir()) - assertEquals(expectedPackage("projects_generated/demo", node, "src/test/kotlin"), layout.testKotlinPackageDir()) - assertEquals(expectedModuleFile("projects_generated/demo", node, "src/main/res/layout"), layout.resourcesLayoutDir()) - assertEquals(expectedModuleFile("projects_generated/demo", node, "src/main/res/values"), layout.resourcesValuesDir()) - assertEquals(expectedModuleFile("projects_generated/demo", node, "src/main/"), layout.manifestDir()) + assertEquals(expectedPackage("projects_generated/demo", node, "src/main/kotlin", emptyNameMaps), layout.mainKotlinPackageDir()) + assertEquals(expectedPackage("projects_generated/demo", node, "src/test/kotlin", emptyNameMaps), layout.testKotlinPackageDir()) + assertEquals(expectedModuleFile("projects_generated/demo", node, "src/main/res/layout", emptyNameMaps), layout.resourcesLayoutDir()) + assertEquals(expectedModuleFile("projects_generated/demo", node, "src/main/res/values", emptyNameMaps), layout.resourcesValuesDir()) + assertEquals(expectedModuleFile("projects_generated/demo", node, "src/main/", emptyNameMaps), layout.manifestDir()) } @Test fun `android library without kmp uses standard source set paths`() { val node = ProjectGraph("module_2_1", 2, emptyList(), TypeProject.ANDROID_LIB, 1) - val layout = GeneratedModuleLayout.of("out", node, kotlinMultiplatformLibrary = false) + val layout = GeneratedModuleLayout.of("out", node, kotlinMultiplatformLibrary = false, nameMaps = emptyNameMaps) - assertEquals(expectedPackage("out", node, "src/main/kotlin"), layout.mainKotlinPackageDir()) - assertEquals(expectedPackage("out", node, "src/test/kotlin"), layout.testKotlinPackageDir()) - assertEquals(expectedModuleFile("out", node, "src/main/res/layout"), layout.resourcesLayoutDir()) - assertEquals(expectedModuleFile("out", node, "src/main/res/values"), layout.resourcesValuesDir()) - assertEquals(expectedModuleFile("out", node, "src/main/"), layout.manifestDir()) + assertEquals(expectedPackage("out", node, "src/main/kotlin", emptyNameMaps), layout.mainKotlinPackageDir()) + assertEquals(expectedPackage("out", node, "src/test/kotlin", emptyNameMaps), layout.testKotlinPackageDir()) + assertEquals(expectedModuleFile("out", node, "src/main/res/layout", emptyNameMaps), layout.resourcesLayoutDir()) + assertEquals(expectedModuleFile("out", node, "src/main/res/values", emptyNameMaps), layout.resourcesValuesDir()) + assertEquals(expectedModuleFile("out", node, "src/main/", emptyNameMaps), layout.manifestDir()) } @Test fun `android kmp library uses androidMain and androidHostTest paths`() { val node = ProjectGraph("module_3_1", 3, emptyList(), TypeProject.ANDROID_LIB, 1) - val layout = GeneratedModuleLayout.of("out", node, kotlinMultiplatformLibrary = true) + val layout = GeneratedModuleLayout.of("out", node, kotlinMultiplatformLibrary = true, nameMaps = emptyNameMaps) - assertEquals(expectedPackage("out", node, "src/androidMain/kotlin"), layout.mainKotlinPackageDir()) - assertEquals(expectedPackage("out", node, "src/androidHostTest/kotlin"), layout.testKotlinPackageDir()) - assertEquals(expectedModuleFile("out", node, "src/androidMain/res/layout"), layout.resourcesLayoutDir()) - assertEquals(expectedModuleFile("out", node, "src/androidMain/res/values"), layout.resourcesValuesDir()) - assertEquals(expectedModuleFile("out", node, "src/androidMain/"), layout.manifestDir()) + assertEquals(expectedPackage("out", node, "src/androidMain/kotlin", emptyNameMaps), layout.mainKotlinPackageDir()) + assertEquals(expectedPackage("out", node, "src/androidHostTest/kotlin", emptyNameMaps), layout.testKotlinPackageDir()) + assertEquals(expectedModuleFile("out", node, "src/androidMain/res/layout", emptyNameMaps), layout.resourcesLayoutDir()) + assertEquals(expectedModuleFile("out", node, "src/androidMain/res/values", emptyNameMaps), layout.resourcesValuesDir()) + assertEquals(expectedModuleFile("out", node, "src/androidMain/", emptyNameMaps), layout.manifestDir()) } @Test fun `android app ignores kmp flag for source set paths`() { val node = ProjectGraph("module_1_2", 1, emptyList(), TypeProject.ANDROID_APP, 1) - val layout = GeneratedModuleLayout.of("out", node, kotlinMultiplatformLibrary = true) + val layout = GeneratedModuleLayout.of("out", node, kotlinMultiplatformLibrary = true, nameMaps = emptyNameMaps) - assertEquals(expectedPackage("out", node, "src/main/kotlin"), layout.mainKotlinPackageDir()) - assertEquals(expectedPackage("out", node, "src/test/kotlin"), layout.testKotlinPackageDir()) - assertEquals(expectedModuleFile("out", node, "src/main/res/layout"), layout.resourcesLayoutDir()) - assertEquals(expectedModuleFile("out", node, "src/main/"), layout.manifestDir()) + assertEquals(expectedPackage("out", node, "src/main/kotlin", emptyNameMaps), layout.mainKotlinPackageDir()) + assertEquals(expectedPackage("out", node, "src/test/kotlin", emptyNameMaps), layout.testKotlinPackageDir()) + assertEquals(expectedModuleFile("out", node, "src/main/res/layout", emptyNameMaps), layout.resourcesLayoutDir()) + assertEquals(expectedModuleFile("out", node, "src/main/", emptyNameMaps), layout.manifestDir()) } @Test @@ -73,19 +82,19 @@ class GeneratedModuleLayoutTest { classes = emptyList() ) - val appLayout = GeneratedModuleLayout.of("out", withType, kotlinMultiplatformLibrary = true) - val libLayout = GeneratedModuleLayout.of("out", withoutType, kotlinMultiplatformLibrary = true) + val appLayout = GeneratedModuleLayout.of("out", withType, kotlinMultiplatformLibrary = true, nameMaps = emptyNameMaps) + val libLayout = GeneratedModuleLayout.of("out", withoutType, kotlinMultiplatformLibrary = true, nameMaps = emptyNameMaps) assertEquals( - File("out/${NameMappings.layerName(4)}/module_4_1/src/main/kotlin/com/awesomeapp/module_4_1/"), + File("out/layer_4/module_4_1/src/main/kotlin/com/awesomeapp/module_4_1/"), appLayout.mainKotlinPackageDir() ) assertEquals( - File("out/${NameMappings.layerName(5)}/module_5_1/src/androidMain/kotlin/com/awesomeapp/module_5_1/"), + File("out/layer_5/module_5_1/src/androidMain/kotlin/com/awesomeapp/module_5_1/"), libLayout.mainKotlinPackageDir() ) assertEquals( - File("out/${NameMappings.layerName(5)}/module_5_1/src/androidHostTest/kotlin/com/awesomeapp/module_5_1/"), + File("out/layer_5/module_5_1/src/androidHostTest/kotlin/com/awesomeapp/module_5_1/"), libLayout.testKotlinPackageDir() ) } @@ -97,23 +106,69 @@ class GeneratedModuleLayoutTest { projectName = "out", node = node, mainKotlinSourceDir = "src/customMain/kotlin", - testKotlinSourceDir = "src/customTest/kotlin" + testKotlinSourceDir = "src/customTest/kotlin", + nameMaps = emptyNameMaps ) - assertEquals(expectedPackage("out", node, "src/customMain/kotlin"), layout.mainKotlinPackageDir()) - assertEquals(expectedPackage("out", node, "src/customTest/kotlin"), layout.testKotlinPackageDir()) + assertEquals(expectedPackage("out", node, "src/customMain/kotlin", emptyNameMaps), layout.mainKotlinPackageDir()) + assertEquals(expectedPackage("out", node, "src/customTest/kotlin", emptyNameMaps), layout.testKotlinPackageDir()) + } + + @Test + fun `builds paths from explicit ProjectNameMaps without configuring NameMappings`() { + val previousLayers = NameMappings.layerNames + val previousModules = NameMappings.moduleNames + NameMappings.layerNames = emptyMap() + NameMappings.moduleNames = emptyMap() + try { + val nameMaps = ProjectNameMaps( + layerNames = mapOf(1 to "platform"), + moduleNames = mapOf("module_1_1" to "sample-lib") + ) + val node = ProjectGraph("module_1_1", 1, emptyList(), TypeProject.ANDROID_LIB, 1) + val layout = GeneratedModuleLayout.of( + projectName = "out", + node = node, + kotlinMultiplatformLibrary = false, + nameMaps = nameMaps + ) + + assertEquals( + File("out/platform/sample-lib/src/main/kotlin/com/awesomeapp/samplelib/"), + layout.mainKotlinPackageDir() + ) + assertEquals( + File("out/platform/sample-lib/src/test/kotlin/com/awesomeapp/samplelib/"), + layout.testKotlinPackageDir() + ) + assertNotEquals(NameMappings.layerName(1), "platform") + assertNotEquals(NameMappings.moduleName("module_1_1"), "sample-lib") + } finally { + NameMappings.layerNames = previousLayers + NameMappings.moduleNames = previousModules + } } - private fun expectedPackage(projectName: String, node: ProjectGraph, sourceDir: String): File { - val layerDir = NameMappings.layerName(node.layer) - val moduleDir = NameMappings.moduleName(node.id) - val packageDir = NameMappings.modulePackageName(node.id) + private fun expectedPackage( + projectName: String, + node: ProjectGraph, + sourceDir: String, + nameMaps: ProjectNameMaps + ): File { + val layerDir = nameMaps.layerNames[node.layer] ?: "layer_${node.layer}" + val moduleDir = nameMaps.moduleNames[node.id] ?: node.id + val packageDir = moduleDir.replace("-", "") return File("$projectName/$layerDir/$moduleDir/$sourceDir/com/awesomeapp/$packageDir/") } - private fun expectedModuleFile(projectName: String, node: ProjectGraph, relativePath: String): File { - val layerDir = NameMappings.layerName(node.layer) - val moduleDir = NameMappings.moduleName(node.id) + private fun expectedModuleFile( + projectName: String, + node: ProjectGraph, + relativePath: String, + nameMaps: ProjectNameMaps + ): File { + val layerDir = nameMaps.layerNames[node.layer] ?: "layer_${node.layer}" + val moduleDir = nameMaps.moduleNames[node.id] ?: node.id return File("$projectName/$layerDir/$moduleDir/$relativePath") } } diff --git a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/writer/ModulesWriterTest.kt b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/writer/ModulesWriterTest.kt index c3daea4d..7be67844 100644 --- a/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/writer/ModulesWriterTest.kt +++ b/project-generator/src/test/kotlin/io/github/cdsap/projectgenerator/writer/ModulesWriterTest.kt @@ -1,6 +1,6 @@ package io.github.cdsap.projectgenerator.writer -import io.github.cdsap.projectgenerator.NameMappings +import io.github.cdsap.projectgenerator.ProjectNameMaps import io.github.cdsap.projectgenerator.generator.BuildFilesGenerator import io.github.cdsap.projectgenerator.generator.ClassGenerator import io.github.cdsap.projectgenerator.generator.ModuleClassPlanner @@ -21,6 +21,8 @@ import java.util.concurrent.atomic.AtomicInteger class ModulesWriterTest { + private val emptyNameMaps = ProjectNameMaps(emptyMap(), emptyMap()) + @TempDir lateinit var tempDir: Path @@ -42,7 +44,8 @@ class ModulesWriterTest { generateUnitTest = false, buildFilesGenerator = NoOpBuildFilesGenerator(), nodes = modules, - languages = languages + languages = languages, + nameMaps = emptyNameMaps ).write() assertEquals(modules.size, planner.planCalls.get()) @@ -72,15 +75,16 @@ class ModulesWriterTest { buildFilesGenerator = NoOpBuildFilesGenerator(), nodes = listOf(module), languages = languages, + nameMaps = emptyNameMaps, sourceSetLayout = layout ).write() assertEquals(listOf(module), layout.mainKotlinCalls) assertEquals(listOf(module), layout.testKotlinCalls) - val layerDir = NameMappings.layerName(module.layer) - val moduleDir = NameMappings.moduleName(module.id) - val packageDir = NameMappings.modulePackageName(module.id) + val layerDir = emptyNameMaps.layerNames[module.layer] ?: "layer_${module.layer}" + val moduleDir = emptyNameMaps.moduleNames[module.id] ?: module.id + val packageDir = moduleDir.replace("-", "") assertTrue( File("$projectRoot/$layerDir/$moduleDir/src/main/kotlin/com/awesomeapp/$packageDir").isDirectory ) @@ -89,6 +93,31 @@ class ModulesWriterTest { ) } + @Test + fun `createModuleStructure uses ProjectNameMaps for directory layout`() = runBlocking { + val module = ProjectGraph("module_1_1", 1, emptyList(), TypeProject.LIB, 1) + val projectRoot = tempDir.resolve("named_project").toString() + val languages = listOf(LanguageAttributes("gradle.kts", projectRoot)) + val nameMaps = ProjectNameMaps( + layerNames = mapOf(1 to "platform"), + moduleNames = mapOf("module_1_1" to "sample-lib") + ) + + TestModulesWrite( + classGenerator = RecordingClassGenerator(), + classPlanner = CountingPlanner(), + testGenerator = NoOpTestGenerator(), + generateUnitTest = true, + buildFilesGenerator = NoOpBuildFilesGenerator(), + nodes = listOf(module), + languages = languages, + nameMaps = nameMaps + ).write() + + assertTrue(File("$projectRoot/platform/sample-lib/src/main/kotlin/com/awesomeapp/samplelib").isDirectory) + assertTrue(File("$projectRoot/platform/sample-lib/src/test/kotlin/com/awesomeapp/samplelib").isDirectory) + } + private class ModulePlan(val moduleId: String) private class CountingPlanner : ModuleClassPlanner { @@ -160,6 +189,7 @@ class ModulesWriterTest { buildFilesGenerator: BuildFilesGenerator, nodes: List, languages: List, + nameMaps: ProjectNameMaps, sourceSetLayout: ModuleSourceSetLayout = JvmModuleSourceSetLayout ) : ModulesWrite( classGenerator = classGenerator, @@ -171,6 +201,7 @@ class ModulesWriterTest { resources = null, nodes = nodes, languages = languages, + nameMaps = nameMaps, sourceSetLayout = sourceSetLayout ) }