From 6e00045fd570c43f8e37109e9bc8b32b1a6cb510 Mon Sep 17 00:00:00 2001 From: Xavier Ducrohet Date: Fri, 22 Nov 2013 17:50:20 -0800 Subject: Improved BuildConfig. - Now contains Package name, Build Type name, flavor names, version name and code. - Improved DSL allow overriding through build type or flavors Change-Id: I8a1bd723c39e714b5eb2cb569da347058d7a3400 --- .../java/com/android/builder/model/BaseConfig.java | 6 +- .../java/com/android/builder/model/ClassField.java | 33 +++++ builder/build.gradle | 1 + .../java/com/android/builder/AndroidBuilder.java | 25 +--- .../com/android/builder/DefaultManifestParser.java | 21 ++++ .../java/com/android/builder/ManifestParser.java | 42 +++++++ .../com/android/builder/VariantConfiguration.java | 105 +++++++++++++--- .../builder/compiling/BuildConfigGenerator.java | 135 +++++++++++++++++++++ .../android/builder/internal/BaseConfigImpl.java | 31 +++-- .../builder/internal/BuildConfigGenerator.java | 111 ----------------- .../android/builder/internal/ClassFieldImpl.java | 86 +++++++++++++ .../android/builder/internal/BuildConfig.template | 7 -- .../android/builder/VariantConfigurationTest.java | 5 + .../compiling/BuildConfigGeneratorTest.java | 102 ++++++++++++++++ .../builder/internal/BuildConfigGeneratorTest.java | 75 ------------ changelog.txt | 10 +- .../com/android/build/gradle/BasePlugin.groovy | 32 ++++- .../build/gradle/internal/dsl/BuildTypeDsl.groovy | 13 +- .../gradle/internal/dsl/ProductFlavorDsl.groovy | 12 +- .../build/gradle/internal/model/BuildTypeImpl.java | 3 +- .../gradle/internal/model/ProductFlavorImpl.java | 3 +- .../build/gradle/tasks/GenerateBuildConfig.groovy | 57 +++++++-- tests/basic/build.gradle | 6 +- .../java/com/android/tests/basic/MainTest.java | 5 + tests/flavored/build.gradle | 7 +- tests/flavors/build.gradle | 5 - .../android/tests/flavors/group1/SomeClass.java | 2 +- tests/flavors/src/f1/res/values/strings.xml | 4 +- .../android/tests/flavors/group1/SomeClass.java | 2 +- tests/flavors/src/f2/res/values/strings.xml | 4 +- .../android/tests/flavors/group2/SomeClass.java | 2 +- tests/flavors/src/fa/res/values/strings.xml | 4 +- .../android/tests/flavors/group2/SomeClass.java | 2 +- tests/flavors/src/fb/res/values/strings.xml | 4 +- .../tests/flavors/MainActivityGroup1Test.java | 8 +- .../tests/flavors/MainActivityGroup1Test.java | 8 +- .../tests/flavors/MainActivityGroup2Test.java | 8 +- .../tests/flavors/MainActivityGroup2Test.java | 8 +- .../com/android/tests/flavors/MainActivity.java | 4 +- 39 files changed, 684 insertions(+), 314 deletions(-) create mode 100644 builder-model/src/main/java/com/android/builder/model/ClassField.java create mode 100644 builder/src/main/java/com/android/builder/compiling/BuildConfigGenerator.java delete mode 100644 builder/src/main/java/com/android/builder/internal/BuildConfigGenerator.java create mode 100644 builder/src/main/java/com/android/builder/internal/ClassFieldImpl.java delete mode 100644 builder/src/main/resources/com/android/builder/internal/BuildConfig.template create mode 100644 builder/src/test/java/com/android/builder/compiling/BuildConfigGeneratorTest.java delete mode 100644 builder/src/test/java/com/android/builder/internal/BuildConfigGeneratorTest.java diff --git a/builder-model/src/main/java/com/android/builder/model/BaseConfig.java b/builder-model/src/main/java/com/android/builder/model/BaseConfig.java index fbf6eb4..713b344 100644 --- a/builder-model/src/main/java/com/android/builder/model/BaseConfig.java +++ b/builder-model/src/main/java/com/android/builder/model/BaseConfig.java @@ -27,11 +27,11 @@ import java.util.List; public interface BaseConfig { /** - * List of Build Config lines. - * @return a non-null list of lines (possibly empty) + * List of Build Config Fields + * @return a non-null list of class fields (possibly empty) */ @NonNull - List getBuildConfig(); + List getBuildConfigFields(); /** * Returns the list of proguard rule files. diff --git a/builder-model/src/main/java/com/android/builder/model/ClassField.java b/builder-model/src/main/java/com/android/builder/model/ClassField.java new file mode 100644 index 0000000..d6b6a26 --- /dev/null +++ b/builder-model/src/main/java/com/android/builder/model/ClassField.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2013 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.builder.model; + +import com.android.annotations.NonNull; + +/** + * A Simple class field with name, type and value, all as strings. + */ +public interface ClassField { + @NonNull + String getType(); + + @NonNull + String getName(); + + @NonNull + String getValue(); +} diff --git a/builder/build.gradle b/builder/build.gradle index a9f1bbe..c765b0d 100644 --- a/builder/build.gradle +++ b/builder/build.gradle @@ -15,6 +15,7 @@ dependencies { compile "com.android.tools.build:manifest-merger:$project.ext.baseAndroidVersion" compile "com.android.tools.ddms:ddmlib:$project.ext.baseAndroidVersion" + compile 'com.squareup:javawriter:2.2.1' compile 'org.bouncycastle:bcpkix-jdk15on:1.48' testCompile 'junit:junit:3.8.1' diff --git a/builder/src/main/java/com/android/builder/AndroidBuilder.java b/builder/src/main/java/com/android/builder/AndroidBuilder.java index feaa7c8..24ff0c8 100644 --- a/builder/src/main/java/com/android/builder/AndroidBuilder.java +++ b/builder/src/main/java/com/android/builder/AndroidBuilder.java @@ -22,7 +22,7 @@ import com.android.annotations.VisibleForTesting; import com.android.builder.compiling.DependencyFileProcessor; import com.android.builder.dependency.ManifestDependency; import com.android.builder.dependency.SymbolFileProvider; -import com.android.builder.internal.BuildConfigGenerator; +import com.android.builder.internal.ClassFieldImpl; import com.android.builder.internal.SymbolLoader; import com.android.builder.internal.SymbolWriter; import com.android.builder.internal.TestManifestGenerator; @@ -33,6 +33,7 @@ import com.android.builder.internal.compiler.SourceSearcher; import com.android.builder.internal.packaging.JavaResourceProcessor; import com.android.builder.internal.packaging.Packager; import com.android.builder.model.AaptOptions; +import com.android.builder.model.ClassField; import com.android.builder.model.ProductFlavor; import com.android.builder.model.SigningConfig; import com.android.builder.packaging.DuplicateFileException; @@ -80,7 +81,6 @@ import static com.google.common.base.Preconditions.checkNotNull; * create a builder with {@link #AndroidBuilder(SdkParser, String, ILogger, boolean)} * * then build steps can be done with - * {@link #generateBuildConfig(String, boolean, java.util.List, String)} * {@link #processManifest(java.io.File, java.util.List, java.util.List, String, int, String, int, int, String)} * {@link #processTestManifest(String, int, int, String, String, Boolean, Boolean, java.util.List, String)} * {@link #processResources(java.io.File, java.io.File, java.io.File, java.util.List, String, String, String, String, String, com.android.builder.VariantConfiguration.Type, boolean, com.android.builder.model.AaptOptions)} @@ -265,24 +265,9 @@ public class AndroidBuilder { return mCmdLineRunner; } - /** - * Generate the BuildConfig class for the project. - * @param packageName the package in which to generate the class - * @param debuggable whether the app is considered debuggable - * @param javaLines additional java lines to put in the class. These must be valid Java lines. - * @param sourceOutputDir directory where to put this. This is the source folder, not the - * package folder. - * @throws IOException - */ - public void generateBuildConfig( - @NonNull String packageName, - boolean debuggable, - @NonNull List javaLines, - @NonNull String sourceOutputDir) throws IOException { - - BuildConfigGenerator generator = new BuildConfigGenerator( - sourceOutputDir, packageName, debuggable); - generator.generate(javaLines); + @NonNull + public static ClassField createClassField(@NonNull String type, @NonNull String name, @NonNull String value) { + return new ClassFieldImpl(type, name, value); } /** diff --git a/builder/src/main/java/com/android/builder/DefaultManifestParser.java b/builder/src/main/java/com/android/builder/DefaultManifestParser.java index 97d8533..e8d70d6 100644 --- a/builder/src/main/java/com/android/builder/DefaultManifestParser.java +++ b/builder/src/main/java/com/android/builder/DefaultManifestParser.java @@ -66,6 +66,27 @@ public class DefaultManifestParser implements ManifestParser { return null; } + @Override + public int getVersionCode(@NonNull File manifestFile) { + XPath xpath = AndroidXPathFactory.newXPath(); + + try { + String value= xpath.evaluate("/manifest/@android:versionCode", + new InputSource(new FileInputStream(manifestFile))); + if (value != null) { + return Integer.parseInt(value); + } + } catch (XPathExpressionException e) { + // won't happen. + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (NumberFormatException e) { + // return -1 below. + } + + return -1; + } + @Override public int getMinSdkVersion(@NonNull File manifestFile) { try { diff --git a/builder/src/main/java/com/android/builder/ManifestParser.java b/builder/src/main/java/com/android/builder/ManifestParser.java index 5b6411c..3b8e4a3 100644 --- a/builder/src/main/java/com/android/builder/ManifestParser.java +++ b/builder/src/main/java/com/android/builder/ManifestParser.java @@ -21,14 +21,56 @@ import com.android.annotations.Nullable; import java.io.File; +/** + * A Manifest parser + */ public interface ManifestParser { + /** + * Returns the package name parsed from the given manifest file. + * + * @param manifestFile the manifest file to parse + * + * @return the package name or null if not found. + */ @Nullable String getPackage(@NonNull File manifestFile); + /** + * Returns the minSdkVersion parsed from the given manifest file. + * + * @param manifestFile the manifest file to parse + * + * @return the minSdkVersion or 1 if not found. + */ int getMinSdkVersion(@NonNull File manifestFile); + + /** + * Returns the targetSdkVersion parsed from the given manifest file. + * + * @param manifestFile the manifest file to parse + * + * @return the targetSdkVersion or -1 if not found. + */ int getTargetSdkVersion(@NonNull File manifestFile); + /** + * Returns the version name parsed from the given manifest file. + * + * @param manifestFile the manifest file to parse + * + * @return the version name or null if not found. + */ @Nullable String getVersionName(@NonNull File manifestFile); + + /** + * Returns the version code parsed from the given manifest file. + * + * @param manifestFile the manifest file to parse + * + * @return the version code or -1 if not found. + */ + int getVersionCode(@NonNull File manifestFile); + } diff --git a/builder/src/main/java/com/android/builder/VariantConfiguration.java b/builder/src/main/java/com/android/builder/VariantConfiguration.java index d21a795..7c5f6b1 100644 --- a/builder/src/main/java/com/android/builder/VariantConfiguration.java +++ b/builder/src/main/java/com/android/builder/VariantConfiguration.java @@ -24,6 +24,7 @@ import com.android.builder.dependency.JarDependency; import com.android.builder.dependency.LibraryDependency; import com.android.builder.internal.NdkConfigImpl; import com.android.builder.internal.StringHelper; +import com.android.builder.model.ClassField; import com.android.builder.model.ProductFlavor; import com.android.builder.model.SigningConfig; import com.android.builder.model.SourceProvider; @@ -35,6 +36,7 @@ import com.google.common.collect.Sets; import java.io.File; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -322,6 +324,26 @@ public class VariantConfiguration implements TestData { return mDirName; } + /** + * Return the names of the applied flavors. + * + * @return the list, possibly empty if there are no flavors. + */ + @NonNull + public List getFlavorNames() { + if (mFlavorConfigs.isEmpty()) { + return Collections.emptyList(); + } + + List names = Lists.newArrayListWithCapacity(mFlavorConfigs.size()); + for (DefaultProductFlavor flavor : mFlavorConfigs) { + names.add(flavor.getName()); + } + + return names; + } + + /** * Add a new configured ProductFlavor. * @@ -640,7 +662,11 @@ public class VariantConfiguration implements TestData { if (versionSuffix != null && versionSuffix.length() > 0) { if (versionName == null) { - versionName = getVersionNameFromManifest(); + if (mType != Type.TEST) { + versionName = getVersionNameFromManifest(); + } else { + versionName = ""; + } } versionName = versionName + versionSuffix; @@ -649,6 +675,24 @@ public class VariantConfiguration implements TestData { return versionName; } + /** + * Returns the version code for this variant. This could be coming from the manifest or + * could be overridden through the product flavors, and can have a suffix specified by + * the build type. + * + * @return the version code or -1 if there was non defined. + */ + public int getVersionCode() { + int versionCode = mMergedFlavor.getVersionCode(); + + if (versionCode == -1 && mType != Type.TEST) { + + versionCode = getVersionCodeFromManifest(); + } + + return versionCode; + } + private final static String DEFAULT_TEST_RUNNER = "android.test.InstrumentationTestRunner"; private final static Boolean DEFAULT_HANDLE_PROFILING = false; private final static Boolean DEFAULT_FUNCTIONAL_TEST = false; @@ -720,6 +764,14 @@ public class VariantConfiguration implements TestData { return sManifestParser.getVersionName(manifestLocation); } + /** + * Reads the version code from the manifest. + */ + public int getVersionCodeFromManifest() { + File manifestLocation = mDefaultSourceProvider.getManifestFile(); + return sManifestParser.getVersionCode(manifestLocation); + } + /** * Return the minSdkVersion for this variant. * @@ -1115,27 +1167,52 @@ public class VariantConfiguration implements TestData { return Lists.newArrayList(jars); } + /** + * Returns a list of items for the BuildConfig class. + * + * Items can be either fields (instance of {@link com.android.builder.model.ClassField}) + * or comments (instance of String). + * + * @return a list of items. + */ @NonNull - public List getBuildConfigLines() { - List fullList = Lists.newArrayList(); + public List getBuildConfigItems() { + List fullList = Lists.newArrayList(); - List list = mDefaultConfig.getBuildConfig(); - if (!list.isEmpty()) { - fullList.add("// lines from default config."); - fullList.addAll(list); - } + Set usedFieldNames = Sets.newHashSet(); - list = mBuildType.getBuildConfig(); + List list = mBuildType.getBuildConfigFields(); if (!list.isEmpty()) { - fullList.add("// lines from build type: " + mBuildType.getName()); - fullList.addAll(list); + fullList.add("Fields from build type: " + mBuildType.getName()); + for (ClassField f : list) { + usedFieldNames.add(f.getName()); + fullList.add(f); + } } for (DefaultProductFlavor flavor : mFlavorConfigs) { - list = flavor.getBuildConfig(); + list = flavor.getBuildConfigFields(); if (!list.isEmpty()) { - fullList.add("// lines from product flavor: " + flavor.getName()); - fullList.addAll(list); + fullList.add("Fields from product flavor: " + flavor.getName()); + for (ClassField f : list) { + String name = f.getName(); + if (!usedFieldNames.contains(name)) { + usedFieldNames.add(f.getName()); + fullList.add(f); + } + } + } + } + + list = mDefaultConfig.getBuildConfigFields(); + if (!list.isEmpty()) { + fullList.add("Fields from default config."); + for (ClassField f : list) { + String name = f.getName(); + if (!usedFieldNames.contains(name)) { + usedFieldNames.add(f.getName()); + fullList.add(f); + } } } diff --git a/builder/src/main/java/com/android/builder/compiling/BuildConfigGenerator.java b/builder/src/main/java/com/android/builder/compiling/BuildConfigGenerator.java new file mode 100644 index 0000000..1e298b4 --- /dev/null +++ b/builder/src/main/java/com/android/builder/compiling/BuildConfigGenerator.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2011 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.builder.compiling; + +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.builder.AndroidBuilder; +import com.android.builder.model.ClassField; +import com.google.common.collect.Lists; +import com.squareup.javawriter.JavaWriter; + +import javax.lang.model.element.Modifier; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Collection; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Class able to generate a BuildConfig class in Android project. + * The BuildConfig class contains constants related to the build target. + */ +public class BuildConfigGenerator { + + public final static String BUILD_CONFIG_NAME = "BuildConfig.java"; + + private final String mGenFolder; + private final String mBuildConfigPackageName; + + private final List mFields = Lists.newArrayList(); + private List mItems = Lists.newArrayList(); + + /** + * Creates a generator + * @param genFolder the gen folder of the project + * @param buildConfigPackageName the package in which to create the class. + */ + public BuildConfigGenerator(@NonNull String genFolder, @NonNull String buildConfigPackageName) { + mGenFolder = checkNotNull(genFolder); + mBuildConfigPackageName = checkNotNull(buildConfigPackageName); + } + + public BuildConfigGenerator addField( + @NonNull String type, @NonNull String name, @NonNull String value) { + mFields.add(AndroidBuilder.createClassField(type, name, value)); + return this; + } + + public BuildConfigGenerator addItems(@Nullable Collection items) { + if (items != null) { + mItems.addAll(items); + } + return this; + } + + /** + * Returns a File representing where the BuildConfig class will be. + */ + public File getFolderPath() { + File genFolder = new File(mGenFolder); + return new File(genFolder, mBuildConfigPackageName.replace('.', File.separatorChar)); + } + + public File getBuildConfigFile() { + File folder = getFolderPath(); + return new File(folder, BUILD_CONFIG_NAME); + } + + /** + * Generates the BuildConfig class. + */ + public void generate() throws IOException { + File pkgFolder = getFolderPath(); + if (!pkgFolder.isDirectory()) { + if (!pkgFolder.mkdirs()) { + throw new RuntimeException("Failed to create " + pkgFolder.getAbsolutePath()); + } + } + + File buildConfigJava = new File(pkgFolder, BUILD_CONFIG_NAME); + FileWriter out = new FileWriter(buildConfigJava); + + JavaWriter writer = new JavaWriter(out); + + Set publicFinal = EnumSet.of(Modifier.PUBLIC, Modifier.FINAL); + Set publicFinalStatic = EnumSet.of(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC); + + writer.emitJavadoc("Automatically generated file. DO NOT MODIFY") + .emitPackage(mBuildConfigPackageName) + .beginType("BuildConfig", "class", publicFinal); + + for (ClassField field : mFields) { + writer.emitField( + field.getType(), + field.getName(), + publicFinalStatic, + field.getValue()); + } + + for (Object item : mItems) { + if (item instanceof ClassField) { + ClassField field = (ClassField)item; + writer.emitField( + field.getType(), + field.getName(), + publicFinalStatic, + field.getValue()); + + } else if (item instanceof String) { + writer.emitSingleLineComment((String) item); + } + } + + writer.endType(); + + out.close(); + } +} diff --git a/builder/src/main/java/com/android/builder/internal/BaseConfigImpl.java b/builder/src/main/java/com/android/builder/internal/BaseConfigImpl.java index 044420b..62653d3 100644 --- a/builder/src/main/java/com/android/builder/internal/BaseConfigImpl.java +++ b/builder/src/main/java/com/android/builder/internal/BaseConfigImpl.java @@ -18,11 +18,13 @@ package com.android.builder.internal; import com.android.annotations.NonNull; import com.android.builder.model.BaseConfig; +import com.android.builder.model.ClassField; import com.google.common.collect.Lists; import java.io.File; import java.io.Serializable; import java.util.Arrays; +import java.util.Collection; import java.util.List; /** @@ -31,24 +33,28 @@ import java.util.List; public class BaseConfigImpl implements Serializable, BaseConfig { private static final long serialVersionUID = 1L; - private final List mBuildConfigLines = Lists.newArrayList(); + private final List mBuildConfigFields = Lists.newArrayList(); private final List mProguardFiles = Lists.newArrayList(); private final List mConsumerProguardFiles = Lists.newArrayList(); - public void setBuildConfig(String... lines) { - mBuildConfigLines.clear(); - mBuildConfigLines.addAll(Arrays.asList(lines)); + public void setBuildConfigFields(@NonNull ClassField... fields) { + mBuildConfigFields.clear(); + mBuildConfigFields.addAll(Arrays.asList(fields)); } - public void setBuildConfig(String line) { - mBuildConfigLines.clear(); - mBuildConfigLines.add(line); + public void setBuildConfigFields(@NonNull Collection fields) { + mBuildConfigFields.clear(); + mBuildConfigFields.addAll(fields); + } + + public void addBuildConfigField(@NonNull ClassField field) { + mBuildConfigFields.add(field); } @Override @NonNull - public List getBuildConfig() { - return mBuildConfigLines; + public List getBuildConfigFields() { + return mBuildConfigFields; } @Override @@ -64,8 +70,7 @@ public class BaseConfigImpl implements Serializable, BaseConfig { } protected void _initWith(BaseConfig that) { - mBuildConfigLines.clear(); - mBuildConfigLines.addAll(that.getBuildConfig()); + setBuildConfigFields(that.getBuildConfigFields()); mProguardFiles.clear(); mProguardFiles.addAll(that.getProguardFiles()); @@ -81,7 +86,7 @@ public class BaseConfigImpl implements Serializable, BaseConfig { BaseConfigImpl that = (BaseConfigImpl) o; - if (!mBuildConfigLines.equals(that.mBuildConfigLines)) return false; + if (!mBuildConfigFields.equals(that.mBuildConfigFields)) return false; if (!mProguardFiles.equals(that.mProguardFiles)) return false; if (!mConsumerProguardFiles.equals(that.mConsumerProguardFiles)) return false; @@ -90,7 +95,7 @@ public class BaseConfigImpl implements Serializable, BaseConfig { @Override public int hashCode() { - int result = mBuildConfigLines.hashCode(); + int result = mBuildConfigFields.hashCode(); result = 31 * result + mProguardFiles.hashCode(); result = 31 * result + mConsumerProguardFiles.hashCode(); return result; diff --git a/builder/src/main/java/com/android/builder/internal/BuildConfigGenerator.java b/builder/src/main/java/com/android/builder/internal/BuildConfigGenerator.java deleted file mode 100644 index 2d01734..0000000 --- a/builder/src/main/java/com/android/builder/internal/BuildConfigGenerator.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2011 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.builder.internal; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.google.common.collect.Maps; - -import java.io.File; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Class able to generate a BuildConfig class in Android project. - * The BuildConfig class contains constants related to the build target. - */ -public class BuildConfigGenerator { - - private final static String TEMPLATE = "BuildConfig.template"; - private final static String PH_PACKAGE = "#PACKAGE#"; - private final static String PH_DEBUG = "#DEBUG#"; - private final static String PH_LINES = "#ADDITIONAL_LINES#"; - - private final String mGenFolder; - private final String mAppPackage; - private final boolean mDebug; - - public final static String BUILD_CONFIG_NAME = "BuildConfig.java"; - - /** - * Creates a generator - * @param genFolder the gen folder of the project - * @param appPackage the application package - * @param debug whether it's a debug build - */ - public BuildConfigGenerator(@NonNull String genFolder, @NonNull String appPackage, - boolean debug) { - mGenFolder = checkNotNull(genFolder); - mAppPackage = checkNotNull(appPackage); - mDebug = debug; - } - - /** - * Returns a File representing where the BuildConfig class will be. - */ - public File getFolderPath() { - File genFolder = new File(mGenFolder); - return new File(genFolder, mAppPackage.replace('.', File.separatorChar)); - } - - public File getBuildConfigFile() { - File folder = getFolderPath(); - return new File(folder, BUILD_CONFIG_NAME); - } - - /** - * Generates the BuildConfig class. - * @param additionalLines a list of additional lines to be added to the class. - */ - public void generate(@Nullable List additionalLines) throws IOException { - Map map = Maps.newHashMap(); - map.put(PH_PACKAGE, mAppPackage); - - // Hack (see IDEA-100046): We want to avoid reporting "condition is always true" - // from the data flow inspection, so use a non-constant value. However, that defeats - // the purpose of this flag (when not in debug mode, if (BuildConfig.DEBUG && ...) will - // be completely removed by the compiler), so as a hack we do it only for the case - // where debug is true, which is the most likely scenario while the user is looking - // at source code. - //map.put(PH_DEBUG, Boolean.toString(mDebug)); - map.put(PH_DEBUG, mDebug ? "Boolean.parseBoolean(\"true\")" : "false"); - - if (additionalLines != null) { - StringBuilder sb = new StringBuilder(); - for (String line : additionalLines) { - sb.append(" ").append(line).append('\n'); - } - map.put(PH_LINES, sb.toString()); - - } else { - map.put(PH_LINES, ""); - } - - File pkgFolder = getFolderPath(); - if (!pkgFolder.isDirectory()) { - pkgFolder.mkdirs(); - } - - File buildConfigJava = new File(pkgFolder, BUILD_CONFIG_NAME); - - TemplateProcessor processor = new TemplateProcessor( - BuildConfigGenerator.class.getResourceAsStream(TEMPLATE), map); - processor.generate(buildConfigJava); - } -} diff --git a/builder/src/main/java/com/android/builder/internal/ClassFieldImpl.java b/builder/src/main/java/com/android/builder/internal/ClassFieldImpl.java new file mode 100644 index 0000000..44824b4 --- /dev/null +++ b/builder/src/main/java/com/android/builder/internal/ClassFieldImpl.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2013 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.builder.internal; + +import com.android.annotations.NonNull; +import com.android.builder.model.ClassField; + +import java.io.Serializable; + +/** + */ +public final class ClassFieldImpl implements ClassField, Serializable { + + private static final long serialVersionUID = 1L; + + @NonNull + private final String type; + @NonNull + private final String name; + @NonNull + private final String value; + + public ClassFieldImpl(@NonNull String type, @NonNull String name, @NonNull String value) { + //noinspection ConstantConditions + if (type == null || name == null || value == null) { + throw new NullPointerException("Build Config field cannot have a null parameter"); + } + this.type = type; + this.name = name; + this.value = value; + } + + @Override + @NonNull + public String getType() { + return type; + } + + @Override + @NonNull + public String getName() { + return name; + } + + @Override + @NonNull + public String getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ClassFieldImpl that = (ClassFieldImpl) o; + + if (!name.equals(that.name)) return false; + if (!type.equals(that.type)) return false; + if (!value.equals(that.value)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = type.hashCode(); + result = 31 * result + name.hashCode(); + result = 31 * result + value.hashCode(); + return result; + } +} diff --git a/builder/src/main/resources/com/android/builder/internal/BuildConfig.template b/builder/src/main/resources/com/android/builder/internal/BuildConfig.template deleted file mode 100644 index 71b4b9c..0000000 --- a/builder/src/main/resources/com/android/builder/internal/BuildConfig.template +++ /dev/null @@ -1,7 +0,0 @@ -/** Automatically generated file. DO NOT MODIFY */ -package #PACKAGE#; - -public final class BuildConfig { - public static final boolean DEBUG = #DEBUG#; - -#ADDITIONAL_LINES#} \ No newline at end of file diff --git a/builder/src/test/java/com/android/builder/VariantConfigurationTest.java b/builder/src/test/java/com/android/builder/VariantConfigurationTest.java index 424a5f3..dfe8ea4 100644 --- a/builder/src/test/java/com/android/builder/VariantConfigurationTest.java +++ b/builder/src/test/java/com/android/builder/VariantConfigurationTest.java @@ -57,6 +57,11 @@ public class VariantConfigurationTest extends TestCase { public String getVersionName(@NonNull File manifestFile) { return "1.0"; } + + @Override + public int getVersionCode(@NonNull File manifestFile) { + return 1; + } } @Override diff --git a/builder/src/test/java/com/android/builder/compiling/BuildConfigGeneratorTest.java b/builder/src/test/java/com/android/builder/compiling/BuildConfigGeneratorTest.java new file mode 100644 index 0000000..0bb2200 --- /dev/null +++ b/builder/src/test/java/com/android/builder/compiling/BuildConfigGeneratorTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013 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.builder.compiling; + +import com.android.builder.AndroidBuilder; +import com.google.common.base.Charsets; +import com.google.common.collect.Lists; +import com.google.common.io.Files; +import junit.framework.TestCase; + +import java.io.File; +import java.util.List; + +@SuppressWarnings("ResultOfMethodCallIgnored") +public class BuildConfigGeneratorTest extends TestCase { + public void testFalse() throws Exception { + File tempDir = Files.createTempDir(); + BuildConfigGenerator generator = new BuildConfigGenerator(tempDir.getPath(), + "my.app.pkg"); + + generator.addField("boolean", "DEBUG", "false").generate(); + + File file = generator.getBuildConfigFile(); + assertTrue(file.exists()); + String actual = Files.toString(file, Charsets.UTF_8); + assertEquals( + "/**\n" + + " * Automatically generated file. DO NOT MODIFY\n" + + " */\n" + + "package my.app.pkg;\n" + + "\n" + + "public final class BuildConfig {\n" + + " public static final boolean DEBUG = false;\n" + + "}\n", actual); + file.delete(); + tempDir.delete(); + } + + public void testTrue() throws Exception { + File tempDir = Files.createTempDir(); + BuildConfigGenerator generator = new BuildConfigGenerator(tempDir.getPath(), + "my.app.pkg"); + generator.addField("boolean", "DEBUG", "Boolean.parseBoolean(\"true\")").generate(); + + File file = generator.getBuildConfigFile(); + assertTrue(file.exists()); + String actual = Files.toString(file, Charsets.UTF_8); + assertEquals( + "/**\n" + + " * Automatically generated file. DO NOT MODIFY\n" + + " */\n" + + "package my.app.pkg;\n" + + "\n" + + "public final class BuildConfig {\n" + + " public static final boolean DEBUG = Boolean.parseBoolean(\"true\");\n" + + "}\n", actual); + file.delete(); + tempDir.delete(); + } + + public void testExtra() throws Exception { + File tempDir = Files.createTempDir(); + BuildConfigGenerator generator = new BuildConfigGenerator(tempDir.getPath(), + "my.app.pkg"); + + List items = Lists.newArrayList(); + items.add("Extra line"); + items.add(AndroidBuilder.createClassField("int", "EXTRA", "42")); + + generator.addItems(items).generate(); + + File file = generator.getBuildConfigFile(); + assertTrue(file.exists()); + String actual = Files.toString(file, Charsets.UTF_8); + assertEquals( + "/**\n" + + " * Automatically generated file. DO NOT MODIFY\n" + + " */\n" + + "package my.app.pkg;\n" + + "\n" + + "public final class BuildConfig {\n" + + " // Extra line\n" + + " public static final int EXTRA = 42;\n" + + "}\n", actual); + file.delete(); + tempDir.delete(); + } +} diff --git a/builder/src/test/java/com/android/builder/internal/BuildConfigGeneratorTest.java b/builder/src/test/java/com/android/builder/internal/BuildConfigGeneratorTest.java deleted file mode 100644 index 0f5ecd3..0000000 --- a/builder/src/test/java/com/android/builder/internal/BuildConfigGeneratorTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.android.builder.internal; - -import com.google.common.base.Charsets; -import com.google.common.io.Files; - -import junit.framework.TestCase; - -import java.io.File; -import java.util.Arrays; -import java.util.Collections; - -@SuppressWarnings("ResultOfMethodCallIgnored") -public class BuildConfigGeneratorTest extends TestCase { - public void testFalse() throws Exception { - File tempDir = Files.createTempDir(); - BuildConfigGenerator generator = new BuildConfigGenerator(tempDir.getPath(), - "my.app.pkg", false); - generator.generate(Collections.emptyList()); - File file = generator.getBuildConfigFile(); - assertTrue(file.exists()); - String actual = Files.toString(file, Charsets.UTF_8); - assertEquals( - "/** Automatically generated file. DO NOT MODIFY */\n" - + "package my.app.pkg;\n" - + "\n" - + "public final class BuildConfig {\n" - + " public static final boolean DEBUG = false;\n" - + "\n" - + "}", actual); - file.delete(); - tempDir.delete(); - } - - public void testTrue() throws Exception { - File tempDir = Files.createTempDir(); - BuildConfigGenerator generator = new BuildConfigGenerator(tempDir.getPath(), - "my.app.pkg", true); - generator.generate(Collections.emptyList()); - File file = generator.getBuildConfigFile(); - assertTrue(file.exists()); - String actual = Files.toString(file, Charsets.UTF_8); - assertEquals( - "/** Automatically generated file. DO NOT MODIFY */\n" - + "package my.app.pkg;\n" - + "\n" - + "public final class BuildConfig {\n" - + " public static final boolean DEBUG = Boolean.parseBoolean(\"true\");\n" - + "\n" - + "}", actual); - file.delete(); - tempDir.delete(); - } - - public void testExtra() throws Exception { - File tempDir = Files.createTempDir(); - BuildConfigGenerator generator = new BuildConfigGenerator(tempDir.getPath(), - "my.app.pkg", false); - generator.generate(Arrays.asList("// Extra line:", "public static int EXTRA = 42;")); - File file = generator.getBuildConfigFile(); - assertTrue(file.exists()); - String actual = Files.toString(file, Charsets.UTF_8); - assertEquals( - "/** Automatically generated file. DO NOT MODIFY */\n" - + "package my.app.pkg;\n" - + "\n" - + "public final class BuildConfig {\n" - + " public static final boolean DEBUG = false;\n" - + "\n" - + " // Extra line:\n" - + " public static int EXTRA = 42;\n" - + "}", actual); - file.delete(); - tempDir.delete(); - } -} diff --git a/changelog.txt b/changelog.txt index 70ed31e..6525120 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,10 +3,18 @@ - You can now have a variant specific source folder if you have flavors. Only for app (not library or test). Name is src/flavorDebug/... or src/flavor1Flavor2Debug/ (note the camelcase naming, with lower case for first letter). - Its compoenents (res, manifest, etc...) have higher priority than components from build type + Its components (res, manifest, etc...) have higher priority than components from build type or flavors. It also comes with dependency configuration, so you can do flavorDebugCompile '...' +- Build config improvements and DSL changes. + The previous DSL proprety: + buildConfigLine "" + has changed to + buildConfigField "", "", "" + This allows override a field (see 'basic' sample) + Also, BuildConfig now automatically contains constants for + PACKAGE_NAME, VERSION_CODE, VERSION_NAME, BUILD_TYPE, FLAVOR s well as FLAVOR1, FLAVOR2, etc... if there are several flavor dimensions. - Switch to ProGuard 4.10 - Added ability to test proguarded (obfuscated) apps. - Jar files are now pre-dexed for faster dexing. 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 d442514..ab56022 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy @@ -374,7 +374,7 @@ public abstract class BasePlugin { getManifestDependencies(config.directLibraries) } processManifestTask.conventionMapping.versionCode = { - mergedFlavor.versionCode + config.versionCode } processManifestTask.conventionMapping.minSdkVersion = { mergedFlavor.minSdkVersion @@ -549,16 +549,40 @@ public abstract class BasePlugin { generateBuildConfigTask.plugin = this generateBuildConfigTask.variant = variantData - generateBuildConfigTask.conventionMapping.packageName = { + generateBuildConfigTask.conventionMapping.buildConfigPackageName = { variantConfiguration.originalPackageName } + generateBuildConfigTask.conventionMapping.appPackageName = { + variantConfiguration.packageName + } + + generateBuildConfigTask.conventionMapping.versionName = { + variantConfiguration.versionName + } + + generateBuildConfigTask.conventionMapping.versionCode = { + variantConfiguration.versionCode + } + generateBuildConfigTask.conventionMapping.debuggable = { variantConfiguration.buildType.isDebuggable() } - generateBuildConfigTask.conventionMapping.javaLines = { - variantConfiguration.buildConfigLines + generateBuildConfigTask.conventionMapping.buildTypeName = { + variantConfiguration.buildType.name + } + + generateBuildConfigTask.conventionMapping.flavorName = { + variantConfiguration.flavorName + } + + generateBuildConfigTask.conventionMapping.flavorNames = { + variantConfiguration.flavorNames + } + + generateBuildConfigTask.conventionMapping.items = { + variantConfiguration.buildConfigItems } generateBuildConfigTask.conventionMapping.sourceOutputDir = { diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy index 6ca387c..a4770b6 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy @@ -18,6 +18,7 @@ package com.android.build.gradle.internal.dsl import com.android.annotations.NonNull import com.android.annotations.Nullable import com.android.annotations.VisibleForTesting +import com.android.builder.AndroidBuilder import com.android.builder.BuilderConstants import com.android.builder.DefaultBuildType import com.android.builder.NdkConfig @@ -25,7 +26,6 @@ import com.android.builder.model.SigningConfig import org.gradle.api.Action import org.gradle.api.internal.file.FileResolver import org.gradle.internal.reflect.Instantiator - /** * DSL overlay to make methods that accept String... work. */ @@ -82,12 +82,11 @@ public class BuildTypeDsl extends DefaultBuildType implements Serializable { // -- DSL Methods. TODO remove once the instantiator does what I expect it to do. - public void buildConfig(String... lines) { - setBuildConfig(lines) - } - - public void buildConfig(String line) { - setBuildConfig(line) + public void buildConfigField( + @NonNull String type, + @NonNull String name, + @NonNull String value) { + addBuildConfigField(AndroidBuilder.createClassField(type, name, value)); } @NonNull diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy index 6b78c86..1645a03 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy @@ -17,6 +17,7 @@ package com.android.build.gradle.internal.dsl import com.android.annotations.NonNull import com.android.annotations.Nullable +import com.android.builder.AndroidBuilder import com.android.builder.DefaultProductFlavor import com.android.builder.NdkConfig import org.gradle.api.Action @@ -50,12 +51,11 @@ class ProductFlavorDsl extends DefaultProductFlavor { // -- DSL Methods. TODO remove once the instantiator does what I expect it to do. - public void buildConfig(String... lines) { - setBuildConfig(lines) - } - - public void buildConfig(String line) { - setBuildConfig(line) + public void buildConfigField( + @NonNull String type, + @NonNull String name, + @NonNull String value) { + addBuildConfigField(AndroidBuilder.createClassField(type, name, value)); } @NonNull diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java index 03daa6f..ccb1e8b 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java @@ -20,6 +20,7 @@ import com.android.annotations.NonNull; import com.android.annotations.Nullable; import com.android.builder.NdkConfig; import com.android.builder.model.BuildType; +import com.android.builder.model.ClassField; import java.io.File; import java.io.Serializable; @@ -112,7 +113,7 @@ class BuildTypeImpl implements BuildType, Serializable { @NonNull @Override - public List getBuildConfig() { + public List getBuildConfigFields() { return Collections.emptyList(); } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java index d03ae14..8380ae3 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java @@ -19,6 +19,7 @@ package com.android.build.gradle.internal.model; import com.android.annotations.NonNull; import com.android.annotations.Nullable; import com.android.builder.NdkConfig; +import com.android.builder.model.ClassField; import com.android.builder.model.ProductFlavor; import java.io.File; @@ -142,7 +143,7 @@ class ProductFlavorImpl implements ProductFlavor, Serializable { @NonNull @Override - public List getBuildConfig() { + public List getBuildConfigFields() { return Collections.emptyList(); } diff --git a/gradle/src/main/groovy/com/android/build/gradle/tasks/GenerateBuildConfig.groovy b/gradle/src/main/groovy/com/android/build/gradle/tasks/GenerateBuildConfig.groovy index 35bc489..cba93f0 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/tasks/GenerateBuildConfig.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/tasks/GenerateBuildConfig.groovy @@ -16,7 +16,9 @@ package com.android.build.gradle.tasks import com.android.build.gradle.internal.tasks.IncrementalTask +import com.android.builder.compiling.BuildConfigGenerator import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional import org.gradle.api.tasks.OutputDirectory public class GenerateBuildConfig extends IncrementalTask { @@ -29,13 +31,31 @@ public class GenerateBuildConfig extends IncrementalTask { // ----- PRIVATE TASK API ----- @Input - String packageName + String buildConfigPackageName + + @Input + String appPackageName @Input boolean debuggable @Input - List javaLines; + String flavorName + + @Input + List flavorNames + + @Input + String buildTypeName + + @Input @Optional + String versionName + + @Input + int versionCode + + @Input + List items; @Override protected void doFullTaskAction() { @@ -44,10 +64,33 @@ public class GenerateBuildConfig extends IncrementalTask { File destinationDir = getSourceOutputDir() emptyFolder(destinationDir) - getBuilder().generateBuildConfig( - getPackageName(), - isDebuggable(), - getJavaLines(), - getSourceOutputDir().absolutePath); + BuildConfigGenerator generator = new BuildConfigGenerator( + getSourceOutputDir().absolutePath, + getBuildConfigPackageName()); + + // Hack (see IDEA-100046): We want to avoid reporting "condition is always true" + // from the data flow inspection, so use a non-constant value. However, that defeats + // the purpose of this flag (when not in debug mode, if (BuildConfig.DEBUG && ...) will + // be completely removed by the compiler), so as a hack we do it only for the case + // where debug is true, which is the most likely scenario while the user is looking + // at source code. + //map.put(PH_DEBUG, Boolean.toString(mDebug)); + generator.addField("boolean", "DEBUG", getDebuggable() ? "Boolean.parseBoolean(\"true\")" : "false") + .addField("String", "PACKAGE_NAME", "\"${getAppPackageName()}\"") + .addField("String", "BUILD_TYPE", "\"${getBuildTypeName()}\"") + .addField("String", "FLAVOR", "\"${getFlavorName()}\"") + .addField("int", "VERSION_CODE", Integer.toString(getVersionCode())) + .addItems(getItems()); + + if (getVersionName() != null) { + generator.addField("String", "VERSION_NAME", "\"${getVersionName()}\"") + } + + int i = 1; + for (String name : getFlavorNames()) { + generator.addField("String", "FLAVOR${i++}", "\"$name\"") + } + + generator.generate(); } } diff --git a/tests/basic/build.gradle b/tests/basic/build.gradle index b020f58..b713714 100644 --- a/tests/basic/build.gradle +++ b/tests/basic/build.gradle @@ -43,8 +43,8 @@ android { testInstrumentationRunner "android.test.InstrumentationTestRunner" testHandleProfiling false - buildConfig "private final static boolean DEFAULT = true;", \ - "private final static String FOO = \"foo\";" + buildConfigField "boolean", "DEFAULT", "true" + buildConfigField "String", "FOO", "\"foo\"" } buildTypes { @@ -52,7 +52,7 @@ android { packageNameSuffix ".debug" signingConfig signingConfigs.myConfig - buildConfig "private final static boolean DEBUG2 = false;" + buildConfigField "String", "FOO", "\"bar\"" } } diff --git a/tests/basic/src/instrumentTest/java/com/android/tests/basic/MainTest.java b/tests/basic/src/instrumentTest/java/com/android/tests/basic/MainTest.java index 7cf7329..9f4b2de 100644 --- a/tests/basic/src/instrumentTest/java/com/android/tests/basic/MainTest.java +++ b/tests/basic/src/instrumentTest/java/com/android/tests/basic/MainTest.java @@ -34,5 +34,10 @@ public class MainTest extends ActivityInstrumentationTestCase2
{ public void testPreconditions() { assertNotNull(mTextView); } + + @MediumTest + public void testBuildConfig() { + assertEquals("bar", BuildConfig.FOO); + } } diff --git a/tests/flavored/build.gradle b/tests/flavored/build.gradle index 41e50d9..d08c3fe 100644 --- a/tests/flavored/build.gradle +++ b/tests/flavored/build.gradle @@ -15,28 +15,23 @@ android { testBuildType = "staging" defaultConfig { - buildConfig "private final static boolean DEFAULT = true;", \ - "private final static String FOO = \"foo\";" } productFlavors { f1 { packageName = "com.android.tests.flavored.f1" versionName = "1.0.0-f1" - buildConfig "public final static String FLAVOR = \"f1\";" } f2 { packageName = "com.android.tests.flavored.f2" versionName = "1.0.0-f2" - buildConfig "public final static String FLAVOR = \"f2\";" } } - + buildTypes { debug { packageNameSuffix = ".debug" versionNameSuffix = ".D" - buildConfig "private final static boolean DEBUG2 = false;" } staging { packageNameSuffix = ".staging" diff --git a/tests/flavors/build.gradle b/tests/flavors/build.gradle index d3f5940..1b1c683 100644 --- a/tests/flavors/build.gradle +++ b/tests/flavors/build.gradle @@ -17,21 +17,16 @@ android { productFlavors { f1 { flavorGroup "group1" - - buildConfig "public final static String GROUP1 = \"F1\";" } f2 { flavorGroup "group1" - buildConfig "public final static String GROUP1 = \"F2\";" } fa { flavorGroup "group2" - buildConfig "public final static String GROUP2 = \"FA\";" } fb { flavorGroup "group2" - buildConfig "public final static String GROUP2 = \"FB\";" } } } diff --git a/tests/flavors/src/f1/java/com/android/tests/flavors/group1/SomeClass.java b/tests/flavors/src/f1/java/com/android/tests/flavors/group1/SomeClass.java index a5c30b2..ffbf5ab 100644 --- a/tests/flavors/src/f1/java/com/android/tests/flavors/group1/SomeClass.java +++ b/tests/flavors/src/f1/java/com/android/tests/flavors/group1/SomeClass.java @@ -2,6 +2,6 @@ package com.android.tests.flavors.group1; public class SomeClass { public static String getString() { - return "F1"; + return "f1"; } } \ No newline at end of file diff --git a/tests/flavors/src/f1/res/values/strings.xml b/tests/flavors/src/f1/res/values/strings.xml index 73e7584..b4db3e8 100644 --- a/tests/flavors/src/f1/res/values/strings.xml +++ b/tests/flavors/src/f1/res/values/strings.xml @@ -1,7 +1,7 @@ - F1 - F1 + f1 + f1 \ No newline at end of file diff --git a/tests/flavors/src/f2/java/com/android/tests/flavors/group1/SomeClass.java b/tests/flavors/src/f2/java/com/android/tests/flavors/group1/SomeClass.java index 5974587..09327a6 100644 --- a/tests/flavors/src/f2/java/com/android/tests/flavors/group1/SomeClass.java +++ b/tests/flavors/src/f2/java/com/android/tests/flavors/group1/SomeClass.java @@ -2,6 +2,6 @@ package com.android.tests.flavors.group1; public class SomeClass { public static String getString() { - return "F2"; + return "f2"; } } \ No newline at end of file diff --git a/tests/flavors/src/f2/res/values/strings.xml b/tests/flavors/src/f2/res/values/strings.xml index 855e7f6..7a306fc 100644 --- a/tests/flavors/src/f2/res/values/strings.xml +++ b/tests/flavors/src/f2/res/values/strings.xml @@ -1,7 +1,7 @@ - F2 - F2 + f2 + f2 \ No newline at end of file diff --git a/tests/flavors/src/fa/java/com/android/tests/flavors/group2/SomeClass.java b/tests/flavors/src/fa/java/com/android/tests/flavors/group2/SomeClass.java index 40a939e..ae7677b 100644 --- a/tests/flavors/src/fa/java/com/android/tests/flavors/group2/SomeClass.java +++ b/tests/flavors/src/fa/java/com/android/tests/flavors/group2/SomeClass.java @@ -2,6 +2,6 @@ package com.android.tests.flavors.group2; public class SomeClass { public static String getString() { - return "FA"; + return "fa"; } } \ No newline at end of file diff --git a/tests/flavors/src/fa/res/values/strings.xml b/tests/flavors/src/fa/res/values/strings.xml index 331cb90..f8cefe7 100644 --- a/tests/flavors/src/fa/res/values/strings.xml +++ b/tests/flavors/src/fa/res/values/strings.xml @@ -1,7 +1,7 @@ - FA - FA + fa + fa \ No newline at end of file diff --git a/tests/flavors/src/fb/java/com/android/tests/flavors/group2/SomeClass.java b/tests/flavors/src/fb/java/com/android/tests/flavors/group2/SomeClass.java index 7441b61..5768d64 100644 --- a/tests/flavors/src/fb/java/com/android/tests/flavors/group2/SomeClass.java +++ b/tests/flavors/src/fb/java/com/android/tests/flavors/group2/SomeClass.java @@ -2,6 +2,6 @@ package com.android.tests.flavors.group2; public class SomeClass { public static String getString() { - return "FB"; + return "fb"; } } \ No newline at end of file diff --git a/tests/flavors/src/fb/res/values/strings.xml b/tests/flavors/src/fb/res/values/strings.xml index fa0733f..8fa24dc 100644 --- a/tests/flavors/src/fb/res/values/strings.xml +++ b/tests/flavors/src/fb/res/values/strings.xml @@ -1,7 +1,7 @@ - FB - FB + fb + fb \ No newline at end of file diff --git a/tests/flavors/src/instrumentTestF1/java/com/android/tests/flavors/MainActivityGroup1Test.java b/tests/flavors/src/instrumentTestF1/java/com/android/tests/flavors/MainActivityGroup1Test.java index 2c043ef..9379d96 100644 --- a/tests/flavors/src/instrumentTestF1/java/com/android/tests/flavors/MainActivityGroup1Test.java +++ b/tests/flavors/src/instrumentTestF1/java/com/android/tests/flavors/MainActivityGroup1Test.java @@ -80,17 +80,17 @@ public class MainActivityGroup1Test extends ActivityInstrumentationTestCase2