Skip to content

Commit

Permalink
Merge pull request #183 from teogor/bug-fix/version-catalog-logging-s…
Browse files Browse the repository at this point in the history
…afety

Add Logging and Safety Checks for Version Catalog-Based Dependencies
  • Loading branch information
teogor authored Mar 4, 2024
2 parents a7bb5b2 + 2bca63b commit a734a15
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
* limitations under the License.
*/

import dev.teogor.ceres.models.hiltAndroid
import dev.teogor.ceres.models.hiltAndroidCompiler
import dev.teogor.ceres.utils.add
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
Expand All @@ -30,9 +33,14 @@ class AndroidHiltConventionPlugin : Plugin<Project> {

val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
"implementation"(libs.findLibrary("hilt.android").get())
"ksp"(libs.findLibrary("hilt.compiler").get())
"kspAndroidTest"(libs.findLibrary("hilt.compiler").get())
add(
dependencies = listOf(
hiltAndroid,
hiltAndroidCompiler,
),
logger = logger,
libs = libs,
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,12 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
configurations.configureEach {
resolutionStrategy {
force(libs.findLibrary("junit4").get())
// Temporary workaround for https://issuetracker.google.com/174733673
force("org.objenesis:objenesis:2.6")
val junit4 = libs.findLibrary("junit4")
if (junit4.isPresent) {
force(libs.findLibrary("junit4").get())
// Temporary workaround for https://issuetracker.google.com/174733673
force("org.objenesis:objenesis:2.6")
}
}
}
dependencies {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

import com.google.devtools.ksp.gradle.KspExtension
import dev.teogor.ceres.models.RoomOptionsExtension
import dev.teogor.ceres.models.roomCompiler
import dev.teogor.ceres.models.roomKtx
import dev.teogor.ceres.models.roomRuntime
import dev.teogor.ceres.utils.add
import java.io.File
import org.gradle.api.Plugin
import org.gradle.api.Project
Expand Down Expand Up @@ -44,17 +48,23 @@ class AndroidRoomConventionPlugin : Plugin<Project> {
// 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.
if(roomOptions.enableSchemaProvider) {
if (roomOptions.enableSchemaProvider) {
arg(RoomSchemaArgProvider(File(projectDir, roomOptions.schemasPath)))
}
}
}

val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
add("implementation", libs.findLibrary("room.runtime").get())
add("implementation", libs.findLibrary("room.ktx").get())
add("ksp", libs.findLibrary("room.compiler").get())
add(
dependencies = listOf(
roomRuntime,
roomKtx,
roomCompiler,
),
logger = logger,
libs = libs,
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,6 @@ internal fun Project.configureAndroidBuildConfig(

val gitHashProvider = providers.of(GitHashValueSource::class) {}

afterEvaluate {
val specificDependency = configurations.findSpecificDependency("dev.teogor.ceres", "bom")

val version = specificDependency?.version
if (version != null) {
println("[CeresBomVersion] Version of dev.teogor.ceres:bom: $version")
} else {
println("[CeresBomVersion] Dependency dev.teogor.ceres:bom not found or has no version.")
}
}

// Enable BuildConfig generation
commonExtension.apply {
buildFeatures {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
package dev.teogor.ceres

import com.android.build.api.dsl.CommonExtension
import dev.teogor.ceres.models.androidxComposeBom
import dev.teogor.ceres.utils.add
import java.io.File
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.File

/**
* Configure Compose-specific options
Expand All @@ -43,9 +45,13 @@ internal fun Project.configureAndroidCompose(
}

dependencies {
val bom = libs.findLibrary("androidx-compose-bom").get()
add("implementation", platform(bom))
add("androidTestImplementation", platform(bom))
add(
dependencies = listOf(
androidxComposeBom,
),
logger = logger,
libs = libs,
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.gradle.kotlin.dsl.invoke
/**
* Configure project for Gradle managed devices
*/
@Suppress("UnstableApiUsage")
internal fun configureGradleManagedDevices(
commonExtension: CommonExtension<*, *, *, *, *>,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package dev.teogor.ceres

import com.android.build.api.variant.AndroidComponentsExtension
import java.util.Locale
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.tasks.testing.Test
Expand All @@ -27,7 +28,6 @@ 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
import java.util.Locale

private val coverageExclusions = listOf(
// Android
Expand All @@ -47,7 +47,11 @@ internal fun Project.configureJacoco(
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")

configure<JacocoPluginExtension> {
toolVersion = libs.findVersion("jacoco").get().toString()
libs.findVersion("jacoco").let { jacoco ->
if (jacoco.isPresent) {
toolVersion = jacoco.get().toString()
}
}
}

val jacocoTestReport = tasks.create("jacocoTestReport")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ internal fun Project.configureKotlinAndroid(
defaultValue = true,
)
) {
add("coreLibraryDesugaring", libs.findLibrary("android.desugarJdkLibs").get())
val desugarJdkLibs = libs.findLibrary("android.desugarJdkLibs")
if (desugarJdkLibs.isPresent) {
add("coreLibraryDesugaring", desugarJdkLibs.get())
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package dev.teogor.ceres.models

enum class DependencyType(val gradleNotation: String) {
KSP("ksp"),
KSP_ANDROID_TEST("kspAndroidTest"),
IMPLEMENTATION("implementation"),
API("api"),
ANDROID_TEST_IMPLEMENTATION("androidTestImplementation"),
TEST_IMPLEMENTATION("testImplementation"),
COMPILE_ONLY("compileOnly"),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package dev.teogor.ceres.models

data class LibrarySpec(
val name: String,
val module: String,
val dependencyTypes: List<DependencyType> = emptyList(),
val isBom: Boolean = false,
)

val roomRuntime = LibrarySpec(
name = "room.runtime",
module = "androidx.room:room-runtime",
dependencyTypes = listOf(
DependencyType.IMPLEMENTATION,
),
)
val roomKtx = LibrarySpec(
name = "room.ktx",
module = "androidx.room:room-ktx",
dependencyTypes = listOf(
DependencyType.IMPLEMENTATION,
),
)
val roomCompiler = LibrarySpec(
name = "room.compiler",
module = "androidx.room:room-compiler",
dependencyTypes = listOf(
DependencyType.KSP,
),
)
val hiltAndroid = LibrarySpec(
name = "hilt.android",
module = "com.google.dagger:hilt-android",
dependencyTypes = listOf(
DependencyType.IMPLEMENTATION,
),
)
val hiltAndroidCompiler = LibrarySpec(
name = "hilt.android.compiler",
module = "com.google.dagger:hilt-android-compiler",
dependencyTypes = listOf(
DependencyType.KSP,
DependencyType.KSP_ANDROID_TEST,
),
)
val androidxComposeBom = LibrarySpec(
name = "androidx.compose.bom",
module = "androidx.compose:compose-bom",
dependencyTypes = listOf(
DependencyType.IMPLEMENTATION,
DependencyType.ANDROID_TEST_IMPLEMENTATION,
),
isBom = true,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package dev.teogor.ceres.utils

import dev.teogor.ceres.models.LibrarySpec
import java.util.Optional
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.logging.Logger
import org.gradle.api.provider.Provider
import org.gradle.kotlin.dsl.DependencyHandlerScope

fun VersionCatalog.findLibrary(
librarySpec: LibrarySpec,
): Optional<Provider<MinimalExternalModuleDependency>> {
return findLibrary(librarySpec.name)
}

fun DependencyHandlerScope.add(
dependencies: List<LibrarySpec>,
logger: Logger,
libs: VersionCatalog,
) {
dependencies.forEach { libraryDependency ->
val library = libs.findLibrary(libraryDependency)
if (!library.isPresent) {
logger.error("Library alias named \"${libraryDependency.name}\" not found in the version catalog. Please ensure it's properly defined.")

libs.resolveLibraryDependency(libraryDependency.name)?.let {
logger.warn("Found library with name \"${it.first}\". Using recommended alias \"${libraryDependency.name}\" is encouraged for consistency and clarity.")
add(libraryDependency, it.second)
}
} else {
add(libraryDependency, library.get().get())
}
}
}

fun DependencyHandlerScope.add(
librarySpec: LibrarySpec,
moduleProvider: MinimalExternalModuleDependency,
) {
librarySpec.dependencyTypes.forEach {
if (librarySpec.isBom) {
add(
configurationName = it.gradleNotation,
dependencyNotation = platform(moduleProvider),
)
} else {
add(
configurationName = it.gradleNotation,
dependencyNotation = moduleProvider,
)
}
}
}

fun VersionCatalog.resolveLibraryDependency(module: String): Pair<String, MinimalExternalModuleDependency>? {
val regex = "[._-]".toRegex()
return libraryAliases
.map { libraryAlias ->
Pair(libraryAlias, findLibrary(libraryAlias).get().getOrNull())
}
.filter { it.second != null }
.map { it.first to it.second!! }
.firstOrNull {
regex.replace(it.second.module.name, ".") == module
}
}
2 changes: 2 additions & 0 deletions plugin/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/

@Suppress("UnstableApiUsage")
dependencyResolutionManagement {
repositories {
google()
Expand All @@ -27,4 +28,5 @@ dependencyResolutionManagement {
}

rootProject.name = "plugin"

include(":library-convention")

0 comments on commit a734a15

Please sign in to comment.