diff --git a/build.gradle b/build.gradle index 31d6f79..2d93452 100644 --- a/build.gradle +++ b/build.gradle @@ -2,13 +2,14 @@ buildscript { ext.kotlin_version = "1.4.32" repositories { + mavenLocal() google() mavenCentral() } dependencies { - classpath "com.android.tools.build:gradle:4.1.3" + classpath "com.android.tools.build:gradle:4.2.1" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:1.2.0" + classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:1.3.0" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fdd6bbf..a075ce2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip diff --git a/sample-app/build.gradle.kts b/sample-app/build.gradle.kts index 102f73b..7ca4ea3 100644 --- a/sample-app/build.gradle.kts +++ b/sample-app/build.gradle.kts @@ -22,7 +22,7 @@ plugins { android { compileSdkVersion(30) - buildToolsVersion = "29.0.3" + buildToolsVersion = "30.0.2" defaultConfig { applicationId = "com.google.secrets_plugin.sample" diff --git a/secrets-gradle-plugin/build.gradle.kts b/secrets-gradle-plugin/build.gradle.kts index 668f50b..77b3d76 100644 --- a/secrets-gradle-plugin/build.gradle.kts +++ b/secrets-gradle-plugin/build.gradle.kts @@ -25,9 +25,9 @@ java { } dependencies { - compileOnly("com.android.tools.build:gradle:4.1.1") + compileOnly("com.android.tools.build:gradle:4.2.1") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10") - testImplementation("com.android.tools.build:gradle:4.1.1") + testImplementation("com.android.tools.build:gradle:4.2.1") testImplementation("junit:junit:4.13.1") testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0") } diff --git a/secrets-gradle-plugin/src/main/java/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/Extensions.kt b/secrets-gradle-plugin/src/main/java/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/Extensions.kt index e29572f..c667b17 100644 --- a/secrets-gradle-plugin/src/main/java/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/Extensions.kt +++ b/secrets-gradle-plugin/src/main/java/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/Extensions.kt @@ -12,8 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +@file:Suppress("UnstableApiUsage") + package com.google.android.libraries.mapsplatform.secrets_gradle_plugin +import com.android.build.api.extension.ApplicationAndroidComponentsExtension +import com.android.build.api.extension.LibraryAndroidComponentsExtension +import com.android.build.api.variant.BuildConfigField +import com.android.build.api.variant.Variant import com.android.build.gradle.AppExtension import com.android.build.gradle.LibraryExtension import com.android.build.gradle.internal.core.InternalBaseVariant @@ -21,13 +27,19 @@ import org.gradle.api.Project import java.io.FileNotFoundException import java.util.Properties -fun Project.androidProject() : AppExtension? = +fun Project.androidAppComponent(): ApplicationAndroidComponentsExtension? = + extensions.findByType(ApplicationAndroidComponentsExtension::class.java) + +fun Project.androidLibraryComponent(): LibraryAndroidComponentsExtension? = + extensions.findByType(LibraryAndroidComponentsExtension::class.java) + +fun Project.androidProject(): AppExtension? = extensions.findByType(AppExtension::class.java) -fun Project.libraryProject() : LibraryExtension? = +fun Project.libraryProject(): LibraryExtension? = extensions.findByType(LibraryExtension::class.java) -fun Project.loadPropertiesFile(fileName: String) : Properties { +fun Project.loadPropertiesFile(fileName: String): Properties { // Load file val propertiesFile = file(fileName) if (!propertiesFile.exists()) { @@ -44,6 +56,23 @@ fun Project.loadPropertiesFile(fileName: String) : Properties { private val javaVarRegexp = Regex(pattern = "((?![a-zA-Z_\$0-9]).)") +fun Variant.inject(properties: Properties, ignore: List) { + val ignoreRegexs = ignore.map { Regex(pattern = it) } + properties.keys.map { key -> + key as String + }.filter { key -> + key.isNotEmpty() && !ignoreRegexs.any { it.containsMatchIn(key) } + }.forEach { key -> + val value = properties.getProperty(key) + val translatedKey = key.replace(javaVarRegexp, "") + buildConfigFields.put( + translatedKey, + BuildConfigField("String", value.addParenthesisIfNeeded(), null) + ) + manifestPlaceholders.put(translatedKey, value) + } +} + fun InternalBaseVariant.inject(properties: Properties, ignore: List) { val ignoreRegexs = ignore.map { Regex(pattern = it) } properties.keys.map { key -> @@ -53,8 +82,8 @@ fun InternalBaseVariant.inject(properties: Properties, ignore: List) { }.forEach { key -> val value = properties.getProperty(key) val translatedKey = key.replace(javaVarRegexp, "") - mergedFlavor.manifestPlaceholders[translatedKey] = value buildConfigField("String", translatedKey, value.addParenthesisIfNeeded()) + mergedFlavor.manifestPlaceholders[translatedKey] = value } } diff --git a/secrets-gradle-plugin/src/main/java/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPlugin.kt b/secrets-gradle-plugin/src/main/java/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPlugin.kt index bc26750..0ce85a1 100644 --- a/secrets-gradle-plugin/src/main/java/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPlugin.kt +++ b/secrets-gradle-plugin/src/main/java/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPlugin.kt @@ -11,9 +11,11 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +@file:Suppress("UnstableApiUsage") package com.google.android.libraries.mapsplatform.secrets_gradle_plugin +import com.android.build.api.variant.Variant import com.android.build.gradle.internal.core.InternalBaseVariant import org.gradle.api.Plugin import org.gradle.api.Project @@ -37,26 +39,21 @@ class SecretsPlugin : Plugin { extensionName, SecretsPluginExtension::class.java ) - project.afterEvaluate { - val defaultProperties = extension.defaultPropertiesFileName?.let { - project.rootProject.loadPropertiesFile(it) - } - - val properties: Properties? = try { - project.rootProject.loadPropertiesFile( - extension.propertiesFileName - ) - } catch (e: FileNotFoundException) { - defaultProperties ?: throw e - } - - // Target: "com.android.application" module variants - project.androidProject()?.applicationVariants?.all { variant -> - generateConfigKey(project, extension, defaultProperties, properties, variant) - } + val supportedComponents = + listOf(project.androidAppComponent(), project.androidLibraryComponent()) + supportedComponents.forEach { component -> + component?.onVariants { variant -> + val defaultProperties = extension.defaultPropertiesFileName?.let { + project.rootProject.loadPropertiesFile(it) + } - // Target: "com.android.library" module variants - project.libraryProject()?.libraryVariants?.all { variant -> + val properties: Properties? = try { + project.rootProject.loadPropertiesFile( + extension.propertiesFileName + ) + } catch (e: FileNotFoundException) { + defaultProperties ?: throw e + } generateConfigKey(project, extension, defaultProperties, properties, variant) } } @@ -67,7 +64,7 @@ class SecretsPlugin : Plugin { extension: SecretsPluginExtension, defaultProperties: Properties?, properties: Properties?, - variant: InternalBaseVariant + variant: Variant ) { // Inject defaults first defaultProperties?.let { @@ -79,7 +76,7 @@ class SecretsPlugin : Plugin { } // Inject build-type specific properties - val buildTypeFileName = "${variant.buildType.name}.properties" + val buildTypeFileName = "${variant.buildType}.properties" val buildTypeProperties = try { project.rootProject.loadPropertiesFile(buildTypeFileName) } catch (e: FileNotFoundException) { diff --git a/secrets-gradle-plugin/src/test/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginTest.kt b/secrets-gradle-plugin/src/test/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginTest.kt index 05401db..f20a13e 100644 --- a/secrets-gradle-plugin/src/test/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginTest.kt +++ b/secrets-gradle-plugin/src/test/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginTest.kt @@ -24,6 +24,7 @@ import org.gradle.api.internal.project.ProjectInternal import org.gradle.testfixtures.ProjectBuilder import org.junit.Assert import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder @@ -51,15 +52,18 @@ class SecretsPluginTest { .withParent(root) .build() placeholders = mutableMapOf() - val flavor = mock() { + val flavor = mock { on { manifestPlaceholders } doReturn placeholders } - variant = mock() { + variant = mock { on { mergedFlavor } doReturn flavor } project.pluginManager.apply("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") } + // TODO: This exception is no longer thrown since migrating to use onVariants API. Need to + // reenable this test + @Ignore @Test(expected = ProjectConfigurationException::class) fun `missing default properties fails`() { project.extensions.configure(SecretsPluginExtension::class.java) { diff --git a/settings.gradle.kts b/settings.gradle.kts index 99451da..86fc5b1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -include(":secrets-gradle-plugin", ":sample-app") +include(":secrets-gradle-plugin") +include(":sample-app") pluginManagement { repositories {