Skip to content

Commit

Permalink
Add --incompatible_use_aapt2_by_default incompatible change (IC) flag…
Browse files Browse the repository at this point in the history
… for enabling aapt2 by default in Bazel.

FR Ref: #4103
IC Ref: #6907

RELNOTES: New incompatible change flag for defaulting to aapt2 in Android builds: `--incompatible_use_aapt2_by_default`. To build with aapt2 today, pass the flag `--incompatible_use_aapt2_by_default=true` or `--android_aapt=aapt2`, or set the `aapt_version`  to `aapt2` on your `android_binary` or `android_local_test` target.
PiperOrigin-RevId: 225593174
  • Loading branch information
jin authored and Copybara-Service committed Dec 14, 2018
1 parent cc4dce3 commit dc7928c
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,23 @@ public static AndroidAaptVersion chooseTargetAaptVersion(RuleContext ruleContext
return null;
}

/**
* Select the aapt version for resource processing actions, based on the combination of
* --android_aapt flag, aapt_version target attribute, and --incompatible_use_aapt2_by_default
* flag.
*
* <p>Order of precedence:
* <li>1. --android_aapt flag
* <li>2. 'aapt_version' attribute on target
* <li>3. --incompatible_use_aapt2_by_default flag
*
* @param dataContext the Android data context for detecting aapt2 and fetching Android configs
* @param errorConsumer the rule context for reporting errors during version selection
* @param attributeString if not null, the aapt version specified by the 'aapt_version' target
* attribute
* @return the selected version: aapt or aapt2
* @throws RuleErrorException error if aapt2 is requested but it's not available in the SDK
*/
@Nullable
public static AndroidAaptVersion chooseTargetAaptVersion(
AndroidDataContext dataContext,
Expand All @@ -257,8 +274,21 @@ public static AndroidAaptVersion chooseTargetAaptVersion(
throw errorConsumer.throwWithRuleError(
"aapt2 processing requested but not available on the android_sdk");
}
// If version is auto, assume aapt.
return version == AndroidAaptVersion.AUTO ? AAPT : version;

if (version != AndroidAaptVersion.AUTO) {
return version;
}

// At this point, the version is still auto. If the user passes
// --incompatible_use_aapt2_by_default explicitly or implicitly via
// --all_incompatible_changes, use aapt2 by default.
//
// We use the --incompatible_use_aapt2_by_default flag to signal a breaking change in Bazel.
// This is required by the Bazel Incompatible Changes policy.
//
// TODO(jingwen): We can remove the incompatible change flag only when the depot migration is
// complete and the default value of --android_aapt is switched from `auto` to `aapt2`.
return dataContext.getAndroidConfig().incompatibleChangeUseAapt2ByDefault() ? AAPT2 : AAPT;
}
}

Expand Down Expand Up @@ -867,6 +897,21 @@ public static class Options extends FragmentOptions {
help = "Tracking flag for when busybox workers are enabled.")
public boolean persistentBusyboxTools;

@Option(
name = "incompatible_use_aapt2_by_default",
documentationCategory = OptionDocumentationCategory.TOOLCHAIN,
effectTags = {OptionEffectTag.LOSES_INCREMENTAL_STATE, OptionEffectTag.AFFECTS_OUTPUTS},
metadataTags = {
OptionMetadataTag.INCOMPATIBLE_CHANGE,
OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES
},
defaultValue = "false",
help =
"Switch the Android rules to use aapt2 by default for resource processing. "
+ "To resolve issues when migrating your app to build with aapt2, see "
+ "https://developer.android.com/studio/command-line/aapt2#aapt2_changes")
public boolean incompatibleUseAapt2ByDefault;

@Override
public FragmentOptions getHost() {
Options host = (Options) super.getHost();
Expand Down Expand Up @@ -954,6 +999,9 @@ public ImmutableSet<Class<? extends FragmentOptions>> requiredOptions() {
private final boolean persistentBusyboxTools;
private final boolean filterRJarsFromAndroidTest;

// Incompatible changes
private final boolean incompatibleUseAapt2ByDefault;

private AndroidConfiguration(Options options) throws InvalidConfigurationException {
this.sdk = options.sdk;
this.useIncrementalNativeLibs = options.incrementalNativeLibs;
Expand Down Expand Up @@ -997,6 +1045,7 @@ private AndroidConfiguration(Options options) throws InvalidConfigurationExcepti
this.dataBindingV2 = options.dataBindingV2;
this.persistentBusyboxTools = options.persistentBusyboxTools;
this.filterRJarsFromAndroidTest = options.filterRJarsFromAndroidTest;
this.incompatibleUseAapt2ByDefault = options.incompatibleUseAapt2ByDefault;

if (incrementalDexingShardsAfterProguard < 0) {
throw new InvalidConfigurationException(
Expand Down Expand Up @@ -1208,6 +1257,10 @@ public boolean persistentBusyboxTools() {
return persistentBusyboxTools;
}

public boolean incompatibleChangeUseAapt2ByDefault() {
return incompatibleUseAapt2ByDefault;
}

@Override
public String getOutputDirectoryName() {
return configurationDistinguisher.suffix;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,28 @@ public void testProcessBinaryDataGeneratesProguardOutput() throws Exception {
assertThat(resourceApk.getMainDexProguardConfig()).isNotNull();
}

@Test
public void test_incompatibleUseAapt2ByDefaultEnabled_targetsAapt2() throws Exception {
mockAndroidSdkWithAapt2();
useConfiguration("--android_sdk=//sdk:sdk", "--incompatible_use_aapt2_by_default");
RuleContext ruleContext =
getRuleContext(
"android_binary", "aapt_version = 'auto',", "manifest = 'AndroidManifest.xml',");
assertThat(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext))
.isEqualTo(AndroidAaptVersion.AAPT2);
}

@Test
public void test_incompatibleUseAapt2ByDefaultDisabled_targetsAapt() throws Exception {
mockAndroidSdkWithAapt2();
useConfiguration("--android_sdk=//sdk:sdk", "--noincompatible_use_aapt2_by_default");
RuleContext ruleContext =
getRuleContext(
"android_binary", "aapt_version = 'auto',", "manifest = 'AndroidManifest.xml',");
assertThat(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext))
.isEqualTo(AndroidAaptVersion.AAPT);
}

/**
* Validates that a parse action was invoked correctly. Returns the {@link ParsedAndroidResources}
* for further validation.
Expand Down

0 comments on commit dc7928c

Please sign in to comment.