11package com.commencis.secretsvaultplugin
22
3- import com.android.build.api.dsl.CommonExtension
4- import com.commencis.secretsvaultplugin.extensions.SecretsVaultExtension
53import com.commencis.secretsvaultplugin.utils.CHECK_APP_SIGNATURE_PLACEHOLDER
64import com.commencis.secretsvaultplugin.utils.CodeGenerator
75import com.commencis.secretsvaultplugin.utils.EMPTY_STRING
86import com.commencis.secretsvaultplugin.utils.Utils
97import com.commencis.secretsvaultplugin.utils.capitalize
108import kotlinx.serialization.json.Json
119import org.gradle.api.DefaultTask
10+ import org.gradle.api.file.Directory
11+ import org.gradle.api.file.DirectoryProperty
12+ import org.gradle.api.file.ProjectLayout
13+ import org.gradle.api.file.RegularFileProperty
14+ import org.gradle.api.provider.ListProperty
1215import org.gradle.api.provider.Property
16+ import org.gradle.api.tasks.Input
1317import org.gradle.api.tasks.InputDirectory
14- import org.gradle.api.tasks.Internal
18+ import org.gradle.api.tasks.InputFile
19+ import org.gradle.api.tasks.Optional
1520import org.gradle.api.tasks.TaskAction
1621import java.io.File
1722import java.io.IOException
1823import java.nio.charset.Charset
1924import java.util.Locale
25+ import javax.inject.Inject
2026
2127internal const val MAIN_SOURCE_SET_NAME = " main"
2228
@@ -52,62 +58,83 @@ private const val ANSI_COLOR_YELLOW = "\u001B[33m"
5258 * replaces them with obfuscated keys from the provided json file.
5359 */
5460@Suppress(" TooManyFunctions" , " UnnecessaryAbstractClass" )
55- internal abstract class KeepSecretsTask : DefaultTask () {
61+ internal abstract class KeepSecretsTask @Inject constructor( private val projectLayout : ProjectLayout ) : DefaultTask() {
5662
5763 /* *
58- * Map containing the secrets
64+ * Plugin source directory that has the cpp and kotlin files
5965 */
60- private var secretsMap: Map <SecretsSourceSet , List <Secret >>? = null
66+ @get:InputDirectory
67+ abstract val pluginSourceFolder: DirectoryProperty
6168
6269 /* *
63- * Map containing the source sets and their respective secrets file names
70+ * The secrets file to read from
6471 */
65- private var sourceSetToSecretFileMap: Map <SecretsSourceSet , Pair <SecretsFileName , CMakeArgument >>? = null
72+ @get:InputFile
73+ abstract val secretsFile: RegularFileProperty
6674
6775 /* *
68- * Plugin source folder that has the cpp and kotlin files
76+ * Optional mapping file for source sets to secret file names
6977 */
70- @get:InputDirectory
71- abstract val pluginSourceFolder: Property <File >
78+ @get:InputFile
79+ @get:Optional
80+ abstract val sourceSetSecretsMappingFile: RegularFileProperty
7281
7382 /* *
74- * Represents the JSON property of the class it's abstracted in.
83+ * The obfuscation key
7584 */
76- @get:Internal
77- abstract val json : Property <Json >
85+ @get:Input
86+ abstract val obfuscationKey : Property <String >
7887
7988 /* *
80- * Provides lazy access to the [SecretsVaultExtension] of the project.
89+ * List of application signatures
8190 */
82- private val secretsVaultExtension by lazy {
83- project.extensions.getByType(SecretsVaultExtension ::class .java)
84- }
91+ @get:Input
92+ abstract val appSignatures: ListProperty <String >
8593
8694 /* *
87- * Provides lazy access to the [CMakeExtension] of the project.
95+ * The package name
8896 */
89- private val cMakeExtension by lazy {
90- secretsVaultExtension.cmake.get()
91- }
97+ @get:Input
98+ abstract val packageName: Property <String >
9299
93100 /* *
94- * Get the package name of the module on which this plugin is used
95- *
96- * The function will first attempt to get the package name from the [SecretsVaultExtension].
97- * If it's not provided (i.e., it's an empty string), the function will attempt to get the namespace
98- * from the [CommonExtension] of the project.
101+ * Whether to make the generated class injectable
99102 */
100- private val packageName: String by lazy {
101- secretsVaultExtension.packageName.getOrElse(EMPTY_STRING ).ifEmpty {
102- project.extensions.getByType(CommonExtension ::class .java).namespace.orEmpty()
103- }
104- }
103+ @get:Input
104+ abstract val makeInjectable: Property <Boolean >
105+
106+ /* *
107+ * CMake project name
108+ */
109+ @get:Input
110+ abstract val cmakeProjectName: Property <String >
111+
112+ /* *
113+ * CMake version
114+ */
115+ @get:Input
116+ abstract val cmakeVersion: Property <String >
117+
118+ private val projectDirectory: Directory
119+ get() = projectLayout.projectDirectory
105120
106121 /* *
107122 * Lazily initialized instance of [CodeGenerator].
108123 */
109124 private val codeGenerator by lazy { CodeGenerator () }
110125
126+ private val json = Json { encodeDefaults = true }
127+
128+ /* *
129+ * Map containing the secrets
130+ */
131+ private var secretsMap: Map <SecretsSourceSet , List <Secret >>? = null
132+
133+ /* *
134+ * Map containing the source sets and their respective secrets file names
135+ */
136+ private var sourceSetToSecretFileMap: Map <SecretsSourceSet , Pair <SecretsFileName , CMakeArgument >>? = null
137+
111138 /* *
112139 * The main task action which is responsible for keeping secrets
113140 */
@@ -135,7 +162,7 @@ internal abstract class KeepSecretsTask : DefaultTask() {
135162 */
136163 @Throws(IllegalArgumentException ::class )
137164 private fun getSecretsFile (): File {
138- val secretsFile = secretsVaultExtension. secretsFile.get()
165+ val secretsFile = secretsFile.get().asFile
139166 require(secretsFile.exists() && secretsFile.isFile) {
140167 " ${secretsFile.name} does not exist or is not a valid file!"
141168 }
@@ -150,7 +177,7 @@ internal abstract class KeepSecretsTask : DefaultTask() {
150177 */
151178 @Throws(IllegalArgumentException ::class )
152179 private fun getSourceSetToSecretMappingFile (): File ? {
153- val mappingFile = secretsVaultExtension. sourceSetSecretsMappingFile.orNull
180+ val mappingFile = sourceSetSecretsMappingFile.orNull?.asFile
154181 if (mappingFile != null ) {
155182 require(mappingFile.exists() && mappingFile.isFile) {
156183 " ${mappingFile.name} does not exist or is not a valid file!"
@@ -167,7 +194,7 @@ internal abstract class KeepSecretsTask : DefaultTask() {
167194 private fun initSecretsFromFile (secretsFile : File ) {
168195 val content = secretsFile.readText(Charsets .UTF_8 )
169196 runCatching {
170- secretsMap = json.get(). decodeFromString<Secrets >(content).secrets.groupBy { it.sourceSet }
197+ secretsMap = json.decodeFromString<Secrets >(content).secrets.groupBy { it.sourceSet }
171198 }.onFailure { throwable ->
172199 logger.error(
173200 """
@@ -193,7 +220,7 @@ internal abstract class KeepSecretsTask : DefaultTask() {
193220 private fun initSourceSetToSecretFileMap (mappingFile : File ) {
194221 val content = mappingFile.readText(Charsets .UTF_8 )
195222 runCatching {
196- sourceSetToSecretFileMap = json.get(). decodeFromString<SourceSetToSecretFileMappingArray >(content).toMap()
223+ sourceSetToSecretFileMap = json.decodeFromString<SourceSetToSecretFileMappingArray >(content).toMap()
197224 if (sourceSetToSecretFileMap?.any { it.value.first.name == MAIN_SOURCE_SET_SECRETS_FILE_NAME } == true ) {
198225 logger.error(
199226 """
@@ -236,7 +263,9 @@ internal abstract class KeepSecretsTask : DefaultTask() {
236263 fileName : String ,
237264 pathSuffix : String = EMPTY_STRING ,
238265 ): File {
239- return project.file(SOURCE_SET_TEMPLATE .format(sourceSet.sourceSet, " cpp" ) + pathSuffix + fileName)
266+ return projectDirectory
267+ .file(SOURCE_SET_TEMPLATE .format(sourceSet.sourceSet, " cpp" ) + pathSuffix + fileName)
268+ .asFile
240269 }
241270
242271 /* *
@@ -249,11 +278,11 @@ internal abstract class KeepSecretsTask : DefaultTask() {
249278 private fun getKotlinDestination (sourceSet : SecretsSourceSet , fileName : String ): File {
250279 val kotlinPath = SOURCE_SET_TEMPLATE .format(sourceSet.sourceSet, " kotlin" )
251280 val javaPath = SOURCE_SET_TEMPLATE .format(sourceSet.sourceSet, " java" )
252- val basePath = kotlinPath.takeIf { project .file(kotlinPath).exists() } ? : javaPath
253- val packagePath = packageName.replace(" ." , File .separator)
281+ val basePath = kotlinPath.takeIf { projectDirectory .file(kotlinPath).asFile .exists() } ? : javaPath
282+ val packagePath = packageName.get(). replace(" ." , File .separator)
254283 val fullPath = basePath + packagePath
255284
256- val directory = project .file(fullPath)
285+ val directory = projectDirectory .file(fullPath).asFile
257286 if (directory.exists().not ()) {
258287 logger.lifecycle(" Directory $fullPath does not exist in the project, creating it." )
259288 directory.mkdirs()
@@ -267,18 +296,18 @@ internal abstract class KeepSecretsTask : DefaultTask() {
267296 */
268297 private fun copyCommonCppFiles () {
269298 runCatching {
270- val appSignaturesCodeBlock = secretsVaultExtension. appSignatures.get().map { appSignature ->
299+ val appSignaturesCodeBlock = appSignatures.get().map { appSignature ->
271300 Utils .encodeSecret(
272301 secretKey = appSignature.replace(" :" , EMPTY_STRING ),
273- obfuscationKey = secretsVaultExtension. obfuscationKey.get(),
302+ obfuscationKey = obfuscationKey.get(),
274303 )
275304 }.let { encodedAppSignatures ->
276305 codeGenerator.getAppSignatureCheck(encodedAppSignatures)
277306 }
278- project.file( " ${ pluginSourceFolder.get().path} / cpp/common/" ).listFiles()?.forEach { file ->
307+ pluginSourceFolder.dir( " cpp/common/" ).get().asFile .listFiles()?.forEach { file ->
279308 var text = file.readText(Charset .defaultCharset())
280309 if (file.name == SECRETS_UTIL_CPP_FILE_NAME ) {
281- text = text.replace(OBFUSCATION_KEY_PLACEHOLDER , secretsVaultExtension. obfuscationKey.get())
310+ text = text.replace(OBFUSCATION_KEY_PLACEHOLDER , obfuscationKey.get())
282311 .replace(CHECK_APP_SIGNATURE_PLACEHOLDER , appSignaturesCodeBlock)
283312 }
284313 val destination = getCppDestination(
@@ -302,7 +331,7 @@ internal abstract class KeepSecretsTask : DefaultTask() {
302331 */
303332 private fun copySecretCppFile (sourceSet : SecretsSourceSet ) {
304333 runCatching {
305- val secretsFile = project.file( " ${ pluginSourceFolder.get().path} / cpp/$SECRETS_CPP_FILE_NAME " )
334+ val secretsFile = pluginSourceFolder.dir( " cpp/$SECRETS_CPP_FILE_NAME " ).get().asFile
306335 val text = secretsFile.readText(Charset .defaultCharset()).replace(
307336 oldValue = COMMON_FOLDER_PATH_PREFIX_PLACEHOLDER ,
308337 newValue = if (sourceSet == SecretsSourceSet (MAIN_SOURCE_SET_NAME )) {
@@ -328,11 +357,11 @@ internal abstract class KeepSecretsTask : DefaultTask() {
328357 private fun copyCMakeListsFile (sourceSets : Set <SecretsSourceSet >) {
329358 runCatching {
330359 val mainSourceSet = SecretsSourceSet (MAIN_SOURCE_SET_NAME )
331- val file = project.file( " ${ pluginSourceFolder.get().path} / cpp/$C_MAKE_LISTS_FILE_NAME " )
360+ val file = pluginSourceFolder.dir( " cpp/$C_MAKE_LISTS_FILE_NAME " ).get().asFile
332361 val textBuilder = StringBuilder (
333362 file.readText(Charset .defaultCharset())
334- .replace(PROJECT_NAME_PLACEHOLDER , cMakeExtension.projectName .get())
335- .replace(CMAKE_VERSION_PLACEHOLDER , cMakeExtension.version .get())
363+ .replace(PROJECT_NAME_PLACEHOLDER , cmakeProjectName .get())
364+ .replace(CMAKE_VERSION_PLACEHOLDER , cmakeVersion .get())
336365 )
337366 if (sourceSets.contains(mainSourceSet)) {
338367 val fileName = getKotlinSecretsFileName(mainSourceSet).removeSuffix(KOTLIN_FILE_NAME_SUFFIX )
@@ -378,18 +407,18 @@ internal abstract class KeepSecretsTask : DefaultTask() {
378407
379408 private fun copyKotlinFile (sourceSet : SecretsSourceSet ) {
380409 runCatching {
381- val kotlinFileName = if (secretsVaultExtension. makeInjectable.get()) {
410+ val kotlinFileName = if (makeInjectable.get()) {
382411 TEMP_KOTLIN_INJECTABLE_FILE_NAME
383412 } else {
384413 TEMP_KOTLIN_NOT_INJECTABLE_FILE_NAME
385414 }
386- val kotlinFiles = project.file( " ${pluginSourceFolder .get().path} /kotlin/ " ) .listFiles()
415+ val kotlinFiles = pluginSourceFolder.dir( " kotlin " ) .get().asFile .listFiles()
387416 val kotlinFile = kotlinFiles?.find { file ->
388417 file.name == kotlinFileName
389418 } ? : throw IOException (" Kotlin file that will be copied not found" )
390419 var text = kotlinFile.readText(Charset .defaultCharset())
391420 val fileName = getKotlinSecretsFileName(sourceSet)
392- text = text.replace(PACKAGE_PLACEHOLDER , packageName)
421+ text = text.replace(PACKAGE_PLACEHOLDER , packageName.get() )
393422 .replace(SECRETS_CLASS_NAME_PLACEHOLDER , fileName.removeSuffix(KOTLIN_FILE_NAME_SUFFIX ))
394423 val destination = getKotlinDestination(
395424 sourceSet = sourceSet,
@@ -480,13 +509,13 @@ internal abstract class KeepSecretsTask : DefaultTask() {
480509 var kotlinPackage = Utils .getKotlinFilePackage(secretsKotlin)
481510 if (kotlinPackage.isNullOrEmpty()) {
482511 logWarning(" Empty package in $fileName " )
483- kotlinPackage = packageName
512+ kotlinPackage = packageName.get()
484513 }
485514
486515 val secretsCpp = getCppDestination(sourceSet = sourceSet, fileName = SECRETS_CPP_FILE_NAME )
487516 secrets.forEach { secret ->
488517 val (key, value) = secret
489- val obfuscatedValue = Utils .encodeSecret(value, secretsVaultExtension. obfuscationKey.get())
518+ val obfuscatedValue = Utils .encodeSecret(value, obfuscationKey.get())
490519 val cppText = secretsCpp.readText(Charset .defaultCharset())
491520 val keyName = " $JVM_NAME_PREFIX${secretKeyToIndexMap[key]} "
492521 if (cppText.contains(keyName)) {
0 commit comments