diff options
author | Scott Barta <sbarta@google.com> | 2012-12-18 15:02:31 -0800 |
---|---|---|
committer | Scott Barta <sbarta@google.com> | 2012-12-21 12:09:15 -0800 |
commit | 740e3ddee7dee67055daf6c542b96b5cf7be3c40 (patch) | |
tree | c7626ab4d4ac4cc4dfcc6f97290133f5b40aaea6 /gradle/src | |
parent | d654e5915e38b7a14fc3c423819bb9b0c272de70 (diff) | |
download | build-740e3ddee7dee67055daf6c542b96b5cf7be3c40.tar.gz |
Keystore objects.
Replaces keystore attributes on build types and flavors with a
SigningKeystore object that can be accessed by reference from
those types. Eliminates the debugSigning attribute in favor
of a default debug keystore that's automatically configured
for all projects.
Change-Id: Icbfc66487e26068ae6edff8395ebc29d0d28f46c
Diffstat (limited to 'gradle/src')
12 files changed, 226 insertions, 30 deletions
diff --git a/gradle/src/main/groovy/com/android/build/gradle/AppExtension.groovy b/gradle/src/main/groovy/com/android/build/gradle/AppExtension.groovy index db43f04..ad6fa0a 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/AppExtension.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/AppExtension.groovy @@ -17,6 +17,7 @@ package com.android.build.gradle import com.android.builder.BuildType import com.android.builder.ProductFlavor +import com.android.builder.Keystore import org.gradle.api.Action import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.internal.project.ProjectInternal @@ -29,16 +30,19 @@ public class AppExtension extends BaseExtension { final NamedDomainObjectContainer<ProductFlavor> productFlavors final NamedDomainObjectContainer<BuildType> buildTypes + final NamedDomainObjectContainer<Keystore> keystores List<String> flavorGroupList String testBuildType = "debug" AppExtension(AppPlugin plugin, ProjectInternal project, Instantiator instantiator, NamedDomainObjectContainer<BuildType> buildTypes, - NamedDomainObjectContainer<ProductFlavor> productFlavors) { + NamedDomainObjectContainer<ProductFlavor> productFlavors, + NamedDomainObjectContainer<Keystore> keystores) { super(plugin, project, instantiator) this.buildTypes = buildTypes this.productFlavors = productFlavors + this.keystores = keystores } void buildTypes(Action<? super NamedDomainObjectContainer<BuildType>> action) { @@ -49,6 +53,10 @@ public class AppExtension extends BaseExtension { action.execute(productFlavors) } + void keystores(Action<? super NamedDomainObjectContainer<Keystore>> action) { + action.execute(keystores) + } + public void flavorGroups(String... groups) { flavorGroupList = Arrays.asList(groups) } diff --git a/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy index d9dffd5..0e868c2 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy @@ -24,10 +24,13 @@ import com.android.build.gradle.internal.GroupableProductFlavorFactory import com.android.build.gradle.internal.PluginHolder import com.android.build.gradle.internal.ProductFlavorData import com.android.build.gradle.internal.ProductionAppVariant + +import com.android.build.gradle.internal.KeystoreFactory import com.android.build.gradle.internal.TestAppVariant import com.android.builder.AndroidDependency import com.android.builder.BuildType import com.android.builder.JarDependency +import com.android.builder.Keystore import com.android.builder.VariantConfiguration import com.google.common.collect.ArrayListMultimap import com.google.common.collect.ListMultimap @@ -47,6 +50,7 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl final Map<String, BuildTypeData> buildTypes = [:] final Map<String, ProductFlavorData<GroupableProductFlavor>> productFlavors = [:] + final Map<String, Keystore> keystores = [:] AppExtension extension @@ -67,10 +71,12 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl def buildTypeContainer = project.container(BuildType, new BuildTypeFactory(instantiator)) def productFlavorContainer = project.container(GroupableProductFlavor, new GroupableProductFlavorFactory(instantiator)) + def keystoreContainer = project.container(Keystore, + new KeystoreFactory(instantiator)) extension = project.extensions.create('android', AppExtension, this, (ProjectInternal) project, instantiator, - buildTypeContainer, productFlavorContainer) + buildTypeContainer, productFlavorContainer, keystoreContainer) setDefaultConfig(extension.defaultConfig, extension.sourceSetsContainer) buildTypeContainer.whenObjectAdded { BuildType buildType -> @@ -91,6 +97,14 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl throw new UnsupportedOperationException( "Removing product flavors is not implemented yet.") } + + keystoreContainer.whenObjectAdded { Keystore keystore -> + keystores[keystore.name] = keystore + } + keystoreContainer.whenObjectRemoved { + throw new UnsupportedOperationException("Removing keystores is not implemented yet.") + } + keystoreContainer.create(Keystore.DEBUG) } private void addBuildType(BuildType buildType) { diff --git a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy index 75e4a39..b4654e6 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy @@ -634,16 +634,19 @@ public abstract class BasePlugin { getOptionalDir(variant.processJavaResources.destinationDir) } - packageApp.conventionMapping.debugSigned = { config.buildType.debugSigned } packageApp.conventionMapping.debugJni = { config.buildType.debugJniBuild } - packageApp.conventionMapping.signingStoreLocation = { - config.mergedFlavor.signingStoreLocation - } - packageApp.conventionMapping.signingStorePassword = { - config.mergedFlavor.signingStorePassword + + + if (config.keystore) { + packageApp.conventionMapping.signingStoreLocation = { + project.file(config.keystore.storeLocation) + } + packageApp.conventionMapping.signingStorePassword = { + config.keystore.storePassword + } + packageApp.conventionMapping.signingKeyAlias = { config.keystore.keyAlias } + packageApp.conventionMapping.signingKeyPassword = { config.keystore.keyPassword } } - packageApp.conventionMapping.signingKeyAlias = { config.mergedFlavor.signingKeyAlias } - packageApp.conventionMapping.signingKeyPassword = { config.mergedFlavor.signingKeyPassword } def signedApk = variant.isSigned() def apkName = signedApk ? diff --git a/gradle/src/main/groovy/com/android/build/gradle/BuildVariant.groovy b/gradle/src/main/groovy/com/android/build/gradle/BuildVariant.groovy index 3ade8fa..7357360 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/BuildVariant.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/BuildVariant.groovy @@ -28,6 +28,7 @@ import com.android.build.gradle.tasks.ProcessResources import com.android.build.gradle.tasks.ZipAlign import com.android.builder.BuildType import com.android.builder.ProductFlavor +import com.android.builder.Keystore import org.gradle.api.Task import org.gradle.api.tasks.Copy import org.gradle.api.tasks.bundling.Zip @@ -99,6 +100,17 @@ public interface BuildVariant { File getOutputFile() /** + * Returns the {@link Keystore} for this build variant, if one has been specified. + */ + @Nullable + Keystore getKeystore() + + /** + * Returns true if this variant has the information it needs to create a signed APK. + */ + boolean isSigningReady() + + /** * Returns the build variant that will test this build variant. * * Will return null if this build variant is a test build already. diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/ApplicationVariant.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/ApplicationVariant.groovy index c778947..c151316 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/ApplicationVariant.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/ApplicationVariant.groovy @@ -86,8 +86,7 @@ public abstract class ApplicationVariant { abstract boolean getZipAlign() boolean isSigned() { - return config.buildType.debugSigned || - config.mergedFlavor.isSigningReady() + return config.isSigningReady() } abstract boolean getRunProguard() diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/DefaultBuildVariant.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/DefaultBuildVariant.groovy index 2af012b..860e701 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/DefaultBuildVariant.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/DefaultBuildVariant.groovy @@ -26,6 +26,7 @@ import com.android.build.gradle.tasks.ProcessResources import com.android.build.gradle.tasks.ZipAlign import com.android.builder.BuildType import com.android.builder.ProductFlavor +import com.android.builder.Keystore import org.gradle.api.Task import org.gradle.api.tasks.Copy import org.gradle.api.tasks.bundling.Zip @@ -165,4 +166,14 @@ public class DefaultBuildVariant implements BuildVariant { Task getRunTests() { return variant.runTestsTask } + + @Override + Keystore getKeystore() { + return variant.config.keystore + } + + @Override + boolean isSigningReady() { + return variant.isSigned() + } } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/DependencyChecker.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/DependencyChecker.groovy index f6121ca..4ea664e 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/DependencyChecker.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/DependencyChecker.groovy @@ -89,6 +89,8 @@ public class DependencyChecker { return "Flavor ${configurationDependencies.sourceSet.name.capitalize()}" case ConfigurationDependencies.ConfigType.BUILDTYPE: return "Build Type ${configurationDependencies.sourceSet.name.capitalize()}" + case ConfigurationDependencies.ConfigType.KEYSTORE: + return "Signing Keystore ${configurationDependencies.sourceSet.name.capitalize()}" } } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/KeystoreFactory.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/KeystoreFactory.groovy new file mode 100644 index 0000000..fe51781 --- /dev/null +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/KeystoreFactory.groovy @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +package com.android.build.gradle.internal + +import com.android.builder.Keystore +import org.gradle.api.NamedDomainObjectFactory +import org.gradle.internal.reflect.Instantiator + +/** + * Factory to create Keystore object using an {@ling Instantiator} to add the DSL methods. + */ +class KeystoreFactory implements NamedDomainObjectFactory<Keystore> { + + final Instantiator instantiator + + public KeystoreFactory(Instantiator instantiator) { + this.instantiator = instantiator + } + + @Override + Keystore create(String name) { + return instantiator.newInstance(Keystore.class, name) + } +} diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/PackageApplicationTask.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/PackageApplicationTask.groovy index e1de634..6b7bb9b 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/PackageApplicationTask.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/PackageApplicationTask.groovy @@ -17,6 +17,7 @@ package com.android.build.gradle.internal.tasks import com.android.build.gradle.tasks.PackageApplication import com.android.builder.packaging.DuplicateFileException import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.Optional @@ -26,13 +27,10 @@ public class PackageApplicationTask extends PackageApplication { List<File> packagedJars @Input - boolean debugSigned - - @Input boolean debugJni - @Input @Optional - String signingStoreLocation + @InputFile @Optional + File signingStoreLocation @Input @Optional String signingStorePassword @@ -52,7 +50,6 @@ public class PackageApplicationTask extends PackageApplication { getPackagedJars(), getJavaResourceDir()?.absolutePath, getJniDir()?.absolutePath, - getDebugSigned(), getDebugJni(), getSigningStoreLocation(), getSigningStorePassword(), diff --git a/gradle/src/test/groovy/com/android/build/gradle/AppPluginDslTest.groovy b/gradle/src/test/groovy/com/android/build/gradle/AppPluginDslTest.groovy index 54788a4..a0519f8 100644 --- a/gradle/src/test/groovy/com/android/build/gradle/AppPluginDslTest.groovy +++ b/gradle/src/test/groovy/com/android/build/gradle/AppPluginDslTest.groovy @@ -82,7 +82,7 @@ public class AppPluginDslTest extends BaseTest { buildTypes { staging { - debugSigned true + keystore owner.keystores.debug } } } @@ -218,7 +218,7 @@ public class AppPluginDslTest extends BaseTest { assertNotNull(variant.assemble) assertNotNull(variant.uninstall) - if (variant.buildType.debugSigned || variant.mergedConfig.isSigningReady()) { + if (variant.isSigningReady()) { assertNotNull(variant.install) // tested variant are never zipAligned. diff --git a/gradle/src/test/groovy/com/android/build/gradle/AppPluginInternalTest.groovy b/gradle/src/test/groovy/com/android/build/gradle/AppPluginInternalTest.groovy index d8cf0ef..c3b7588 100644 --- a/gradle/src/test/groovy/com/android/build/gradle/AppPluginInternalTest.groovy +++ b/gradle/src/test/groovy/com/android/build/gradle/AppPluginInternalTest.groovy @@ -19,6 +19,8 @@ import com.android.build.gradle.internal.ApplicationVariant import com.android.build.gradle.internal.BaseTest import com.android.build.gradle.internal.PluginHolder import com.android.builder.BuildType +import com.android.builder.Keystore +import com.android.builder.internal.signing.DebugKeyHelper import org.gradle.api.Project import org.gradle.testfixtures.ProjectBuilder @@ -74,16 +76,22 @@ public class AppPluginInternalTest extends BaseTest { project.android { target "android-15" + keystores { + fakeKeystore { + storeLocation "aa" + storePassword "bb" + keyAlias "cc" + keyPassword "dd" + } + } + defaultConfig { versionCode 1 versionName "2.0" minSdkVersion 2 targetSdkVersion 3 - signingStoreLocation "aa" - signingStorePassword "bb" - signingKeyAlias "cc" - signingKeyPassword "dd" + keystore keystores.fakeKeystore } } @@ -95,10 +103,10 @@ public class AppPluginInternalTest extends BaseTest { assertEquals(3, plugin.extension.defaultConfig.targetSdkVersion) assertEquals("2.0", plugin.extension.defaultConfig.versionName) - assertEquals("aa", plugin.extension.defaultConfig.signingStoreLocation) - assertEquals("bb", plugin.extension.defaultConfig.signingStorePassword) - assertEquals("cc", plugin.extension.defaultConfig.signingKeyAlias) - assertEquals("dd", plugin.extension.defaultConfig.signingKeyPassword) + assertEquals("aa", plugin.extension.defaultConfig.keystore.storeLocation) + assertEquals("bb", plugin.extension.defaultConfig.keystore.storePassword) + assertEquals("cc", plugin.extension.defaultConfig.keystore.keyAlias) + assertEquals("dd", plugin.extension.defaultConfig.keystore.keyPassword) } public void testBuildTypes() { @@ -113,7 +121,7 @@ public class AppPluginInternalTest extends BaseTest { buildTypes { staging { - debugSigned true + keystore owner.keystores.debug } } } @@ -234,6 +242,110 @@ public class AppPluginInternalTest extends BaseTest { assertNotNull(findVariant(variants, "F2FcTest")) } + public void testKeystores() { + Project project = ProjectBuilder.builder().withProjectDir( + new File(testDir, "basic")).build() + + project.apply plugin: 'android' + + project.android { + target "android-15" + + keystores { + one { + storeLocation "a1" + storePassword "b1" + keyAlias "c1" + keyPassword "d1" + } + two { + storeLocation "a2" + storePassword "b2" + keyAlias "c2" + keyPassword "d2" + } + three { + storeLocation "a3" + storePassword "b3" + keyAlias "c3" + keyPassword "d3" + } + } + + defaultConfig { + versionCode 1 + versionName "2.0" + minSdkVersion 2 + targetSdkVersion 3 + } + + buildTypes { + debug { + } + staging { + } + release { + keystore owner.keystores.three + } + } + + productFlavors { + flavor1 { + } + flavor2 { + keystore owner.keystores.one + } + } + + } + + AppPlugin plugin = AppPlugin.pluginHolder.plugin + plugin.createAndroidTasks() + + List<ApplicationVariant> variants = plugin.variants + assertEquals(8, variants.size()) // includes the test variant(s) + + ApplicationVariant variant + Keystore keystore + + variant = findVariant(variants, "Flavor1Debug") + assertNotNull(variant) + keystore = variant.config.keystore + assertNotNull(keystore) + assertEquals(DebugKeyHelper.defaultDebugKeyStoreLocation(), keystore.storeLocation) + + variant = findVariant(variants, "Flavor1Staging") + assertNotNull(variant) + keystore = variant.config.keystore + assertNull(keystore) + + variant = findVariant(variants, "Flavor1Release") + assertNotNull(variant) + keystore = variant.config.keystore + assertNotNull(keystore) + assertEquals("a3", keystore.storeLocation) + + variant = findVariant(variants, "Flavor2Debug") + assertNotNull(variant) + keystore = variant.config.keystore + assertNotNull(keystore) + assertEquals(DebugKeyHelper.defaultDebugKeyStoreLocation(), keystore.storeLocation) + + variant = findVariant(variants, "Flavor2Staging") + assertNotNull(variant) + keystore = variant.config.keystore + assertNotNull(keystore) + assertEquals("a1", keystore.storeLocation) + + variant = findVariant(variants, "Flavor2Release") + assertNotNull(variant) + keystore = variant.config.keystore + assertNotNull(keystore) + assertEquals("a3", keystore.storeLocation) + } + + + private static ApplicationVariant findVariant(Collection<ApplicationVariant> variants, String name) { for (ApplicationVariant variant : variants) { diff --git a/gradle/src/test/groovy/com/android/build/gradle/LibraryPluginDslTest.groovy b/gradle/src/test/groovy/com/android/build/gradle/LibraryPluginDslTest.groovy index 79c85a5..dcedc6f 100644 --- a/gradle/src/test/groovy/com/android/build/gradle/LibraryPluginDslTest.groovy +++ b/gradle/src/test/groovy/com/android/build/gradle/LibraryPluginDslTest.groovy @@ -83,7 +83,7 @@ public class LibraryPluginDslTest extends BaseTest { assertNull(variant.zipAlign) - if (variant.buildType.debugSigned || variant.mergedConfig.isSigningReady()) { + if (variant.isSigningReady()) { assertNotNull(variant.install) } else { assertNull(variant.install) |