Skip to content

Commit 29eff5d

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 9fca19d commit 29eff5d

26 files changed

+198
-103
lines changed

lib/commands/debug.ts

Lines changed: 2 additions & 3 deletions
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

Lines changed: 10 additions & 0 deletions
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

Lines changed: 8 additions & 9 deletions
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,15 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper {
167167
};
168168

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

lib/project-data.ts

Lines changed: 37 additions & 2 deletions
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

Lines changed: 9 additions & 8 deletions
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

Lines changed: 6 additions & 1 deletion
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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
246246
if (options && options.provision) {
247247
plistTemplate += ` <key>provisioningProfiles</key>
248248
<dict>
249-
<key>${projectData.projectId}</key>
249+
<key>${projectData.projectIdentifiers.ios}</key>
250250
<string>${options.provision}</string>
251251
</dict>`;
252252
}
@@ -295,7 +295,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
295295
if (options && options.provision) {
296296
plistTemplate += ` <key>provisioningProfiles</key>
297297
<dict>
298-
<key>${projectData.projectId}</key>
298+
<key>${projectData.projectIdentifiers.ios}</key>
299299
<string>${options.provision}</string>
300300
</dict>`;
301301
}
@@ -512,7 +512,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
512512

513513
if (shouldUpdateXcode) {
514514
const pickStart = Date.now();
515-
const mobileprovision = mobileProvisionData || await this.$iOSProvisionService.pick(provision, projectData.projectId);
515+
const mobileprovision = mobileProvisionData || await this.$iOSProvisionService.pick(provision, projectData.projectIdentifiers.ios);
516516
const pickEnd = Date.now();
517517
this.$logger.trace("Searched and " + (mobileprovision ? "found" : "failed to find ") + " matching provisioning profile. (" + (pickEnd - pickStart) + "ms.)");
518518
if (!mobileprovision) {
@@ -777,10 +777,10 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
777777
await this.$iOSEntitlementsService.merge(projectData);
778778
await this.mergeProjectXcconfigFiles(release, projectData);
779779
for (const pluginData of await this.getAllInstalledPlugins(projectData)) {
780-
await this.$pluginVariablesService.interpolatePluginVariables(pluginData, this.getPlatformData(projectData).configurationFilePath, projectData);
780+
await this.$pluginVariablesService.interpolatePluginVariables(pluginData, this.getPlatformData(projectData).configurationFilePath, projectData.projectDir);
781781
}
782782

783-
this.$pluginVariablesService.interpolateAppIdentifier(this.getPlatformData(projectData).configurationFilePath, projectData);
783+
this.$pluginVariablesService.interpolateAppIdentifier(this.getPlatformData(projectData).configurationFilePath, projectData.projectIdentifiers.ios);
784784
}
785785

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

842842
makePatch(infoPlistPath);
843843

844-
if (projectData.projectId) {
844+
if (projectData.projectIdentifiers && projectData.projectIdentifiers.ios) {
845845
session.patch({
846846
name: "CFBundleIdentifier from package.json nativescript.id",
847847
read: () =>
@@ -850,13 +850,13 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
850850
<plist version="1.0">
851851
<dict>
852852
<key>CFBundleIdentifier</key>
853-
<string>${projectData.projectId}</string>
853+
<string>${projectData.projectIdentifiers.ios}</string>
854854
</dict>
855855
</plist>`
856856
});
857857
}
858858

859-
if (!buildOptions.release && projectData.projectId) {
859+
if (!buildOptions.release && projectData.projectIdentifiers && projectData.projectIdentifiers.ios) {
860860
session.patch({
861861
name: "CFBundleURLTypes from package.json nativescript.id",
862862
read: () =>
@@ -871,7 +871,7 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
871871
<string>Editor</string>
872872
<key>CFBundleURLSchemes</key>
873873
<array>
874-
<string>${projectData.projectId.replace(/[^A-Za-z0-9]/g, "")}</string>
874+
<string>${projectData.projectIdentifiers.ios.replace(/[^A-Za-z0-9]/g, "")}</string>
875875
</array>
876876
</dict>
877877
</array>

0 commit comments

Comments
 (0)