Skip to content

Commit bc52ef9

Browse files
Get latest application package for current specified configuration
When we try to get the latest application package for device/emulator, we check the build output directory and get latest available .apk/.ipa. However this is not always correct as sometimes we do not build the app. Consider the following case: * tns build android --release * tns build android * tns build android --release At the last point, the build will not be executed, as there are no changes. However the last built .apk is from the debug build (we have release .apk, but it's older). So in case we try to get the last build output from last operation, CLI will return the debug.apk Fix this by checking the current build configuration and get the latest result by using it. For iOS respect the expected output - is it for device or for simulator as the output is different.
1 parent 2cb3ac3 commit bc52ef9

12 files changed

+49
-39
lines changed

lib/commands/appstore-upload.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export class PublishIOS implements ICommand {
7373
// This is not very correct as if we build multiple targets we will try to sign all of them using the signing identity here.
7474
await this.$platformService.preparePlatform(platform, appFilesUpdaterOptions, this.$options.platformTemplate, this.$projectData, { provision: this.$options.provision, sdk: this.$options.sdk });
7575
await this.$platformService.buildPlatform(platform, iOSBuildConfig, this.$projectData);
76-
ipaFilePath = this.$platformService.lastOutputPath(platform, { isForDevice: iOSBuildConfig.buildForDevice }, this.$projectData);
76+
ipaFilePath = this.$platformService.lastOutputPath(platform, { isForDevice: iOSBuildConfig.buildForDevice, isReleaseBuild: iOSBuildConfig.release }, this.$projectData);
7777
} else {
7878
this.$logger.info("No .ipa, mobile provision or certificate set. Perfect! Now we'll build .xcarchive and let Xcode pick the distribution certificate and provisioning profile for you when exporting .ipa for AppStore submission.");
7979
await this.$platformService.preparePlatform(platform, appFilesUpdaterOptions, this.$options.platformTemplate, this.$projectData, { provision: this.$options.provision, sdk: this.$options.sdk });

lib/commands/build.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class BuildCommandBase {
2626
};
2727
await this.$platformService.buildPlatform(platform, buildConfig, this.$projectData);
2828
if (this.$options.copyTo) {
29-
this.$platformService.copyLastOutput(platform, this.$options.copyTo, { isForDevice: this.$options.forDevice }, this.$projectData);
29+
this.$platformService.copyLastOutput(platform, this.$options.copyTo, { isForDevice: this.$options.forDevice, isReleaseBuild: buildConfig.release }, this.$projectData);
3030
}
3131
}
3232
}

lib/definitions/platform.d.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -143,28 +143,30 @@ interface IPlatformService extends NodeJS.EventEmitter {
143143
/**
144144
* Returns information about the latest built application for device in the current project.
145145
* @param {IPlatformData} platformData Data describing the current platform.
146+
* @param {any} buildOptions Defines if the build is for release configuration.
146147
* @returns {IApplicationPackage} Information about latest built application.
147148
*/
148-
getLatestApplicationPackageForDevice(platformData: IPlatformData): IApplicationPackage;
149+
getLatestApplicationPackageForDevice(platformData: IPlatformData, buildOptions: { isReleaseBuild: boolean }): IApplicationPackage;
149150

150151
/**
151152
* Returns information about the latest built application for simulator in the current project.
152153
* @param {IPlatformData} platformData Data describing the current platform.
154+
* @param {any} buildOptions Defines if the build is for release configuration.
153155
* @returns {IApplicationPackage} Information about latest built application.
154156
*/
155-
getLatestApplicationPackageForEmulator(platformData: IPlatformData): IApplicationPackage;
157+
getLatestApplicationPackageForEmulator(platformData: IPlatformData, buildOptions: { isReleaseBuild: boolean }): IApplicationPackage;
156158

157159
/**
158160
* Copies latest build output to a specified location.
159161
* @param {string} platform Mobile platform - Android, iOS.
160162
* @param {string} targetPath Destination where the build artifact should be copied.
161-
* @param {{isForDevice: boolean}} settings Defines if the searched artifact should be for simulator.
163+
* @param {{isForDevice: boolean, isReleaseBuild: boolean}} settings Defines if the searched artifact should be for simulator and is it built for release.
162164
* @param {IProjectData} projectData DTO with information about the project.
163165
* @returns {void}
164166
*/
165-
copyLastOutput(platform: string, targetPath: string, settings: {isForDevice: boolean}, projectData: IProjectData): void;
167+
copyLastOutput(platform: string, targetPath: string, settings: { isForDevice: boolean, isReleaseBuild: boolean }, projectData: IProjectData): void;
166168

167-
lastOutputPath(platform: string, settings: { isForDevice: boolean }, projectData: IProjectData): string;
169+
lastOutputPath(platform: string, settings: { isForDevice: boolean, isReleaseBuild: boolean }, projectData: IProjectData): string;
168170

169171
/**
170172
* Reads contents of a file on device.
@@ -209,8 +211,7 @@ interface IPlatformData {
209211
appDestinationDirectoryPath: string;
210212
deviceBuildOutputPath: string;
211213
emulatorBuildOutputPath?: string;
212-
validPackageNamesForDevice: string[];
213-
validPackageNamesForEmulator?: string[];
214+
getValidPackageNames(buildOptions: { isReleaseBuild?: boolean, isForDevice?: boolean }): string[];
214215
frameworkFilesExtensions: string[];
215216
frameworkDirectoriesExtensions?: string[];
216217
frameworkDirectoriesNames?: string[];

lib/providers/livesync-provider.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ export class LiveSyncProvider implements ILiveSyncProvider {
4545
await this.$platformService.buildPlatform(device.deviceInfo.platform, buildConfig, projectData);
4646
let platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform, projectData);
4747
if (device.isEmulator) {
48-
return this.$platformService.getLatestApplicationPackageForEmulator(platformData).packageName;
48+
return this.$platformService.getLatestApplicationPackageForEmulator(platformData, { isReleaseBuild: buildConfig.release }).packageName;
4949
}
5050

51-
return this.$platformService.getLatestApplicationPackageForDevice(platformData).packageName;
51+
return this.$platformService.getLatestApplicationPackageForDevice(platformData, { isReleaseBuild: buildConfig.release }).packageName;
5252
}
5353

5454
public async preparePlatformForSync(platform: string, provision: any, projectData: IProjectData): Promise<void> {

lib/services/android-debug-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class AndroidDebugService implements IDebugService {
117117
this.$options.forDevice = !!cachedDeviceOption;
118118

119119
let platformData = this.$platformsData.getPlatformData(this.platform, projectData);
120-
packageFile = this.$platformService.getLatestApplicationPackageForDevice(platformData).packageName;
120+
packageFile = this.$platformService.getLatestApplicationPackageForDevice(platformData, { isReleaseBuild: this.$options.release }).packageName;
121121
this.$logger.out("Using ", packageFile);
122122
}
123123

lib/services/android-project-service.ts

+13-6
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,19 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
5757
emulatorServices: this.$androidEmulatorServices,
5858
projectRoot: projectRoot,
5959
deviceBuildOutputPath: path.join(projectRoot, "build", "outputs", "apk"),
60-
validPackageNamesForDevice: [
61-
`${packageName}-debug.apk`,
62-
`${packageName}-release.apk`,
63-
`${projectData.projectName}-debug.apk`,
64-
`${projectData.projectName}-release.apk`
65-
],
60+
getValidPackageNames: (buildOptions: { isReleaseBuild?: boolean, isForDevice?: boolean }): string[] => {
61+
if (buildOptions.isReleaseBuild) {
62+
return [
63+
`${packageName}-release.apk`,
64+
`${projectData.projectName}-release.apk`
65+
];
66+
}
67+
68+
return [
69+
`${packageName}-debug.apk`,
70+
`${projectData.projectName}-debug.apk`,
71+
];
72+
},
6673
frameworkFilesExtensions: [".jar", ".dat", ".so"],
6774
configurationFileName: "AndroidManifest.xml",
6875
configurationFilePath: path.join(projectRoot, "src", "main", "AndroidManifest.xml"),

lib/services/ios-debug-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class IOSDebugService implements IDebugService {
9696
private async emulatorDebugBrk(projectData: IProjectData, shouldBreak?: boolean): Promise<void> {
9797
let platformData = this.$platformsData.getPlatformData(this.platform, projectData);
9898

99-
let emulatorPackage = this.$platformService.getLatestApplicationPackageForEmulator(platformData);
99+
let emulatorPackage = this.$platformService.getLatestApplicationPackageForEmulator(platformData, { isReleaseBuild: this.$options.release });
100100

101101
let args = shouldBreak ? "--nativescript-debug-brk" : "--nativescript-debug-start";
102102
let child_process = await this.$iOSEmulatorServices.runApplicationOnEmulator(emulatorPackage.packageName, {

lib/services/ios-project-service.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,13 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
6464
projectRoot: projectRoot,
6565
deviceBuildOutputPath: path.join(projectRoot, "build", "device"),
6666
emulatorBuildOutputPath: path.join(projectRoot, "build", "emulator"),
67-
validPackageNamesForDevice: [
68-
projectData.projectName + ".ipa"
69-
],
70-
validPackageNamesForEmulator: [
71-
projectData.projectName + ".app"
72-
],
67+
getValidPackageNames: (buildOptions: { isReleaseBuild?: boolean, isForDevice?: boolean }): string[] => {
68+
if (buildOptions.isForDevice) {
69+
return [projectData.projectName + ".ipa"];
70+
}
71+
72+
return [projectData.projectName + ".app"];
73+
},
7374
frameworkFilesExtensions: [".a", ".framework", ".bin"],
7475
frameworkDirectoriesExtensions: [".framework"],
7576
frameworkDirectoriesNames: ["Metadata", "metadataGenerator", "NativeScript", "internal"],

lib/services/local-build-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class LocalBuildService extends EventEmitter {
1717
});
1818
platformBuildOptions.buildOutputStdio = "pipe";
1919
await this.$platformService.buildPlatform(platform, platformBuildOptions, this.$projectData);
20-
return this.$platformService.lastOutputPath(platform, { isForDevice: platformBuildOptions.buildForDevice }, this.$projectData);
20+
return this.$platformService.lastOutputPath(platform, { isForDevice: platformBuildOptions.buildForDevice, isReleaseBuild: platformBuildOptions.release }, this.$projectData);
2121
}
2222
}
2323

lib/services/platform-service.ts

+11-11
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ export class PlatformService extends EventEmitter implements IPlatformService {
363363
if (!this.$fs.exists(outputPath)) {
364364
return true;
365365
}
366-
let packageNames = forDevice ? platformData.validPackageNamesForDevice : platformData.validPackageNamesForEmulator;
366+
let packageNames = platformData.getValidPackageNames({ isForDevice: forDevice });
367367
let packages = this.getApplicationPackages(outputPath, packageNames);
368368
if (packages.length === 0) {
369369
return true;
@@ -429,9 +429,9 @@ export class PlatformService extends EventEmitter implements IPlatformService {
429429
let platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform, projectData);
430430
let packageFile = "";
431431
if (this.$devicesService.isiOSSimulator(device)) {
432-
packageFile = this.getLatestApplicationPackageForEmulator(platformData).packageName;
432+
packageFile = this.getLatestApplicationPackageForEmulator(platformData, { isReleaseBuild: options.release }).packageName;
433433
} else {
434-
packageFile = this.getLatestApplicationPackageForDevice(platformData).packageName;
434+
packageFile = this.getLatestApplicationPackageForDevice(platformData, { isReleaseBuild: options.release }).packageName;
435435
}
436436

437437
await platformData.platformProjectService.cleanDeviceTempFolder(device.deviceInfo.identifier, projectData);
@@ -580,21 +580,21 @@ export class PlatformService extends EventEmitter implements IPlatformService {
580580
appUpdater.cleanDestinationApp();
581581
}
582582

583-
public lastOutputPath(platform: string, settings: { isForDevice: boolean }, projectData: IProjectData): string {
583+
public lastOutputPath(platform: string, settings: { isForDevice: boolean, isReleaseBuild: boolean }, projectData: IProjectData): string {
584584
let packageFile: string;
585585
let platformData = this.$platformsData.getPlatformData(platform, projectData);
586586
if (settings.isForDevice) {
587-
packageFile = this.getLatestApplicationPackageForDevice(platformData).packageName;
587+
packageFile = this.getLatestApplicationPackageForDevice(platformData, settings).packageName;
588588
} else {
589-
packageFile = this.getLatestApplicationPackageForEmulator(platformData).packageName;
589+
packageFile = this.getLatestApplicationPackageForEmulator(platformData, settings).packageName;
590590
}
591591
if (!packageFile || !this.$fs.exists(packageFile)) {
592592
this.$errors.failWithoutHelp("Unable to find built application. Try 'tns build %s'.", platform);
593593
}
594594
return packageFile;
595595
}
596596

597-
public copyLastOutput(platform: string, targetPath: string, settings: { isForDevice: boolean }, projectData: IProjectData): void {
597+
public copyLastOutput(platform: string, targetPath: string, settings: { isForDevice: boolean, isReleaseBuild: boolean }, projectData: IProjectData): void {
598598
platform = platform.toLowerCase();
599599
targetPath = path.resolve(targetPath);
600600

@@ -741,12 +741,12 @@ export class PlatformService extends EventEmitter implements IPlatformService {
741741
return packages[0];
742742
}
743743

744-
public getLatestApplicationPackageForDevice(platformData: IPlatformData): IApplicationPackage {
745-
return this.getLatestApplicationPackage(platformData.deviceBuildOutputPath, platformData.validPackageNamesForDevice);
744+
public getLatestApplicationPackageForDevice(platformData: IPlatformData, buildOptions: { isReleaseBuild: boolean }): IApplicationPackage {
745+
return this.getLatestApplicationPackage(platformData.deviceBuildOutputPath, platformData.getValidPackageNames({ isForDevice: true, isReleaseBuild: buildOptions.isReleaseBuild }));
746746
}
747747

748-
public getLatestApplicationPackageForEmulator(platformData: IPlatformData): IApplicationPackage {
749-
return this.getLatestApplicationPackage(platformData.emulatorBuildOutputPath || platformData.deviceBuildOutputPath, platformData.validPackageNamesForEmulator || platformData.validPackageNamesForDevice);
748+
public getLatestApplicationPackageForEmulator(platformData: IPlatformData, buildOptions: { isReleaseBuild: boolean }): IApplicationPackage {
749+
return this.getLatestApplicationPackage(platformData.emulatorBuildOutputPath || platformData.deviceBuildOutputPath, platformData.getValidPackageNames({ isForDevice: false, isReleaseBuild: buildOptions.isReleaseBuild }));
750750
}
751751

752752
private async updatePlatform(platform: string, version: string, platformTemplate: string, projectData: IProjectData, platformSpecificData: IPlatformSpecificData): Promise<void> {

test/platform-commands.ts

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class PlatformData implements IPlatformData {
3232
emulatorServices: Mobile.IEmulatorPlatformServices = null;
3333
projectRoot = "";
3434
deviceBuildOutputPath = "";
35+
getValidPackageNames = (buildOptions: {isForDevice?: boolean, isReleaseBuild?: boolean}) => [""];
3536
validPackageNamesForDevice: string[] = [];
3637
frameworkFilesExtensions = [".jar", ".dat"];
3738
appDestinationDirectoryPath = "";

test/stubs.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ export class PlatformsDataStub extends EventEmitter implements IPlatformsData {
255255
normalizedPlatformName: "",
256256
appDestinationDirectoryPath: "",
257257
deviceBuildOutputPath: "",
258-
validPackageNamesForDevice: [],
258+
getValidPackageNames: (buildOptions: {isForDevice?: boolean, isReleaseBuild?: boolean}) => [],
259259
frameworkFilesExtensions: [],
260260
relativeToFrameworkConfigurationFilePath: "",
261261
fastLivesyncFileExtensions: []
@@ -276,7 +276,7 @@ export class PlatformProjectServiceStub extends EventEmitter implements IPlatfor
276276
emulatorServices: undefined,
277277
projectRoot: "",
278278
deviceBuildOutputPath: "",
279-
validPackageNamesForDevice: [],
279+
getValidPackageNames: (buildOptions: {isForDevice?: boolean, isReleaseBuild?: boolean}) => [],
280280
frameworkFilesExtensions: [],
281281
appDestinationDirectoryPath: "",
282282
relativeToFrameworkConfigurationFilePath: "",

0 commit comments

Comments
 (0)