diff --git a/.gitignore b/.gitignore
index a8632df..f17a628 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,3 +59,4 @@ Icon
Network Trash Folder
Temporary Items
.apdisk
+/.kotlin/
diff --git a/Readme.md b/Readme.md
index 2990a19..629594d 100644
--- a/Readme.md
+++ b/Readme.md
@@ -75,7 +75,7 @@ An Offline first Android app to consume the SpaceX Backend API [`https://github.
- Cacheing
- [Delegation](https://kotlinlang.org/docs/delegation.html)
- [Multibindings with Hilt](https://dagger.dev/dev-guide/multibindings.html)
-- [Gradle Convention Plugins](https://docs.gradle.org/current/samples/sample_convention_plugins.html) | PR [#5](https://github.com/nisrulz/android-spacex-app/pull/5) [#7](https://github.com/nisrulz/android-spacex-app/pull/7)
+- [Convention Plugins](https://github.com/nisrulz/android-spacex-app/pull/29/commits/2e05a6c3fa972cd29c89a28cb5a735aa073d4f43)
- [Github Actions](https://docs.github.com/en/actions) | [Workflows used](.github/workflows)
## Dependency Graph
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 8a46e48..6ae6bc5 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,31 +1,15 @@
-@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
+import com.nisrulz.example.spacexapi.info.ApplicationInfo
+
plugins {
- id("app-convention")
- id("hilt-convention")
+ alias(libs.plugins.spacexapi.android.application)
+ alias(libs.plugins.spacexapi.android.app.hilt)
}
android {
- namespace = "com.nisrulz.example.spacexapi"
-
- defaultConfig {
- applicationId = "com.nisrulz.example.spacexapi"
- versionCode = 1
- versionName = "1.0"
- }
+ namespace = ApplicationInfo.BASE_NAMESPACE
}
dependencies {
// Module Dependency
implementation(projects.presentation)
-
- /**
- * @TODO: Remove this workaround when below issues are solved with AGP 8.3.0
- * https://github.com/google/guava/issues/6618
- * https://github.com/android/nowinandroid/pull/1140#issuecomment-1979431658
- */
- modules {
- module("com.google.guava:listenablefuture") {
- replacedBy("com.google.guava:guava", "listenablefuture is part of guava")
- }
- }
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9f8497a..8e48d51 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -10,7 +10,6 @@
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
- android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.SpacexAPI"
tools:targetApi="tiramisu">
diff --git a/app/src/main/play_store_512.png b/app/src/main/play_store_512.png
new file mode 100644
index 0000000..a08e67a
Binary files /dev/null and b/app/src/main/play_store_512.png differ
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index 6f3b755..345888d 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,6 +1,6 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
deleted file mode 100644
index 6f3b755..0000000
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..f583e15
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
deleted file mode 100644
index c209e78..0000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_background.png b/app/src/main/res/mipmap-hdpi/ic_launcher_background.png
new file mode 100644
index 0000000..48cd37b
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_background.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..cbb023c
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png b/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png
new file mode 100644
index 0000000..15609b8
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
deleted file mode 100644
index b2dfe3d..0000000
Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..5a9ae15
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
deleted file mode 100644
index 4f0f1d6..0000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_background.png b/app/src/main/res/mipmap-mdpi/ic_launcher_background.png
new file mode 100644
index 0000000..5c1735d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_background.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..6dec9d8
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png b/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png
new file mode 100644
index 0000000..fc6975b
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
deleted file mode 100644
index 62b611d..0000000
Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..f234801
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
deleted file mode 100644
index 948a307..0000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png
new file mode 100644
index 0000000..086c3fb
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..042800b
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png
new file mode 100644
index 0000000..42a1a4f
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
deleted file mode 100644
index 1b9a695..0000000
Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..97e8fec
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
deleted file mode 100644
index 28d4b77..0000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png
new file mode 100644
index 0000000..ac5b0b7
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..0c240fd
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png
new file mode 100644
index 0000000..e9adc58
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
deleted file mode 100644
index 9287f50..0000000
Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..d357681
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
deleted file mode 100644
index aa7d642..0000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and /dev/null differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png
new file mode 100644
index 0000000..5bf8f2c
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..892d51b
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png
new file mode 100644
index 0000000..827dec0
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
deleted file mode 100644
index 9126ae3..0000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ
diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts
deleted file mode 100644
index db87a20..0000000
--- a/build-logic/build.gradle.kts
+++ /dev/null
@@ -1,16 +0,0 @@
-plugins {
- `kotlin-dsl`
- `kotlin-dsl-precompiled-script-plugins`
-}
-
-repositories {
- google()
- mavenCentral()
- gradlePluginPortal()
-}
-
-dependencies {
- implementation(libs.gradle)
- implementation(libs.kotlin.gradle.plugin)
- implementation(libs.symbol.processing.gradle.plugin)
-}
diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts
new file mode 100644
index 0000000..0a7bdbd
--- /dev/null
+++ b/build-logic/convention/build.gradle.kts
@@ -0,0 +1,73 @@
+plugins {
+ `kotlin-dsl`
+}
+
+// Note: Replace with your package name
+group = "com.nisrulz.example.spacexapi"
+
+// https://kotlinlang.org/docs/gradle-configure-project.html#gradle-java-toolchains-support
+// Note: Setting a toolchain via the kotlin extension updates the toolchain for Java compile
+// tasks as well.
+kotlin {
+ jvmToolchain(17)
+}
+
+tasks {
+ validatePlugins {
+ enableStricterValidation = true
+ failOnWarning = true
+ }
+}
+
+dependencies {
+ // Android
+ compileOnly(libs.android.gradle.plugin)
+ compileOnly(libs.android.tools.common)
+ compileOnly(libs.kotlin.gradle.plugin)
+
+ // Compose
+ compileOnly(libs.compose.gradle.plugin)
+
+ // Hilt
+ compileOnly(libs.symbol.processing.gradle.plugin)
+}
+
+// Register Convention Plugins
+gradlePlugin {
+ plugins {
+
+ register("androidApplication") {
+ id = "spacexapi.android.application"
+ implementationClass = "com.nisrulz.example.spacexapi.AndroidApplicationConventionPlugin"
+ }
+
+ register("androidLibrary") {
+ id = "spacexapi.android.library"
+ implementationClass = "com.nisrulz.example.spacexapi.AndroidLibraryConventionPlugin"
+ }
+
+ register("testing") {
+ id = "spacexapi.android.testing"
+ implementationClass =
+ "com.nisrulz.example.spacexapi.TestingConventionPlugin"
+ }
+
+ register("hiltApp") {
+ id = "spacexapi.android.app.hilt"
+ implementationClass =
+ "com.nisrulz.example.spacexapi.HiltAppConventionPlugin"
+ }
+
+ register("hiltLib") {
+ id = "spacexapi.android.lib.hilt"
+ implementationClass =
+ "com.nisrulz.example.spacexapi.HiltLibConventionPlugin"
+ }
+
+ register("androidCompose") {
+ id = "spacexapi.android.compose"
+ implementationClass =
+ "com.nisrulz.example.spacexapi.AndroidComposeConventionPlugin"
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/AndroidApplicationConventionPlugin.kt
new file mode 100644
index 0000000..5f907b7
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/AndroidApplicationConventionPlugin.kt
@@ -0,0 +1,18 @@
+package com.nisrulz.example.spacexapi
+
+import com.nisrulz.example.spacexapi.ktx.configureAndroidApp
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+class AndroidApplicationConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("com.android.application")
+ apply("org.jetbrains.kotlin.android")
+ }
+
+ configureAndroidApp()
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/AndroidComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/AndroidComposeConventionPlugin.kt
new file mode 100644
index 0000000..734fd5b
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/AndroidComposeConventionPlugin.kt
@@ -0,0 +1,18 @@
+package com.nisrulz.example.spacexapi
+
+import com.nisrulz.example.spacexapi.ktx.configureAndroidCompose
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+class AndroidComposeConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("com.android.library")
+ apply("org.jetbrains.kotlin.plugin.compose")
+ }
+
+ configureAndroidCompose()
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/AndroidLibraryConventionPlugin.kt
new file mode 100644
index 0000000..6e2c6aa
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/AndroidLibraryConventionPlugin.kt
@@ -0,0 +1,18 @@
+package com.nisrulz.example.spacexapi
+
+import com.nisrulz.example.spacexapi.ktx.configureAndroidLibrary
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+class AndroidLibraryConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("com.android.library")
+ apply("org.jetbrains.kotlin.android")
+ }
+
+ configureAndroidLibrary()
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/HiltAppConventionPlugin.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/HiltAppConventionPlugin.kt
new file mode 100644
index 0000000..4a98454
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/HiltAppConventionPlugin.kt
@@ -0,0 +1,23 @@
+package com.nisrulz.example.spacexapi
+
+import com.android.build.api.dsl.ApplicationExtension
+import com.nisrulz.example.spacexapi.ktx.configureHilt
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+
+class HiltAppConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("com.android.application")
+ apply("com.google.devtools.ksp")
+ apply("dagger.hilt.android.plugin")
+ }
+
+ extensions.configure {
+ configureHilt(this)
+ }
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/HiltLibConventionPlugin.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/HiltLibConventionPlugin.kt
new file mode 100644
index 0000000..cd9d6ec
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/HiltLibConventionPlugin.kt
@@ -0,0 +1,23 @@
+package com.nisrulz.example.spacexapi
+
+import com.android.build.api.dsl.LibraryExtension
+import com.nisrulz.example.spacexapi.ktx.configureHilt
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+
+class HiltLibConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("com.android.library")
+ apply("com.google.devtools.ksp")
+ apply("dagger.hilt.android.plugin")
+ }
+
+ extensions.configure {
+ configureHilt(this)
+ }
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/TestingConventionPlugin.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/TestingConventionPlugin.kt
new file mode 100644
index 0000000..fa1032b
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/TestingConventionPlugin.kt
@@ -0,0 +1,17 @@
+package com.nisrulz.example.spacexapi
+
+import com.nisrulz.example.spacexapi.ktx.configureTesting
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+class TestingConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("com.android.library")
+ }
+
+ configureTesting()
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/info/ApplicationInfo.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/info/ApplicationInfo.kt
new file mode 100644
index 0000000..5bac41b
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/info/ApplicationInfo.kt
@@ -0,0 +1,7 @@
+package com.nisrulz.example.spacexapi.info
+
+object ApplicationInfo {
+ const val VERSION_NAME = "1.0"
+ const val VERSION_CODE = 1
+ const val BASE_NAMESPACE = "com.nisrulz.example.spacexapi"
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/info/BuildSdkInfo.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/info/BuildSdkInfo.kt
new file mode 100644
index 0000000..0d207a9
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/info/BuildSdkInfo.kt
@@ -0,0 +1,8 @@
+package com.nisrulz.example.spacexapi.info
+
+object BuildSdkInfo {
+ const val COMPILE_SDK_VERSION = 34
+ const val MIN_SDK_VERSION = 21
+ const val TARGET_SDK_VERSION = 34
+ const val JVM_TARGET = 17
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/AndroidComposeProjectExtensions.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/AndroidComposeProjectExtensions.kt
new file mode 100644
index 0000000..560b8fa
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/AndroidComposeProjectExtensions.kt
@@ -0,0 +1,29 @@
+package com.nisrulz.example.spacexapi.ktx
+
+import com.android.build.api.dsl.LibraryExtension
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.assign
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension
+
+/**
+ * Configure Compose-specific options
+ */
+internal fun Project.configureAndroidCompose() = configure {
+ buildFeatures {
+ compose = true
+ }
+
+ dependencies {
+ val bom = catalogLibrary("compose-bom")
+ add("implementation", platform(bom))
+ add("androidTestImplementation", platform(bom))
+ add("implementation", catalogLibrary("ui-tooling-preview"))
+ add("debugImplementation", catalogLibrary("ui-tooling"))
+ }
+
+ extensions.configure {
+ enableStrongSkippingMode = true
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/AndroidProjectExtenions.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/AndroidProjectExtenions.kt
new file mode 100644
index 0000000..558d3f9
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/AndroidProjectExtenions.kt
@@ -0,0 +1,91 @@
+package com.nisrulz.example.spacexapi.ktx
+
+import com.android.build.api.dsl.ApplicationExtension
+import com.android.build.api.dsl.CommonExtension
+import com.android.build.api.dsl.LibraryExtension
+import com.nisrulz.example.spacexapi.info.ApplicationInfo
+import com.nisrulz.example.spacexapi.info.BuildSdkInfo
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
+
+/**
+ * Set JVM toolchain
+ */
+private fun Project.configureKotlin(commonExtension: CommonExtension<*, *, *, *, *, *>) =
+ commonExtension.apply {
+ // https://kotlinlang.org/docs/gradle-configure-project.html#gradle-java-toolchains-support
+ // Note: Setting a toolchain via the kotlin extension updates the toolchain for Java compile
+ // tasks as well.
+ kotlinExtension.jvmToolchain(BuildSdkInfo.JVM_TARGET)
+ }
+
+/**
+ * Common configuration for Android modules
+ */
+private fun Project.configureAndroid(commonExtension: CommonExtension<*, *, *, *, *, *>) =
+ commonExtension.apply {
+ compileSdk = BuildSdkInfo.COMPILE_SDK_VERSION
+
+ defaultConfig {
+ minSdk = BuildSdkInfo.MIN_SDK_VERSION
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ configureKotlin(this)
+ }
+
+/**
+ * Configuration for Android Application
+ */
+internal fun Project.configureAndroidApp() = configure {
+ configureAndroid(this)
+
+ defaultConfig {
+ targetSdk = BuildSdkInfo.TARGET_SDK_VERSION
+
+ versionCode = ApplicationInfo.VERSION_CODE
+ versionName = ApplicationInfo.VERSION_NAME
+
+ vectorDrawables.useSupportLibrary = true
+ }
+
+ packaging {
+ resources {
+ excludes += "/META-INF/{AL2.0,LGPL2.1}"
+ }
+ }
+
+ buildFeatures {
+ buildConfig = true
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+}
+
+internal fun Project.configureAndroidLibrary() = configure {
+ configureAndroid(this)
+
+ defaultConfig {
+ consumerProguardFiles("consumer-rules.pro")
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/HiltExtensions.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/HiltExtensions.kt
new file mode 100644
index 0000000..39f66c4
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/HiltExtensions.kt
@@ -0,0 +1,13 @@
+package com.nisrulz.example.spacexapi.ktx
+
+import com.android.build.api.dsl.CommonExtension
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.dependencies
+
+internal fun Project.configureHilt(commonExtension: CommonExtension<*, *, *, *, *, *>) =
+ commonExtension.apply {
+ dependencies {
+ add("implementation", catalogBundle("hilt"))
+ add("ksp", catalogLibrary("hilt-compiler"))
+ }
+ }
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/TestingExtensions.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/TestingExtensions.kt
new file mode 100644
index 0000000..984efb8
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/TestingExtensions.kt
@@ -0,0 +1,14 @@
+package com.nisrulz.example.spacexapi.ktx
+
+import com.android.build.api.dsl.LibraryExtension
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+
+internal fun Project.configureTesting() = configure {
+ dependencies {
+ add("testImplementation", catalogBundle("testing"))
+ add("testImplementation", catalogBundle("mockk"))
+ add("androidTestImplementation", catalogBundle("android-testing"))
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/VersionCatalogExtensions.kt b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/VersionCatalogExtensions.kt
new file mode 100644
index 0000000..30e8d67
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/com/nisrulz/example/spacexapi/ktx/VersionCatalogExtensions.kt
@@ -0,0 +1,21 @@
+package com.nisrulz.example.spacexapi.ktx
+
+import org.gradle.api.Project
+import org.gradle.api.artifacts.ExternalModuleDependencyBundle
+import org.gradle.api.artifacts.MinimalExternalModuleDependency
+import org.gradle.api.artifacts.VersionCatalog
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.api.provider.Provider
+import org.gradle.kotlin.dsl.getByType
+
+private val Project.catalog
+ get() = extensions.getByType()
+
+private val Project.libs: VersionCatalog
+ get() = catalog.named("libs")
+
+internal fun Project.catalogLibrary(alias: String): Provider =
+ libs.findLibrary(alias).get()
+
+internal fun Project.catalogBundle(alias: String): Provider =
+ libs.findBundle(alias).get()
diff --git a/build-logic/gradle.properties b/build-logic/gradle.properties
new file mode 100644
index 0000000..6977b71
--- /dev/null
+++ b/build-logic/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.parallel=true
+org.gradle.caching=true
+org.gradle.configureondemand=true
\ No newline at end of file
diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts
index aa5e146..c7ab439 100644
--- a/build-logic/settings.gradle.kts
+++ b/build-logic/settings.gradle.kts
@@ -1,4 +1,11 @@
+@Suppress("UnstableApiUsage")
dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
@@ -7,3 +14,4 @@ dependencyResolutionManagement {
}
rootProject.name = "build-logic"
+include(":convention")
diff --git a/build-logic/src/main/kotlin/VersionCatalogExtensions.kt b/build-logic/src/main/kotlin/VersionCatalogExtensions.kt
deleted file mode 100644
index 464be86..0000000
--- a/build-logic/src/main/kotlin/VersionCatalogExtensions.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-import org.gradle.api.Project
-import org.gradle.api.artifacts.ExternalModuleDependencyBundle
-import org.gradle.api.artifacts.MinimalExternalModuleDependency
-import org.gradle.api.artifacts.VersionCatalog
-import org.gradle.api.artifacts.VersionCatalogsExtension
-import org.gradle.api.provider.Provider
-import org.gradle.kotlin.dsl.getByType
-import org.gradle.plugin.use.PluginDependency
-
-private val Project.catalog
- get() = extensions.getByType()
-
-internal val Project.libs: VersionCatalog
- get() = catalog.named("libs")
-
-internal val VersionCatalog.compileSdk
- get() = findVersionOrThrow("compileSdk").toInt()
-
-internal val VersionCatalog.minSdk
- get() = findVersionOrThrow("minSdk").toInt()
-
-internal val VersionCatalog.targetSdk
- get() = findVersionOrThrow("targetSdk").toInt()
-
-internal val VersionCatalog.kotlinCompilerExtensionVersion
- get() = findVersionOrThrow("composeCompiler").toString()
-
-private fun VersionCatalog.findVersionOrThrow(name: String) = findVersion(name)
- .orElseThrow { NoSuchElementException("Version $name not found in version catalog") }
- .requiredVersion
-
-internal fun Project.applyPlugin(alias: String, block: (Provider) -> Unit) {
- libs.findPlugin(alias).ifPresent { plugin ->
- block(plugin)
- }
-}
-
-internal fun Project.applyBundle(
- alias: String,
- block: (Provider) -> Unit
-) {
- libs.findBundle(alias).ifPresent { bundle ->
- block(bundle)
- }
-}
-
-internal fun Project.applyLibrary(
- alias: String,
- block: (Provider) -> Unit
-) {
- libs.findLibrary(alias).ifPresent { lib ->
- block(lib)
- }
-}
diff --git a/build-logic/src/main/kotlin/app-convention.gradle.kts b/build-logic/src/main/kotlin/app-convention.gradle.kts
deleted file mode 100644
index 0916a6e..0000000
--- a/build-logic/src/main/kotlin/app-convention.gradle.kts
+++ /dev/null
@@ -1,47 +0,0 @@
-plugins {
- id("com.android.application")
- id("org.jetbrains.kotlin.android")
-}
-
-android {
-
- compileSdk = libs.compileSdk
-
- defaultConfig {
- minSdk = libs.minSdk
- targetSdk = libs.targetSdk
-
- testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
- vectorDrawables {
- useSupportLibrary = true
- }
- }
-
- buildTypes {
- release {
- isMinifyEnabled = false
- proguardFiles(
- getDefaultProguardFile("proguard-android-optimize.txt"),
- "proguard-rules.pro"
- )
- }
- }
-
- buildFeatures {
- buildConfig = true
- }
- packaging {
- resources {
- excludes += "/META-INF/{AL2.0,LGPL2.1}"
- }
- }
-
- compileOptions {
- targetCompatibility = JavaVersion.VERSION_11
- sourceCompatibility = JavaVersion.VERSION_11
- }
-
- kotlinOptions {
- jvmTarget = JavaVersion.VERSION_11.toString()
- }
-}
diff --git a/build-logic/src/main/kotlin/hilt-convention.gradle.kts b/build-logic/src/main/kotlin/hilt-convention.gradle.kts
deleted file mode 100644
index 31dfbab..0000000
--- a/build-logic/src/main/kotlin/hilt-convention.gradle.kts
+++ /dev/null
@@ -1,20 +0,0 @@
-import gradle.kotlin.dsl.accessors._f498a892b084b6e1620083bdb51439d5.implementation
-
-plugins {
- id("com.google.devtools.ksp")
-}
-
-applyPlugin("ksp") { plugins { alias(it) } }
-applyPlugin("hilt") { plugins { alias(it) } }
-
-applyBundle("hilt") {
- dependencies {
- implementation(it)
- }
-}
-
-applyLibrary("hilt-compiler") {
- dependencies {
- ksp(it)
- }
-}
diff --git a/build-logic/src/main/kotlin/jetpack-compose-convention.gradle.kts b/build-logic/src/main/kotlin/jetpack-compose-convention.gradle.kts
deleted file mode 100644
index e8fc85f..0000000
--- a/build-logic/src/main/kotlin/jetpack-compose-convention.gradle.kts
+++ /dev/null
@@ -1,32 +0,0 @@
-import gradle.kotlin.dsl.accessors._1c35da307f1540a2fdd9273b146bf0a7.android
-import gradle.kotlin.dsl.accessors._1c35da307f1540a2fdd9273b146bf0a7.debugImplementation
-import gradle.kotlin.dsl.accessors._f498a892b084b6e1620083bdb51439d5.implementation
-import org.gradle.kotlin.dsl.dependencies
-
-
-android {
- buildFeatures {
- compose = true
- }
- composeOptions {
- kotlinCompilerExtensionVersion = libs.kotlinCompilerExtensionVersion
- }
-}
-
-applyBundle("compose") {
- dependencies {
- implementation(it)
- }
-}
-
-applyLibrary("compose-bom") {
- dependencies {
- implementation(platform(it))
- }
-}
-
-applyLibrary("compose-debug") {
- dependencies {
- debugImplementation(it)
- }
-}
diff --git a/build-logic/src/main/kotlin/library-convention.gradle.kts b/build-logic/src/main/kotlin/library-convention.gradle.kts
deleted file mode 100644
index 8cf74bd..0000000
--- a/build-logic/src/main/kotlin/library-convention.gradle.kts
+++ /dev/null
@@ -1,34 +0,0 @@
-plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
-}
-
-android {
- compileSdk = libs.compileSdk
-
- defaultConfig {
- minSdk = libs.minSdk
-
- testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
- consumerProguardFiles("consumer-rules.pro")
- }
-
- buildTypes {
- release {
- isMinifyEnabled = false
- proguardFiles(
- getDefaultProguardFile("proguard-android-optimize.txt"),
- "proguard-rules.pro"
- )
- }
- }
-
- compileOptions {
- targetCompatibility = JavaVersion.VERSION_11
- sourceCompatibility = JavaVersion.VERSION_11
- }
-
- kotlinOptions {
- jvmTarget = JavaVersion.VERSION_11.toString()
- }
-}
diff --git a/build-logic/src/main/kotlin/testing-convention.gradle.kts b/build-logic/src/main/kotlin/testing-convention.gradle.kts
deleted file mode 100644
index 48b3fd4..0000000
--- a/build-logic/src/main/kotlin/testing-convention.gradle.kts
+++ /dev/null
@@ -1,20 +0,0 @@
-import gradle.kotlin.dsl.accessors._1c35da307f1540a2fdd9273b146bf0a7.androidTestImplementation
-import gradle.kotlin.dsl.accessors._1c35da307f1540a2fdd9273b146bf0a7.testImplementation
-
-applyBundle("testing") {
- dependencies {
- testImplementation(it)
- }
-}
-
-applyBundle("mockk") {
- dependencies {
- testImplementation(it)
- }
-}
-
-applyBundle("android-testing") {
- dependencies {
- androidTestImplementation(it)
- }
-}
diff --git a/build.gradle.kts b/build.gradle.kts
index 8802afe..044a883 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,18 +1,23 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
-@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
+ // Android
alias(libs.plugins.com.android.application) apply false
- alias(libs.plugins.org.jetbrains.kotlin.android) apply false
alias(libs.plugins.com.android.library) apply false
+ // Kotlin
+ alias(libs.plugins.org.jetbrains.kotlin.android) apply false
+
+ // Hilt
alias(libs.plugins.ksp) apply false
alias(libs.plugins.hilt) apply false
+ // Serialization
alias(libs.plugins.kotlin.serialization) apply false
+
+ // Compose
+ alias(libs.plugins.compose.compiler) apply false
}
tasks.register("clean") {
delete(rootProject.layout.buildDirectory)
}
-
-true // Needed to make the Suppress annotation work for the plugins block
diff --git a/core/analytics/build.gradle.kts b/core/analytics/build.gradle.kts
index 5ce8efc..1a60494 100644
--- a/core/analytics/build.gradle.kts
+++ b/core/analytics/build.gradle.kts
@@ -1,11 +1,12 @@
-@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
+import com.nisrulz.example.spacexapi.info.ApplicationInfo
+
plugins {
- id("library-convention")
- id("hilt-convention")
+ alias(libs.plugins.spacexapi.android.library)
+ alias(libs.plugins.spacexapi.android.lib.hilt)
}
android {
- namespace = "com.nisrulz.example.spacexapi.analytics"
+ namespace = "${ApplicationInfo.BASE_NAMESPACE}.analytics"
buildFeatures {
buildConfig = true
diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts
index 2c2b5f7..ab8fe7f 100644
--- a/core/common/build.gradle.kts
+++ b/core/common/build.gradle.kts
@@ -1,11 +1,12 @@
-@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
+import com.nisrulz.example.spacexapi.info.ApplicationInfo
+
plugins {
- id("library-convention")
- id("hilt-convention")
+ alias(libs.plugins.spacexapi.android.library)
+ alias(libs.plugins.spacexapi.android.lib.hilt)
}
android {
- namespace = "com.nisrulz.example.spacexapi.common"
+ namespace = "${ApplicationInfo.BASE_NAMESPACE}.common"
buildFeatures {
buildConfig = true
diff --git a/core/logger/build.gradle.kts b/core/logger/build.gradle.kts
index 723d8ae..dfcab7b 100644
--- a/core/logger/build.gradle.kts
+++ b/core/logger/build.gradle.kts
@@ -1,11 +1,12 @@
-@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
+import com.nisrulz.example.spacexapi.info.ApplicationInfo
+
plugins {
- id("library-convention")
- id("hilt-convention")
+ alias(libs.plugins.spacexapi.android.library)
+ alias(libs.plugins.spacexapi.android.lib.hilt)
}
android {
- namespace = "com.nisrulz.example.spacexapi.logger"
+ namespace = "${ApplicationInfo.BASE_NAMESPACE}.logger"
buildFeatures {
buildConfig = true
diff --git a/core/network-retrofit/build.gradle.kts b/core/network-retrofit/build.gradle.kts
index ad183d3..e72b2f8 100644
--- a/core/network-retrofit/build.gradle.kts
+++ b/core/network-retrofit/build.gradle.kts
@@ -1,19 +1,21 @@
-@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
+import com.nisrulz.example.spacexapi.info.ApplicationInfo
+
plugins {
- id("library-convention")
- id("hilt-convention")
- id("testing-convention")
+ alias(libs.plugins.spacexapi.android.library)
+ alias(libs.plugins.spacexapi.android.lib.hilt)
+ alias(libs.plugins.spacexapi.android.testing)
alias(libs.plugins.kotlin.serialization)
}
android {
- namespace = "com.nisrulz.example.spacexapi.network.retrofit"
+ namespace = "${ApplicationInfo.BASE_NAMESPACE}.network.retrofit"
}
dependencies {
// Retrofit
implementation(platform(libs.okhttp.bom))
+ implementation(platform(libs.retrofit.bom))
implementation(libs.bundles.retrofit)
testImplementation(libs.okhttp.mockwebserver)
}
diff --git a/core/network-retrofit/src/main/java/com/nisrulz/example/spacexapi/network/retrofit/di/NetworkModule.kt b/core/network-retrofit/src/main/java/com/nisrulz/example/spacexapi/network/retrofit/di/NetworkModule.kt
index 6bc1bc1..12bdb7d 100644
--- a/core/network-retrofit/src/main/java/com/nisrulz/example/spacexapi/network/retrofit/di/NetworkModule.kt
+++ b/core/network-retrofit/src/main/java/com/nisrulz/example/spacexapi/network/retrofit/di/NetworkModule.kt
@@ -1,7 +1,6 @@
package com.nisrulz.example.spacexapi.network.retrofit.di
import android.app.Application
-import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.nisrulz.example.spacexapi.network.retrofit.SpaceXLaunchesApi
import dagger.Module
import dagger.Provides
@@ -18,6 +17,7 @@ import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Converter
import retrofit2.Retrofit
+import retrofit2.converter.kotlinx.serialization.asConverterFactory
@Module
@InstallIn(SingletonComponent::class)
diff --git a/core/network-retrofit/src/test/java/com/nisrulz/example/spacexapi/network/retrofit/util/MockWebServerHelper.kt b/core/network-retrofit/src/test/java/com/nisrulz/example/spacexapi/network/retrofit/util/MockWebServerHelper.kt
index 817756b..144e4b6 100644
--- a/core/network-retrofit/src/test/java/com/nisrulz/example/spacexapi/network/retrofit/util/MockWebServerHelper.kt
+++ b/core/network-retrofit/src/test/java/com/nisrulz/example/spacexapi/network/retrofit/util/MockWebServerHelper.kt
@@ -1,6 +1,5 @@
package com.nisrulz.example.spacexapi.network.retrofit.util
-import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import java.io.File
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
@@ -10,6 +9,7 @@ import okhttp3.mockwebserver.SocketPolicy
import okio.Buffer
import retrofit2.Converter
import retrofit2.Retrofit
+import retrofit2.converter.kotlinx.serialization.asConverterFactory
object MockWebServerHelper {
/**
diff --git a/core/storage-roomdb/build.gradle.kts b/core/storage-roomdb/build.gradle.kts
index 963320a..10a2438 100644
--- a/core/storage-roomdb/build.gradle.kts
+++ b/core/storage-roomdb/build.gradle.kts
@@ -1,12 +1,13 @@
-@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
+import com.nisrulz.example.spacexapi.info.ApplicationInfo
+
plugins {
- id("library-convention")
- id("hilt-convention")
- id("testing-convention")
+ alias(libs.plugins.spacexapi.android.library)
+ alias(libs.plugins.spacexapi.android.lib.hilt)
+ alias(libs.plugins.spacexapi.android.testing)
}
android {
- namespace = "com.nisrulz.example.spacexapi.storage.roomdb"
+ namespace = "${ApplicationInfo.BASE_NAMESPACE}.storage.roomdb"
}
dependencies {
diff --git a/data/build.gradle.kts b/data/build.gradle.kts
index 8516683..edd63e1 100644
--- a/data/build.gradle.kts
+++ b/data/build.gradle.kts
@@ -1,12 +1,13 @@
-@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
+import com.nisrulz.example.spacexapi.info.ApplicationInfo
+
plugins {
- id("library-convention")
- id("hilt-convention")
- id("testing-convention")
+ alias(libs.plugins.spacexapi.android.library)
+ alias(libs.plugins.spacexapi.android.lib.hilt)
+ alias(libs.plugins.spacexapi.android.testing)
}
android {
- namespace = "com.nisrulz.example.spacexapi.data"
+ namespace = "${ApplicationInfo.BASE_NAMESPACE}.data"
buildFeatures {
buildConfig = true
diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts
index a6dcffb..eb7d229 100644
--- a/domain/build.gradle.kts
+++ b/domain/build.gradle.kts
@@ -1,10 +1,11 @@
-@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
+import com.nisrulz.example.spacexapi.info.ApplicationInfo
+
plugins {
- id("library-convention")
- id("hilt-convention")
- id("testing-convention")
+ alias(libs.plugins.spacexapi.android.library)
+ alias(libs.plugins.spacexapi.android.lib.hilt)
+ alias(libs.plugins.spacexapi.android.testing)
}
android {
- namespace = "com.nisrulz.example.spacexapi.domain"
+ namespace = "${ApplicationInfo.BASE_NAMESPACE}.domain"
}
diff --git a/gradle.properties b/gradle.properties
index 2e7e7ed..f567e93 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -21,4 +21,7 @@ kotlin.code.style=official
# 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
+# Enable caching between builds.
+org.gradle.caching=true
+# Enable configuration caching between builds.
org.gradle.configuration-cache=true
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 44d182e..d3618ef 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,23 +1,17 @@
[versions]
-#region ---- SDK
-compileSdk = "34"
-targetSdk = "34"
-minSdk = "23"
-
#region ---- Kotlin version dependent
-# https://developer.android.com/jetpack/androidx/releases/compose-kotlin#pre-release_kotlin_compatibility
-composeCompiler = "1.5.10"
# https://github.com/JetBrains/kotlin/releases
-org-jetbrains-kotlin-android = "1.9.22"
+kotlin = "2.0.0"
# https://github.com/google/ksp/releases
-ksp = "1.9.22-1.0.17"
+ksp = "2.0.0-1.0.21"
#endregion
#region ---- Android Core
-agp = "8.3.0"
-core-ktx = "1.12.0"
-lifecycleVer = "2.8.1"
+agp = "8.5.0"
+androidTools = "31.4.2"
+core-ktx = "1.13.1"
+lifecycleVer = "2.8.2"
appcompat = "1.7.0"
#endregion
@@ -34,7 +28,7 @@ kotlinxSerializationJson = "1.6.2"
#region ---- Jetpack Compose
activity-compose = "1.9.0"
-compose-bom = "2024.05.00"
+compose-bom = "2024.06.00"
#endregion
# Navigation
@@ -48,11 +42,10 @@ hiltExt = "1.2.0"
#region ---- Retrofit
okhttp = "4.12.0"
-retrofit = "2.11.0"
+retrofit-bom = "2.11.0"
#endregion
#region ---- Room
-retrofit2KotlinxSerializationConverter = "1.0.0"
room = "2.6.1"
#endregion
@@ -71,9 +64,14 @@ coreTesting = "2.2.0"
kotlinxCoroutinesTest = "1.8.1"
[libraries]
-gradle = { module = "com.android.tools.build:gradle", version.ref = "agp" }
-kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "org-jetbrains-kotlin-android" }
+# build-logic
+android-gradle-plugin = { module = "com.android.tools.build:gradle", version.ref = "agp" }
+android-tools-common = { module = "com.android.tools:common", version.ref = "androidTools" }
+compose-gradle-plugin = { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin" }
+kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
symbol-processing-gradle-plugin = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "ksp" }
+#----- end
+
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" }
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" }
@@ -100,7 +98,6 @@ appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "a
material = { group = "androidx.compose.material", name = "material" }
material3 = { group = "androidx.compose.material3", name = "material3" }
-
# Coil
coil-kt = { group = "io.coil-kt", name = "coil", version.ref = "coil" }
coil-kt-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" }
@@ -116,11 +113,13 @@ hilt-navigation = { group = "androidx.hilt", name = "hilt-navigation-compose", v
navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
# Retrofit
-retrofit-core = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
+retrofit-bom = { group = "com.squareup.retrofit2", name = "retrofit-bom", version.ref = "retrofit-bom" }
+retrofit-core = { group = "com.squareup.retrofit2", name = "retrofit" }
+retrofit2-kotlinx-serialization-converter = { group = "com.squareup.retrofit2", name = "converter-kotlinx-serialization" }
+
# Serialization
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
-retrofit2-kotlinx-serialization-converter = { module = "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter", version.ref = "retrofit2KotlinxSerializationConverter" }
# Okhttp
okhttp-bom = { group = "com.squareup.okhttp3", name = "okhttp-bom", version.ref = "okhttp" }
@@ -145,16 +144,27 @@ kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-t
turbine = { module = "app.cash.turbine:turbine", version.ref = "turbineVer" }
[plugins]
+
+org-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
+kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
+
com-android-application = { id = "com.android.application", version.ref = "agp" }
com-android-library = { id = "com.android.library", version.ref = "agp" }
-org-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "org-jetbrains-kotlin-android" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "org-jetbrains-kotlin-android" }
# Hilt
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
+# Plugins defined by this project
+spacexapi-android-application = { id = "spacexapi.android.application", version = "unspecified" }
+spacexapi-android-library = { id = "spacexapi.android.library", version = "unspecified" }
+spacexapi-android-compose = { id = "spacexapi.android.compose", version = "unspecified" }
+spacexapi-android-testing = { id = "spacexapi.android.testing", version = "unspecified" }
+spacexapi-android-app-hilt = { id = "spacexapi.android.app.hilt", version = "unspecified" }
+spacexapi-android-lib-hilt = { id = "spacexapi.android.lib.hilt", version = "unspecified" }
+
[bundles]
lifecycle = ["lifecycle-runtime-ktx", "lifecycle-runtime-compose"]
ktx = ["core-ktx", "androidx-junit-ktx"]
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index d64cd49..e644113 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradlew b/gradlew
index 1aa94a4..b740cf1 100755
--- a/gradlew
+++ b/gradlew
@@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
diff --git a/gradlew.bat b/gradlew.bat
index 6689b85..7101f8e 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
@@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
diff --git a/presentation/build.gradle.kts b/presentation/build.gradle.kts
index fddc76a..85146a6 100644
--- a/presentation/build.gradle.kts
+++ b/presentation/build.gradle.kts
@@ -1,12 +1,14 @@
-@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
+import com.nisrulz.example.spacexapi.info.ApplicationInfo
+
plugins {
- id("library-convention")
- id("hilt-convention")
- id("testing-convention")
- id("jetpack-compose-convention")
+ alias(libs.plugins.spacexapi.android.library)
+ alias(libs.plugins.spacexapi.android.lib.hilt)
+ alias(libs.plugins.spacexapi.android.testing)
+
+ alias(libs.plugins.spacexapi.android.compose)
}
android {
- namespace = "com.nisrulz.example.spacexapi.presentation"
+ namespace = "${ApplicationInfo.BASE_NAMESPACE}.presentation"
}
dependencies {
diff --git a/presentation/src/main/java/com/nisrulz/example/spacexapi/presentation/navigation/AppNavigation.kt b/presentation/src/main/java/com/nisrulz/example/spacexapi/presentation/navigation/AppNavigation.kt
index f2cbe9a..ec46bd2 100644
--- a/presentation/src/main/java/com/nisrulz/example/spacexapi/presentation/navigation/AppNavigation.kt
+++ b/presentation/src/main/java/com/nisrulz/example/spacexapi/presentation/navigation/AppNavigation.kt
@@ -1,7 +1,5 @@
package com.nisrulz.example.spacexapi.presentation.navigation
-import androidx.compose.animation.EnterTransition
-import androidx.compose.animation.ExitTransition
import androidx.compose.runtime.Composable
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController
@@ -17,9 +15,7 @@ fun AppNavigation() {
val navController = rememberNavController()
NavHost(
navController = navController,
- startDestination = NavigationRoute.HOME_ROUTE,
- enterTransition = { EnterTransition.None },
- exitTransition = { ExitTransition.None }
+ startDestination = NavigationRoute.HOME_ROUTE
) {
homeScreen(
onNavigateToDetails = { launchId ->
diff --git a/presentation/src/main/java/com/nisrulz/example/spacexapi/presentation/navigation/NavigationRoute.kt b/presentation/src/main/java/com/nisrulz/example/spacexapi/presentation/navigation/NavigationRoute.kt
index d7ac61a..3b55a89 100644
--- a/presentation/src/main/java/com/nisrulz/example/spacexapi/presentation/navigation/NavigationRoute.kt
+++ b/presentation/src/main/java/com/nisrulz/example/spacexapi/presentation/navigation/NavigationRoute.kt
@@ -39,9 +39,7 @@ internal object NavigationRoute {
onNavigateToBookmarks: () -> Unit
) {
composable(
- HOME_ROUTE,
- enterTransition = { customFadeIn() },
- exitTransition = { customFadeOut() }
+ HOME_ROUTE
) {
ListOfLaunchesScreen(navigateToDetails = { launchId ->
onNavigateToDetails(launchId)
@@ -56,9 +54,7 @@ internal object NavigationRoute {
onBackAction: () -> Unit
) {
composable(
- BOOKMARK_ROUTE,
- enterTransition = { customFadeIn() },
- exitTransition = { customFadeOut() }
+ BOOKMARK_ROUTE
) {
BookmarkedLaunchesScreen(
navigateToDetails = { launchId ->
@@ -71,9 +67,7 @@ internal object NavigationRoute {
fun NavGraphBuilder.detailsScreen(onBackAction: () -> Unit) {
composable(
- DETAILS_ROUTE,
- enterTransition = { customFadeIn() },
- exitTransition = { customFadeOut() }
+ DETAILS_ROUTE
) { backStackEntry ->
val id = backStackEntry.getArgLaunchId()
if (id.isNotEmpty()) {
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 4f301e3..e0ac9d8 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -2,7 +2,13 @@ pluginManagement {
includeBuild("build-logic")
repositories {
- google()
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
mavenCentral()
gradlePluginPortal()
}
@@ -14,6 +20,10 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
+
+ // Try mavenLocal only if the dependency cannot
+ // be found on Maven Central
+ mavenLocal()
}
}