From ac0dd4525dd38ccf442eaf7e303435c32077a095 Mon Sep 17 00:00:00 2001 From: Altay Iskender Date: Wed, 26 Nov 2025 15:59:50 +0300 Subject: [PATCH 1/4] Maintenance: Bump dependencies - Update Kotlin to 2.2.21 - Update Android Gradle Plugin to 8.13.1 - Update Gradle to 8.14.3 - Set JVM target to 17 - Update sample app `compileSdk` and `targetSdk` to 36 - Update sample app `minSdk` to 23 - Update `androidx.activity:activity-ktx` to 1.12.0 - Add edge-to-edge support in the sample app --- gradle/libs.versions.toml | 9 +++++---- gradle/wrapper/gradle-wrapper.properties | 2 +- sampleapp/build.gradle.kts | 19 +++++++------------ .../sampleapp/MainActivity.kt | 15 +++++++++++++++ secretsvaultplugin/build.gradle.kts | 11 ++--------- 5 files changed, 30 insertions(+), 26 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a48c982..20f2ad3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,9 +1,10 @@ [versions] -kotlin = "1.8.21" -androidGradlePlugin = "8.0.1" +kotlin = "2.2.21" +androidGradlePlugin = "8.13.1" gradlePublish = "1.2.0" detekt = "1.22.0" kotlinxSerializationJson = "1.5.1" +jvmTarget = "17" [libraries] # Android Gradle Api Plugin @@ -17,7 +18,7 @@ detekt-formating = { group = "io.gitlab.arturbosch.detekt", name = "detekt-forma detekt-rules = { group = "io.gitlab.arturbosch.detekt", name = "detekt-rules", version.ref = "detekt" } # Sample App -androidx-activityKtx = { module = "androidx.activity:activity-ktx", version = "1.7.2" } +androidx-activityKtx = { module = "androidx.activity:activity-ktx", version = "1.12.0" } [plugins] android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } @@ -28,4 +29,4 @@ gradle-publish = { id = "com.gradle.plugin-publish", version.ref = "gradlePublis detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } [bundles] -detekt = ["detekt.formating", "detekt.rules"] +detekt = ["detekt-formating", "detekt-rules"] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fae0804..e69d040 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/sampleapp/build.gradle.kts b/sampleapp/build.gradle.kts index db7208b..3f31a20 100644 --- a/sampleapp/build.gradle.kts +++ b/sampleapp/build.gradle.kts @@ -1,5 +1,3 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) @@ -8,12 +6,12 @@ plugins { android { namespace = "com.commencis.secretsvaultplugin.sampleapp" - compileSdk = 33 + compileSdk = 36 defaultConfig { applicationId = "com.commencis.secretsvaultplugin.sampleapp" - minSdk = 21 - targetSdk = 33 + minSdk = 23 + targetSdk = 36 versionCode = 1 versionName = "1.0" @@ -50,11 +48,6 @@ android { } } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - externalNativeBuild { cmake { path("src/main/cpp/CMakeLists.txt") @@ -80,9 +73,11 @@ android { } } } +} - kotlinOptions { - jvmTarget = JvmTarget.JVM_11.target +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(libs.versions.jvmTarget.get())) } } diff --git a/sampleapp/src/main/kotlin/com/commencis/secretsvaultplugin/sampleapp/MainActivity.kt b/sampleapp/src/main/kotlin/com/commencis/secretsvaultplugin/sampleapp/MainActivity.kt index 296abda..0ab8099 100644 --- a/sampleapp/src/main/kotlin/com/commencis/secretsvaultplugin/sampleapp/MainActivity.kt +++ b/sampleapp/src/main/kotlin/com/commencis/secretsvaultplugin/sampleapp/MainActivity.kt @@ -6,6 +6,9 @@ import android.view.ViewGroup import android.widget.ScrollView import android.widget.TextView import androidx.activity.ComponentActivity +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updateLayoutParams internal class MainActivity : ComponentActivity() { @@ -51,6 +54,18 @@ internal class MainActivity : ComponentActivity() { ViewGroup.LayoutParams.MATCH_PARENT, ) ) + + ViewCompat.setOnApplyWindowInsetsListener(scrollView) { v, windowInsets -> + val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + v.updateLayoutParams { + topMargin = insets.top + leftMargin = insets.left + bottomMargin = insets.bottom + rightMargin = insets.right + } + WindowInsetsCompat.CONSUMED + } + } } diff --git a/secretsvaultplugin/build.gradle.kts b/secretsvaultplugin/build.gradle.kts index 3488f14..2ddca2d 100644 --- a/secretsvaultplugin/build.gradle.kts +++ b/secretsvaultplugin/build.gradle.kts @@ -1,6 +1,4 @@ import io.gitlab.arturbosch.detekt.extensions.DetektExtension -import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { alias(libs.plugins.gradle.publish) @@ -17,13 +15,8 @@ dependencies { } java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 -} - -tasks.withType().configureEach { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) + toolchain { + languageVersion.set(JavaLanguageVersion.of(libs.versions.jvmTarget.get())) } } From 93f0f368d71373084ac1d2e85c63d0c8c1e30222 Mon Sep 17 00:00:00 2001 From: Altay Iskender Date: Wed, 26 Nov 2025 16:40:03 +0300 Subject: [PATCH 2/4] Refactor: Modernize gradle task inputs for configuration cache compatibility --- .../secretsvaultplugin/KeepSecretsTask.kt | 135 +++++++++++------- .../secretsvaultplugin/SecretsVaultPlugin.kt | 30 +++- .../extensions/SecretsVaultExtension.kt | 6 +- 3 files changed, 111 insertions(+), 60 deletions(-) diff --git a/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/KeepSecretsTask.kt b/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/KeepSecretsTask.kt index 2756117..df92c5c 100644 --- a/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/KeepSecretsTask.kt +++ b/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/KeepSecretsTask.kt @@ -1,7 +1,5 @@ package com.commencis.secretsvaultplugin -import com.android.build.api.dsl.CommonExtension -import com.commencis.secretsvaultplugin.extensions.SecretsVaultExtension import com.commencis.secretsvaultplugin.utils.CHECK_APP_SIGNATURE_PLACEHOLDER import com.commencis.secretsvaultplugin.utils.CodeGenerator import com.commencis.secretsvaultplugin.utils.EMPTY_STRING @@ -9,14 +7,22 @@ import com.commencis.secretsvaultplugin.utils.Utils import com.commencis.secretsvaultplugin.utils.capitalize import kotlinx.serialization.json.Json import org.gradle.api.DefaultTask +import org.gradle.api.file.Directory +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.ProjectLayout +import org.gradle.api.file.RegularFileProperty +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.Internal +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.Optional import org.gradle.api.tasks.TaskAction import java.io.File import java.io.IOException import java.nio.charset.Charset import java.util.Locale +import javax.inject.Inject internal const val MAIN_SOURCE_SET_NAME = "main" @@ -52,62 +58,83 @@ private const val ANSI_COLOR_YELLOW = "\u001B[33m" * replaces them with obfuscated keys from the provided json file. */ @Suppress("TooManyFunctions", "UnnecessaryAbstractClass") -internal abstract class KeepSecretsTask : DefaultTask() { +internal abstract class KeepSecretsTask @Inject constructor(private val projectLayout: ProjectLayout) : DefaultTask() { /** - * Map containing the secrets + * Plugin source directory that has the cpp and kotlin files */ - private var secretsMap: Map>? = null + @get:InputDirectory + abstract val pluginSourceFolder: DirectoryProperty /** - * Map containing the source sets and their respective secrets file names + * The secrets file to read from */ - private var sourceSetToSecretFileMap: Map>? = null + @get:InputFile + abstract val secretsFile: RegularFileProperty /** - * Plugin source folder that has the cpp and kotlin files + * Optional mapping file for source sets to secret file names */ - @get:InputDirectory - abstract val pluginSourceFolder: Property + @get:InputFile + @get:Optional + abstract val sourceSetSecretsMappingFile: RegularFileProperty /** - * Represents the JSON property of the class it's abstracted in. + * The obfuscation key */ - @get:Internal - abstract val json: Property + @get:Input + abstract val obfuscationKey: Property /** - * Provides lazy access to the [SecretsVaultExtension] of the project. + * List of application signatures */ - private val secretsVaultExtension by lazy { - project.extensions.getByType(SecretsVaultExtension::class.java) - } + @get:Input + abstract val appSignatures: ListProperty /** - * Provides lazy access to the [CMakeExtension] of the project. + * The package name */ - private val cMakeExtension by lazy { - secretsVaultExtension.cmake.get() - } + @get:Input + abstract val packageName: Property /** - * Get the package name of the module on which this plugin is used - * - * The function will first attempt to get the package name from the [SecretsVaultExtension]. - * If it's not provided (i.e., it's an empty string), the function will attempt to get the namespace - * from the [CommonExtension] of the project. + * Whether to make the generated class injectable */ - private val packageName: String by lazy { - secretsVaultExtension.packageName.getOrElse(EMPTY_STRING).ifEmpty { - project.extensions.getByType(CommonExtension::class.java).namespace.orEmpty() - } - } + @get:Input + abstract val makeInjectable: Property + + /** + * CMake project name + */ + @get:Input + abstract val cmakeProjectName: Property + + /** + * CMake version + */ + @get:Input + abstract val cmakeVersion: Property + + private val projectDirectory: Directory + get() = projectLayout.projectDirectory /** * Lazily initialized instance of [CodeGenerator]. */ private val codeGenerator by lazy { CodeGenerator() } + private val json = Json { encodeDefaults = true } + + /** + * Map containing the secrets + */ + private var secretsMap: Map>? = null + + /** + * Map containing the source sets and their respective secrets file names + */ + private var sourceSetToSecretFileMap: Map>? = null + /** * The main task action which is responsible for keeping secrets */ @@ -135,7 +162,7 @@ internal abstract class KeepSecretsTask : DefaultTask() { */ @Throws(IllegalArgumentException::class) private fun getSecretsFile(): File { - val secretsFile = secretsVaultExtension.secretsFile.get() + val secretsFile = secretsFile.get().asFile require(secretsFile.exists() && secretsFile.isFile) { "${secretsFile.name} does not exist or is not a valid file!" } @@ -150,7 +177,7 @@ internal abstract class KeepSecretsTask : DefaultTask() { */ @Throws(IllegalArgumentException::class) private fun getSourceSetToSecretMappingFile(): File? { - val mappingFile = secretsVaultExtension.sourceSetSecretsMappingFile.orNull + val mappingFile = sourceSetSecretsMappingFile.orNull?.asFile if (mappingFile != null) { require(mappingFile.exists() && mappingFile.isFile) { "${mappingFile.name} does not exist or is not a valid file!" @@ -167,7 +194,7 @@ internal abstract class KeepSecretsTask : DefaultTask() { private fun initSecretsFromFile(secretsFile: File) { val content = secretsFile.readText(Charsets.UTF_8) runCatching { - secretsMap = json.get().decodeFromString(content).secrets.groupBy { it.sourceSet } + secretsMap = json.decodeFromString(content).secrets.groupBy { it.sourceSet } }.onFailure { throwable -> logger.error( """ @@ -193,7 +220,7 @@ internal abstract class KeepSecretsTask : DefaultTask() { private fun initSourceSetToSecretFileMap(mappingFile: File) { val content = mappingFile.readText(Charsets.UTF_8) runCatching { - sourceSetToSecretFileMap = json.get().decodeFromString(content).toMap() + sourceSetToSecretFileMap = json.decodeFromString(content).toMap() if (sourceSetToSecretFileMap?.any { it.value.first.name == MAIN_SOURCE_SET_SECRETS_FILE_NAME } == true) { logger.error( """ @@ -236,7 +263,9 @@ internal abstract class KeepSecretsTask : DefaultTask() { fileName: String, pathSuffix: String = EMPTY_STRING, ): File { - return project.file(SOURCE_SET_TEMPLATE.format(sourceSet.sourceSet, "cpp") + pathSuffix + fileName) + return projectDirectory + .file(SOURCE_SET_TEMPLATE.format(sourceSet.sourceSet, "cpp") + pathSuffix + fileName) + .asFile } /** @@ -249,11 +278,11 @@ internal abstract class KeepSecretsTask : DefaultTask() { private fun getKotlinDestination(sourceSet: SecretsSourceSet, fileName: String): File { val kotlinPath = SOURCE_SET_TEMPLATE.format(sourceSet.sourceSet, "kotlin") val javaPath = SOURCE_SET_TEMPLATE.format(sourceSet.sourceSet, "java") - val basePath = kotlinPath.takeIf { project.file(kotlinPath).exists() } ?: javaPath - val packagePath = packageName.replace(".", File.separator) + val basePath = kotlinPath.takeIf { projectDirectory.file(kotlinPath).asFile.exists() } ?: javaPath + val packagePath = packageName.get().replace(".", File.separator) val fullPath = basePath + packagePath - val directory = project.file(fullPath) + val directory = projectDirectory.file(fullPath).asFile if (directory.exists().not()) { logger.lifecycle("Directory $fullPath does not exist in the project, creating it.") directory.mkdirs() @@ -267,18 +296,18 @@ internal abstract class KeepSecretsTask : DefaultTask() { */ private fun copyCommonCppFiles() { runCatching { - val appSignaturesCodeBlock = secretsVaultExtension.appSignatures.get().map { appSignature -> + val appSignaturesCodeBlock = appSignatures.get().map { appSignature -> Utils.encodeSecret( secretKey = appSignature.replace(":", EMPTY_STRING), - obfuscationKey = secretsVaultExtension.obfuscationKey.get(), + obfuscationKey = obfuscationKey.get(), ) }.let { encodedAppSignatures -> codeGenerator.getAppSignatureCheck(encodedAppSignatures) } - project.file("${pluginSourceFolder.get().path}/cpp/common/").listFiles()?.forEach { file -> + pluginSourceFolder.dir("cpp/common/").get().asFile.listFiles()?.forEach { file -> var text = file.readText(Charset.defaultCharset()) if (file.name == SECRETS_UTIL_CPP_FILE_NAME) { - text = text.replace(OBFUSCATION_KEY_PLACEHOLDER, secretsVaultExtension.obfuscationKey.get()) + text = text.replace(OBFUSCATION_KEY_PLACEHOLDER, obfuscationKey.get()) .replace(CHECK_APP_SIGNATURE_PLACEHOLDER, appSignaturesCodeBlock) } val destination = getCppDestination( @@ -302,7 +331,7 @@ internal abstract class KeepSecretsTask : DefaultTask() { */ private fun copySecretCppFile(sourceSet: SecretsSourceSet) { runCatching { - val secretsFile = project.file("${pluginSourceFolder.get().path}/cpp/$SECRETS_CPP_FILE_NAME") + val secretsFile = pluginSourceFolder.dir("cpp/$SECRETS_CPP_FILE_NAME").get().asFile val text = secretsFile.readText(Charset.defaultCharset()).replace( oldValue = COMMON_FOLDER_PATH_PREFIX_PLACEHOLDER, newValue = if (sourceSet == SecretsSourceSet(MAIN_SOURCE_SET_NAME)) { @@ -328,11 +357,11 @@ internal abstract class KeepSecretsTask : DefaultTask() { private fun copyCMakeListsFile(sourceSets: Set) { runCatching { val mainSourceSet = SecretsSourceSet(MAIN_SOURCE_SET_NAME) - val file = project.file("${pluginSourceFolder.get().path}/cpp/$C_MAKE_LISTS_FILE_NAME") + val file = pluginSourceFolder.dir("cpp/$C_MAKE_LISTS_FILE_NAME").get().asFile val textBuilder = StringBuilder( file.readText(Charset.defaultCharset()) - .replace(PROJECT_NAME_PLACEHOLDER, cMakeExtension.projectName.get()) - .replace(CMAKE_VERSION_PLACEHOLDER, cMakeExtension.version.get()) + .replace(PROJECT_NAME_PLACEHOLDER, cmakeProjectName.get()) + .replace(CMAKE_VERSION_PLACEHOLDER, cmakeVersion.get()) ) if (sourceSets.contains(mainSourceSet)) { val fileName = getKotlinSecretsFileName(mainSourceSet).removeSuffix(KOTLIN_FILE_NAME_SUFFIX) @@ -378,18 +407,18 @@ internal abstract class KeepSecretsTask : DefaultTask() { private fun copyKotlinFile(sourceSet: SecretsSourceSet) { runCatching { - val kotlinFileName = if (secretsVaultExtension.makeInjectable.get()) { + val kotlinFileName = if (makeInjectable.get()) { TEMP_KOTLIN_INJECTABLE_FILE_NAME } else { TEMP_KOTLIN_NOT_INJECTABLE_FILE_NAME } - val kotlinFiles = project.file("${pluginSourceFolder.get().path}/kotlin/").listFiles() + val kotlinFiles = pluginSourceFolder.dir("kotlin").get().asFile.listFiles() val kotlinFile = kotlinFiles?.find { file -> file.name == kotlinFileName } ?: throw IOException("Kotlin file that will be copied not found") var text = kotlinFile.readText(Charset.defaultCharset()) val fileName = getKotlinSecretsFileName(sourceSet) - text = text.replace(PACKAGE_PLACEHOLDER, packageName) + text = text.replace(PACKAGE_PLACEHOLDER, packageName.get()) .replace(SECRETS_CLASS_NAME_PLACEHOLDER, fileName.removeSuffix(KOTLIN_FILE_NAME_SUFFIX)) val destination = getKotlinDestination( sourceSet = sourceSet, @@ -480,13 +509,13 @@ internal abstract class KeepSecretsTask : DefaultTask() { var kotlinPackage = Utils.getKotlinFilePackage(secretsKotlin) if (kotlinPackage.isNullOrEmpty()) { logWarning("Empty package in $fileName") - kotlinPackage = packageName + kotlinPackage = packageName.get() } val secretsCpp = getCppDestination(sourceSet = sourceSet, fileName = SECRETS_CPP_FILE_NAME) secrets.forEach { secret -> val (key, value) = secret - val obfuscatedValue = Utils.encodeSecret(value, secretsVaultExtension.obfuscationKey.get()) + val obfuscatedValue = Utils.encodeSecret(value, obfuscationKey.get()) val cppText = secretsCpp.readText(Charset.defaultCharset()) val keyName = "$JVM_NAME_PREFIX${secretKeyToIndexMap[key]}" if (cppText.contains(keyName)) { diff --git a/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt b/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt index 2cc666a..f772f25 100644 --- a/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt +++ b/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt @@ -1,9 +1,10 @@ package com.commencis.secretsvaultplugin +import com.android.build.api.dsl.CommonExtension import com.commencis.secretsvaultplugin.extensions.CMakeExtension import com.commencis.secretsvaultplugin.extensions.SecretsVaultExtension +import com.commencis.secretsvaultplugin.utils.EMPTY_STRING import com.commencis.secretsvaultplugin.utils.Utils -import kotlinx.serialization.json.Json import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.tasks.Copy @@ -57,14 +58,35 @@ internal class SecretsVaultPlugin : Plugin { into(project.layout.buildDirectory.dir("intermediates/secrets_vault_plugin")) } + val secretsVaultExtension = project.extensions.getByType(SecretsVaultExtension::class.java) + /** * Create a gradle task to keep secrets from a json file. */ project.tasks.register(TASK_KEEP_SECRETS_FROM_JSON_FILE, KeepSecretsTask::class.java).configure { group = TASK_GROUP description = "Re-generate and obfuscate keys from the json file and add it to your Android project" - pluginSourceFolder.set(unzipTaskProvider.map { task -> task.destinationDir }) - json.set(Json { encodeDefaults = true }) + pluginSourceFolder.set( + unzipTaskProvider.map { + project.layout.projectDirectory.dir(it.destinationDir.path) + } + ) + secretsFile.set(secretsVaultExtension.secretsFile) + sourceSetSecretsMappingFile.set(secretsVaultExtension.sourceSetSecretsMappingFile) + obfuscationKey.set(secretsVaultExtension.obfuscationKey) + appSignatures.set(secretsVaultExtension.appSignatures) + makeInjectable.set(secretsVaultExtension.makeInjectable) + + // Provide the package name in the extension unless it is not specified or empty, + // in which case the namespace is used. + packageName.set( + secretsVaultExtension.packageName.getOrElse(EMPTY_STRING).ifEmpty { + project.extensions.getByType(CommonExtension::class.java).namespace.orEmpty() + } + ) + + cmakeProjectName.set(secretsVaultExtension.cmake.flatMap { it.projectName }) + cmakeVersion.set(secretsVaultExtension.cmake.flatMap { it.version }) } } @@ -91,7 +113,7 @@ internal class SecretsVaultPlugin : Plugin { private fun createSecretsVaultExtension(project: Project, cmakeExtension: CMakeExtension): SecretsVaultExtension { return project.extensions.create(EXTENSION_NAME_SECRETS_VAULT, SecretsVaultExtension::class.java).apply { obfuscationKey.convention(Utils.generateObfuscationKey()) - secretsFile.convention(project.file(DEFAULT_SECRETS_FILE_NAME)) + secretsFile.convention(project.layout.projectDirectory.file(DEFAULT_SECRETS_FILE_NAME)) appSignatures.convention(emptyList()) makeInjectable.convention(DEFAULT_MAKE_INJECTABLE_VALUE) cmake.convention(cmakeExtension) diff --git a/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/extensions/SecretsVaultExtension.kt b/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/extensions/SecretsVaultExtension.kt index 58f91b6..26360fd 100644 --- a/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/extensions/SecretsVaultExtension.kt +++ b/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/extensions/SecretsVaultExtension.kt @@ -1,9 +1,9 @@ package com.commencis.secretsvaultplugin.extensions import com.commencis.secretsvaultplugin.utils.EMPTY_STRING +import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property -import java.io.File /** * Provides extension properties for the SecretVault, allowing configurations to be set. @@ -25,8 +25,8 @@ import java.io.File */ interface SecretsVaultExtension { val obfuscationKey: Property - val secretsFile: Property - val sourceSetSecretsMappingFile: Property + val secretsFile: RegularFileProperty + val sourceSetSecretsMappingFile: RegularFileProperty val appSignatures: ListProperty val packageName: Property val makeInjectable: Property From c03aa936234935b80c5435efae4f870d3c6bb75d Mon Sep 17 00:00:00 2001 From: Iskender Date: Wed, 26 Nov 2025 17:16:15 +0300 Subject: [PATCH 3/4] Detekt: Update detekt version to 1.23.8 Fix new issues --- gradle/libs.versions.toml | 2 +- .../commencis/secretsvaultplugin/SecretsVaultPlugin.kt | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 20f2ad3..3ba75fa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ kotlin = "2.2.21" androidGradlePlugin = "8.13.1" gradlePublish = "1.2.0" -detekt = "1.22.0" +detekt = "1.23.8" kotlinxSerializationJson = "1.5.1" jvmTarget = "17" diff --git a/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt b/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt index f772f25..3603f56 100644 --- a/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt +++ b/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt @@ -67,8 +67,8 @@ internal class SecretsVaultPlugin : Plugin { group = TASK_GROUP description = "Re-generate and obfuscate keys from the json file and add it to your Android project" pluginSourceFolder.set( - unzipTaskProvider.map { - project.layout.projectDirectory.dir(it.destinationDir.path) + unzipTaskProvider.map { copyTask -> + project.layout.projectDirectory.dir(copyTask.destinationDir.path) } ) secretsFile.set(secretsVaultExtension.secretsFile) @@ -85,8 +85,8 @@ internal class SecretsVaultPlugin : Plugin { } ) - cmakeProjectName.set(secretsVaultExtension.cmake.flatMap { it.projectName }) - cmakeVersion.set(secretsVaultExtension.cmake.flatMap { it.version }) + cmakeProjectName.set(secretsVaultExtension.cmake.flatMap { cMakeExtension -> cMakeExtension.projectName }) + cmakeVersion.set(secretsVaultExtension.cmake.flatMap { cMakeExtension -> cMakeExtension.version }) } } From 461af112b63b4327b11faa06adb87ef4f4b92b94 Mon Sep 17 00:00:00 2001 From: Iskender Date: Wed, 26 Nov 2025 21:44:54 +0300 Subject: [PATCH 4/4] Refactor: Simplify package name and plugin source folder retrieval - Use `orElse` with namespace provider to lazily get the package name - Simplify setting the `pluginSourceFolder` path. --- .../secretsvaultplugin/SecretsVaultPlugin.kt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt b/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt index 3603f56..c0c8510 100644 --- a/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt +++ b/secretsvaultplugin/src/main/kotlin/com/commencis/secretsvaultplugin/SecretsVaultPlugin.kt @@ -3,7 +3,6 @@ package com.commencis.secretsvaultplugin import com.android.build.api.dsl.CommonExtension import com.commencis.secretsvaultplugin.extensions.CMakeExtension import com.commencis.secretsvaultplugin.extensions.SecretsVaultExtension -import com.commencis.secretsvaultplugin.utils.EMPTY_STRING import com.commencis.secretsvaultplugin.utils.Utils import org.gradle.api.Plugin import org.gradle.api.Project @@ -67,9 +66,9 @@ internal class SecretsVaultPlugin : Plugin { group = TASK_GROUP description = "Re-generate and obfuscate keys from the json file and add it to your Android project" pluginSourceFolder.set( - unzipTaskProvider.map { copyTask -> - project.layout.projectDirectory.dir(copyTask.destinationDir.path) - } + project.layout.projectDirectory.dir( + unzipTaskProvider.map { task -> task.destinationDir.absolutePath } + ) ) secretsFile.set(secretsVaultExtension.secretsFile) sourceSetSecretsMappingFile.set(secretsVaultExtension.sourceSetSecretsMappingFile) @@ -77,12 +76,14 @@ internal class SecretsVaultPlugin : Plugin { appSignatures.set(secretsVaultExtension.appSignatures) makeInjectable.set(secretsVaultExtension.makeInjectable) - // Provide the package name in the extension unless it is not specified or empty, + // Provide the package name in the extension unless it is not specified, // in which case the namespace is used. packageName.set( - secretsVaultExtension.packageName.getOrElse(EMPTY_STRING).ifEmpty { - project.extensions.getByType(CommonExtension::class.java).namespace.orEmpty() - } + secretsVaultExtension.packageName.orElse( + project.provider { + project.extensions.findByType(CommonExtension::class.java)?.namespace.orEmpty() + } + ) ) cmakeProjectName.set(secretsVaultExtension.cmake.flatMap { cMakeExtension -> cMakeExtension.projectName })