From e5f0df92735ae56171d1ab33979264274dbb7e17 Mon Sep 17 00:00:00 2001 From: M57 <41645758+Hy4ri@users.noreply.github.com> Date: Mon, 22 Jun 2026 21:35:40 +0300 Subject: [PATCH] chore(#297) * fix: fix ktlint issues in gradle files Fixed code style and formatting issues across `build.gradle.kts` and `app/build.gradle.kts` to resolve CI failures during the `ktlint` task. * fix: fix ktlint and tests for PR 306 Updates dependencies logic to use `MasterKeys` properly based on the `androidx.security:security-crypto` upgrade to 1.0.0, and fixes `ktlint` formatting errors across the build scripts. --- app/build.gradle.kts | 155 +++++++++--------- .../hermescontrol/data/local/AuthManager.kt | 9 +- .../data/local/AuthManagerTest.kt | 12 +- build.gradle.kts | 8 +- gradle/libs.versions.toml | 4 +- 5 files changed, 94 insertions(+), 94 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 700683f1..8f5b9cf4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,11 +1,11 @@ import org.gradle.api.tasks.testing.Test plugins { - alias(libs.plugins.android.application) - alias(libs.plugins.compose.compiler) - alias(libs.plugins.kotlin.serialization) - alias(libs.plugins.room) - alias(libs.plugins.ksp) + alias(libs.plugins.android.application) + alias(libs.plugins.compose.compiler) + alias(libs.plugins.kotlin.serialization) + alias(libs.plugins.room) + alias(libs.plugins.ksp) } android { @@ -21,17 +21,19 @@ android { versionName = (project.findProperty("versionName") as? String) ?: "1.0-dev" // Embed git commit SHA for the About card in Settings - val gitSha = providers.exec { - commandLine("git", "rev-parse", "--short", "HEAD") - }.standardOutput.asText.get().trim() + val gitSha = + providers.exec { + commandLine("git", "rev-parse", "--short", "HEAD") + }.standardOutput.asText.get().trim() buildConfigField("String", "GIT_SHA", "\"$gitSha\"") } signingConfigs { create("release") { - val isReleaseBuild = gradle.startParameter.taskNames.any { name -> - name.contains("Release", ignoreCase = true) || name == "build" - } + val isReleaseBuild = + gradle.startParameter.taskNames.any { name -> + name.contains("Release", ignoreCase = true) || name == "build" + } if (isReleaseBuild) { val storePath = System.getenv("KEYSTORE_PATH") @@ -71,22 +73,22 @@ android { targetCompatibility = JavaVersion.VERSION_17 } buildFeatures { - compose = true - aidl = false - buildConfig = true - shaders = false + compose = true + aidl = false + buildConfig = true + shaders = false } packaging { - resources { - pickFirsts += "META-INF/AL2.0" - pickFirsts += "META-INF/LGPL2.1" - pickFirsts += "META-INF/LICENSE" - pickFirsts += "META-INF/LICENSE.md" - pickFirsts += "META-INF/LICENSE-notice.md" - pickFirsts += "META-INF/NOTICE" - pickFirsts += "META-INF/NOTICE.md" - } + resources { + pickFirsts += "META-INF/AL2.0" + pickFirsts += "META-INF/LGPL2.1" + pickFirsts += "META-INF/LICENSE" + pickFirsts += "META-INF/LICENSE.md" + pickFirsts += "META-INF/LICENSE-notice.md" + pickFirsts += "META-INF/NOTICE" + pickFirsts += "META-INF/NOTICE.md" + } } } @@ -99,67 +101,68 @@ room { } dependencies { - val composeBom = platform(libs.androidx.compose.bom) - implementation(composeBom) - androidTestImplementation(composeBom) + val composeBom = platform(libs.androidx.compose.bom) + implementation(composeBom) + androidTestImplementation(composeBom) - // Core Android dependencies - implementation(libs.androidx.core.ktx) - implementation(libs.androidx.lifecycle.runtime.ktx) - implementation(libs.androidx.activity.compose) + // Core Android dependencies + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) - // Arch Components - implementation(libs.androidx.lifecycle.runtime.compose) - implementation(libs.androidx.lifecycle.viewmodel.compose) + // Arch Components + implementation(libs.androidx.lifecycle.runtime.compose) + implementation(libs.androidx.lifecycle.viewmodel.compose) - // Compose - implementation(libs.androidx.compose.ui) - implementation(libs.androidx.compose.ui.tooling.preview) - implementation(libs.androidx.compose.material3) - implementation(libs.androidx.compose.material.icons.extended) - // Tooling - debugImplementation(libs.androidx.compose.ui.tooling) - // Instrumented tests - androidTestImplementation(libs.androidx.compose.ui.test.junit4) - debugImplementation(libs.androidx.compose.ui.test.manifest) + // Compose + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.compose.material3) + implementation(libs.androidx.compose.material.icons.extended) + // Tooling + debugImplementation(libs.androidx.compose.ui.tooling) + debugImplementation(libs.leakcanary.android) + // Instrumented tests + androidTestImplementation(libs.androidx.compose.ui.test.junit4) + debugImplementation(libs.androidx.compose.ui.test.manifest) - // Networking - implementation(libs.okhttp) - implementation(libs.okhttp.logging) - implementation(libs.retrofit) - implementation(libs.retrofit.converter.gson) - implementation(libs.gson) + // Networking + implementation(libs.okhttp) + debugImplementation(libs.okhttp.logging) + implementation(libs.retrofit) + implementation(libs.retrofit.converter.gson) + implementation(libs.gson) - // Encrypted storage - implementation(libs.androidx.security.crypto) - implementation("androidx.startup:startup-runtime:1.1.1") + // Encrypted storage + implementation(libs.androidx.security.crypto) + implementation("androidx.startup:startup-runtime:1.1.1") - // Local database (Room) — message persistence - implementation(libs.androidx.room.runtime) - implementation(libs.androidx.room.ktx) - ksp(libs.androidx.room.compiler) + // Local database (Room) — message persistence + implementation(libs.androidx.room.runtime) + implementation(libs.androidx.room.ktx) + ksp(libs.androidx.room.compiler) - // Local tests: jUnit, coroutines, Android runner - testImplementation(libs.junit) - testImplementation(libs.junit.jupiter.api) - testRuntimeOnly(libs.junit.jupiter.engine) - testRuntimeOnly(libs.junit.vintage.engine) - testRuntimeOnly(libs.junit.platform.launcher) - testImplementation(libs.okhttp.mockwebserver) - testImplementation(libs.kotlinx.coroutines.test) - testImplementation(libs.mockk) + // Local tests: jUnit, coroutines, Android runner + testImplementation(libs.junit) + testImplementation(libs.junit.jupiter.api) + testRuntimeOnly(libs.junit.jupiter.engine) + testRuntimeOnly(libs.junit.vintage.engine) + testRuntimeOnly(libs.junit.platform.launcher) + testImplementation(libs.okhttp.mockwebserver) + testImplementation(libs.kotlinx.coroutines.test) + testImplementation(libs.mockk) - // Instrumented tests: jUnit rules and runners - androidTestImplementation(libs.androidx.test.core) - androidTestImplementation(libs.androidx.test.ext.junit) - androidTestImplementation(libs.androidx.test.runner) - androidTestImplementation(libs.androidx.test.espresso.core) - androidTestImplementation(libs.mockk.android) + // Instrumented tests: jUnit rules and runners + androidTestImplementation(libs.androidx.test.core) + androidTestImplementation(libs.androidx.test.ext.junit) + androidTestImplementation(libs.androidx.test.runner) + androidTestImplementation(libs.androidx.test.espresso.core) + androidTestImplementation(libs.mockk.android) - // Navigation - implementation(libs.androidx.navigation3.ui) - implementation(libs.androidx.navigation3.runtime) - implementation(libs.androidx.lifecycle.viewmodel.navigation3) + // Navigation + implementation(libs.androidx.navigation3.ui) + implementation(libs.androidx.navigation3.runtime) + implementation(libs.androidx.lifecycle.viewmodel.navigation3) } tasks.register("ktlintCheck") { diff --git a/app/src/main/java/com/m57/hermescontrol/data/local/AuthManager.kt b/app/src/main/java/com/m57/hermescontrol/data/local/AuthManager.kt index 78deba70..f2eccc7e 100644 --- a/app/src/main/java/com/m57/hermescontrol/data/local/AuthManager.kt +++ b/app/src/main/java/com/m57/hermescontrol/data/local/AuthManager.kt @@ -3,7 +3,7 @@ package com.m57.hermescontrol.data.local import android.content.Context import android.content.SharedPreferences import androidx.security.crypto.EncryptedSharedPreferences -import androidx.security.crypto.MasterKey +import androidx.security.crypto.MasterKeys import com.m57.hermescontrol.theme.BottomNavDisplayMode import com.m57.hermescontrol.theme.ThemePreference import com.m57.hermescontrol.theme.ThemePreset @@ -68,16 +68,13 @@ object AuthManager { synchronized(this) { if (prefs != null) return val masterKey = - MasterKey - .Builder(context.applicationContext) - .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) - .build() + MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) prefs = EncryptedSharedPreferences.create( - context.applicationContext, PREFS_FILE, masterKey, + context.applicationContext, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM, ) diff --git a/app/src/test/java/com/m57/hermescontrol/data/local/AuthManagerTest.kt b/app/src/test/java/com/m57/hermescontrol/data/local/AuthManagerTest.kt index 96e0d64f..96cea770 100644 --- a/app/src/test/java/com/m57/hermescontrol/data/local/AuthManagerTest.kt +++ b/app/src/test/java/com/m57/hermescontrol/data/local/AuthManagerTest.kt @@ -3,7 +3,7 @@ package com.m57.hermescontrol.data.local import android.content.Context import android.content.SharedPreferences import androidx.security.crypto.EncryptedSharedPreferences -import androidx.security.crypto.MasterKey +import androidx.security.crypto.MasterKeys import io.mockk.* import org.junit.After import org.junit.Assert.assertEquals @@ -31,18 +31,16 @@ class AuthManagerTest { mockkStatic(EncryptedSharedPreferences::class) every { EncryptedSharedPreferences.create( - any(), any(), - any(), + any(), + any(), any(), any(), ) } returns mockPrefs - // Mock MasterKey.Builder constructor and its build method - mockkConstructor(MasterKey.Builder::class) - val mockMasterKey = mockk(relaxed = true) - every { anyConstructed().build() } returns mockMasterKey + mockkStatic(MasterKeys::class) + every { MasterKeys.getOrCreate(any()) } returns "mockMasterKey" // Reset prefs singleton instance using reflection val field = AuthManager::class.java.getDeclaredField("prefs") diff --git a/build.gradle.kts b/build.gradle.kts index bb92a46f..8d88dee5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - alias(libs.plugins.android.application) apply false - alias(libs.plugins.compose.compiler) apply false - alias(libs.plugins.kotlin.serialization) apply false -} \ No newline at end of file + alias(libs.plugins.android.application) apply false + alias(libs.plugins.compose.compiler) apply false + alias(libs.plugins.kotlin.serialization) apply false +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 831314cb..ef6eb18a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -18,10 +18,11 @@ kotlin = "2.3.20" ksp = "2.3.9" nav3Core = "1.0.1" lifecycleViewmodelNav3 = "2.10.0" +leakcanary = "2.14" okhttp = "4.12.0" retrofit = "2.11.0" gson = "2.11.0" -securityCrypto = "1.1.0-alpha06" +securityCrypto = "1.0.0" mockk = "1.13.12" room = "2.7.1" @@ -49,6 +50,7 @@ junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", vers junit-vintage-engine = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit5" } junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junitPlatform" } kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } +leakcanary-android = { module = "com.squareup.leakcanary:leakcanary-android", version.ref = "leakcanary" } mockk = { module = "io.mockk:mockk", version.ref = "mockk" } mockk-android = { module = "io.mockk:mockk-android", version.ref = "mockk" } androidx-navigation3-runtime = { module = "androidx.navigation3:navigation3-runtime", version.ref = "nav3Core" }