Skip to content

Commit 499ca4b

Browse files
authored
Added backwards support for Android Studio Meerkat. (#25)
1 parent 04a568b commit 499ca4b

File tree

15 files changed

+108
-74
lines changed

15 files changed

+108
-74
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ fun main(arguments: Array<String>) {
9999
projectName = request.projectName,
100100
packageName = request.packageName,
101101
overrideMinimumAndroidSdk = null,
102+
overrideAndroidGradlePluginVersion = null,
102103
enableCompose = request.enableCompose,
103104
enableKtlint = request.enableKtlint,
104105
enableDetekt = request.enableDetekt,

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

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import com.mitteloupe.cag.core.generation.architecture.CoroutineModuleContentGen
2626
import com.mitteloupe.cag.core.generation.versioncatalog.DependencyConfiguration
2727
import com.mitteloupe.cag.core.generation.versioncatalog.LibraryConstants
2828
import com.mitteloupe.cag.core.generation.versioncatalog.PluginConstants
29-
import com.mitteloupe.cag.core.generation.versioncatalog.SectionEntryRequirement
3029
import com.mitteloupe.cag.core.generation.versioncatalog.VersionCatalogConstants
3130
import com.mitteloupe.cag.core.generation.versioncatalog.VersionCatalogUpdater
3231
import com.mitteloupe.cag.core.generation.withoutSpaces
@@ -392,12 +391,13 @@ class Generator(
392391
throw GenerationException("Package name is missing.")
393392
}
394393

395-
println("Comparing ${request.destinationRootDirectory.name} to ${projectName.withoutSpaces()}")
394+
val sanitizedProjectName = projectName.withoutSpaces()
395+
println("Comparing ${request.destinationRootDirectory.name} to $sanitizedProjectName")
396396
val projectRoot =
397-
if (request.destinationRootDirectory.name == projectName.withoutSpaces()) {
397+
if (request.destinationRootDirectory.name.matches("$sanitizedProjectName\\d*".toRegex())) {
398398
request.destinationRootDirectory
399399
} else {
400-
File(request.destinationRootDirectory, projectName.withoutSpaces())
400+
File(request.destinationRootDirectory, sanitizedProjectName)
401401
}
402402

403403
if (projectRoot != request.destinationRootDirectory && projectRoot.exists()) {
@@ -434,24 +434,21 @@ class Generator(
434434
add(PluginConstants.DETEKT)
435435
}
436436
}
437-
val overrideVersions =
438-
if (request.overrideMinimumAndroidSdk == null) {
439-
VersionCatalogConstants.ANDROID_VERSIONS
440-
} else {
441-
VersionCatalogConstants.ANDROID_VERSIONS.map { androidVersion ->
442-
if (androidVersion.key == VersionCatalogConstants.MIN_SDK_VERSION.key) {
443-
SectionEntryRequirement.VersionRequirement(
444-
key = androidVersion.key,
445-
version = request.overrideMinimumAndroidSdk.toString()
446-
)
447-
} else {
448-
androidVersion
449-
}
450-
}
437+
val versionOverrides =
438+
listOf(
439+
VersionCatalogConstants.MIN_SDK_VERSION to request.overrideMinimumAndroidSdk?.toString(),
440+
VersionCatalogConstants.ANDROID_GRADLE_PLUGIN_VERSION to request.overrideAndroidGradlePluginVersion
441+
).mapNotNull { override -> override.second?.let { override.first to it } }
442+
.toMap()
443+
val androidVersions =
444+
VersionCatalogConstants.ANDROID_VERSIONS.map { version ->
445+
versionOverrides[version]?.let { versionOverride ->
446+
version.copy(version = versionOverride)
447+
} ?: version
451448
}
452449
val dependencyConfiguration =
453450
DependencyConfiguration(
454-
versions = overrideVersions,
451+
versions = androidVersions,
455452
libraries = libraries,
456453
plugins = plugins
457454
)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ fun buildAndroidManifest(appName: String): String =
3030
</manifest>
3131
""".trimIndent()
3232

33-
fun buildStringsXml(packageName: String): String =
33+
fun buildStringsXml(appName: String): String =
3434
"""
3535
<?xml version="1.0" encoding="utf-8"?>
3636
<resources>
37-
<string name="app_name">${packageName.split('.').last().capitalized}</string>
37+
<string name="app_name">$appName</string>
3838
</resources>
3939
""".trimIndent()
4040

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,15 @@ class AppModuleContentGenerator(
6464

6565
fileCreator.createDirectoryIfNotExists(basePackageDir)
6666

67+
val sanitizedAppName = appName.withoutSpaces()
6768
val mainActivityFile = File(basePackageDir, "MainActivity.kt")
68-
val mainActivityContent =
69+
fileCreator.createFileIfNotExists(mainActivityFile) {
6970
buildMainActivityKotlinFile(
70-
appName = appName,
71+
appName = sanitizedAppName,
7172
projectNamespace = projectNamespace,
7273
enableCompose = enableCompose
7374
)
74-
fileCreator.createFileIfNotExists(mainActivityFile) { mainActivityContent }
75+
}
7576

7677
val applicationFile = File(basePackageDir, "Application.kt")
7778
val applicationContent = buildApplicationKotlinFile(projectNamespace)
@@ -91,24 +92,25 @@ class AppModuleContentGenerator(
9192
packageName: String,
9293
enableCompose: Boolean
9394
) {
95+
val sanitizedAppName = appName.withoutSpaces()
9496
val manifestFile = File(appModuleDirectory, "src/main/AndroidManifest.xml")
95-
fileCreator.createOrUpdateFile(manifestFile) { buildAndroidManifest(appName) }
97+
fileCreator.createOrUpdateFile(manifestFile) { buildAndroidManifest(sanitizedAppName) }
9698

9799
val valuesDirectory = File(appModuleDirectory, "src/main/res/values")
98100
fileCreator.createDirectoryIfNotExists(valuesDirectory)
99101
val stringsFile = File(valuesDirectory, "strings.xml")
100-
fileCreator.createFileIfNotExists(stringsFile) { buildStringsXml(packageName) }
102+
fileCreator.createFileIfNotExists(stringsFile) { buildStringsXml(appName) }
101103
val xmlDirectory = File(appModuleDirectory, "src/main/res/xml")
102104
fileCreator.createDirectoryIfNotExists(xmlDirectory)
103105

104106
if (enableCompose) {
105107
val themeFile = File(valuesDirectory, "themes.xml")
106-
fileCreator.createFileIfNotExists(themeFile) { buildThemesXml(appName) }
108+
fileCreator.createFileIfNotExists(themeFile) { buildThemesXml(sanitizedAppName) }
107109

108110
val uiDirectory = File(appModuleDirectory, "src/main/java/${packageName.replace('.', '/')}/ui/theme")
109111
fileCreator.createDirectoryIfNotExists(uiDirectory)
110112
val themeKtFile = File(uiDirectory, "Theme.kt")
111-
fileCreator.createFileIfNotExists(themeKtFile) { buildThemeKt(appName = appName, packageName = packageName) }
113+
fileCreator.createFileIfNotExists(themeKtFile) { buildThemeKt(appName = sanitizedAppName, packageName = packageName) }
112114

113115
val colorsKtFile = File(uiDirectory, "Color.kt")
114116
fileCreator.createFileIfNotExists(colorsKtFile) { buildColorsKt(packageName) }

core/src/main/kotlin/com/mitteloupe/cag/core/generation/GradleWrapperCreator.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,13 @@ class GradleWrapperCreator(private val fileCreator: FileCreator) {
1111
fileCreator.createDirectoryIfNotExists(gradleWrapperDirectory)
1212

1313
val gradleWrapperPropertiesFile = File(gradleWrapperDirectory, "gradle-wrapper.properties")
14-
val gradleWrapperPropertiesContent = buildGradleWrapperPropertiesFile()
15-
16-
fileCreator.createFileIfNotExists(gradleWrapperPropertiesFile) { gradleWrapperPropertiesContent }
14+
fileCreator.createOrUpdateFile(gradleWrapperPropertiesFile) { buildGradleWrapperPropertiesFile() }
1715

1816
val gradleWrapperJarFile = File(gradleWrapperDirectory, "gradle-wrapper.jar")
1917
fileCreator.createBinaryFileIfNotExists(gradleWrapperJarFile) { getGradleWrapperResourceAsBytes() }
2018

2119
val gradlewFile = File(projectRoot, "gradlew")
22-
val gradlewContent = getResourceAsString("gradlew")
23-
fileCreator.createFileIfNotExists(gradlewFile) { gradlewContent }
20+
fileCreator.createFileIfNotExists(gradlewFile) { getResourceAsString("gradlew") }
2421
if (!gradlewFile.setExecutable(true)) {
2522
throw GenerationException("Failed to make gradlew executable")
2623
}

core/src/main/kotlin/com/mitteloupe/cag/core/generation/SettingsFileUpdater.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,10 @@ class SettingsFileUpdater(private val fileCreator: FileCreator) {
162162
featureNames: List<String>
163163
) {
164164
val settingsFile = File(projectRoot, "settings.gradle.kts")
165-
val content = buildSettingsGradleScript(projectName, featureNames)
166-
runCatching { fileCreator.createOrUpdateFile(settingsFile) { content } }
167-
.onFailure { throw GenerationException("Failed to create settings.gradle.kts: ${it.message}") }
165+
runCatching {
166+
fileCreator.createOrUpdateFile(settingsFile) {
167+
buildSettingsGradleScript(projectName.withoutSpaces(), featureNames)
168+
}
169+
}.onFailure { throw GenerationException("Failed to create settings.gradle.kts: ${it.message}") }
168170
}
169171
}

core/src/main/kotlin/com/mitteloupe/cag/core/generation/versioncatalog/VersionCatalogUpdater.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,9 @@ class VersionCatalogUpdater(
169169
insertPositionIfMissing = CatalogInsertPosition.Start,
170170
requirements =
171171
(dependencyConfiguration.versions + pluginRequirements.versions + libraryRequirements.versions)
172-
.distinct()
172+
.associateBy { it.key }
173+
.values
174+
.toList()
173175
),
174176
SectionTransaction(
175177
insertPositionIfMissing = CatalogInsertPosition.End,
@@ -221,8 +223,10 @@ class VersionCatalogUpdater(
221223
}
222224

223225
val versionRequirements =
224-
(dependencyConfiguration.versions + pluginRequirements.versions + libraryRequirements.versions)
225-
.distinct()
226+
(pluginRequirements.versions + libraryRequirements.versions + dependencyConfiguration.versions)
227+
.associateBy { it.key }
228+
.values
229+
.toList()
226230

227231
updateVersionCatalogIfPresent(
228232
projectRootDir = projectRootDir,

core/src/main/kotlin/com/mitteloupe/cag/core/request/GenerateProjectTemplateRequest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ data class GenerateProjectTemplateRequest(
77
val projectName: String,
88
val packageName: String,
99
val overrideMinimumAndroidSdk: Int?,
10+
val overrideAndroidGradlePluginVersion: String?,
1011
val enableCompose: Boolean,
1112
val enableKtlint: Boolean,
1213
val enableDetekt: Boolean,

core/src/test/kotlin/com/mitteloupe/cag/core/GeneratorTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -527,12 +527,12 @@ class GeneratorTest {
527527
val expectedContent =
528528
"""
529529
[versions]
530+
kotlin = "2.2.10"
531+
ksp = "2.2.10-2.0.2"
532+
androidGradlePlugin = "8.12.2"
530533
compileSdk = "36"
531534
minSdk = "24"
532535
targetSdk = "36"
533-
androidGradlePlugin = "8.12.2"
534-
kotlin = "2.2.10"
535-
ksp = "2.2.10-2.0.2"
536536
537537
[plugins]
538538
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }

core/src/test/kotlin/com/mitteloupe/cag/core/generation/GradleWrapperCreatorTest.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class GradleWrapperCreatorTest {
8989
}
9090

9191
@Test
92-
fun `Given existing gradle-wrapper-properties when writeGradleWrapperFiles then does not overwrite existing file`() {
92+
fun `Given existing gradle-wrapper-properties when writeGradleWrapperFiles then overwrites existing file`() {
9393
// Given
9494
val projectRoot = createTempDirectory(prefix = "projectRoot").toFile()
9595
val gradleWrapperDirectory = File(projectRoot, "gradle/wrapper")
@@ -98,12 +98,21 @@ class GradleWrapperCreatorTest {
9898
val gradleWrapperPropertiesFile = File(gradleWrapperDirectory, "gradle-wrapper.properties")
9999
val initialContent = "initial content"
100100
gradleWrapperPropertiesFile.writeText(initialContent)
101+
val expectedContent =
102+
"""
103+
distributionBase=GRADLE_USER_HOME
104+
distributionPath=wrapper/dists
105+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
106+
zipStoreBase=GRADLE_USER_HOME
107+
zipStorePath=wrapper/dists
108+
""".trimIndent()
101109

102110
// When
103111
classUnderTest.writeGradleWrapperFiles(projectRoot)
112+
val actualContent = gradleWrapperPropertiesFile.readText()
104113

105114
// Then
106-
assertEquals("Existing gradle wrapper properties should not be overwritten", initialContent, gradleWrapperPropertiesFile.readText())
115+
assertEquals("Existing gradle wrapper properties should be overwritten", expectedContent, actualContent)
107116
}
108117

109118
@Test

0 commit comments

Comments
 (0)