Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

린트 추가 및 모듈 네이밍 수정 #3

Merged
merged 14 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
root = true

[*]
# 인코딩 방식
charset = utf-8
# 줄바꿈 타입
end_of_line = lf
# 들여쓰기 타입
indent_style = space
# true 경우, 문자 앞의 공백을 제거
trim_trailing_whitespace = true
# ture 경우, 파일을 저장할 때 새 줄로 끝남
insert_final_newline = true
# 최대 길이
max_line_length = 120
# indent_size
indent_size = 4

[*.{kt,kts}]
disabled_rules = import-ordering,comment-spacing
8 changes: 8 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# What's Changed




### Memo

별도 메모 사항이 있을 경우 작성
24 changes: 18 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,30 @@

안드로이드에서 공통적으로 사용될 모듈 저장소

**Authors** : raine@lemoncloud.io

## Module

| module | description |
|----------------------------------|---------------------------|
| ui-architecture | mvi 기반 architecture 인터페이스 |
| android-component(Not implement) | android component 관련 유틸리티 |

| module | description |
|------------------------------|---------------------------|
| lemon-core-ui:architecture | mvi 기반 architecture 인터페이스 |
| lemon-core-android:component | android component 유틸리티 |

### UI-Architecture
안드로이드 UI 구조를 효과적으로 빌딩하기 위한 아키텍처 라이브러리. MVI 기반의 아키텍처로 State Event Effect를 제어하여 사용자와 UI간의 상태 및 이벤트 흐름과 사이에 발생하는 이펙트를 효과적으로 처리할 수 있습니다.

안드로이드 UI 구조를 효과적으로 빌딩하기 위한 아키텍처 라이브러리. MVI 기반의 아키텍처로 State Event Effect를 제어하여 사용자와 UI간의 상태 및 이벤트 흐름과 사이에 발생하는 이펙트를 효과적으로
처리할 수 있습니다.

### Android-Component

안드로이드 컴포넌트 제어 라이브러리 안드로이드 컴포넌트 초기화, 설정 및 컴포넌트간의 통신과 같은 작업을 수행합니다.

## 초기화

최초로 프로젝트를 다운받은 후 `./init_lint_settings.sh` 를 실행해주세요. commit changes 에 대한 lint를 자동적으로 수행합니다.

## AAR 배포

Lemon Android Core Module에서 사용되는 라이브러리를 배포해야 할 상황이 존재할 경우 루트 디렉터리에 존재하는 `assemble_aar.sh` 스크립트 파일을 실행하면 됩니다.
이때 생성되는 AAR들은 난독화가 적용되어 있습니다. 배포되는 aar들의 난독화 여부와 flavor 구성들을 수정하고 싶을 경우, `build-system` 모듈의 `Config` 를 확인하세요.

13 changes: 13 additions & 0 deletions assemble_aar.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

chmod +x "./gradlew"

# ktlint 검사
./gradlew ktlintCheck

# AAR 배포
./gradlew assembleRelease

# 모든 모듈의 AAR 을 수집하여 ./build/outputs 에 배치
./gradlew assembleAAR

File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ dependencyResolutionManagement {
}


rootProject.name = "buildSystem"
rootProject.name = "build-system"


Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.lemon.android.buildSystem

import io.lemon.android.buildSystem.extensions.type.FlavorType
import io.lemon.android.buildSystem.extensions.type.ResourceType
import org.gradle.api.JavaVersion
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import java.time.ZonedDateTime
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.lemon.android.buildSystem.plugin

import com.android.build.api.dsl.ApplicationExtension
import io.lemon.android.buildSystem.Config
import io.lemon.android.buildSystem.Config.COMPILE_SDK
import io.lemon.android.buildSystem.Config.MIN_SDK
import io.lemon.android.buildSystem.Config.TARGET_SDK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class AndroidFeaturePlugin : Plugin<Project> {
add("implementation", versionCatalog.findLibrary("androidx-appcompat").get())
add("implementation", versionCatalog.findLibrary("androidx-core-ktx").get())
add("implementation", versionCatalog.findLibrary("androidx-core-splashscreen").get())
add("implementation", versionCatalog.findLibrary("androidx-lifecycle-service").get())
add("implementation", versionCatalog.findLibrary("androidx-lifecycle-viewmodel-ktx").get())
add("implementation", versionCatalog.findLibrary("androidx-lifecycle-runtime-ktx").get())
add("implementation", versionCatalog.findLibrary("androidx-navigation-runtime-ktx").get())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.lemon.android.buildSystem.plugin

import com.android.build.gradle.LibraryExtension
import io.lemon.android.buildSystem.Config
import io.lemon.android.buildSystem.Config.BuildType.DEBUG
import io.lemon.android.buildSystem.Config.BuildType.RELEASE
import io.lemon.android.buildSystem.Config.COMPILE_SDK
Expand Down Expand Up @@ -36,11 +35,11 @@ class AndroidLibraryPlugin : Plugin<Project> {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
"proguard-rules.pro",
)
}
}
}
}
}
}
}
34 changes: 32 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
import org.jlleitschuh.gradle.ktlint.reporter.ReporterType
import org.jlleitschuh.gradle.ktlint.tasks.GenerateReportsTask

plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
Expand All @@ -10,5 +12,33 @@ plugins {
alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.parcelize) apply false
alias(libs.plugins.ktlint) apply true
}

allprojects {
apply {
plugin("org.jlleitschuh.gradle.ktlint")
}
ktlint {
reporters {
reporter(ReporterType.JSON)
reporter(ReporterType.CHECKSTYLE)
}
}
tasks.withType<GenerateReportsTask> {
reportsOutputDirectory.set(
rootProject.layout.buildDirectory.dir("reports/ktlint/${project.name}")
)
}
}

}
tasks.register<Copy>("assembleAAR") {
from(
project.provider {
subprojects.flatMap { subproject ->
subproject.layout.buildDirectory.dir("outputs/aar").get().asFile.listFiles()?.toList() ?: emptyList()
}
}
)
into(rootProject.layout.buildDirectory.dir("outputs/aar"))
}
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ espresso = "3.0.2"
gradle = "8.5.1"
hilt = "2.49"
junit = "4.13.2"
ktlint = "10.3.0"
kotlin = "2.0.0"
kotlinxCoroutines = "1.8.0"
kotlinxDatetime = "0.5.0"
Expand All @@ -38,6 +39,7 @@ android-library = { id = "com.android.library", version.ref = "gradle" }
android-test = { id = "com.android.test", version.ref = "gradle" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
Expand Down Expand Up @@ -86,6 +88,7 @@ androidx-test-core = { group = "androidx.test", name = "core", version.ref = "an
androidx-test-rules = { group = "androidx.test", name = "rules", version.ref = "androidxTestRules" }
androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidxTestRunner" }
androidx-test-ext = { group = "androidx.test.ext", name = "junit", version.ref = "androidxTestExt" }
androidx-lifecycle-service = { group = "androidx.lifecycle", name = "lifecycle-service", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" }
androidx-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidxLifecycle" }
Expand Down
8 changes: 8 additions & 0 deletions init_lint_settings.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

chmod +x "./gradlew"

# pre commit 린트 검사 훅 등록
./gradlew addKtlintCheckGitPreCommitHook

echo "린트 검사 규칙이 적용되었습니다."
File renamed without changes.
18 changes: 18 additions & 0 deletions lemon-core-android/component/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Android-Component
android component 유틸리티

### Intent
`Intent` 설정을 빌드하는 모듈입니다. `IntentBuilder`를 사용하여 Intent를 구성할 수 있으며, 이는 `Component` 의 `Launcher`와 연동하여 사용할 수 있습니다.
또한 특수한 목적으로 사용되는 `Intent`를 빠르게 구성하는 확장 람다 함수가 존재합니다. (예를 들어, URL에 대한 사이트를 빠르게 불러오는 `getUrlIntent`, Application 설정으로 빠르게 이동하는 `getSettingIntent`)
`Intent`를 컴포넌트 목적에 따른 `PendingIntent`로 변환하는 함수는 `PendingIntent` Object 내에 존재합니다.

### Launcher
`Android Component` 설정을 빠르게 구성하는 모듈입니다.
`Launcher` 생성 시 `Intent` 가 구성되며, 컴포넌트를 수행할 수 있는 함수가 존재합니다. 내부 `Intent` 정보는 `IntentBuilder`를 사용하여 수정할 수 있습니다. 이를 통해 extra,data 그리고 특수한 flag등을 설정할 수 있습니다.







9 changes: 9 additions & 0 deletions lemon-core-android/component/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
plugins {
alias(libs.plugins.lemon.android.library)
alias(libs.plugins.lemon.android.feature)
alias(libs.plugins.lemon.android.kotlin)
}

android {
namespace = "io.lemon.android.core.android.component"
}
Empty file.
4 changes: 4 additions & 0 deletions lemon-core-android/component/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package io.remon.android.core.android.component.intent

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Parcelable
import android.provider.Settings
import java.io.Serializable

/**
* [Intent]
*
* Intent 유틸리티
*
* @author raine@lemoncloud.io
*/
object Intent {

/**
* [intentBuilder]
*
* 인텐트 빌더를 생성합니다.
*
* context를 포함하지 않는 인텐트의 경우 해당 메서드를 사용합니다.
*
* @see IntentBuilder
*/
fun intentBuilder(): IntentBuilder = IntentBuilder()

/**
* [intentBuilder]
*
* 인텐트 빌더를 생성합니다.
*
* intent 타겟을 포함할 경우 헤당 메서드를 사용합니다.
*
* @see IntentBuilder
*/
fun intentBuilder(context: Context, `class`: Class<*>): IntentBuilder = IntentBuilder(context, `class`)

/**
* [getParcelableExtraExt]
*
* intent extra에 포함되어 있는 parcelable 객체를 가져올 때 사용합니다.
*/
fun <T : Parcelable> Intent.getParcelableExtraExt(key: String, `class`: Class<T>): T? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
getParcelableExtra(key, `class`)
else getParcelableExtra(key)
}

/**
* [getSerializableExtraExt]
*
* intent extra에 포함되어 있는 serializable 객체를 가져올 때 사용합니다.
*/
@Suppress("UNCHECKED_CAST")
fun <T : Serializable> Intent.getSerializableExtraExt(key: String, `class`: Class<T>): T? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
this.getSerializableExtra(key, `class`)
} else {
this.getSerializableExtra(key) as T?
}
}

/**
* [getUrlIntent]
*
* url 주소를 포함한 intent를 생성합니다.
*
* `startActivity()`와 연계하여 사용합니다.
*/
val getUrlIntent: (String) -> Intent =
{ url -> intentBuilder().setAction(Intent.ACTION_VIEW).setData(Uri.parse(url)).build() }

/**
* [getSettingsIntent]
*
* 애플리케이션의 설정으로 이동하는 intent를 생성합니다.
*
* `startActivity()`와 연계하여 사용합니다.
*/
val getSettingsIntent: (Context) -> Intent = { context ->
intentBuilder().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(
Uri.parse("package:${context.packageName}")
).build()
}
}
Loading