Skip to content

Commit d58298a

Browse files
committed
Add platform specific app identifier in package.json.
Rename projectId to projectIdentifiers. projectId is left as getter and setter to avoid breaking change in hooks and CLI extensions Fix ui tests for platform service and safeguard missing id. Remove breaking change from debug data. Use IProjectDefinition from mobile-cli-lib Fix comments. Fix comments chore: send projectDir instead of projectData to PluginVariableService. chore: fix comments chore: fix tests
1 parent 3c77d2a commit d58298a

26 files changed

+198
-103
lines changed

lib/commands/debug.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,10 @@ export class DebugPlatformCommand extends ValidatePlatformCommandBase implements
3333

3434
const debugOptions = <IDebugOptions>_.cloneDeep(this.$options.argv);
3535

36-
const debugData = this.$debugDataService.createDebugData(this.$projectData, this.$options);
37-
3836
await this.$platformService.trackProjectType(this.$projectData);
3937
const selectedDeviceForDebug = await this.getDeviceForDebug();
40-
debugData.deviceIdentifier = selectedDeviceForDebug.deviceInfo.identifier;
38+
39+
const debugData = this.$debugDataService.createDebugData(this.$projectData, {device: selectedDeviceForDebug.deviceInfo.identifier});
4140

4241
if (this.$options.start) {
4342
await this.$liveSyncService.printDebugInformation(await this.$debugService.debug(debugData, debugOptions));

lib/definitions/livesync.d.ts

+10
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,16 @@ interface IHasUseHotModuleReloadOption {
183183
useHotModuleReload?: boolean;
184184
}
185185

186+
interface ILiveSyncEventData {
187+
deviceIdentifier: string,
188+
applicationIdentifier?: string,
189+
projectDir: string,
190+
syncedFiles?: Object
191+
error? : Error,
192+
notification?: string,
193+
isFullSync?: boolean
194+
}
195+
186196
interface ILatestAppPackageInstalledSettings extends IDictionary<IDictionary<boolean>> { /* empty */ }
187197

188198
interface IIsEmulator {

lib/definitions/plugins.d.ts

+8-9
Original file line numberDiff line numberDiff line change
@@ -50,40 +50,39 @@ interface IPluginVariablesService {
5050
/**
5151
* Saves plugin variables in project package.json file.
5252
* @param {IPluginData} pluginData for the plugin.
53-
* @param {IProjectData} projectData DTO with information about the project.
53+
* @param {string} projectDir: Specifies the directory of the project.
5454
* @return {Promise<void>}
5555
*/
56-
savePluginVariablesInProjectFile(pluginData: IPluginData, projectData: IProjectData): Promise<void>;
56+
savePluginVariablesInProjectFile(pluginData: IPluginData, projectDir: string): Promise<void>;
5757

5858
/**
5959
* Removes plugin variables from project package.json file.
6060
* @param {string} pluginName Name of the plugin.
61-
* @param {IProjectData} projectData DTO with information about the project.
61+
* @param {string} projectDir: Specifies the directory of the project.
6262
* @return {void}
6363
*/
64-
removePluginVariablesFromProjectFile(pluginName: string, projectData: IProjectData): void;
64+
removePluginVariablesFromProjectFile(pluginName: string, projectDir: string): void;
6565

6666
/**
6767
* Replaces all plugin variables with their corresponding values.
6868
* @param {IPluginData} pluginData for the plugin.
6969
* @param {pluginConfigurationFilePath} pluginConfigurationFilePath for the plugin.
70-
* @param {IProjectData} projectData DTO with information about the project.
70+
* @param {string} projectDir: Specifies the directory of the project.
7171
* @return {Promise<void>}
7272
*/
73-
interpolatePluginVariables(pluginData: IPluginData, pluginConfigurationFilePath: string, projectData: IProjectData): Promise<void>;
73+
interpolatePluginVariables(pluginData: IPluginData, pluginConfigurationFilePath: string, projectDir: string): Promise<void>;
7474

7575
/**
7676
* Replaces {nativescript.id} expression with the application identifier from package.json.
7777
* @param {pluginConfigurationFilePath} pluginConfigurationFilePath for the plugin.
78-
* @param {IProjectData} projectData DTO with information about the project.
7978
* @return {void}
8079
*/
81-
interpolateAppIdentifier(pluginConfigurationFilePath: string, projectData: IProjectData): void;
80+
interpolateAppIdentifier(pluginConfigurationFilePath: string, projectIdentifier: string): void;
8281

8382
/**
8483
* Replaces both plugin variables and appIdentifier
8584
*/
86-
interpolate(pluginData: IPluginData, pluginConfigurationFilePath: string, projectData: IProjectData): Promise<void>;
85+
interpolate(pluginData: IPluginData, pluginConfigurationFilePath: string, projectDir: string, projectIdentifier: string): Promise<void>;
8786

8887
/**
8988
* Returns the

lib/definitions/project.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ interface INsConfig {
7777
interface IProjectData extends ICreateProjectData {
7878
platformsDir: string;
7979
projectFilePath: string;
80-
projectId?: string;
80+
projectId: string;
81+
projectIdentifiers?: Mobile.IProjectIdentifier;
8182
dependencies: any;
8283
devDependencies: IStringDictionary;
8384
appDirectoryPath: string;

lib/helpers/livesync-command-helper.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,15 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper {
166166
};
167167

168168
await this.$platformService.deployPlatform(deployPlatformInfo);
169-
await this.$platformService.startApplication(currentPlatform, runPlatformOptions, { appId: this.$projectData.projectId, projectName: this.$projectData.projectName });
169+
170+
await this.$platformService.startApplication(
171+
currentPlatform,
172+
runPlatformOptions,
173+
{
174+
appId: this.$projectData.projectIdentifiers[currentPlatform.toLowerCase()],
175+
projectName: this.$projectData.projectName
176+
}
177+
);
170178
await this.$platformService.trackProjectType(this.$projectData);
171179
}
172180
}

lib/project-data.ts

+37-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as constants from "./constants";
22
import * as path from "path";
33
import { parseJson } from "./common/helpers";
44
import { EOL } from "os";
5+
import { cache } from "./common/decorators";
56

67
interface IProjectType {
78
type: string;
@@ -35,7 +36,17 @@ export class ProjectData implements IProjectData {
3536
public projectDir: string;
3637
public platformsDir: string;
3738
public projectFilePath: string;
38-
public projectId: string;
39+
public projectIdentifiers: Mobile.IProjectIdentifier;
40+
get projectId(): string {
41+
this.warnProjectId();
42+
return this.projectIdentifiers.ios;
43+
}
44+
//just in case hook/extension modifies it.
45+
set projectId(identifier: string) {
46+
this.warnProjectId();
47+
this.projectIdentifiers.ios = identifier;
48+
this.projectIdentifiers.android = identifier;
49+
}
3950
public projectName: string;
4051
public nsConfig: INsConfig;
4152
public appDirectoryPath: string;
@@ -108,7 +119,7 @@ export class ProjectData implements IProjectData {
108119
this.projectName = this.$projectHelper.sanitizeName(path.basename(projectDir));
109120
this.platformsDir = path.join(projectDir, constants.PLATFORMS_DIR_NAME);
110121
this.projectFilePath = projectFilePath;
111-
this.projectId = nsData.id;
122+
this.projectIdentifiers = this.initializeProjectIdentifiers(nsData.id);
112123
this.dependencies = packageJsonData.dependencies;
113124
this.devDependencies = packageJsonData.devDependencies;
114125
this.projectType = this.getProjectType();
@@ -206,6 +217,25 @@ export class ProjectData implements IProjectData {
206217
return path.resolve(projectDir, pathToResolve);
207218
}
208219

220+
private initializeProjectIdentifiers(data: string | Mobile.IProjectIdentifier): Mobile.IProjectIdentifier {
221+
let identifier: Mobile.IProjectIdentifier;
222+
data = data || "";
223+
224+
if (typeof data === "string") {
225+
identifier = {
226+
android: data,
227+
ios: data
228+
};
229+
} else {
230+
identifier = {
231+
android: data.android || "",
232+
ios: data.ios || ""
233+
};
234+
}
235+
236+
return identifier;
237+
}
238+
209239
private getProjectType(): string {
210240
let detectedProjectType = _.find(ProjectData.PROJECT_TYPES, (projectType) => projectType.isDefaultProjectType).type;
211241

@@ -220,5 +250,10 @@ export class ProjectData implements IProjectData {
220250

221251
return detectedProjectType;
222252
}
253+
254+
@cache()
255+
private warnProjectId(): void {
256+
this.$logger.warnWithLabel("IProjectData.projectId is deprecated. Please use IProjectData.projectIdentifiers[platform].");
257+
}
223258
}
224259
$injector.register("projectData", ProjectData);

lib/services/android-project-service.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
120120
}
121121

122122
public async validate(projectData: IProjectData, options: IOptions, notConfiguredEnvOptions?: INotConfiguredEnvOptions): Promise<IValidatePlatformOutput> {
123-
this.validatePackageName(projectData.projectId);
123+
this.validatePackageName(projectData.projectIdentifiers.android);
124124
this.validateProjectName(projectData.projectName);
125125

126126
const checkEnvironmentRequirementsOutput = await this.$platformEnvironmentRequirements.checkEnvironmentRequirements({
@@ -269,16 +269,17 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
269269
// will replace applicationId in app/App_Resources/Android/app.gradle if it has not been edited by the user
270270
const appGradleContent = this.$fs.readText(projectData.appGradlePath);
271271
if (appGradleContent.indexOf(constants.PACKAGE_PLACEHOLDER_NAME) !== -1) {
272-
shell.sed('-i', new RegExp(constants.PACKAGE_PLACEHOLDER_NAME), projectData.projectId, projectData.appGradlePath);
272+
//TODO: For compatibility with old templates. Once all templates are updated should delete.
273+
shell.sed('-i', new RegExp(constants.PACKAGE_PLACEHOLDER_NAME), projectData.projectIdentifiers.android, projectData.appGradlePath);
273274
}
274275
} catch (e) {
275-
this.$logger.warn(`\n${e}.\nCheck if you're using an outdated template and update it.`);
276+
this.$logger.trace(`Templates updated and no need for replace in app.gradle.`);
276277
}
277278
}
278279

279280
public interpolateConfigurationFile(projectData: IProjectData, platformSpecificData: IPlatformSpecificData): void {
280281
const manifestPath = this.getPlatformData(projectData).configurationFilePath;
281-
shell.sed('-i', /__PACKAGE__/, projectData.projectId, manifestPath);
282+
shell.sed('-i', /__PACKAGE__/, projectData.projectIdentifiers.android, manifestPath);
282283
if (this.$androidToolsInfo.getToolsInfo().androidHomeEnvVar) {
283284
const sdk = (platformSpecificData && platformSpecificData.sdk) || (this.$androidToolsInfo.getToolsInfo().compileSdkVersion || "").toString();
284285
shell.sed('-i', /__APILEVEL__/, sdk, manifestPath);
@@ -287,8 +288,8 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
287288

288289
private getProjectNameFromId(projectData: IProjectData): string {
289290
let id: string;
290-
if (projectData && projectData.projectId) {
291-
const idParts = projectData.projectId.split(".");
291+
if (projectData && projectData.projectIdentifiers && projectData.projectIdentifiers.android) {
292+
const idParts = projectData.projectIdentifiers.android.split(".");
292293
id = idParts[idParts.length - 1];
293294
}
294295

@@ -532,7 +533,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
532533
const filesForInterpolation = this.$fs.enumerateFilesInDirectorySync(resourcesDestinationDirectoryPath, file => this.$fs.getFsStats(file).isDirectory() || path.extname(file) === constants.XML_FILE_EXTENSION) || [];
533534
for (const file of filesForInterpolation) {
534535
this.$logger.trace(`Interpolate data for plugin file: ${file}`);
535-
await this.$pluginVariablesService.interpolate(pluginData, file, projectData);
536+
await this.$pluginVariablesService.interpolate(pluginData, file, projectData.projectDir, projectData.projectIdentifiers.android);
536537
}
537538
}
538539

@@ -642,7 +643,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
642643

643644
public async cleanDeviceTempFolder(deviceIdentifier: string, projectData: IProjectData): Promise<void> {
644645
const adb = this.$injector.resolve(DeviceAndroidDebugBridge, { identifier: deviceIdentifier });
645-
const deviceRootPath = `${LiveSyncPaths.ANDROID_TMP_DIR_NAME}/${projectData.projectId}`;
646+
const deviceRootPath = `${LiveSyncPaths.ANDROID_TMP_DIR_NAME}/${projectData.projectIdentifiers.android}`;
646647
await adb.executeShellCommand(["rm", "-rf", deviceRootPath]);
647648
}
648649

lib/services/debug-data-service.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
export class DebugDataService implements IDebugDataService {
2+
constructor(
3+
private $devicesService: Mobile.IDevicesService
4+
) { }
25
public createDebugData(projectData: IProjectData, options: IDeviceIdentifier): IDebugData {
6+
const device = this.$devicesService.getDeviceByIdentifier(options.device);
7+
38
return {
4-
applicationIdentifier: projectData.projectId,
9+
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
510
projectDir: projectData.projectDir,
611
deviceIdentifier: options.device,
712
projectName: projectData.projectName

lib/services/ios-project-service.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
252252
if (options && options.provision) {
253253
plistTemplate += ` <key>provisioningProfiles</key>
254254
<dict>
255-
<key>${projectData.projectId}</key>
255+
<key>${projectData.projectIdentifiers.ios}</key>
256256
<string>${options.provision}</string>
257257
</dict>`;
258258
}
@@ -301,7 +301,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
301301
if (options && options.provision) {
302302
plistTemplate += ` <key>provisioningProfiles</key>
303303
<dict>
304-
<key>${projectData.projectId}</key>
304+
<key>${projectData.projectIdentifiers.ios}</key>
305305
<string>${options.provision}</string>
306306
</dict>`;
307307
}
@@ -518,7 +518,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
518518

519519
if (shouldUpdateXcode) {
520520
const pickStart = Date.now();
521-
const mobileprovision = mobileProvisionData || await this.$iOSProvisionService.pick(provision, projectData.projectId);
521+
const mobileprovision = mobileProvisionData || await this.$iOSProvisionService.pick(provision, projectData.projectIdentifiers.ios);
522522
const pickEnd = Date.now();
523523
this.$logger.trace("Searched and " + (mobileprovision ? "found" : "failed to find ") + " matching provisioning profile. (" + (pickEnd - pickStart) + "ms.)");
524524
if (!mobileprovision) {
@@ -783,10 +783,10 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
783783
await this.$iOSEntitlementsService.merge(projectData);
784784
await this.mergeProjectXcconfigFiles(release, projectData);
785785
for (const pluginData of await this.getAllInstalledPlugins(projectData)) {
786-
await this.$pluginVariablesService.interpolatePluginVariables(pluginData, this.getPlatformData(projectData).configurationFilePath, projectData);
786+
await this.$pluginVariablesService.interpolatePluginVariables(pluginData, this.getPlatformData(projectData).configurationFilePath, projectData.projectDir);
787787
}
788788

789-
this.$pluginVariablesService.interpolateAppIdentifier(this.getPlatformData(projectData).configurationFilePath, projectData);
789+
this.$pluginVariablesService.interpolateAppIdentifier(this.getPlatformData(projectData).configurationFilePath, projectData.projectIdentifiers.ios);
790790
}
791791

792792
private getInfoPlistPath(projectData: IProjectData): string {
@@ -847,7 +847,7 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
847847

848848
makePatch(infoPlistPath);
849849

850-
if (projectData.projectId) {
850+
if (projectData.projectIdentifiers && projectData.projectIdentifiers.ios) {
851851
session.patch({
852852
name: "CFBundleIdentifier from package.json nativescript.id",
853853
read: () =>
@@ -856,13 +856,13 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
856856
<plist version="1.0">
857857
<dict>
858858
<key>CFBundleIdentifier</key>
859-
<string>${projectData.projectId}</string>
859+
<string>${projectData.projectIdentifiers.ios}</string>
860860
</dict>
861861
</plist>`
862862
});
863863
}
864864

865-
if (!buildOptions.release && projectData.projectId) {
865+
if (!buildOptions.release && projectData.projectIdentifiers && projectData.projectIdentifiers.ios) {
866866
session.patch({
867867
name: "CFBundleURLTypes from package.json nativescript.id",
868868
read: () =>
@@ -877,7 +877,7 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
877877
<string>Editor</string>
878878
<key>CFBundleURLSchemes</key>
879879
<array>
880-
<string>${projectData.projectId.replace(/[^A-Za-z0-9]/g, "")}</string>
880+
<string>${projectData.projectIdentifiers.ios.replace(/[^A-Za-z0-9]/g, "")}</string>
881881
</array>
882882
</dict>
883883
</array>

lib/services/itmstransporter-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export class ITMSTransporterService implements IITMSTransporterService {
110110
private async getBundleIdentifier(ipaFileFullPath?: string): Promise<string> {
111111
if (!this._bundleIdentifier) {
112112
if (!ipaFileFullPath) {
113-
this._bundleIdentifier = this.$projectData.projectId;
113+
this._bundleIdentifier = this.$projectData.projectIdentifiers.ios;
114114
} else {
115115
if (!this.$fs.exists(ipaFileFullPath) || path.extname(ipaFileFullPath) !== ".ipa") {
116116
this.$errors.failWithoutHelp(`Cannot use specified ipa file ${ipaFileFullPath}. File either does not exist or is not an ipa file.`);

lib/services/livesync/android-device-livesync-sockets-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export class AndroidDeviceSocketsLiveSyncService extends AndroidDeviceLiveSyncSe
3232
this.$fs.writeFile(pathToLiveSyncFile, "");
3333
await this.device.fileSystem.putFile(pathToLiveSyncFile, this.getPathToLiveSyncFileOnDevice(deviceAppData.appIdentifier), deviceAppData.appIdentifier);
3434
await this.device.applicationManager.startApplication({ appId: deviceAppData.appIdentifier, projectName: this.data.projectName, justLaunch: true });
35-
await this.connectLivesyncTool(this.data.projectId);
35+
await this.connectLivesyncTool(this.data.projectIdentifiers.android);
3636
}
3737

3838
private getPathToLiveSyncFileOnDevice(appIdentifier: string): string {

lib/services/livesync/ios-device-livesync-service.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,18 @@ export class IOSDeviceLiveSyncService extends DeviceLiveSyncServiceBase implemen
2626
return true;
2727
}
2828

29+
const appId = projectData.projectIdentifiers.ios;
30+
2931
if (this.device.isEmulator) {
30-
await this.$iOSEmulatorServices.postDarwinNotification(this.$iOSNotification.getAttachRequest(projectData.projectId, this.device.deviceInfo.identifier), this.device.deviceInfo.identifier);
31-
const port = await this.$iOSDebuggerPortService.getPort({ projectDir: projectData.projectDir, deviceId: this.device.deviceInfo.identifier, appId: projectData.projectId });
32+
await this.$iOSEmulatorServices.postDarwinNotification(this.$iOSNotification.getAttachRequest(appId, this.device.deviceInfo.identifier), this.device.deviceInfo.identifier);
33+
const port = await this.$iOSDebuggerPortService.getPort({ projectDir: projectData.projectDir, deviceId: this.device.deviceInfo.identifier, appId });
3234
this.socket = await this.$iOSEmulatorServices.connectToPort({ port });
3335
if (!this.socket) {
3436
return false;
3537
}
3638
} else {
37-
await this.$iOSSocketRequestExecutor.executeAttachRequest(this.device, constants.AWAIT_NOTIFICATION_TIMEOUT_SECONDS, projectData.projectId);
38-
const port = await this.$iOSDebuggerPortService.getPort({ projectDir: projectData.projectDir, deviceId: this.device.deviceInfo.identifier, appId: projectData.projectId });
39+
await this.$iOSSocketRequestExecutor.executeAttachRequest(this.device, constants.AWAIT_NOTIFICATION_TIMEOUT_SECONDS, appId);
40+
const port = await this.$iOSDebuggerPortService.getPort({ projectDir: projectData.projectDir, deviceId: this.device.deviceInfo.identifier, appId });
3941
this.socket = await this.device.connectToPort(port);
4042
}
4143

0 commit comments

Comments
 (0)