diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 4a5facfb..27009a3d 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,6 +1,9 @@
+import java.util.Properties
+
plugins {
- id("com.android.application")
- id("org.jetbrains.kotlin.android")
+ hmh("application")
+ hmh("compose")
+ hmh("test")
}
android {
@@ -54,6 +57,7 @@ dependencies {
implementation(libs.core.ktx)
implementation(libs.lifecycle)
implementation(libs.activity.compose)
+ implementation(libs.retrofit)
implementation(platform(libs.compose.bom))
//appcompat implementation
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 0527c564..d2f90472 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,5 +1,4 @@
-
diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts
new file mode 100644
index 00000000..88bc17a2
--- /dev/null
+++ b/build-logic/convention/build.gradle.kts
@@ -0,0 +1,54 @@
+plugins {
+ `kotlin-dsl`
+}
+
+group = "com.hmh.hamyeonham.buildlogic"
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+}
+
+
+dependencies {
+ compileOnly(libs.agp)
+ compileOnly(libs.kotlin.gradleplugin)
+}
+
+gradlePlugin {
+ plugins {
+ create("android-application") {
+ id = "com.hmh.hamyeonham.application"
+ implementationClass = "com.hmh.hamyeonham.plugin.AndroidApplicationPlugin"
+ }
+ create("android-feature") {
+ id = "com.hmh.hamyeonham.feature"
+ implementationClass = "com.hmh.hamyeonham.plugin.AndroidFeaturePlugin"
+ }
+ create("android-kotlin") {
+ id = "com.hmh.hamyeonham.kotlin"
+ implementationClass = "com.hmh.hamyeonham.plugin.AndroidKotlinPlugin"
+ }
+ create("android-hilt") {
+ id = "com.hmh.hamyeonham.hilt"
+ implementationClass = "com.hmh.hamyeonham.plugin.AndroidHiltPlugin"
+ }
+ create("kotlin-serialization") {
+ id = "com.hmh.hamyeonham.serialization"
+ implementationClass = "com.hmh.hamyeonham.plugin.KotlinSerializationPlugin"
+ }
+ create("junit5") {
+ id = "com.hmh.hamyeonham.junit5"
+ implementationClass = "com.hmh.hamyeonham.plugin.JUnit5Plugin"
+ }
+ create("android-test") {
+ id = "com.hmh.hamyeonham.test"
+ implementationClass = "com.hmh.hamyeonham.plugin.AndroidTestPlugin"
+ }
+ create("compose") {
+ id = "com.hmh.hamyeonham.compose"
+ implementationClass = "com.hmh.hamyeonham.plugin.ComposePlugin"
+ }
+ }
+}
+
diff --git a/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidApplicationPlugin.kt b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidApplicationPlugin.kt
new file mode 100644
index 00000000..d0dfe3cf
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidApplicationPlugin.kt
@@ -0,0 +1,11 @@
+package com.hmh.hamyeonham.plugin
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+class AndroidApplicationPlugin: Plugin {
+ override fun apply(target: Project) = with(target) {
+ plugins.apply("com.android.application")
+ configureAndroidCommonPlugin()
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidHiltPlugin.kt b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidHiltPlugin.kt
new file mode 100644
index 00000000..bb6629a9
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidHiltPlugin.kt
@@ -0,0 +1,24 @@
+package com.hmh.hamyeonham.plugin
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+
+class AndroidHiltPlugin : Plugin {
+ override fun apply(target: Project) = with(target) {
+ with(plugins) {
+ apply("com.google.devtools.ksp")
+ apply("com.google.dagger.hilt.android")
+ }
+
+ val libs = extensions.getByType().named("libs")
+ dependencies {
+ "implementation"(libs.findLibrary("hilt").get())
+ "ksp"(libs.findLibrary("hilt.compiler").get())
+ "testImplementation"(libs.findLibrary("hilt.testing").get())
+ "kspTest"(libs.findLibrary("hilt.testing.compiler").get())
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidKotlinPlugin.kt b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidKotlinPlugin.kt
new file mode 100644
index 00000000..b62ac038
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidKotlinPlugin.kt
@@ -0,0 +1,47 @@
+package com.hmh.hamyeonham.plugin
+
+import com.android.build.gradle.BaseExtension
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.api.plugins.ExtensionAware
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
+
+class AndroidKotlinPlugin : Plugin {
+ override fun apply(target: Project) = with(target) {
+ with(plugins) {
+ apply("kotlin-android")
+ }
+
+ val libs = extensions.getByType().named("libs")
+ extensions.getByType().apply {
+ setCompileSdkVersion(libs.findVersion("compileSdk").get().requiredVersion.toInt())
+
+ defaultConfig {
+ minSdk = libs.findVersion("minSdk").get().requiredVersion.toInt()
+ targetSdk = libs.findVersion("targetSdk").get().requiredVersion.toInt()
+ }
+
+ compileOptions {
+ isCoreLibraryDesugaringEnabled = true
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+
+ (this as ExtensionAware).configure {
+ jvmTarget = "17"
+ }
+ }
+
+ dependencies {
+ "coreLibraryDesugaring"(libs.findLibrary("desugarLibs").get())
+ "implementation"(libs.findLibrary("kotlin").get())
+ "implementation"(libs.findLibrary("kotlin.coroutines").get())
+ "implementation"(libs.findLibrary("kotlin.datetime").get())
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidTestPlugin.kt b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidTestPlugin.kt
new file mode 100644
index 00000000..8c44b4ef
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/AndroidTestPlugin.kt
@@ -0,0 +1,40 @@
+package com.hmh.hamyeonham.plugin
+
+import com.android.build.gradle.BaseExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.apply
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+
+class AndroidTestPlugin: Plugin {
+ override fun apply(target: Project): Unit = with(target) {
+ apply()
+ val libs = extensions.getByType().named("libs")
+
+ extensions.getByType().apply {
+ defaultConfig {
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ testInstrumentationRunnerArguments["runnerBuilder"] = "de.mannodermaus.junit5.AndroidJUnit5Builder"
+ }
+
+ testOptions {
+ unitTests {
+ isIncludeAndroidResources = true
+ }
+ }
+
+ packagingOptions {
+ resources.excludes.add("META-INF/LICENSE*")
+ }
+ }
+
+ dependencies {
+ "testImplementation"(libs.findLibrary("junit").get())
+ "debugImplementation"(libs.findLibrary("truth").get())
+ "testImplementation"(libs.findLibrary("robolectric").get())
+ "androidTestImplementation"(libs.findBundle("androidx.android.test").get())
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/CommonConfigs.kt b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/CommonConfigs.kt
new file mode 100644
index 00000000..e353c0e0
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/CommonConfigs.kt
@@ -0,0 +1,39 @@
+package com.hmh.hamyeonham.plugin
+
+import com.android.build.gradle.BaseExtension
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.apply
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+import java.util.Properties
+
+internal fun Project.configureAndroidCommonPlugin() {
+ val properties = Properties().apply {
+ load(rootProject.file("local.properties").inputStream())
+ }
+
+ apply()
+ apply()
+ with(plugins) {
+ apply("kotlin-parcelize")
+ }
+ apply()
+
+ extensions.getByType().apply {
+ defaultConfig {}
+ buildFeatures.apply {
+ viewBinding = true
+ buildConfig = true
+ }
+ }
+
+ val libs = extensions.getByType().named("libs")
+ dependencies {
+ "implementation"(libs.findLibrary("core.ktx").get())
+ "implementation"(libs.findLibrary("appcompat").get())
+ "implementation"(libs.findBundle("lifecycle").get())
+ "implementation"(libs.findLibrary("material").get())
+ "implementation"(libs.findLibrary("timber").get())
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/ComposePlugin.kt b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/ComposePlugin.kt
new file mode 100644
index 00000000..6115b414
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/ComposePlugin.kt
@@ -0,0 +1,27 @@
+package com.hmh.hamyeonham.plugin
+
+import com.android.build.gradle.BaseExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+
+class ComposePlugin : Plugin {
+ override fun apply(target: Project) = with(target) {
+ val libs = extensions.getByType().named("libs")
+ extensions.getByType().apply {
+ buildFeatures.apply {
+ compose = true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion = libs.findVersion("compose.compiler").get().requiredVersion
+ }
+ }
+
+ dependencies {
+ "implementation"(platform(libs.findLibrary("compose.bom").get()))
+ "implementation"(libs.findBundle("compose").get())
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/JUnit5Plugin.kt b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/JUnit5Plugin.kt
new file mode 100644
index 00000000..927e8019
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/JUnit5Plugin.kt
@@ -0,0 +1,24 @@
+package com.hmh.hamyeonham.plugin
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+
+class JUnit5Plugin : Plugin {
+ override fun apply(target: Project): Unit = with(target) {
+ with(plugins) {
+ apply("de.mannodermaus.android-junit5")
+ }
+ val libs = extensions.getByType().named("libs")
+
+ dependencies {
+ "testImplementation"(libs.findBundle("junit5").get())
+ "androidTestImplementation"(libs.findLibrary("junit5").get())
+ "androidTestImplementation"(libs.findLibrary("junit5.params").get())
+ "androidTestImplementation"(libs.findLibrary("junit5.android.test.core").get())
+ "androidTestRuntimeOnly"(libs.findLibrary("junit5.android.test.runner").get())
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/KotlinSerializationPlugin.kt b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/KotlinSerializationPlugin.kt
new file mode 100644
index 00000000..1556787c
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/hmh/hamyeonham/plugin/KotlinSerializationPlugin.kt
@@ -0,0 +1,20 @@
+package com.hmh.hamyeonham.plugin
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+
+class KotlinSerializationPlugin : Plugin {
+ override fun apply(target: Project) = with(target) {
+ with(plugins) {
+ apply("org.jetbrains.kotlin.plugin.serialization")
+ }
+
+ val libs = extensions.getByType().named("libs")
+ dependencies {
+ "implementation"(libs.findLibrary("kotlin.serialization.json").get())
+ }
+ }
+}
diff --git a/build-logic/gradle.properties b/build-logic/gradle.properties
new file mode 100644
index 00000000..1c9073eb
--- /dev/null
+++ b/build-logic/gradle.properties
@@ -0,0 +1,4 @@
+# Gradle properties are not passed to included builds https://github.com/gradle/gradle/issues/2534
+org.gradle.parallel=true
+org.gradle.caching=true
+org.gradle.configureondemand=true
diff --git a/build-logic/gradle/wrapper/gradle-wrapper.properties b/build-logic/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..67767e46
--- /dev/null
+++ b/build-logic/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Jan 13 12:46:38 KST 2023
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts
new file mode 100644
index 00000000..b48fae49
--- /dev/null
+++ b/build-logic/settings.gradle.kts
@@ -0,0 +1,15 @@
+dependencyResolutionManagement {
+ repositories {
+ google()
+ mavenCentral()
+ }
+ versionCatalogs {
+ create("libs") {
+ from(files("../gradle/libs.versions.toml"))
+ }
+ }
+}
+
+rootProject.name = "build-logic"
+include(":convention")
+
diff --git a/build.gradle.kts b/build.gradle.kts
index acd1ada7..73196533 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,6 +1,33 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+
+ dependencies {
+ classpath(libs.kotlin.gradleplugin)
+ classpath(libs.hilt.plugin)
+ classpath(libs.agp)
+ classpath(libs.ktlint)
+ classpath(libs.oss.plugin)
+ }
+}
+
plugins {
- id("com.android.application") version "8.2.0" apply false
- id("org.jetbrains.kotlin.android") version "1.9.0" apply false
- id("com.android.library") version "8.2.0" apply false
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.android.library) apply false
+ alias(libs.plugins.kotlin.android) apply false
+ alias(libs.plugins.dagger.hilt) apply false
+ alias(libs.plugins.ktlint) apply false
+ alias(libs.plugins.ksp) apply false
+ alias(libs.plugins.kotlinx.serialization) apply false
+ alias(libs.plugins.junit5) apply false
+ alias(libs.plugins.google.services) apply false
+ alias(libs.plugins.app.distribution) apply false
+ alias(libs.plugins.crashlytics) apply false
+}
+
+tasks.register("clean", Delete::class) {
+ delete(rootProject.layout.buildDirectory)
}
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
new file mode 100644
index 00000000..0a2aabde
--- /dev/null
+++ b/buildSrc/build.gradle.kts
@@ -0,0 +1,8 @@
+plugins {
+ `kotlin-dsl`
+}
+
+repositories {
+ mavenCentral()
+ gradlePluginPortal()
+}
diff --git a/buildSrc/gradle.properties b/buildSrc/gradle.properties
new file mode 100644
index 00000000..b5af1b68
--- /dev/null
+++ b/buildSrc/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx4g -XX:+UseParallelGC
+org.gradle.configureondemand=true
+org.gradle.parallel=true
+org.gradle.caching=true
diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts
new file mode 100644
index 00000000..29744ec1
--- /dev/null
+++ b/buildSrc/settings.gradle.kts
@@ -0,0 +1 @@
+rootProject.name = "buildSrc"
diff --git a/buildSrc/src/main/kotlin/plugin.kt b/buildSrc/src/main/kotlin/plugin.kt
new file mode 100644
index 00000000..4343b9f5
--- /dev/null
+++ b/buildSrc/src/main/kotlin/plugin.kt
@@ -0,0 +1,6 @@
+import org.gradle.plugin.use.PluginDependenciesSpec
+import org.gradle.plugin.use.PluginDependencySpec
+
+fun PluginDependenciesSpec.hmh(pluginName: String): PluginDependencySpec {
+ return id("com.hmh.hamyeonham.$pluginName")
+}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index dbd35967..b9f507f8 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -6,7 +6,7 @@ appVersion = "1.0.0"
versionCode = "1"
# kotlin
-kotlin = "1.9.20"
+kotlin = "1.9.0"
kotlinx-serialization-json = "1.6.0"
kotlinx-serialization-converter = "1.0.0"
kotlinx-coroutines = "1.7.3"
@@ -200,7 +200,6 @@ zxing-android-embedded = { module = "com.journeyapps:zxing-android-embedded", ve
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
-kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
dagger-hilt = { id = "com.google.dagger.hilt.android", version.ref = "dagger-hilt" }
google-services = { id = "com.google.gms.google-services", version.ref = "google-services" }
crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "crashlytics" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 9ca82673..741511ca 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,4 +1,7 @@
+enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
+
pluginManagement {
+ includeBuild("build-logic")
repositories {
google()
mavenCentral()