Skip to content

Commit 1860059

Browse files
committed
feat: inital work on Android Application Bundle Build (.aab)
1 parent be0701b commit 1860059

File tree

7 files changed

+50
-17
lines changed

7 files changed

+50
-17
lines changed

lib/commands/build.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ export abstract class BuildCommandBase extends ValidatePlatformCommandBase {
4141
keyStoreAlias: this.$options.keyStoreAlias,
4242
keyStorePath: this.$options.keyStorePath,
4343
keyStoreAliasPassword: this.$options.keyStoreAliasPassword,
44-
keyStorePassword: this.$options.keyStorePassword
44+
keyStorePassword: this.$options.keyStorePassword,
45+
androidBundle: this.$options.aab
4546
};
4647
await this.$platformService.buildPlatform(platform, buildConfig, this.$projectData);
4748
if (this.$options.copyTo) {

lib/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ export const BUILD_XCCONFIG_FILE_NAME = "build.xcconfig";
3333
export const BUILD_DIR = "build";
3434
export const OUTPUTS_DIR = "outputs";
3535
export const APK_DIR = "apk";
36+
export const BUNDLE_DIR = "bundle";
3637
export const RESOURCES_DIR = "res";
3738
export const CONFIG_NS_FILE_NAME = "nsconfig.json";
3839
export const CONFIG_NS_APP_RESOURCES_ENTRY = "appResourcesPath";
3940
export const CONFIG_NS_APP_ENTRY = "appPath";
4041
export const DEPENDENCIES_JSON_NAME = "dependencies.json";
4142
export const APK_EXTENSION_NAME = ".apk";
43+
export const AAB_EXTENSION_NAME = ".aab"
4244
export const HASHES_FILE_NAME = ".nshashes";
4345

4446
export class PackageVersion {

lib/declarations.d.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,11 @@ interface IPluginSeedOptions {
458458
pluginName: string;
459459
}
460460

461-
interface IOptions extends IRelease, IDeviceIdentifier, IJustLaunch, IAvd, IAvailableDevices, IProfileDir, IHasEmulatorOption, IBundleString, IPlatformTemplate, IHasEmulatorOption, IClean, IProvision, ITeamIdentifier, IAndroidReleaseOptions, INpmInstallConfigurationOptions, IPort, IEnvOptions, IPluginSeedOptions, IGenerateOptions {
461+
interface IAndroidBundleOptions {
462+
aab: boolean;
463+
}
464+
465+
interface IOptions extends IRelease, IDeviceIdentifier, IJustLaunch, IAvd, IAvailableDevices, IProfileDir, IHasEmulatorOption, IBundleString, IPlatformTemplate, IHasEmulatorOption, IClean, IProvision, ITeamIdentifier, IAndroidReleaseOptions, IAndroidBundleOptions, INpmInstallConfigurationOptions, IPort, IEnvOptions, IPluginSeedOptions, IGenerateOptions {
462466
argv: IYargArgv;
463467
validateOptions(commandSpecificDashedOptions?: IDictionary<IDashedOption>): void;
464468
options: IDictionary<IDashedOption>;
@@ -531,7 +535,11 @@ interface IEnvOptions {
531535
env: Object;
532536
}
533537

534-
interface IAndroidBuildOptionsSettings extends IAndroidReleaseOptions, IRelease { }
538+
interface IAndroidBuildOptionsSettings extends IAndroidReleaseOptions, IRelease, IAndroidBundle { }
539+
540+
interface IAndroidBundle {
541+
androidBundle?: boolean;
542+
}
535543

536544
interface IAppFilesUpdaterOptions extends IBundle, IRelease, IOptionalWatchAllFiles, IHasUseHotModuleReloadOption { }
537545

lib/definitions/platform.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ interface IPlatformData {
268268
normalizedPlatformName: string;
269269
appDestinationDirectoryPath: string;
270270
deviceBuildOutputPath: string;
271+
bundleBuildOutputPath?: string;
271272
emulatorBuildOutputPath?: string;
272273
getValidBuildOutputData(buildOptions: IBuildOutputOptions): IValidBuildOutputData;
273274
frameworkFilesExtensions: string[];
@@ -285,7 +286,7 @@ interface IValidBuildOutputData {
285286
regexes?: RegExp[];
286287
}
287288

288-
interface IBuildOutputOptions {
289+
interface IBuildOutputOptions extends IAndroidBundle {
289290
isReleaseBuild?: boolean;
290291
isForDevice?: boolean;
291292
}

lib/options.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ export class Options {
115115
default: { type: OptionType.Boolean },
116116
count: { type: OptionType.Number },
117117
hooks: { type: OptionType.Boolean, default: true },
118-
link: { type: OptionType.Boolean, default: false }
118+
link: { type: OptionType.Boolean, default: false },
119+
aab: { type: OptionType.Boolean }
119120
};
120121
}
121122

lib/services/android-project-service.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,25 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
7474
platformProjectService: this,
7575
projectRoot: projectRoot,
7676
deviceBuildOutputPath: path.join(...deviceBuildOutputArr),
77+
bundleBuildOutputPath: path.join(projectRoot, constants.APP_FOLDER_NAME, constants.BUILD_DIR, constants.OUTPUTS_DIR, constants.BUNDLE_DIR),
7778
getValidBuildOutputData: (buildOptions: IBuildOutputOptions): IValidBuildOutputData => {
7879
const buildMode = buildOptions.isReleaseBuild ? Configurations.Release.toLowerCase() : Configurations.Debug.toLowerCase();
7980

81+
if(buildOptions.androidBundle) {
82+
return {
83+
packageNames: [
84+
`${constants.APP_FOLDER_NAME}${constants.AAB_EXTENSION_NAME}`
85+
]
86+
}
87+
}
88+
8089
return {
8190
packageNames: [
8291
`${packageName}-${buildMode}${constants.APK_EXTENSION_NAME}`,
8392
`${projectData.projectName}-${buildMode}${constants.APK_EXTENSION_NAME}`,
8493
`${projectData.projectName}${constants.APK_EXTENSION_NAME}`,
8594
`${constants.APP_FOLDER_NAME}-${buildMode}${constants.APK_EXTENSION_NAME}`
95+
8696
],
8797
regexes: [new RegExp(`${constants.APP_FOLDER_NAME}-.*-(${Configurations.Debug}|${Configurations.Release})${constants.APK_EXTENSION_NAME}`, "i"), new RegExp(`${packageName}-.*-(${Configurations.Debug}|${Configurations.Release})${constants.APK_EXTENSION_NAME}`, "i")]
8898
};
@@ -316,17 +326,21 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
316326
}
317327

318328
public async buildProject(projectRoot: string, projectData: IProjectData, buildConfig: IBuildConfig): Promise<void> {
329+
let task;
319330
const gradleArgs = this.getGradleBuildOptions(buildConfig, projectData);
331+
const baseTask = buildConfig.androidBundle ? "bundle" : "assemble";
320332
if (this.$logger.getLevel() === "TRACE") {
321333
gradleArgs.unshift("--stacktrace");
322334
gradleArgs.unshift("--debug");
323335
}
324336
if (buildConfig.release) {
325-
gradleArgs.unshift("assembleRelease");
337+
task = baseTask + "Release";
326338
} else {
327-
gradleArgs.unshift("assembleDebug");
339+
task = baseTask + "Debug";
328340
}
329341

342+
gradleArgs.unshift(task);
343+
330344
const handler = (data: any) => {
331345
this.emit(constants.BUILD_OUTPUT_EVENT_NAME, data);
332346
};

lib/services/platform-service.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
373373
return true;
374374
}
375375

376-
const validBuildOutputData = platformData.getValidBuildOutputData({ isForDevice: forDevice });
376+
const validBuildOutputData = platformData.getValidBuildOutputData({ isForDevice: forDevice, isReleaseBuild: buildConfig.release });
377377
const packages = this.getApplicationPackages(outputPath, validBuildOutputData);
378378
if (packages.length === 0) {
379379
return true;
@@ -449,7 +449,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
449449

450450
await attachAwaitDetach(constants.BUILD_OUTPUT_EVENT_NAME, platformData.platformProjectService, handler, platformData.platformProjectService.buildProject(platformData.projectRoot, projectData, buildConfig));
451451

452-
const buildInfoFilePath = this.getBuildOutputPath(platform, platformData, buildConfig);
452+
const buildInfoFilePath = this.getBuildOutputPath(platform, platformData, { isForDevice: buildConfig.buildForDevice, isReleaseBuild: buildConfig.release, androidBundle: buildConfig.androidBundle });
453453
this.saveBuildInfoFile(platform, projectData.projectDir, buildInfoFilePath);
454454

455455
this.$logger.out("Project successfully built.");
@@ -468,15 +468,15 @@ export class PlatformService extends EventEmitter implements IPlatformService {
468468
this.$fs.writeJson(buildInfoFile, buildInfo);
469469
}
470470

471-
public async shouldInstall(device: Mobile.IDevice, projectData: IProjectData, release: IBuildConfig, outputPath?: string): Promise<boolean> {
471+
public async shouldInstall(device: Mobile.IDevice, projectData: IProjectData, release: IRelease, outputPath?: string): Promise<boolean> {
472472
const platform = device.deviceInfo.platform;
473473
if (!(await device.applicationManager.isApplicationInstalled(projectData.projectIdentifiers[platform.toLowerCase()]))) {
474474
return true;
475475
}
476476

477477
const platformData = this.$platformsData.getPlatformData(platform, projectData);
478478
const deviceBuildInfo: IBuildInfo = await this.getDeviceBuildInfo(device, projectData);
479-
const localBuildInfo = this.getBuildInfo(platform, platformData, { buildForDevice: !device.isEmulator }, outputPath);
479+
const localBuildInfo = this.getBuildInfo(platform, platformData, { isForDevice: !device.isEmulator, isReleaseBuild: release.release }, outputPath);
480480
return !localBuildInfo || !deviceBuildInfo || deviceBuildInfo.buildTime !== localBuildInfo.buildTime;
481481
}
482482

@@ -514,7 +514,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
514514
const deviceFilePath = await this.getDeviceBuildInfoFilePath(device, projectData);
515515
const options = buildConfig;
516516
options.buildForDevice = !device.isEmulator;
517-
const buildInfoFilePath = outputFilePath || this.getBuildOutputPath(device.deviceInfo.platform, platformData, options);
517+
const buildInfoFilePath = outputFilePath || this.getBuildOutputPath(device.deviceInfo.platform, platformData, { isForDevice: buildConfig.buildForDevice, isReleaseBuild: buildConfig.release, androidBundle: buildConfig.androidBundle });
518518
const appIdentifier = projectData.projectIdentifiers[platform];
519519

520520
await device.fileSystem.putFile(path.join(buildInfoFilePath, buildInfoFileName), deviceFilePath, appIdentifier);
@@ -611,9 +611,13 @@ export class PlatformService extends EventEmitter implements IPlatformService {
611611
await this.$devicesService.execute(action, this.getCanExecuteAction(platform, runOptions));
612612
}
613613

614-
private getBuildOutputPath(platform: string, platformData: IPlatformData, options: IBuildForDevice): string {
614+
private getBuildOutputPath(platform: string, platformData: IPlatformData, options: IBuildOutputOptions): string {
615+
if(options.androidBundle) {
616+
return platformData.bundleBuildOutputPath;
617+
}
618+
615619
if (platform.toLowerCase() === this.$devicePlatformsConstants.iOS.toLowerCase()) {
616-
return options.buildForDevice ? platformData.deviceBuildOutputPath : platformData.emulatorBuildOutputPath;
620+
return options.isForDevice ? platformData.deviceBuildOutputPath : platformData.emulatorBuildOutputPath;
617621
}
618622

619623
return platformData.deviceBuildOutputPath;
@@ -637,7 +641,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
637641
}
638642
}
639643

640-
private getBuildInfo(platform: string, platformData: IPlatformData, options: IBuildForDevice, buildOutputPath?: string): IBuildInfo {
644+
private getBuildInfo(platform: string, platformData: IPlatformData, options: IBuildOutputOptions, buildOutputPath?: string): IBuildInfo {
641645
buildOutputPath = buildOutputPath || this.getBuildOutputPath(platform, platformData, options);
642646
const buildInfoFile = path.join(buildOutputPath, buildInfoFileName);
643647
if (this.$fs.exists(buildInfoFile)) {
@@ -899,11 +903,13 @@ export class PlatformService extends EventEmitter implements IPlatformService {
899903
}
900904

901905
public getLatestApplicationPackageForDevice(platformData: IPlatformData, buildConfig: IBuildConfig, outputPath?: string): IApplicationPackage {
902-
return this.getLatestApplicationPackage(outputPath || platformData.deviceBuildOutputPath, platformData.getValidBuildOutputData({ isForDevice: true, isReleaseBuild: buildConfig.release }));
906+
return this.getLatestApplicationPackage(outputPath || platformData.deviceBuildOutputPath, platformData.getValidBuildOutputData({ isForDevice: true, isReleaseBuild: buildConfig.release, androidBundle: buildConfig.androidBundle }));
903907
}
904908

905909
public getLatestApplicationPackageForEmulator(platformData: IPlatformData, buildConfig: IBuildConfig, outputPath?: string): IApplicationPackage {
906-
return this.getLatestApplicationPackage(outputPath || platformData.emulatorBuildOutputPath || platformData.deviceBuildOutputPath, platformData.getValidBuildOutputData({ isForDevice: false, isReleaseBuild: buildConfig.release }));
910+
const buildOutputOptions: IBuildOutputOptions = { isForDevice: false, isReleaseBuild: buildConfig.release, androidBundle: buildConfig.androidBundle };
911+
outputPath = outputPath || this.getBuildOutputPath(platformData.normalizedPlatformName.toLowerCase(), platformData, buildOutputOptions);
912+
return this.getLatestApplicationPackage(outputPath || platformData.emulatorBuildOutputPath || platformData.deviceBuildOutputPath, platformData.getValidBuildOutputData(buildOutputOptions));
907913
}
908914

909915
private async updatePlatform(platform: string, version: string, platformTemplate: string, projectData: IProjectData, config: IPlatformOptions): Promise<void> {

0 commit comments

Comments
 (0)