Unverified Commit 368cd7da authored by Pranay Airan's avatar Pranay Airan Committed by GitHub

Adding support for android app bundle - Issue #17829 (#24440)

* adding support for android app bundle.

* removing the debug statement.

* fixing formatting and code review changes.

* Revert "fixing formatting and code review changes."

This reverts commit 2041d459f335242555a0b75e445343134c245494.

* Fixing code formatting issues.

* updating review comments fixing comments and spacing.

* changing and to & to rerun the CI and tests.

* updating the comment to re-run the test

updating the comment to re-run the test

* fixing the formatting.

* updating comments to re-trigger build

updating comments to re-trigger build
parent 8426910a
......@@ -44,5 +44,6 @@ Future<void> buildApk({
project: project,
buildInfo: buildInfo,
target: target,
isBuildingBundle: false
);
}
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:meta/meta.dart';
import '../base/common.dart';
import '../build_info.dart';
import '../globals.dart';
import '../project.dart';
import 'android_sdk.dart';
import 'gradle.dart';
Future<void> buildAppBundle({
@required FlutterProject project,
@required String target,
BuildInfo buildInfo = BuildInfo.debug
}) async {
if (!project.android.isUsingGradle) {
throwToolExit(
'The build process for Android has changed, and the current project configuration\n'
'is no longer valid. Please consult\n\n'
'https://github.com/flutter/flutter/wiki/Upgrading-Flutter-projects-to-build-with-gradle\n\n'
'for details on how to upgrade the project.'
);
}
// Validate that we can find an android sdk.
if (androidSdk == null)
throwToolExit('No Android SDK found. Try setting the ANDROID_HOME environment variable.');
final List<String> validationResult = androidSdk.validateSdkWellFormed();
if (validationResult.isNotEmpty) {
for (String message in validationResult) {
printError(message, wrap: false);
}
throwToolExit('Try re-installing or updating your Android SDK.');
}
return buildGradleProject(
project: project,
buildInfo: buildInfo,
target: target,
isBuildingBundle: true
);
}
......@@ -12,6 +12,7 @@ import '../globals.dart';
import '../runner/flutter_command.dart';
import 'build_aot.dart';
import 'build_apk.dart';
import 'build_appbundle.dart';
import 'build_bundle.dart';
import 'build_flx.dart';
import 'build_ios.dart';
......@@ -19,6 +20,7 @@ import 'build_ios.dart';
class BuildCommand extends FlutterCommand {
BuildCommand({bool verboseHelp = false}) {
addSubcommand(BuildApkCommand(verboseHelp: verboseHelp));
addSubcommand(BuildAppBundleCommand(verboseHelp: verboseHelp));
addSubcommand(BuildAotCommand());
addSubcommand(BuildIOSCommand());
addSubcommand(BuildFlxCommand());
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import '../android/app_bundle.dart';
import '../project.dart';
import '../runner/flutter_command.dart' show FlutterCommandResult;
import 'build.dart';
class BuildAppBundleCommand extends BuildSubCommand {
BuildAppBundleCommand({bool verboseHelp = false}) {
usesTargetOption();
addBuildModeFlags();
usesFlavorOption();
usesPubOption();
usesBuildNumberOption();
usesBuildNameOption();
argParser
..addFlag('track-widget-creation', negatable: false, hide: !verboseHelp)
..addFlag('build-shared-library',
negatable: false,
help: 'Whether to prefer compiling to a *.so file (android only).',
)
..addOption('target-platform',
defaultsTo: 'android-arm',
allowed: <String>['android-arm', 'android-arm64']);
}
@override
final String name = 'appbundle';
@override
final String description = 'Build an Android App Bundle file from your app.\n\n'
'This command can build debug and release versions of an app bundle for your application. \'debug\' builds support '
'debugging and a quick development cycle. \'release\' builds don\'t support debugging and are '
'suitable for deploying to app stores. \n app bundle improves your app size';
@override
Future<FlutterCommandResult> runCommand() async {
await super.runCommand();
await buildAppBundle(
project: await FlutterProject.current(),
target: targetFile,
buildInfo: getBuildInfo(),
);
return null;
}
}
......@@ -361,6 +361,10 @@ class AndroidProject {
return fs.directory(fs.path.join(hostAppGradleRoot.path, 'app', 'build', 'outputs', 'apk'));
}
Directory get gradleAppBundleOutV1Directory {
return fs.directory(fs.path.join(hostAppGradleRoot.path, 'app', 'build', 'outputs', 'bundle'));
}
bool get isUsingGradle {
return hostAppGradleRoot.childFile('build.gradle').existsSync();
}
......
......@@ -113,35 +113,65 @@ someOtherTask
expect(project.productFlavors, <String>['free', 'paid']);
});
test('should provide apk file name for default build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>[], fs.directory('/some/dir'));
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>[], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.apkFileFor(BuildInfo.debug), 'app-debug.apk');
expect(project.apkFileFor(BuildInfo.profile), 'app-profile.apk');
expect(project.apkFileFor(BuildInfo.release), 'app-release.apk');
expect(project.apkFileFor(const BuildInfo(BuildMode.release, 'unknown')), isNull);
});
test('should provide apk file name for flavored build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>['free', 'paid'], fs.directory('/some/dir'));
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>['free', 'paid'], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.apkFileFor(const BuildInfo(BuildMode.debug, 'free')), 'app-free-debug.apk');
expect(project.apkFileFor(const BuildInfo(BuildMode.release, 'paid')), 'app-paid-release.apk');
expect(project.apkFileFor(const BuildInfo(BuildMode.release, 'unknown')), isNull);
});
test('should provide bundle file name for default build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>[], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.bundleFileFor(BuildInfo.debug), 'app.aab');
expect(project.bundleFileFor(BuildInfo.profile), 'app.aab');
expect(project.bundleFileFor(BuildInfo.release), 'app.aab');
expect(project.bundleFileFor(const BuildInfo(BuildMode.release, 'unknown')), 'app.aab');
});
test('should provide bundle file name for flavored build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>['free', 'paid'], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.bundleFileFor(const BuildInfo(BuildMode.debug, 'free')), 'app.aab');
expect(project.bundleFileFor(const BuildInfo(BuildMode.release, 'paid')), 'app.aab');
expect(project.bundleFileFor(const BuildInfo(BuildMode.release, 'unknown')), 'app.aab');
});
test('should provide assemble task name for default build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>[], fs.directory('/some/dir'));
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>[], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.assembleTaskFor(BuildInfo.debug), 'assembleDebug');
expect(project.assembleTaskFor(BuildInfo.profile), 'assembleProfile');
expect(project.assembleTaskFor(BuildInfo.release), 'assembleRelease');
expect(project.assembleTaskFor(const BuildInfo(BuildMode.release, 'unknown')), isNull);
});
test('should provide assemble task name for flavored build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>['free', 'paid'], fs.directory('/some/dir'));
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>['free', 'paid'], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.assembleTaskFor(const BuildInfo(BuildMode.debug, 'free')), 'assembleFreeDebug');
expect(project.assembleTaskFor(const BuildInfo(BuildMode.release, 'paid')), 'assemblePaidRelease');
expect(project.assembleTaskFor(const BuildInfo(BuildMode.release, 'unknown')), isNull);
});
test('should respect format of the flavored build types', () {
final GradleProject project = GradleProject(<String>['debug'], <String>['randomFlavor'], fs.directory('/some/dir'));
final GradleProject project = GradleProject(<String>['debug'], <String>['randomFlavor'], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.assembleTaskFor(const BuildInfo(BuildMode.debug, 'randomFlavor')), 'assembleRandomFlavorDebug');
});
test('bundle should provide assemble task name for default build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>[], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.bundleTaskFor(BuildInfo.debug), 'bundleDebug');
expect(project.bundleTaskFor(BuildInfo.profile), 'bundleProfile');
expect(project.bundleTaskFor(BuildInfo.release), 'bundleRelease');
expect(project.bundleTaskFor(const BuildInfo(BuildMode.release, 'unknown')), isNull);
});
test('bundle should provide assemble task name for flavored build types', () {
final GradleProject project = GradleProject(<String>['debug', 'profile', 'release'], <String>['free', 'paid'], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.bundleTaskFor(const BuildInfo(BuildMode.debug, 'free')), 'bundleFreeDebug');
expect(project.bundleTaskFor(const BuildInfo(BuildMode.release, 'paid')), 'bundlePaidRelease');
expect(project.bundleTaskFor(const BuildInfo(BuildMode.release, 'unknown')), isNull);
});
test('bundle should respect format of the flavored build types', () {
final GradleProject project = GradleProject(<String>['debug'], <String>['randomFlavor'], fs.directory('/some/dir'),fs.directory('/some/dir'));
expect(project.bundleTaskFor(const BuildInfo(BuildMode.debug, 'randomFlavor')), 'bundleRandomFlavorDebug');
});
});
group('Gradle local.properties', () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment