diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9ea56bf..f0a23c9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,26 +1,20 @@ -import com.loodos.buildsrc.getDateTime - -// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed -@Suppress("DSL_SCOPE_VIOLATION") plugins { - kotlin("kapt") - alias(libs.plugins.android.application) - alias(libs.plugins.kotlin.android) - alias(libs.plugins.dagger.hilt) - alias(libs.plugins.kotlinter) + id("samplecomposeanroid.android.application") + id("samplecomposeanroid.android.application.compose") + id("samplecomposeanroid.android.room") + id("samplecomposeanroid.android.hilt") + id("samplecomposeanroid.kotlinter") } android { - namespace = "com.loodos.samplecomposeandroid" - compileSdk = 33 - + buildFeatures { + buildConfig = true + } defaultConfig { applicationId = "com.loodos.samplecomposeandroid" - minSdk = 21 - targetSdk = 33 versionCode = 1 versionName = "1.0" - flavorDimensions("version") + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true @@ -36,13 +30,14 @@ android { getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) + } getByName("debug") { - isMinifyEnabled = false isDebuggable = true + isMinifyEnabled = false isShrinkResources = false - versionNameSuffix = ".${getDateTime()}" + enableUnitTestCoverage = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" @@ -50,112 +45,61 @@ android { } } - productFlavors { - create("dev") { - dimension = "version" - applicationIdSuffix = ".dev" - versionNameSuffix = "-dev" - resValue("string", "app_name", "Sample Compose Android Dev") - buildConfigField("String", "BASE_URL", "\"https://fakestoreapi.com/\"") - - } - create("prod") { - dimension = "version" - applicationIdSuffix = ".prod" - versionNameSuffix = "-prod" - resValue("string", "app_name", "Sample Compose Android") - buildConfigField("String", "BASE_URL", "\"https://fakestoreapi.com/\"") - - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 - } - kotlinOptions { - jvmTarget = "17" - } - buildFeatures { - buildConfig = true - compose = true - } - composeOptions { - kotlinCompilerExtensionVersion = "1.4.7" - } packagingOptions { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } - lint { - baseline = file("lint-baseline.xml") - } -} + namespace = "com.loodos.samplecomposeandroid" +} dependencies { - val composeBom = platform(libs.androidx.compose.bom) - implementation(composeBom) - androidTestImplementation(composeBom) - + implementation(libs.accompanist.systemuicontroller) implementation(libs.androidx.activity.compose) - implementation(libs.androidx.compose.ui) - - implementation(libs.androidx.compose.material3) + implementation(libs.androidx.appcompat) + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.android.material) + implementation(libs.compose.ui) + implementation(libs.compose.material) implementation(libs.androidx.compose.material.iconsExtended) + implementation(libs.compose.ui.tooling) + implementation(libs.square.moshi.kotlin) + implementation(libs.square.retrofit) + implementation(libs.square.retrofit.converter.moshi) + implementation(libs.androidx.core.splashscreen) + implementation(libs.okhttp.logging.interceptor) - implementation(libs.androidx.compose.ui.tooling.preview) - debugImplementation(libs.androidx.compose.ui.tooling) - debugImplementation(libs.androidx.compose.ui.testManifest) - - implementation(libs.androidx.ktx) - implementation(libs.androidx.lifecycle.runtime.ktx) - implementation(libs.androidx.lifecycle.runtimeCompose) + implementation(projects.core.common) + implementation(projects.core.designsystem) + implementation(projects.core.data) + implementation(projects.core.domain) - //Splash - implementation(libs.androidx.core.splashscreen) + testImplementation(libs.junit4) - //Hilt - implementation(libs.hilt.android) - kapt(libs.hilt.compiler) + androidTestImplementation(libs.androidx.test.junit) + androidTestImplementation(libs.androidx.test.espresso.core) + androidTestImplementation(libs.compose.ui.test.junit) + androidTestImplementation(libs.hilt.android.testing) implementation(libs.androidx.hilt.navigation.compose) - // lint - lintChecks(libs.lint.checks) - // compose state events - implementation(libs.compose.state.events) - // Retrofit - implementation(libs.retrofit) + debugImplementation(libs.compose.ui.test.manifest) + debugImplementation(libs.compose.ui.tooling) + debugImplementation(libs.square.leakcanary) implementation(libs.retrofit.converter.gson) - implementation(libs.okhttp) - implementation(libs.okhttp.logging.interceptor) - // chucker + kapt(libs.square.moshi.kotlin.codegen) + debugImplementation(libs.chucker) releaseImplementation(libs.chucker.no.op) + implementation(libs.androidx.compose.runtime) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.lifecycle.runtimeCompose) + implementation(libs.compose.state.events) + implementation(libs.androidx.fragment.ktx) + implementation(libs.androidx.navigation.compose) - testImplementation(libs.turbine) - testImplementation(libs.truth) - - // To use the androidx.test.core APIs - androidTestImplementation(libs.androidx.test.core) - // Kotlin extensions for androidx.test.core - androidTestImplementation(libs.androidx.test.ktx) - - // To use the JUnit Extension APIs - testImplementation(libs.androidx.test.ext) - // Kotlin extensions for androidx.test.ext.junit - testImplementation(libs.androidx.test.ext.ktx) - - // To use the Truth Extension APIs - testImplementation(libs.truth.ext) - testImplementation(libs.jetbrains.kotlin.test) - implementation(libs.androidx.navigation.testing) - testImplementation(libs.junit4) - androidTestImplementation(libs.androidx.test.ext) - androidTestImplementation(libs.androidx.test.espresso.core) - androidTestImplementation(libs.androidx.compose.ui.test) } \ No newline at end of file diff --git a/app/src/androidTest/java/com/loodos/samplecomposeandroid/util/TestNetworkMonitor.kt b/app/src/androidTest/java/com/loodos/samplecomposeandroid/util/TestNetworkMonitor.kt index 7956fd4..0e90480 100644 --- a/app/src/androidTest/java/com/loodos/samplecomposeandroid/util/TestNetworkMonitor.kt +++ b/app/src/androidTest/java/com/loodos/samplecomposeandroid/util/TestNetworkMonitor.kt @@ -1,6 +1,6 @@ package com.loodos.samplecomposeandroid.util -import com.loodos.samplecomposeandroid.core.util.NetworkMonitor +import com.loodos.data.util.NetworkMonitor import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.MutableStateFlow * Created by mertcantoptas on 21.03.2023 */ -class TestNetworkMonitor : NetworkMonitor { +class TestNetworkMonitor : com.loodos.data.util.NetworkMonitor { private val connectivityFlow = MutableStateFlow(true) diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainApp.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainApp.kt index b1bd881..7de81db 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainApp.kt +++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainApp.kt @@ -25,14 +25,12 @@ import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavDestination import androidx.navigation.NavDestination.Companion.hierarchy +import com.loodos.data.util.NetworkMonitor +import com.loodos.designsystems.component.MainAppScaffold +import com.loodos.designsystems.icon.Icon import com.loodos.samplecomposeandroid.R -import com.loodos.samplecomposeandroid.core.designsystem.icon.Icon -import com.loodos.samplecomposeandroid.core.designsystem.slideIn -import com.loodos.samplecomposeandroid.core.designsystem.slideOut -import com.loodos.samplecomposeandroid.core.util.NetworkMonitor -import com.loodos.samplecomposeandroid.feature.navigation.MainNavHost -import com.loodos.samplecomposeandroid.feature.navigation.TopLevelDestination -import com.loodos.samplecomposeandroid.ui.components.MainAppScaffold +import com.loodos.samplecomposeandroid.navigation.MainNavHost +import com.loodos.samplecomposeandroid.navigation.TopLevelDestination /** * Created by mertcantoptas on 10.03.2023 @@ -68,8 +66,8 @@ fun MainApp( bottomBar = { AnimatedVisibility( visible = appState.shouldShowBottomBar, - enter = slideIn, - exit = slideOut, + enter = com.loodos.designsystems.animation.slideIn, + exit = com.loodos.designsystems.animation.slideOut, ) { AppNavBar( destinations = AppDestinations(appState.topLevelDestinations), diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainAppState.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainAppState.kt index 272ae68..a5c6699 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainAppState.kt +++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainAppState.kt @@ -10,12 +10,12 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions -import com.loodos.samplecomposeandroid.core.util.NetworkMonitor +import com.loodos.data.util.NetworkMonitor import com.loodos.samplecomposeandroid.feature.category.navigateToCategory import com.loodos.samplecomposeandroid.feature.home.navigation.HomeNavigationRoute import com.loodos.samplecomposeandroid.feature.home.navigation.navigateToHome -import com.loodos.samplecomposeandroid.feature.navigation.TopLevelDestination import com.loodos.samplecomposeandroid.feature.profile.navigateToProfile +import com.loodos.samplecomposeandroid.navigation.TopLevelDestination import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.map @@ -27,7 +27,7 @@ import kotlinx.coroutines.flow.stateIn @Composable fun rememberMainAppState( - networkMonitor: NetworkMonitor, + networkMonitor: com.loodos.data.util.NetworkMonitor, coroutineScope: CoroutineScope = rememberCoroutineScope(), navController: NavHostController = rememberNavController(), ): MainAppState { @@ -40,7 +40,7 @@ fun rememberMainAppState( class MainAppState( val navController: NavHostController, val coroutineScope: CoroutineScope, - networkMonitor: NetworkMonitor, + networkMonitor: com.loodos.data.util.NetworkMonitor, ) { val currentDestination: NavDestination? @Composable get() = navController diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/home/HomeScreen.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/home/HomeScreen.kt index 9d7dc5e..d12fb15 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/home/HomeScreen.kt +++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/home/HomeScreen.kt @@ -32,7 +32,6 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.loodos.samplecomposeandroid.R -import com.loodos.samplecomposeandroid.ui.components.MainAppScaffold import de.palm.composestateevents.EventEffect /** @@ -65,7 +64,7 @@ fun HomeScreen( onProductClick: (ProductItem) -> Unit, modifier: Modifier = Modifier, ) { - MainAppScaffold( + com.loodos.designsystems.component.MainAppScaffold( modifier = modifier.fillMaxSize(), topBar = { CenterAlignedTopAppBar( diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginScreen.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginScreen.kt index 8843d97..3f3489c 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginScreen.kt +++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginScreen.kt @@ -35,9 +35,6 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.loodos.samplecomposeandroid.R -import com.loodos.samplecomposeandroid.ui.components.CustomTextField -import com.loodos.samplecomposeandroid.ui.components.MainAppScaffold -import com.loodos.samplecomposeandroid.ui.theme.SampleComposeAndroidTheme import de.palm.composestateevents.EventEffect /** @@ -75,7 +72,7 @@ fun LoginScreen( modifier: Modifier = Modifier, onLoginClicked: () -> Unit, ) { - MainAppScaffold( + com.loodos.designsystems.component.MainAppScaffold( modifier = modifier.fillMaxSize(), ) { Content( @@ -140,7 +137,7 @@ private fun UserNameTextField( onValueChange: (String) -> Unit, modifier: Modifier = Modifier, ) { - CustomTextField( + com.loodos.designsystems.component.CustomTextField( modifier = modifier .fillMaxWidth() .padding(horizontal = 16.dp), @@ -183,7 +180,7 @@ private fun PasswordTextField( modifier: Modifier = Modifier, ) { var isPasswordVisible by remember { mutableStateOf(false) } - CustomTextField( + com.loodos.designsystems.component.CustomTextField( modifier = modifier .fillMaxWidth() .padding(horizontal = 16.dp), @@ -229,7 +226,7 @@ private fun PasswordTextField( @Preview(showBackground = true) @Composable fun LoginScreenPreview() { - SampleComposeAndroidTheme() { + com.loodos.designsystems.theme.SampleComposeAndroidTheme() { Content( LoginViewState(), onUserNameValueChange = {}, diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginViewModel.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginViewModel.kt index 869372a..0e5d4a8 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginViewModel.kt +++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginViewModel.kt @@ -1,17 +1,17 @@ package com.loodos.samplecomposeandroid.feature.login import androidx.lifecycle.viewModelScope +import com.loodos.common.result.Resource +import com.loodos.common.result.asResource +import com.loodos.domain.login.LoginUseCase +import com.loodos.domain.login.ValidateAuthUseCase import com.loodos.samplecomposeandroid.R import com.loodos.samplecomposeandroid.arch.BaseViewModel import com.loodos.samplecomposeandroid.arch.IViewState -import com.loodos.samplecomposeandroid.core.common.Resource -import com.loodos.samplecomposeandroid.core.common.asResource import com.loodos.samplecomposeandroid.core.domain.PasswordLengthException import com.loodos.samplecomposeandroid.core.domain.PasswordRequiredException import com.loodos.samplecomposeandroid.core.domain.UsernameLengthException import com.loodos.samplecomposeandroid.core.domain.UsernameRequiredException -import com.loodos.samplecomposeandroid.core.domain.login.LoginUseCase -import com.loodos.samplecomposeandroid.core.domain.login.ValidateAuthUseCase import dagger.hilt.android.lifecycle.HiltViewModel import de.palm.composestateevents.StateEvent import de.palm.composestateevents.StateEventWithContent diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/main/MainActivity.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/main/MainActivity.kt index 96bd901..e8f6c9d 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/main/MainActivity.kt +++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/main/MainActivity.kt @@ -17,9 +17,8 @@ import androidx.core.view.WindowCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import com.loodos.samplecomposeandroid.core.util.NetworkMonitor +import com.loodos.data.util.NetworkMonitor import com.loodos.samplecomposeandroid.feature.appstate.MainApp -import com.loodos.samplecomposeandroid.ui.theme.SampleComposeAndroidTheme import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.onEach @@ -30,7 +29,7 @@ import javax.inject.Inject class MainActivity : ComponentActivity() { @Inject - lateinit var networkMonitor: NetworkMonitor + lateinit var networkMonitor: com.loodos.data.util.NetworkMonitor companion object { const val splashFadeDurationMillis = 1000L @@ -84,7 +83,7 @@ class MainActivity : ComponentActivity() { private fun setContent() { setContent { - SampleComposeAndroidTheme { + com.loodos.designsystems.theme.SampleComposeAndroidTheme { MainApp(networkMonitor = networkMonitor) } } @@ -101,7 +100,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) { @Preview(showBackground = true) @Composable fun DefaultPreview() { - SampleComposeAndroidTheme { + com.loodos.designsystems.theme.SampleComposeAndroidTheme { Greeting("Android") } } diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/MainNavHost.kt b/app/src/main/java/com/loodos/samplecomposeandroid/navigation/MainNavHost.kt similarity index 96% rename from app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/MainNavHost.kt rename to app/src/main/java/com/loodos/samplecomposeandroid/navigation/MainNavHost.kt index 1eaef9c..0b8755d 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/MainNavHost.kt +++ b/app/src/main/java/com/loodos/samplecomposeandroid/navigation/MainNavHost.kt @@ -1,4 +1,4 @@ -package com.loodos.samplecomposeandroid.feature.navigation +package com.loodos.samplecomposeandroid.navigation import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/TopLevelDestination.kt b/app/src/main/java/com/loodos/samplecomposeandroid/navigation/TopLevelDestination.kt similarity index 52% rename from app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/TopLevelDestination.kt rename to app/src/main/java/com/loodos/samplecomposeandroid/navigation/TopLevelDestination.kt index f3dc3c3..e4fd885 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/TopLevelDestination.kt +++ b/app/src/main/java/com/loodos/samplecomposeandroid/navigation/TopLevelDestination.kt @@ -1,9 +1,8 @@ -package com.loodos.samplecomposeandroid.feature.navigation +package com.loodos.samplecomposeandroid.navigation +import com.loodos.designsystems.icon.AppIcons +import com.loodos.designsystems.icon.Icon import com.loodos.samplecomposeandroid.R -import com.loodos.samplecomposeandroid.core.designsystem.icon.AppIcons -import com.loodos.samplecomposeandroid.core.designsystem.icon.Icon -import com.loodos.samplecomposeandroid.core.designsystem.icon.Icon.ImageVectorIcon import com.loodos.samplecomposeandroid.feature.category.CategoryRoute import com.loodos.samplecomposeandroid.feature.home.navigation.HomeNavigationRoute import com.loodos.samplecomposeandroid.feature.profile.ProfileRoute @@ -16,20 +15,20 @@ enum class TopLevelDestination( ) { HOME( route = HomeNavigationRoute, - selectedIcon = ImageVectorIcon(AppIcons.Home), - unselectedIcon = ImageVectorIcon(AppIcons.HomeOutlined), + selectedIcon = Icon.ImageVectorIcon(AppIcons.Home), + unselectedIcon = Icon.ImageVectorIcon(AppIcons.HomeOutlined), titleTextId = R.string.nav_home_title, ), CATEGORY( route = CategoryRoute, - selectedIcon = ImageVectorIcon(AppIcons.Category), - unselectedIcon = ImageVectorIcon(AppIcons.CategoryOutlined), + selectedIcon = Icon.ImageVectorIcon(AppIcons.Category), + unselectedIcon = Icon.ImageVectorIcon(AppIcons.CategoryOutlined), titleTextId = R.string.nav_category_title, ), PROFILE( route = ProfileRoute, - selectedIcon = ImageVectorIcon(AppIcons.Person), - unselectedIcon = ImageVectorIcon(AppIcons.PersonOutlined), + selectedIcon = Icon.ImageVectorIcon(AppIcons.Person), + unselectedIcon = Icon.ImageVectorIcon(AppIcons.PersonOutlined), titleTextId = R.string.nav_profile_title, ), } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 30c2b27..0bdf79b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,6 +3,7 @@ Username Password Login + Sample Compose Username cannot be blank! diff --git a/build-logic/README.md b/build-logic/README.md new file mode 100644 index 0000000..0458b4f --- /dev/null +++ b/build-logic/README.md @@ -0,0 +1,38 @@ +# Convention Plugins + +The `build-logic` folder defines project-specific convention plugins, used to keep a single +source of truth for common module configurations. + +This approach is heavily based on +[https://developer.squareup.com/blog/herding-elephants/](https://developer.squareup.com/blog/herding-elephants/) +and +[https://github.com/jjohannes/idiomatic-gradle](https://github.com/jjohannes/idiomatic-gradle). + +By setting up convention plugins in `build-logic`, we can avoid duplicated build script setup, +messy `subproject` configurations, without the pitfalls of the `buildSrc` directory. + +`build-logic` is an included build, as configured in the root +[`settings.gradle.kts`](../settings.gradle.kts). + +Inside `build-logic` is a `convention` module, which defines a set of plugins that all normal +modules can use to configure themselves. + +`build-logic` also includes a set of `Kotlin` files used to share logic between plugins themselves, +which is most useful for configuring Android components (libraries vs applications) with shared +code. + +These plugins are *additive* and *composable*, and try to only accomplish a single responsibility. +Modules can then pick and choose the configurations they need. +If there is one-off logic for a module without shared code, it's preferable to define that directly +in the module's `build.gradle`, as opposed to creating a convention plugin with module-specific +setup. + +Current list of convention plugins: + +- [`nowinandroid.android.application`](convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt), + [`nowinandroid.android.library`](convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt), + [`nowinandroid.android.test`](convention/src/main/kotlin/AndroidTestConventionPlugin.kt): + Configures common Android and Kotlin options. +- [`nowinandroid.android.application.compose`](convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt), + [`nowinandroid.android.library.compose`](convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt): + Configures Jetpack Compose options diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts new file mode 100644 index 0000000..651a5b9 --- /dev/null +++ b/build-logic/convention/build.gradle.kts @@ -0,0 +1,85 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + `kotlin-dsl` +} + +group = "com.loodos.samplecomposeanroid.buildlogic" + +// Configure the build-logic plugins to target JDK 17 +// This matches the JDK used to build the project, and is not related to what is running on device. +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} +tasks.withType().configureEach { + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17.toString() + } +} + +dependencies { + compileOnly(libs.android.gradlePlugin) + compileOnly(libs.kotlin.gradlePlugin) + compileOnly(libs.firebase.crashlytics.gradlePlugin) + compileOnly(libs.ksp.gradlePlugin) +} + +gradlePlugin { + plugins { + register("androidApplicationCompose") { + id = "samplecomposeanroid.android.application.compose" + implementationClass = "AndroidApplicationComposeConventionPlugin" + } + register("androidApplication") { + id = "samplecomposeanroid.android.application" + implementationClass = "AndroidApplicationConventionPlugin" + } + register("androidApplicationJacoco") { + id = "samplecomposeanroid.android.application.jacoco" + implementationClass = "AndroidApplicationJacocoConventionPlugin" + } + register("androidLibraryCompose") { + id = "samplecomposeanroid.android.library.compose" + implementationClass = "AndroidLibraryComposeConventionPlugin" + } + register("androidLibrary") { + id = "samplecomposeanroid.android.library" + implementationClass = "AndroidLibraryConventionPlugin" + } + register("androidFeature") { + id = "samplecomposeanroid.android.feature" + implementationClass = "AndroidFeatureConventionPlugin" + } + register("androidLibraryJacoco") { + id = "samplecomposeanroid.android.library.jacoco" + implementationClass = "AndroidLibraryJacocoConventionPlugin" + } + + register("androidTest") { + id = "samplecomposeanroid.android.test" + implementationClass = "AndroidTestConventionPlugin" + } + register("androidHilt") { + id = "samplecomposeanroid.android.hilt" + implementationClass = "AndroidHiltConventionPlugin" + } + register("androidRoom") { + id = "samplecomposeanroid.android.room" + implementationClass = "AndroidRoomConventionPlugin" + } + register("firebase-perf") { + id = "samplecomposeanroid.firebase-perf" + implementationClass = "FirebasePerfConventionPlugin" + } + register("androidFlavors") { + id = "samplecomposeanroid.android.application.flavors" + implementationClass = "AndroidApplicationFlavorsConventionPlugin" + } + + register("kotlinter") { + id = "samplecomposeanroid.kotlinter" + implementationClass = "KotlinLinterPlugin" + } + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt new file mode 100644 index 0000000..8698abf --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt @@ -0,0 +1,16 @@ +import com.android.build.api.dsl.ApplicationExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType +import samplecomposeandroid.configureAndroidCompose + +class AndroidApplicationComposeConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("com.android.application") + val extension = extensions.getByType() + configureAndroidCompose(extension) + } + } + +} diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt new file mode 100644 index 0000000..1a17097 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -0,0 +1,33 @@ +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.variant.ApplicationAndroidComponentsExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.getByType +import samplecomposeandroid.configureFlavors +import samplecomposeandroid.configureKotlinAndroid +import samplecomposeandroid.configurePrintApksTask + +class AndroidApplicationConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.application") + apply("org.jetbrains.kotlin.android") + } + + val libs = extensions.getByType().named("libs") + + extensions.configure { + configureKotlinAndroid(this) + defaultConfig.targetSdk = libs.findVersion("compileSdk").get().toString().toInt() + configureFlavors(this) + } + extensions.configure { + configurePrintApksTask(this) + } + } + } + +} diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationFlavorsConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationFlavorsConventionPlugin.kt new file mode 100644 index 0000000..57ea342 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationFlavorsConventionPlugin.kt @@ -0,0 +1,15 @@ +import com.android.build.api.dsl.ApplicationExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import samplecomposeandroid.configureFlavors + +class AndroidApplicationFlavorsConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + extensions.configure { + configureFlavors(this) + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt new file mode 100644 index 0000000..1384a96 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.android.build.api.variant.ApplicationAndroidComponentsExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType +import samplecomposeandroid.configureJacoco + +class AndroidApplicationJacocoConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.gradle.jacoco") + apply("com.android.application") + } + val extension = extensions.getByType() + configureJacoco(extension) + } + } + +} diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt new file mode 100644 index 0000000..773a765 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt @@ -0,0 +1,50 @@ +import com.android.build.gradle.LibraryExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.kotlin + +class AndroidFeatureConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply { + apply("samplecomposeanroid.android.library") + apply("samplecomposeanroid.android.hilt") + } + extensions.configure { + defaultConfig { + testInstrumentationRunner = + "samplecomposeanroid.core.testing.NiaTestRunner" + } + } + + val libs = extensions.getByType().named("libs") + + dependencies { + add("implementation", project(":core:model")) + add("implementation", project(":core:ui")) + add("implementation", project(":core:designsystem")) + add("implementation", project(":core:data")) + add("implementation", project(":core:common")) + add("implementation", project(":core:domain")) + + add("testImplementation", kotlin("test")) + add("testImplementation", project(":core:testing")) + add("androidTestImplementation", kotlin("test")) + add("androidTestImplementation", project(":core:testing")) + + add("implementation", libs.findLibrary("coil.kt").get()) + add("implementation", libs.findLibrary("coil.kt.compose").get()) + + add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get()) + add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get()) + add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get()) + + add("implementation", libs.findLibrary("kotlinx.coroutines.android").get()) + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt new file mode 100644 index 0000000..9e374aa --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt @@ -0,0 +1,24 @@ +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 AndroidHiltConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.jetbrains.kotlin.kapt") + apply("dagger.hilt.android.plugin") + } + + val libs = extensions.getByType().named("libs") + dependencies { + "implementation"(libs.findLibrary("hilt.android").get()) + "kapt"(libs.findLibrary("hilt.compiler").get()) + "kaptAndroidTest"(libs.findLibrary("hilt.compiler").get()) + } + + } + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt new file mode 100644 index 0000000..cbcbcb7 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt @@ -0,0 +1,15 @@ +import com.android.build.gradle.LibraryExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType +import samplecomposeandroid.configureAndroidCompose + +class AndroidLibraryComposeConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("com.android.library") + val extension = extensions.getByType() + configureAndroidCompose(extension) + } + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt new file mode 100644 index 0000000..fcf0160 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -0,0 +1,44 @@ +import com.android.build.api.variant.LibraryAndroidComponentsExtension +import com.android.build.gradle.LibraryExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.kotlin +import samplecomposeandroid.configureFlavors +import samplecomposeandroid.configureKotlinAndroid +import samplecomposeandroid.configurePrintApksTask + +class AndroidLibraryConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.library") + apply("org.jetbrains.kotlin.android") + } + + val libs = extensions.getByType().named("libs") + + extensions.configure { + defaultConfig.targetSdk = libs.findVersion("targetSdk").get().toString().toInt() + configureKotlinAndroid(this) + configureFlavors(this) + } + extensions.configure { + configurePrintApksTask(this) + } + configurations.configureEach { + resolutionStrategy { + force(libs.findLibrary("junit4").get()) + force("org.objenesis:objenesis:2.6") + } + } + dependencies { + add("androidTestImplementation", kotlin("test")) + add("testImplementation", kotlin("test")) + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt new file mode 100644 index 0000000..bb35a7d --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt @@ -0,0 +1,19 @@ +import com.android.build.api.variant.LibraryAndroidComponentsExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType +import samplecomposeandroid.configureJacoco + +class AndroidLibraryJacocoConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("org.gradle.jacoco") + apply("com.android.library") + } + val extension = extensions.getByType() + configureJacoco(extension) + } + } + +} diff --git a/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt new file mode 100644 index 0000000..852dd48 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt @@ -0,0 +1,48 @@ +import com.google.devtools.ksp.gradle.KspExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.getByType +import org.gradle.process.CommandLineArgumentProvider +import java.io.File + +class AndroidRoomConventionPlugin : Plugin { + + override fun apply(target: Project) { + with(target) { + pluginManager.apply("com.google.devtools.ksp") + + extensions.configure { + // The schemas directory contains a schema file for each version of the Room database. + // This is required to enable Room auto migrations. + // See https://developer.android.com/reference/kotlin/androidx/room/AutoMigration. +// arg(RoomSchemaArgProvider(File(projectDir, "schemas"))) + } + + val libs = extensions.getByType().named("libs") + dependencies { + add("implementation", libs.findLibrary("androidx.room.runtime").get()) + add("implementation", libs.findLibrary("androidx.room.ktx").get()) + add("implementation", libs.findLibrary("androidx.room.paging").get()) + add("ksp", libs.findLibrary("androidx.room.compiler").get()) + } + } + } + + /** + * https://issuetracker.google.com/issues/132245929 + * [Export schemas](https://developer.android.com/training/data-storage/room/migrating-db-versions#export-schemas) + */ + class RoomSchemaArgProvider( + @get:InputDirectory + @get:PathSensitive(PathSensitivity.RELATIVE) + val schemaDir: File, + ) : CommandLineArgumentProvider { + override fun asArguments() = listOf("room.schemaLocation=${schemaDir.path}") + } +} diff --git a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt new file mode 100644 index 0000000..8e11033 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt @@ -0,0 +1,25 @@ +import com.android.build.gradle.TestExtension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.getByType +import samplecomposeandroid.configureKotlinAndroid + +class AndroidTestConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + with(pluginManager) { + apply("com.android.test") + apply("org.jetbrains.kotlin.android") + } + val libs = extensions.getByType().named("libs") + + extensions.configure { + configureKotlinAndroid(this) + defaultConfig.targetSdk = libs.findVersion("targetSdk").get().toString().toInt() + } + } + } + +} diff --git a/build-logic/convention/src/main/kotlin/FirebasePerfConventionPlugin.kt b/build-logic/convention/src/main/kotlin/FirebasePerfConventionPlugin.kt new file mode 100644 index 0000000..1b855c1 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/FirebasePerfConventionPlugin.kt @@ -0,0 +1,15 @@ +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.getByType + +class FirebasePerfConventionPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + val libs = extensions.getByType().named("libs") + pluginManager.findPlugin("com.google.firebase.firebase-perf").apply { + version = libs.findVersion("firebase-pref").get().toString() + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/KotlinLinterPlugin.kt b/build-logic/convention/src/main/kotlin/KotlinLinterPlugin.kt new file mode 100644 index 0000000..96dd2da --- /dev/null +++ b/build-logic/convention/src/main/kotlin/KotlinLinterPlugin.kt @@ -0,0 +1,11 @@ +import org.gradle.api.Plugin +import org.gradle.api.Project + +class KotlinLinterPlugin : Plugin { + override fun apply(target: Project) { + with(target) { + pluginManager.apply("org.jmailen.kotlinter") + } + } + +} diff --git a/build-logic/convention/src/main/kotlin/samplecomposeandroid/AndroidCompose.kt b/build-logic/convention/src/main/kotlin/samplecomposeandroid/AndroidCompose.kt new file mode 100644 index 0000000..d18fc61 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/samplecomposeandroid/AndroidCompose.kt @@ -0,0 +1,61 @@ +package samplecomposeandroid + +import com.android.build.api.dsl.CommonExtension +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.getByType +import java.io.File + +/** + * Configure Compose-specific options + */ +internal fun Project.configureAndroidCompose( + commonExtension: CommonExtension<*, *, *, *>, +) { + val libs = extensions.getByType().named("libs") + + commonExtension.apply { + buildFeatures { + compose = true + } + + composeOptions { + kotlinCompilerExtensionVersion = libs.findVersion("composeCompiler").get().toString() + } + + kotlinOptions { + freeCompilerArgs = freeCompilerArgs + buildComposeMetricsParameters() + } + + dependencies { + val bom = libs.findLibrary("compose-bom").get() + add("implementation", platform(bom)) + add("androidTestImplementation", platform(bom)) + } + } +} + +private fun Project.buildComposeMetricsParameters(): List { + val metricParameters = mutableListOf() + val enableMetricsProvider = project.providers.gradleProperty("enableComposeCompilerMetrics") + val enableMetrics = (enableMetricsProvider.orNull == "true") + if (enableMetrics) { + val metricsFolder = File(project.buildDir, "compose-metrics") + metricParameters.add("-P") + metricParameters.add( + "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + metricsFolder.absolutePath + ) + } + + val enableReportsProvider = project.providers.gradleProperty("enableComposeCompilerReports") + val enableReports = (enableReportsProvider.orNull == "true") + if (enableReports) { + val reportsFolder = File(project.buildDir, "compose-reports") + metricParameters.add("-P") + metricParameters.add( + "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + reportsFolder.absolutePath + ) + } + return metricParameters.toList() +} diff --git a/build-logic/convention/src/main/kotlin/samplecomposeandroid/Flavor.kt b/build-logic/convention/src/main/kotlin/samplecomposeandroid/Flavor.kt new file mode 100644 index 0000000..b30bbf8 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/samplecomposeandroid/Flavor.kt @@ -0,0 +1,38 @@ +package samplecomposeandroid + +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.dsl.ApplicationProductFlavor +import com.android.build.api.dsl.CommonExtension +import org.gradle.api.Project + +enum class FlavorDimension { + CONTENT_TYPE +} + +// The content for the app can either come from local static data which is useful for demo +// purposes, or from a production backend server which supplies up-to-date, real content. +// These two product flavors reflect this behaviour. +enum class Flavor (val dimension : FlavorDimension, val applicationIdSuffix : String? = null) { + DEMO(FlavorDimension.CONTENT_TYPE), + PROD(FlavorDimension.CONTENT_TYPE, ".prod") +} + +fun Project.configureFlavors( + commonExtension: CommonExtension<*, *, *, *> +) { + commonExtension.apply { + flavorDimensions += FlavorDimension.CONTENT_TYPE.name + productFlavors { + Flavor.values().forEach{ + create(it.name) { + dimension = it.dimension.name + if (this@apply is ApplicationExtension && this is ApplicationProductFlavor) { + if (it.applicationIdSuffix != null) { + this.applicationIdSuffix = it.applicationIdSuffix + } + } + } + } + } + } +} diff --git a/build-logic/convention/src/main/kotlin/samplecomposeandroid/Jacoco.kt b/build-logic/convention/src/main/kotlin/samplecomposeandroid/Jacoco.kt new file mode 100644 index 0000000..d65fd7d --- /dev/null +++ b/build-logic/convention/src/main/kotlin/samplecomposeandroid/Jacoco.kt @@ -0,0 +1,70 @@ +package samplecomposeandroid + +import com.android.build.api.variant.AndroidComponentsExtension +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.api.tasks.testing.Test +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.withType +import org.gradle.testing.jacoco.plugins.JacocoPluginExtension +import org.gradle.testing.jacoco.plugins.JacocoTaskExtension +import org.gradle.testing.jacoco.tasks.JacocoReport + +private val coverageExclusions = listOf( + // Android + "**/R.class", + "**/R\$*.class", + "**/BuildConfig.*", + "**/Manifest*.*" +) + +internal fun Project.configureJacoco( + androidComponentsExtension: AndroidComponentsExtension<*, *, *>, +) { + val libs = extensions.getByType().named("libs") + + configure { + toolVersion = libs.findVersion("jacoco").get().toString() + } + + val jacocoTestReport = tasks.create("jacocoTestReport") + + androidComponentsExtension.onVariants { variant -> + val testTaskName = "test${variant.name.capitalize()}UnitTest" + + val reportTask = tasks.register("jacoco${testTaskName.capitalize()}Report", JacocoReport::class) { + dependsOn(testTaskName) + + reports { + xml.required.set(true) + html.required.set(true) + } + + classDirectories.setFrom( + fileTree("$buildDir/tmp/kotlin-classes/${variant.name}") { + exclude(coverageExclusions) + } + ) + + sourceDirectories.setFrom(files("$projectDir/src/main/java", "$projectDir/src/main/kotlin")) + executionData.setFrom(file("$buildDir/jacoco/$testTaskName.exec")) + } + + jacocoTestReport.dependsOn(reportTask) + } + + tasks.withType().configureEach { + configure { + // Required for JaCoCo + Robolectric + // https://github.com/robolectric/robolectric/issues/2230 + // TODO: Consider removing if not we don't add Robolectric + isIncludeNoLocationClasses = true + + // Required for JDK 11 with the above + // https://github.com/gradle/gradle/issues/5184#issuecomment-391982009 + excludes = listOf("jdk.internal.*") + } + } +} diff --git a/build-logic/convention/src/main/kotlin/samplecomposeandroid/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/samplecomposeandroid/KotlinAndroid.kt new file mode 100644 index 0000000..34da9a7 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/samplecomposeandroid/KotlinAndroid.kt @@ -0,0 +1,62 @@ +package samplecomposeandroid + +import com.android.build.api.dsl.CommonExtension +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.api.plugins.ExtensionAware +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.provideDelegate +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions + +/** + * Configure base Kotlin with Android options + */ +internal fun Project.configureKotlinAndroid( + commonExtension: CommonExtension<*, *, *, *>, +) { + commonExtension.apply { + val libs = extensions.getByType().named("libs") + + compileSdk = libs.findVersion("compileSdk").get().toString().toInt() + + defaultConfig { + minSdk = libs.findVersion("minSdk").get().toString().toInt() + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + isCoreLibraryDesugaringEnabled = true + } + + kotlinOptions { + // Treat all Kotlin warnings as errors (disabled by default) + // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties + val warningsAsErrors: String? by project + allWarningsAsErrors = warningsAsErrors.toBoolean() + + freeCompilerArgs = freeCompilerArgs + listOf( + "-opt-in=kotlin.RequiresOptIn", + // Enable experimental coroutines APIs, including Flow + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", + "-opt-in=kotlinx.coroutines.FlowPreview", + "-opt-in=kotlin.Experimental", + ) + + // Set JVM target to 17 + jvmTarget = JavaVersion.VERSION_17.toString() + } + } + + val libs = extensions.getByType().named("libs") + + dependencies { + add("coreLibraryDesugaring", libs.findLibrary("android.desugarJdkLibs").get()) + } +} + +fun CommonExtension<*, *, *, *>.kotlinOptions(block: KotlinJvmOptions.() -> Unit) { + (this as ExtensionAware).extensions.configure("kotlinOptions", block) +} diff --git a/build-logic/convention/src/main/kotlin/samplecomposeandroid/PrintTestApks.kt b/build-logic/convention/src/main/kotlin/samplecomposeandroid/PrintTestApks.kt new file mode 100644 index 0000000..337aa3c --- /dev/null +++ b/build-logic/convention/src/main/kotlin/samplecomposeandroid/PrintTestApks.kt @@ -0,0 +1,82 @@ +package samplecomposeandroid + +import com.android.build.api.artifact.SingleArtifact +import com.android.build.api.variant.AndroidComponentsExtension +import com.android.build.api.variant.BuiltArtifactsLoader +import com.android.build.api.variant.HasAndroidTest +import org.gradle.api.DefaultTask +import org.gradle.api.Project +import org.gradle.api.file.Directory +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.TaskAction +import java.io.File + +internal fun Project.configurePrintApksTask(extension: AndroidComponentsExtension<*, *, *>) { + extension.onVariants { variant -> + if (variant is HasAndroidTest) { + val loader = variant.artifacts.getBuiltArtifactsLoader() + val artifact = variant.androidTest?.artifacts?.get(SingleArtifact.APK) + val javaSources = variant.androidTest?.sources?.java?.all + val kotlinSources = variant.androidTest?.sources?.kotlin?.all + + val testSources = if (javaSources != null && kotlinSources != null) { + javaSources.zip(kotlinSources) { javaDirs, kotlinDirs -> + javaDirs + kotlinDirs + } + } else javaSources ?: kotlinSources + + if (artifact != null && testSources != null) { + tasks.register( + "${variant.name}PrintTestApk", + PrintApkLocationTask::class.java + ) { + apkFolder.set(artifact) + builtArtifactsLoader.set(loader) + variantName.set(variant.name) + sources.set(testSources) + } + } + } + } +} + +internal abstract class PrintApkLocationTask : DefaultTask() { + @get:InputDirectory + abstract val apkFolder: DirectoryProperty + + @get:InputFiles + abstract val sources: ListProperty + + @get:Internal + abstract val builtArtifactsLoader: Property + + @get:Input + abstract val variantName: Property + + @TaskAction + fun taskAction() { + val hasFiles = sources.orNull?.any { directory -> + directory.asFileTree.files.any { + it.isFile && it.parentFile.path.contains("build${File.separator}generated").not() + } + } ?: throw UnsupportedOperationException("Cannot check androidTest sources") + + // Don't print APK location if there are no androidTest source files + if (!hasFiles) { + return + } + + val builtArtifacts = builtArtifactsLoader.get().load(apkFolder.get()) + ?: throw IllegalStateException("Cannot load APKs") + if (builtArtifacts.elements.size != 1) + throw IllegalArgumentException("Expected one APK !") + val apk = File(builtArtifacts.elements.single().outputFile).toPath() + println(apk) + } +} diff --git a/build-logic/gradle.properties b/build-logic/gradle.properties new file mode 100644 index 0000000..1c9073e --- /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/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 0000000..de9224e --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,30 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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 c56e0f6..6035384 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,14 +1,19 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. -// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed -@Suppress("DSL_SCOPE_VIOLATION") plugins { alias(libs.plugins.detekt) + alias(libs.plugins.gradle.versions) alias(libs.plugins.kotlinter) 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.kotlin.jvm) apply false - alias(libs.plugins.dagger.hilt) apply false + alias(libs.plugins.com.android.application) apply false + alias(libs.plugins.kotlin.serialization) apply false + alias(libs.plugins.org.jetbrains.kotlin.android) apply false + alias(libs.plugins.dagger.hilt.android) apply false + alias(libs.plugins.com.android.test) apply false + alias(libs.plugins.google.services) apply false + alias(libs.plugins.firebase.crashlytics) apply false + alias(libs.plugins.ksp) apply false + alias(libs.plugins.com.android.library) apply false + alias(libs.plugins.secrets) apply false + } apply(from = "buildscripts/githooks.gradle") diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts deleted file mode 100644 index d4aad3d..0000000 --- a/buildSrc/build.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -plugins { - `kotlin-dsl` -} - -repositories { - google() - mavenCentral() - gradlePluginPortal() -} - -java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 -} \ No newline at end of file diff --git a/buildSrc/src/main/java/com/loodos/buildsrc/GradleUtils.kt b/buildSrc/src/main/java/com/loodos/buildsrc/GradleUtils.kt deleted file mode 100644 index 53e2c9d..0000000 --- a/buildSrc/src/main/java/com/loodos/buildsrc/GradleUtils.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.loodos.buildsrc - -import java.util.* - -fun getDateTime(): Long { - val date = Date() - return date.time -} diff --git a/buildSrc/.gitignore b/core/common/.gitignore similarity index 100% rename from buildSrc/.gitignore rename to core/common/.gitignore diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts new file mode 100644 index 0000000..01e6472 --- /dev/null +++ b/core/common/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("samplecomposeanroid.android.library") + id("samplecomposeanroid.android.hilt") +} + +android { + namespace = "com.loodos.samplecomposeanroid.core.common" +} + +dependencies { + implementation(libs.kotlinx.coroutines.android) +} \ No newline at end of file diff --git a/core/common/consumer-rules.pro b/core/common/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/core/common/proguard-rules.pro b/core/common/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/core/common/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/common/src/androidTest/java/com/loodos/common/ExampleInstrumentedTest.kt b/core/common/src/androidTest/java/com/loodos/common/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..b1f710f --- /dev/null +++ b/core/common/src/androidTest/java/com/loodos/common/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.loodos.common + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.merttoptas.common.test", appContext.packageName) + } +} diff --git a/core/common/src/main/AndroidManifest.xml b/core/common/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a5918e6 --- /dev/null +++ b/core/common/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/core/common/src/main/java/com/loodos/common/network/AppDispatchers.kt b/core/common/src/main/java/com/loodos/common/network/AppDispatchers.kt new file mode 100644 index 0000000..b6a67aa --- /dev/null +++ b/core/common/src/main/java/com/loodos/common/network/AppDispatchers.kt @@ -0,0 +1,13 @@ +package com.loodos.common.network + +import javax.inject.Qualifier + + +@Qualifier +@Retention(AnnotationRetention.RUNTIME) +annotation class Dispatcher(val appDispatcher: AppDispatchers) + +enum class AppDispatchers { + Default, + IO, +} diff --git a/core/common/src/main/java/com/loodos/common/network/di/CoroutineScopesModule.kt b/core/common/src/main/java/com/loodos/common/network/di/CoroutineScopesModule.kt new file mode 100644 index 0000000..4480d9d --- /dev/null +++ b/core/common/src/main/java/com/loodos/common/network/di/CoroutineScopesModule.kt @@ -0,0 +1,28 @@ +package com.loodos.common.network.di + +import com.loodos.common.network.AppDispatchers +import com.loodos.common.network.Dispatcher +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import javax.inject.Qualifier +import javax.inject.Singleton + +@Retention(AnnotationRetention.RUNTIME) +@Qualifier +annotation class ApplicationScope + +@Module +@InstallIn(SingletonComponent::class) +object CoroutineScopesModule { + @Provides + @Singleton + @ApplicationScope + fun providesCoroutineScope( + @Dispatcher(AppDispatchers.Default) dispatcher: CoroutineDispatcher, + ): CoroutineScope = CoroutineScope(SupervisorJob() + dispatcher) +} diff --git a/core/common/src/main/java/com/loodos/common/network/di/DispatchersModule.kt b/core/common/src/main/java/com/loodos/common/network/di/DispatchersModule.kt new file mode 100644 index 0000000..fc8832a --- /dev/null +++ b/core/common/src/main/java/com/loodos/common/network/di/DispatchersModule.kt @@ -0,0 +1,22 @@ +package com.loodos.common.network.di + +import com.loodos.common.network.AppDispatchers +import com.loodos.common.network.Dispatcher +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +@Module +@InstallIn(SingletonComponent::class) +object DispatchersModule { + @Provides + @Dispatcher(AppDispatchers.IO) + fun providesIODispatcher(): CoroutineDispatcher = Dispatchers.IO + + @Provides + @Dispatcher(AppDispatchers.Default) + fun providesDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default +} diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/common/Resource.kt b/core/common/src/main/java/com/loodos/common/result/Resource.kt similarity index 91% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/common/Resource.kt rename to core/common/src/main/java/com/loodos/common/result/Resource.kt index ec3f8d4..f1c1868 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/common/Resource.kt +++ b/core/common/src/main/java/com/loodos/common/result/Resource.kt @@ -1,4 +1,4 @@ -package com.loodos.samplecomposeandroid.core.common +package com.loodos.common.result import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch diff --git a/core/common/src/test/java/com/loodos/common/ExampleUnitTest.kt b/core/common/src/test/java/com/loodos/common/ExampleUnitTest.kt new file mode 100644 index 0000000..bc9350b --- /dev/null +++ b/core/common/src/test/java/com/loodos/common/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.loodos.common + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/core/data/.gitignore b/core/data/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/core/data/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/core/data/build.gradle.kts b/core/data/build.gradle.kts new file mode 100644 index 0000000..20194dc --- /dev/null +++ b/core/data/build.gradle.kts @@ -0,0 +1,36 @@ +plugins { + id("samplecomposeanroid.android.library") + id("samplecomposeanroid.android.hilt") + id("kotlinx-serialization") + id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") + +} + +android { + namespace = "com.loodos.samplecomposeanroid.core.data" + testOptions { + unitTests { + isIncludeAndroidResources = true + isReturnDefaultValues = true + } + } +} + +secrets { + defaultPropertiesFileName = "secrets.defaults.properties" +} + +dependencies { + implementation(libs.androidx.core.ktx) + implementation(libs.kotlinx.coroutines.android) + implementation(libs.kotlinx.serialization.json) + implementation(libs.kotlinx.datetime) + implementation(libs.retrofit.converter.gson) + implementation(libs.square.retrofit) + implementation(libs.square.retrofit.converter.moshi) + implementation(libs.okhttp.logging.interceptor) + + debugImplementation(libs.chucker) + releaseImplementation(libs.chucker.no.op) + implementation(projects.core.common) +} diff --git a/core/data/consumer-rules.pro b/core/data/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/core/data/proguard-rules.pro b/core/data/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/core/data/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/data/src/androidTest/java/com/loodos/data/ExampleInstrumentedTest.kt b/core/data/src/androidTest/java/com/loodos/data/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..ade89b0 --- /dev/null +++ b/core/data/src/androidTest/java/com/loodos/data/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.loodos.data + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.merttoptas.data.test", appContext.packageName) + } +} diff --git a/core/data/src/main/AndroidManifest.xml b/core/data/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a5918e6 --- /dev/null +++ b/core/data/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/DataModule.kt b/core/data/src/main/java/com/loodos/data/di/DataModule.kt similarity index 64% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/DataModule.kt rename to core/data/src/main/java/com/loodos/data/di/DataModule.kt index 9b146e1..1b91197 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/DataModule.kt +++ b/core/data/src/main/java/com/loodos/data/di/DataModule.kt @@ -1,7 +1,7 @@ -package com.loodos.samplecomposeandroid.core.data.di +package com.loodos.data.di -import com.loodos.samplecomposeandroid.core.util.ConnectivityManagerNetworkMonitor -import com.loodos.samplecomposeandroid.core.util.NetworkMonitor +import com.loodos.data.util.ConnectivityManagerNetworkMonitor +import com.loodos.data.util.NetworkMonitor import dagger.Binds import dagger.Module import dagger.hilt.InstallIn diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/LoginModule.kt b/core/data/src/main/java/com/loodos/data/di/LoginModule.kt similarity index 53% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/LoginModule.kt rename to core/data/src/main/java/com/loodos/data/di/LoginModule.kt index 3f5aa78..b79266e 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/LoginModule.kt +++ b/core/data/src/main/java/com/loodos/data/di/LoginModule.kt @@ -1,9 +1,9 @@ -package com.loodos.samplecomposeandroid.core.data.di +package com.loodos.data.di -import com.loodos.samplecomposeandroid.core.data.remote.source.AuthenticationRemoteDataSource -import com.loodos.samplecomposeandroid.core.data.remote.source.AuthenticationRemoteDataSourceImpl -import com.loodos.samplecomposeandroid.core.data.repository.AuthenticationRepository -import com.loodos.samplecomposeandroid.core.data.repository.AuthenticationRepositoryImpl +import com.loodos.data.remote.source.AuthenticationRemoteDataSource +import com.loodos.data.remote.source.AuthenticationRemoteDataSourceImpl +import com.loodos.data.repository.AuthenticationRepository +import com.loodos.data.repository.AuthenticationRepositoryImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/RemoteDataModule.kt b/core/data/src/main/java/com/loodos/data/di/RemoteDataModule.kt similarity index 91% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/RemoteDataModule.kt rename to core/data/src/main/java/com/loodos/data/di/RemoteDataModule.kt index 581b220..6feadd6 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/RemoteDataModule.kt +++ b/core/data/src/main/java/com/loodos/data/di/RemoteDataModule.kt @@ -1,11 +1,11 @@ -package com.loodos.samplecomposeandroid.core.data.di +package com.loodos.data.di import android.content.Context import com.chuckerteam.chucker.api.ChuckerCollector import com.chuckerteam.chucker.api.ChuckerInterceptor import com.chuckerteam.chucker.api.RetentionManager -import com.loodos.samplecomposeandroid.BuildConfig -import com.loodos.samplecomposeandroid.core.data.remote.api.AuthenticationService +import com.loodos.data.remote.api.AuthenticationService +import com.loodos.samplecomposeanroid.core.data.BuildConfig import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -33,7 +33,7 @@ object RemoteDataModule { okHttpClient: OkHttpClient, gsonConverterFactory: GsonConverterFactory, ): Retrofit { - return Retrofit.Builder().baseUrl(BuildConfig.BASE_URL) + return Retrofit.Builder().baseUrl(BuildConfig.BACKEND_URL) .addConverterFactory(gsonConverterFactory) .client(okHttpClient).build() } diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginBody.kt b/core/data/src/main/java/com/loodos/data/model/login/LoginBody.kt similarity index 79% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginBody.kt rename to core/data/src/main/java/com/loodos/data/model/login/LoginBody.kt index f163812..19fbd28 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginBody.kt +++ b/core/data/src/main/java/com/loodos/data/model/login/LoginBody.kt @@ -1,4 +1,4 @@ -package com.loodos.samplecomposeandroid.core.data.model.login +package com.loodos.data.model.login import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginResponse.kt b/core/data/src/main/java/com/loodos/data/model/login/LoginResponse.kt similarity index 62% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginResponse.kt rename to core/data/src/main/java/com/loodos/data/model/login/LoginResponse.kt index 64b7ccd..d8cf539 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginResponse.kt +++ b/core/data/src/main/java/com/loodos/data/model/login/LoginResponse.kt @@ -1,4 +1,4 @@ -package com.loodos.samplecomposeandroid.core.data.model.login +package com.loodos.data.model.login /** * Created by mertcantoptas on 13.04.2023 diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/api/AuthenticationService.kt b/core/data/src/main/java/com/loodos/data/remote/api/AuthenticationService.kt similarity index 54% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/api/AuthenticationService.kt rename to core/data/src/main/java/com/loodos/data/remote/api/AuthenticationService.kt index 3c9df17..cc8f1e9 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/api/AuthenticationService.kt +++ b/core/data/src/main/java/com/loodos/data/remote/api/AuthenticationService.kt @@ -1,7 +1,7 @@ -package com.loodos.samplecomposeandroid.core.data.remote.api +package com.loodos.data.remote.api -import com.loodos.samplecomposeandroid.core.data.model.login.LoginBody -import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse +import com.loodos.data.model.login.LoginBody +import com.loodos.data.model.login.LoginResponse import retrofit2.http.Body import retrofit2.http.POST diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSource.kt b/core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSource.kt similarity index 56% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSource.kt rename to core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSource.kt index 5b11a37..6cff1a7 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSource.kt +++ b/core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSource.kt @@ -1,6 +1,6 @@ -package com.loodos.samplecomposeandroid.core.data.remote.source +package com.loodos.data.remote.source -import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse +import com.loodos.data.model.login.LoginResponse /** * Created by mertcantoptas on 13.04.2023 diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSourceImpl.kt b/core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSourceImpl.kt similarity index 57% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSourceImpl.kt rename to core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSourceImpl.kt index 597efc3..0f0f4c4 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSourceImpl.kt +++ b/core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSourceImpl.kt @@ -1,8 +1,8 @@ -package com.loodos.samplecomposeandroid.core.data.remote.source +package com.loodos.data.remote.source -import com.loodos.samplecomposeandroid.core.data.model.login.LoginBody -import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse -import com.loodos.samplecomposeandroid.core.data.remote.api.AuthenticationService +import com.loodos.data.model.login.LoginBody +import com.loodos.data.model.login.LoginResponse +import com.loodos.data.remote.api.AuthenticationService import javax.inject.Inject class AuthenticationRemoteDataSourceImpl @Inject constructor( diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepository.kt b/core/data/src/main/java/com/loodos/data/repository/AuthenticationRepository.kt similarity index 55% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepository.kt rename to core/data/src/main/java/com/loodos/data/repository/AuthenticationRepository.kt index 993897a..8be8764 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepository.kt +++ b/core/data/src/main/java/com/loodos/data/repository/AuthenticationRepository.kt @@ -1,6 +1,6 @@ -package com.loodos.samplecomposeandroid.core.data.repository +package com.loodos.data.repository -import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse +import com.loodos.data.model.login.LoginResponse /** * Created by mertcantoptas on 13.04.2023 diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepositoryImpl.kt b/core/data/src/main/java/com/loodos/data/repository/AuthenticationRepositoryImpl.kt similarity index 61% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepositoryImpl.kt rename to core/data/src/main/java/com/loodos/data/repository/AuthenticationRepositoryImpl.kt index 896ba33..ebdd68e 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepositoryImpl.kt +++ b/core/data/src/main/java/com/loodos/data/repository/AuthenticationRepositoryImpl.kt @@ -1,7 +1,7 @@ -package com.loodos.samplecomposeandroid.core.data.repository +package com.loodos.data.repository -import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse -import com.loodos.samplecomposeandroid.core.data.remote.source.AuthenticationRemoteDataSource +import com.loodos.data.model.login.LoginResponse +import com.loodos.data.remote.source.AuthenticationRemoteDataSource import javax.inject.Inject class AuthenticationRepositoryImpl @Inject constructor( diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/util/ConnectivityManagerNetworkMonitor.kt b/core/data/src/main/java/com/loodos/data/util/ConnectivityManagerNetworkMonitor.kt similarity index 97% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/util/ConnectivityManagerNetworkMonitor.kt rename to core/data/src/main/java/com/loodos/data/util/ConnectivityManagerNetworkMonitor.kt index 663f1a3..dc33772 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/util/ConnectivityManagerNetworkMonitor.kt +++ b/core/data/src/main/java/com/loodos/data/util/ConnectivityManagerNetworkMonitor.kt @@ -1,4 +1,4 @@ -package com.loodos.samplecomposeandroid.core.util +package com.loodos.data.util import android.content.Context import android.net.ConnectivityManager diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/util/NetworkMonitor.kt b/core/data/src/main/java/com/loodos/data/util/NetworkMonitor.kt similarity index 75% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/util/NetworkMonitor.kt rename to core/data/src/main/java/com/loodos/data/util/NetworkMonitor.kt index fa1d9ec..bdd1800 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/util/NetworkMonitor.kt +++ b/core/data/src/main/java/com/loodos/data/util/NetworkMonitor.kt @@ -1,4 +1,4 @@ -package com.loodos.samplecomposeandroid.core.util +package com.loodos.data.util import kotlinx.coroutines.flow.Flow diff --git a/core/data/src/test/java/com/loodos/data/ExampleUnitTest.kt b/core/data/src/test/java/com/loodos/data/ExampleUnitTest.kt new file mode 100644 index 0000000..d148c91 --- /dev/null +++ b/core/data/src/test/java/com/loodos/data/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.loodos.data + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/core/designsystem/.gitignore b/core/designsystem/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/core/designsystem/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/core/designsystem/build.gradle.kts b/core/designsystem/build.gradle.kts new file mode 100644 index 0000000..f78c4cf --- /dev/null +++ b/core/designsystem/build.gradle.kts @@ -0,0 +1,27 @@ +plugins { + id("samplecomposeanroid.android.library") + id("samplecomposeanroid.android.library.compose") +} + +android { + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + namespace = "com.loodos.samplecomposeanroid.core.designsystem" +} + +dependencies { + api(libs.androidx.compose.foundation) + api(libs.androidx.compose.foundation.layout) + api(libs.androidx.compose.material.iconsExtended) + api(libs.androidx.compose.material3) + api(libs.androidx.compose.runtime) + api(libs.androidx.compose.ui.tooling.preview) + api(libs.androidx.compose.ui.util) + + debugApi(libs.androidx.compose.ui.tooling) + + implementation(libs.androidx.core.ktx) + implementation(libs.coil.kt.compose) + +} diff --git a/core/designsystem/consumer-rules.pro b/core/designsystem/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/core/designsystem/proguard-rules.pro b/core/designsystem/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/core/designsystem/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/designsystem/src/androidTest/java/com/loodos/designsystems/ExampleInstrumentedTest.kt b/core/designsystem/src/androidTest/java/com/loodos/designsystems/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..3d74044 --- /dev/null +++ b/core/designsystem/src/androidTest/java/com/loodos/designsystems/ExampleInstrumentedTest.kt @@ -0,0 +1,25 @@ +package com.loodos.designsystems + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.merttoptas.designsystems.test", appContext.packageName) + } +} + diff --git a/core/designsystem/src/main/AndroidManifest.xml b/core/designsystem/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a5918e6 --- /dev/null +++ b/core/designsystem/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/Animations.kt b/core/designsystem/src/main/java/com/loodos/designsystems/animation/Animations.kt similarity index 90% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/Animations.kt rename to core/designsystem/src/main/java/com/loodos/designsystems/animation/Animations.kt index 3a6ab30..68b03d3 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/Animations.kt +++ b/core/designsystem/src/main/java/com/loodos/designsystems/animation/Animations.kt @@ -1,4 +1,4 @@ -package com.loodos.samplecomposeandroid.core.designsystem +package com.loodos.designsystems.animation import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/ui/components/CustomTextField.kt b/core/designsystem/src/main/java/com/loodos/designsystems/component/CustomTextField.kt similarity index 75% rename from app/src/main/java/com/loodos/samplecomposeandroid/ui/components/CustomTextField.kt rename to core/designsystem/src/main/java/com/loodos/designsystems/component/CustomTextField.kt index 475a6df..326f231 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/ui/components/CustomTextField.kt +++ b/core/designsystem/src/main/java/com/loodos/designsystems/component/CustomTextField.kt @@ -1,27 +1,18 @@ -@file:OptIn(ExperimentalMaterial3Api::class) +package com.loodos.designsystems.component -package com.loodos.samplecomposeandroid.ui.components - -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.size import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Favorite -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.Text import androidx.compose.material3.TextFieldColors -import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.loodos.samplecomposeandroid.R /** * Created by mertcantoptas on 10.05.2023 @@ -33,7 +24,7 @@ fun CustomTextField( label: @Composable (() -> Unit), onValueChange: (String) -> Unit, modifier: Modifier = Modifier, - colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors(), + colors: TextFieldColors = OutlinedTextFieldDefaults.colors(), enabled: Boolean = true, trailingIcon: @Composable (() -> Unit)? = null, placeholder: @Composable (() -> Unit)? = null, @@ -82,13 +73,7 @@ private fun CustomTextFieldFillTextPreview() { label = { Text(text = "Label") }, placeholder = { Text(text = "Placeholder") }, isError = true, - trailingIcon = { - Image( - modifier = Modifier.size(24.dp), - imageVector = ImageVector.vectorResource(id = R.drawable.ic_cancel), - contentDescription = "", - ) - }, + trailingIcon = {}, supportingText = { Text(text = "Supporting Text") }, ) } diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/ui/components/MainAppScaffold.kt b/core/designsystem/src/main/java/com/loodos/designsystems/component/MainAppScaffold.kt similarity index 92% rename from app/src/main/java/com/loodos/samplecomposeandroid/ui/components/MainAppScaffold.kt rename to core/designsystem/src/main/java/com/loodos/designsystems/component/MainAppScaffold.kt index be8879b..19f257e 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/ui/components/MainAppScaffold.kt +++ b/core/designsystem/src/main/java/com/loodos/designsystems/component/MainAppScaffold.kt @@ -1,4 +1,4 @@ -package com.loodos.samplecomposeandroid.ui.components +package com.loodos.designsystems.component import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.imePadding @@ -12,10 +12,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -/** - * Created by mertcantoptas on 10.03.2023 - */ - @OptIn(ExperimentalMaterial3Api::class) @Composable fun MainAppScaffold( diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/icon/AppIcons.kt b/core/designsystem/src/main/java/com/loodos/designsystems/icon/AppIcons.kt similarity index 86% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/icon/AppIcons.kt rename to core/designsystem/src/main/java/com/loodos/designsystems/icon/AppIcons.kt index 55252c8..348e914 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/icon/AppIcons.kt +++ b/core/designsystem/src/main/java/com/loodos/designsystems/icon/AppIcons.kt @@ -1,4 +1,4 @@ -package com.loodos.samplecomposeandroid.core.designsystem.icon +package com.loodos.designsystems.icon import androidx.annotation.DrawableRes import androidx.compose.material.icons.Icons @@ -11,6 +11,9 @@ import androidx.compose.material.icons.outlined.Person import androidx.compose.runtime.Stable import androidx.compose.ui.graphics.vector.ImageVector +/** + * Loodos Sample App in Android icons. Material icons are [ImageVector]s, custom icons are drawable resource IDs. + */ object AppIcons { val Home = Icons.Default.Home val HomeOutlined = Icons.Outlined.Home diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Color.kt b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Color.kt similarity index 67% rename from app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Color.kt rename to core/designsystem/src/main/java/com/loodos/designsystems/theme/Color.kt index 85d4c6a..fabd2be 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Color.kt +++ b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Color.kt @@ -1,7 +1,11 @@ -package com.loodos.samplecomposeandroid.ui.theme +package com.loodos.designsystems.theme import androidx.compose.ui.graphics.Color +/** + * Loodos Sample App in Android colors. All colors must be defined here + */ + val Purple80 = Color(0xFFD0BCFF) val PurpleGrey80 = Color(0xFFCCC2DC) val Pink80 = Color(0xFFEFB8C8) diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Theme.kt b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Theme.kt similarity index 95% rename from app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Theme.kt rename to core/designsystem/src/main/java/com/loodos/designsystems/theme/Theme.kt index b2fa5a2..780541e 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Theme.kt +++ b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Theme.kt @@ -1,4 +1,4 @@ -package com.loodos.samplecomposeandroid.ui.theme +package com.loodos.designsystems.theme import android.app.Activity import android.os.Build @@ -22,6 +22,9 @@ private val DarkColorScheme = darkColorScheme( tertiary = Pink80, ) +/** + * Light default theme color scheme + */ private val LightColorScheme = lightColorScheme( primary = Purple40, secondary = PurpleGrey40, @@ -45,6 +48,7 @@ fun SampleComposeAndroidTheme( dynamicColor: Boolean = true, content: @Composable () -> Unit, ) { + // Color scheme val colorScheme = when { dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { val context = LocalContext.current diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Type.kt b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Type.kt similarity index 95% rename from app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Type.kt rename to core/designsystem/src/main/java/com/loodos/designsystems/theme/Type.kt index 79e8797..7672eaa 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Type.kt +++ b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Type.kt @@ -1,4 +1,4 @@ -package com.loodos.samplecomposeandroid.ui.theme +package com.loodos.designsystems.theme import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle diff --git a/core/designsystem/src/test/java/com/loodos/designsystems/ExampleUnitTest.kt b/core/designsystem/src/test/java/com/loodos/designsystems/ExampleUnitTest.kt new file mode 100644 index 0000000..7d197b4 --- /dev/null +++ b/core/designsystem/src/test/java/com/loodos/designsystems/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.loodos.designsystems + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/core/domain/.gitignore b/core/domain/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/core/domain/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/core/domain/build.gradle.kts b/core/domain/build.gradle.kts new file mode 100644 index 0000000..b18511b --- /dev/null +++ b/core/domain/build.gradle.kts @@ -0,0 +1,25 @@ +@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed +plugins { + id("samplecomposeanroid.android.library") + id("samplecomposeanroid.android.library.compose") + kotlin("kapt") +} + + +android { + namespace = "com.loodos.samplecomposeanroid.core.domain" +} + +dependencies { + implementation(libs.hilt.android) + implementation(libs.kotlinx.coroutines.android) + implementation(libs.kotlinx.datetime) + api(libs.androidx.compose.runtime) + api(libs.androidx.compose.runtime.livedata) + + implementation(projects.core.data) + implementation(projects.core.common) + + kapt(libs.hilt.compiler) + +} \ No newline at end of file diff --git a/core/domain/consumer-rules.pro b/core/domain/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/core/domain/proguard-rules.pro b/core/domain/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/core/domain/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/domain/src/main/AndroidManifest.xml b/core/domain/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a5918e6 --- /dev/null +++ b/core/domain/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/LoginExceptions.kt b/core/domain/src/main/java/com/loodos/domain/LoginExceptions.kt similarity index 100% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/domain/LoginExceptions.kt rename to core/domain/src/main/java/com/loodos/domain/LoginExceptions.kt diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginResult.kt b/core/domain/src/main/java/com/loodos/domain/login/LoginResult.kt similarity index 50% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginResult.kt rename to core/domain/src/main/java/com/loodos/domain/login/LoginResult.kt index 9f1e793..313b70f 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginResult.kt +++ b/core/domain/src/main/java/com/loodos/domain/login/LoginResult.kt @@ -1,6 +1,7 @@ -package com.loodos.samplecomposeandroid.core.domain.login +package com.loodos.domain.login + +import com.loodos.data.model.login.LoginResponse -import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse data class LoginResult( val token: String = "", diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginUseCase.kt b/core/domain/src/main/java/com/loodos/domain/login/LoginUseCase.kt similarity index 79% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginUseCase.kt rename to core/domain/src/main/java/com/loodos/domain/login/LoginUseCase.kt index 2047ae9..4d42f2c 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginUseCase.kt +++ b/core/domain/src/main/java/com/loodos/domain/login/LoginUseCase.kt @@ -1,6 +1,6 @@ -package com.loodos.samplecomposeandroid.core.domain.login +package com.loodos.domain.login -import com.loodos.samplecomposeandroid.core.data.repository.AuthenticationRepository +import com.loodos.data.repository.AuthenticationRepository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import javax.inject.Inject diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/ValidateAuthUseCase.kt b/core/domain/src/main/java/com/loodos/domain/login/ValidateAuthUseCase.kt similarity index 86% rename from app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/ValidateAuthUseCase.kt rename to core/domain/src/main/java/com/loodos/domain/login/ValidateAuthUseCase.kt index 3eb69f2..81b56c0 100644 --- a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/ValidateAuthUseCase.kt +++ b/core/domain/src/main/java/com/loodos/domain/login/ValidateAuthUseCase.kt @@ -1,11 +1,11 @@ -package com.loodos.samplecomposeandroid.core.domain.login +package com.loodos.domain.login -import com.loodos.samplecomposeandroid.core.common.Resource -import com.loodos.samplecomposeandroid.core.common.asResource import com.loodos.samplecomposeandroid.core.domain.PasswordLengthException import com.loodos.samplecomposeandroid.core.domain.PasswordRequiredException import com.loodos.samplecomposeandroid.core.domain.UsernameLengthException import com.loodos.samplecomposeandroid.core.domain.UsernameRequiredException +import com.loodos.common.result.Resource +import com.loodos.common.result.asResource import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import javax.inject.Inject diff --git a/core/domain/src/test/java/com/loodos/domain/ExampleUnitTest.kt b/core/domain/src/test/java/com/loodos/domain/ExampleUnitTest.kt new file mode 100644 index 0000000..d7354fe --- /dev/null +++ b/core/domain/src/test/java/com/loodos/domain/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.loodos.domain + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/core/ui/.gitignore b/core/ui/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/core/ui/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts new file mode 100644 index 0000000..270bf0e --- /dev/null +++ b/core/ui/build.gradle.kts @@ -0,0 +1,31 @@ +plugins { + id("samplecomposeanroid.android.library") + id("samplecomposeanroid.android.library.compose") + +} + +android { + defaultConfig { + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + namespace = "com.loodos.samplecomposeanroid.core.ui" +} + +dependencies { + api(libs.androidx.compose.foundation) + api(libs.androidx.compose.foundation.layout) + api(libs.androidx.compose.material.iconsExtended) + api(libs.androidx.compose.material3) + api(libs.androidx.compose.runtime) + api(libs.androidx.compose.runtime.livedata) + api(libs.androidx.compose.ui.tooling.preview) + api(libs.androidx.compose.ui.util) + api(libs.androidx.metrics) + + debugApi(libs.androidx.compose.ui.tooling) + + implementation(libs.androidx.core.ktx) + implementation(libs.coil.kt) + implementation(libs.coil.kt.compose) + implementation(libs.kotlinx.datetime) +} \ No newline at end of file diff --git a/core/ui/proguard-rules.pro b/core/ui/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/core/ui/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/ui/src/androidTest/java/com/loodos/ui/ExampleInstrumentedTest.kt b/core/ui/src/androidTest/java/com/loodos/ui/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..c24be3a --- /dev/null +++ b/core/ui/src/androidTest/java/com/loodos/ui/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.loodos.ui + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.merttoptas.ui", appContext.packageName) + } +} diff --git a/core/ui/src/main/AndroidManifest.xml b/core/ui/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b93358b --- /dev/null +++ b/core/ui/src/main/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/core/ui/src/main/res/values/colors.xml b/core/ui/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/core/ui/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml new file mode 100644 index 0000000..e5f8fdc --- /dev/null +++ b/core/ui/src/main/res/values/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/core/ui/src/test/java/com/loodos/ui/ExampleUnitTest.kt b/core/ui/src/test/java/com/loodos/ui/ExampleUnitTest.kt new file mode 100644 index 0000000..994dd10 --- /dev/null +++ b/core/ui/src/test/java/com/loodos/ui/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.loodos.ui + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/gradle.properties b/gradle.properties index 3c5031e..c69b90e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,4 +20,16 @@ kotlin.code.style=official # Enables namespacing of each library's R class so that its R class includes only the # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file +android.nonTransitiveRClass=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true +android.defaults.buildfeatures.resvalues=false +android.defaults.buildfeatures.shaders=false +android.features.buildConfig = true +android.suppressUnsupportedCompileSdk=34 +android.defaults.buildfeatures.buildconfig=true + + + + + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 66809fe..89f14a2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,79 +1,136 @@ [versions] -androidxCore = "1.10.1" -androidxTestCore = "1.5.0" -androidxLifecycle = "2.6.1" -androidGradlePlugin = "8.0.0" -androidxActivity = "1.7.1" +accompanist = "0.30.1" +appCompat = "1.6.1" +androidDesugarJdkLibs = "2.0.3" +androidGradlePlugin = "8.0.2" +androidxActivity = "1.8.0" +navigationCompose = "2.7.4" +fragmentKtx = "1.6.1" +okhttp = "4.10.0" +kotlinxSerializationJson = "1.5.1" +kotlinxCoroutines = "1.6.4" +androidxComposeBom = "2023.10.00" androidxCoreSplashscreen = "1.0.1" -androidxTestExt = "1.1.5" -androidxNavigation = "2.5.3" -androidxEspresso = "3.5.1" -androidxComposeBom = "2023.05.01" -chucker = "3.5.2" -hilt = "2.46.1" -hiltPlugin = "2.44.2" +androidxDataStore = "1.0.0" +androidxMetrics = "1.0.0-alpha04" +androidxEspresso = "3.5.0" +androidxHiltNavigationCompose = "1.0.0" +androidxLifecycle = "2.6.2" +androidxTest = "1.1.5" +firebaseBom = "31.2.0" +firebaseCrashlyticsPlugin = "2.9.4" +kotlin = "1.8.21" +gmsPlugin = "4.4.0" +composeStateEvents = "1.2.3" +kotlinxDatetime = "0.4.0" +ksp = "1.8.21-1.0.11" +coil = "2.2.2" +dagger = "2.45" +com-android-test = "8.0.0" +compileSdk = "34" +composeCompiler = "1.4.7" detektGradlePlugin = "1.22.0" -kotlinterGradlePlugin = "3.14.0" +espresso = "3.5.1" +gradleVersionsPlugin = "0.46.0" hiltNavigationCompose = "1.0.0" -composeLintChecks = "1.2.0" -composeStateEvents = "1.2.3" -turbine = "0.12.1" -truth = "1.1.3" -junit4 = "4.13.2" -truthExt = "1.5.0" -kotlinTest = "1.8.21" -kotlin = "1.8.21" +androidxNavigation = "2.7.4" +hilt = "2.47" +junit = "4.13.2" +kotlinter = "3.14.0" +ktxCore = "1.12.0" +leakCanary = "2.10" +lifecycle = "2.6.2" +material = "1.10.0" +minSdk = "21" +targetSdk = "34" +moshi = "1.15.0" retrofit = "2.9.0" -okhttp = "4.10.0" -appcompat = "1.6.1" -material = "1.9.0" +room = "2.5.1" +chucker = "3.5.2" +firebase-pref = "1.4.1" +secrets = "2.0.1" + [libraries] -androidx-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidxCore" } -androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" } -androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" } androidx-core-splashscreen = { group = "androidx.core", name = "core-splashscreen", version.ref = "androidxCoreSplashscreen" } -androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidxLifecycle" } +accompanist-systemuicontroller = { group = "com.google.accompanist", name = "accompanist-systemuicontroller", version.ref = "accompanist" } +android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" } +android-material = { group = "com.google.android.material", name = "material", version.ref = "material" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" } +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "ktxCore" } +androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appCompat" } +androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "fragmentKtx" } +androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" } +androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" } +androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" } +androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" } +androidx-room-paging = { group = "androidx.room", name = "room-paging", version.ref = "room" } +androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" } +androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime" } +androidx-compose-runtime-livedata = { group = "androidx.compose.runtime", name = "runtime-livedata" } +androidx-compose-foundation-layout = { group = "androidx.compose.foundation", name = "foundation-layout" } +androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-compose-material3-windowSizeClass = { group = "androidx.compose.material3", name = "material3-window-size-class" } androidx-lifecycle-runtimeCompose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidxLifecycle" } -androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } -androidx-compose-ui-testManifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } -androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" } +androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" } +androidx-metrics = { group = "androidx.metrics", name = "metrics-performance", version.ref = "androidxMetrics" } +androidx-room-testing = { group = "androidx.room", name = "room-testing", version.ref = "room" } +androidx-test-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso" } +androidx-test-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidxTest" } +compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" } androidx-compose-material-iconsExtended = { group = "androidx.compose.material", name = "material-icons-extended" } -androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } -androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } -androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" } -androidx-navigation-testing = { group = "androidx.navigation", name = "navigation-testing", version.ref = "androidxNavigation" } -androidx-test-ktx = { group = "androidx.test", name = "core-ktx", version.ref = "androidxTestCore" } -androidx-test-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "androidxEspresso" } -androidx-test-ext-ktx = { group = "androidx.test.ext", name = "junit-ktx", version.ref = "androidxTestExt" } -androidx-test-ext = { group = "androidx.test.ext", name = "junit", version.ref = "androidxTestExt" } -androidx-compose-ui-test = { group = "androidx.compose.ui", name = "ui-test-junit4" } -androidx-test-core = { group = "androidx.test", name = "core", version.ref = "androidxTestCore" } +compose-material = { group = "androidx.compose.material3", name = "material3" } +compose-ui = { group = "androidx.compose.ui", name = "ui" } +compose-ui-test-junit = { group = "androidx.compose.ui", name = "ui-test-junit4" } +compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } chucker = { group = "com.github.chuckerteam.chucker", name = "library", version.ref = "chucker" } chucker-no-op = { group = "com.github.chuckerteam.chucker", name = "library-no-op", version.ref = "chucker" } -hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } -hilt-android-testing = { group = "com.google.dagger", name = "hilt-android-testing", version.ref = "hilt" } -hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" } -lint-checks = { group = "com.slack.lint.compose", name = "compose-lint-checks", version.ref = "composeLintChecks" } -retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" } +compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } +androidx-navigation-testing = { group = "androidx.navigation", name = "navigation-testing", version.ref = "androidxNavigation" } +androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" } retrofit-converter-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" } -okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" } +compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-compose-ui-util = { group = "androidx.compose.ui", name = "ui-util" } okhttp-logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" } +compose-ui-util = { group = "androidx.compose.ui", name = "ui-util" } +dependency-versions-plugin = { module = "com.github.ben-manes:gradle-versions-plugin", version.ref = "gradleVersionsPlugin" } +hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" } +hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" } +hilt-android-testing = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt" } +hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" } +junit4 = { module = "junit:junit", version.ref = "junit" } +kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" } +coil-kt = { group = "io.coil-kt", name = "coil", version.ref = "coil" } +coil-kt-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" } +coil-kt-svg = { group = "io.coil-kt", name = "coil-svg", version.ref = "coil" } +square-leakcanary = { module = "com.squareup.leakcanary:leakcanary-android", version.ref = "leakCanary" } +square-moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" } +square-moshi-kotlin-codegen = { module = "com.squareup.moshi:moshi-kotlin-codegen", version.ref = "moshi" } +square-retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" } +square-retrofit-converter-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" } compose-state-events = { group = "com.github.leonard-palm", name = "compose-state-events", version.ref = "composeStateEvents" } -turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine" } -truth = { group = "com.google.truth", name = "truth", version.ref = "truth" } -truth-ext = { group = "androidx.test.ext", name = "truth", version.ref = "truthExt" } -junit4 = { group = "junit", name = "junit", version.ref = "junit4" } -jetbrains-kotlin-test = { group = "org.jetbrains.kotlin", name = "kotlin-test", version.ref = "kotlinTest" } -jetbrains-kotlin-test-junit = { group = "org.jetbrains.kotlin", name = "kotlin-test-junit", version.ref = "kotlinTest" } -appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } -material = { group = "com.google.android.material", name = "material", version.ref = "material" } + +# Dependencies of the included build-logic +android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" } +kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } +firebase-crashlytics-gradlePlugin = { group = "com.google.firebase", name = "firebase-crashlytics-gradle", version.ref = "firebaseCrashlyticsPlugin" } +ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } [plugins] -android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } -android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" } -kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } -kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -dagger-hilt = { id = "com.google.dagger.hilt.android", version.ref = "hiltPlugin" } +com-android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } +com-android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" } +org-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +dagger-hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "dagger" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +google-services = { id = "com.google.gms.google-services", version.ref = "gmsPlugin" } +firebase-crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlyticsPlugin" } +com-android-test = { id = "com.android.test", version.ref = "com-android-test" } +gradle-versions = { id = "com.github.ben-manes.versions", version.ref = "gradleVersionsPlugin" } detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detektGradlePlugin" } -kotlinter = { id = "org.jmailen.kotlinter", version.ref = "kotlinterGradlePlugin" } \ No newline at end of file +kotlinter = { id = "org.jmailen.kotlinter", version.ref = "kotlinter" } +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +secrets = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", version.ref = "secrets" } diff --git a/secrets.defaults.properties b/secrets.defaults.properties new file mode 100644 index 0000000..c9e114b --- /dev/null +++ b/secrets.defaults.properties @@ -0,0 +1,4 @@ +## This file provides default values to modules using the secrets-gradle-plugin. It is necessary +# because the secrets properties file is not under source control so CI builds will fail without +# default values. +BACKEND_URL="https://fakestoreapi.com/" \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 74bf3c2..bf72b70 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,8 +1,10 @@ pluginManagement { + includeBuild("build-logic") repositories { google() mavenCentral() gradlePluginPortal() + maven(url = "https://plugins.gradle.org/m2/") } } dependencyResolutionManagement { @@ -13,5 +15,11 @@ dependencyResolutionManagement { maven { url = uri("https://jitpack.io") } } } -rootProject.name = "Sample Compose Android" +rootProject.name = "samplecomposeandroid" +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") include(":app") +include(":core:ui") +include(":core:common") +include(":core:data") +include(":core:designsystem") +include(":core:domain")