Skip to content

Kddimitrov/add platform application identifier setting #3120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

KristianDD
Copy link
Contributor

@KristianDD KristianDD commented Sep 13, 2017

DO NOT MERGE

Allow adding separate application identifiers for each platform inside package.json

Description

While still overwrite of applicationId from app.gradle is possible, user is able to specify a platform specific identifier inside package.json. This addresses problems related to livesync not working when applicationId is changed inside app.gradle.

Does your commit message include the wording below to reference a specific issue in this repo?

Fixes #3040.

Related Pull Requests

NativeScript/android#848

Does your pull request have [unit tests]

@KristianDD KristianDD force-pushed the kddimitrov/add-platform-application-identifier-setting branch 2 times, most recently from 63a0357 to bca04be Compare September 13, 2017 15:01
@KristianDD KristianDD force-pushed the kddimitrov/add-platform-application-identifier-setting branch from bca04be to 6f2df11 Compare September 15, 2017 11:29
@@ -80,7 +80,7 @@ export class ProjectService implements IProjectService {
public isValidNativeScriptProject(pathToProject?: string): boolean {
try {
this.$projectData.initializeProjectData(pathToProject);
return !!this.$projectData.projectDir && !!this.$projectData.projectId;
return !!this.$projectData.projectDir && !!this.$projectData.projectIdentifiers;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should check this. Not sure if we should verify for both iOS and android identifiers here or only for at least one.

@KristianDD KristianDD force-pushed the kddimitrov/add-platform-application-identifier-setting branch 3 times, most recently from 2d62804 to ad87f08 Compare September 25, 2017 14:41
public projectIdentifiers: IProjectIdentifier;
get projectId(): string {
this.warnProjectId();
return this.projectIdentifiers.ios;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does a common module project-data.ts return only an iOS project identifier?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intended to let hooks and extension that use the old property to behave as before.
Before if the user changed the application identifier for Android he must use the gradle file and the rest of the code will still use the one inside the package.json (the one for iOS).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe put a comment in the code, because it looks a bit strange returning only ios identifier in a common file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do that.

@@ -5,7 +5,7 @@ interface IDebugData extends Mobile.IDeviceIdentifier {
/**
* Application identifier of the app that it will be debugged.
*/
applicationIdentifier: string;
applicationIdentifier: IProjectIdentifier;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a breaking change for the PublicAPI

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will check what this affects and whether we will need to add new property and change this to setter and getter.

@@ -87,6 +97,25 @@ export class ProjectData implements IProjectData {
this.$errors.fail("No project found at or above '%s' and neither was a --path specified.", projectDir || this.$options.path || currentDir);
}

private getProjectIdentifiers(data :any): IProjectIdentifier {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe you can use data: string | IProjectIdentifier

}
set projectId(identifier: string) {
this.warnProjectId();
this.projectIdentifiers.ios = identifier;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a validation for the identifier somewhere before this line? (check if valid ios identifier)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No the validation happens at a later stage.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think validation should happen as early as possible, but it's up to you.

set projectId(identifier: string) {
this.warnProjectId();
this.projectIdentifiers.ios = identifier;
this.projectIdentifiers.android = identifier;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a valid android identifier?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No the validation happens at a later stage.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's up to you, but as I mentioned earlier validation should happen as early as possible so other modules can be sure validation is already done

this.warnProjectId();
return this.projectIdentifiers.ios;
}
set projectId(identifier: string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is setting project id used only in initializeProjectData?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its not used but its intended for hooks and extensions that might try to modify it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a comment as this is not easily deducted

android: data,
ios: data
};
} else {
Copy link
Contributor

@Plamen5kov Plamen5kov Oct 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the case when the android and ios package identifiers should be set to an empty string? Shouldn't we throw an error/warning here? (nvm, I got this is a default setting, but rename method)

@@ -87,6 +97,25 @@ export class ProjectData implements IProjectData {
this.$errors.fail("No project found at or above '%s' and neither was a --path specified.", projectDir || this.$options.path || currentDir);
}

private getProjectIdentifiers(data :any): IProjectIdentifier {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this is a private function, used only once, why don't we change the signature to:
private getProjectIdentifiers(projectIdentifier :string): IProjectIdentifier

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rosen is right that the argument might be a string and an object. This depends on the use case of the user - if he needs different identifiers for Android and iOS the argument will be object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case please rename data: any to projectIdentifierInfo: any or something better, but let it not be just data

} catch (e) {
this.$logger.warn(`\n${e}.\nCheck if you're using an outdated template and update it.`);
// Ignore
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should at least trace here, so we don't forget to remove this code later on

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I left a comment to remind us to remove this peace of code. If you consider tracing is better I can remove the comment. Do you prefer both the comment and trace?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I prefer trace, because it see it anytime I'm debugging as opposed to looking at the code (not so often)

@@ -70,7 +80,7 @@ export class ProjectData implements IProjectData {
this.projectFilePath = projectFilePath;
this.appDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME);
this.appResourcesDirectoryPath = path.join(projectDir, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME);
this.projectId = data.id;
this.projectIdentifiers = this.getProjectIdentifiers(data.id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please rename getProjectIdentifiers to something that better describes what the method does

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand what the naming of the method should be. I am open to suggestions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my suggestion is initializeProjectIdentifiers

@@ -375,7 +376,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
const filesForInterpolation = this.$fs.enumerateFilesInDirectorySync(resourcesDestinationDirectoryPath, file => this.$fs.getFsStats(file).isDirectory() || path.extname(file) === constants.XML_FILE_EXTENSION) || [];
for (const file of filesForInterpolation) {
this.$logger.trace(`Interpolate data for plugin file: ${file}`);
await this.$pluginVariablesService.interpolate(pluginData, file, projectData);
await this.$pluginVariablesService.interpolate(pluginData, file, projectData, projectData.projectIdentifiers.android);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you pass projectData.projectIdentifiers.android as an additional parameter when you already pass projectData?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because pluginVariablesService doesn't have the platform context to get the proper identifier for the case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Optional] I agree that it is really strange to pass both projectData and property from projectData. In this case I would suggest to pass projectData.projectDir and projectData.projectIdentifiers.android as two args and remove passing of projectData itself.

this.$errors.failWithoutHelp(`The application ${debugData.applicationIdentifier} is not installed on device with identifier ${debugData.deviceIdentifier}.`);
const devicePlatform = device.deviceInfo.platform;

if (!(await device.applicationManager.isApplicationInstalled(debugData.applicationIdentifier[devicePlatform.toLowerCase()]))) {
Copy link
Contributor

@Plamen5kov Plamen5kov Oct 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please change all the toLowerCase() all over the PR to a commonplace, wherever it makes sence

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I discussed the options with @PanayotCankov and @rosen-vladimirov and this was the least bad way to handle it.

The other was to make a getter and setter for the lowercase properties inside an implementation of IProjectIdentifier.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the platforms and other constants are living only in our CLI code, I don't understand the issue of not constantly using toLowerCase?

@@ -118,7 +118,7 @@ export class IOSDebugService extends DebugServiceBase implements IPlatformDebugS
waitForDebugger: true,
captureStdin: true,
args: args,
appId: debugData.applicationIdentifier,
appId: debugData.applicationIdentifier.ios,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally this should be named applicationIdentifiers plural

@@ -671,6 +672,10 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
}
}

public emitLivesyncEvent (event: string, livesyncData: ILivesyncEventData): boolean {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this only a rename of the function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not exactly. There is still a calls to this.emit that made the introduction of ILivesyncEventData very ugly(all of the properties had to be optional).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and why was the introduction of ILivesyncEventData necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that we have types of the properties of the data object. I was going to miss it and break Sidekick.

@@ -236,13 +236,21 @@ export class PlatformService extends EventEmitter implements IPlatformService {
platform = this.$mobileHelper.normalizePlatformName(platform);
this.$logger.trace("Validate options for platform: " + platform);
const platformData = this.$platformsData.getPlatformData(platform, projectData);
return await platformData.platformProjectService.validateOptions(projectData.projectId, provision, teamId);
return await platformData.platformProjectService.validateOptions(
projectData.projectIdentifiers[platform.toLowerCase()],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why don't we just validate both project identifiers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because its not relevant to validate android identifier when trying to run the application on iOS device,

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codewise it kind of makes sense, but I get what you mean.

return await platformData.platformProjectService.validateOptions(projectData.projectId, provision, teamId);
return await platformData.platformProjectService.validateOptions(
projectData.projectIdentifiers[platform.toLowerCase()],
provision,
Copy link
Contributor

@Plamen5kov Plamen5kov Oct 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a bit strange to pass provision in a common file like platform-service.ts when it's iOS specific. Is there a better way?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will check it, but will probably fix in separate PR.

} else {
let valid = true;
for (const availablePlatform in this.$platformsData.availablePlatforms) {
this.$logger.trace("Validate options for platform: " + availablePlatform);
const platformData = this.$platformsData.getPlatformData(availablePlatform, projectData);
valid = valid && await platformData.platformProjectService.validateOptions(projectData.projectId, provision, teamId);
valid = valid && await platformData.platformProjectService.validateOptions(
projectData.projectIdentifiers[availablePlatform.toLowerCase()],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comments as above

Copy link
Contributor

@Plamen5kov Plamen5kov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please take a look at the comments.
Because

platfrom = ...
 ... = projectIdenfiers[platform]

is a repeating pattern, is there a way to extract to common place?

@NativeScript NativeScript deleted a comment from Plamen5kov Oct 10, 2017
if (projectData && projectData.projectId) {
const idParts = projectData.projectId.split(".");
if (projectData && projectData.projectIdentifiers && projectData.projectIdentifiers.android) {
const idParts = projectData.projectIdentifiers.android.split(".");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Plamen5kov(accidently deleted the comment) Yes there is validation for the identifier.

@KristianDD KristianDD force-pushed the kddimitrov/add-platform-application-identifier-setting branch from 6c00599 to b62a907 Compare October 23, 2017 14:00
@KristianDD KristianDD force-pushed the kddimitrov/add-platform-application-identifier-setting branch from 81e987f to 1814c4b Compare November 8, 2017 15:33
@miroslavaivanova
Copy link
Contributor

run ci

@Natalia-Hristova Natalia-Hristova modified the milestone: 4.2.0 Jul 6, 2018
@rosen-vladimirov rosen-vladimirov modified the milestones: 4.2.0, 4.3.0 Jul 17, 2018
@mpochron
Copy link

@KristianDD what status now?

@KristianDD KristianDD force-pushed the kddimitrov/add-platform-application-identifier-setting branch from 002f8a0 to 228893d Compare September 4, 2018 13:45
@NativeScript NativeScript deleted a comment from miroslavaivanova Sep 10, 2018
@NativeScript NativeScript deleted a comment from miroslavaivanova Sep 10, 2018
@NativeScript NativeScript deleted a comment from miroslavaivanova Sep 10, 2018
@NativeScript NativeScript deleted a comment from miroslavaivanova Sep 10, 2018
@NativeScript NativeScript deleted a comment from miroslavaivanova Sep 10, 2018
@NativeScript NativeScript deleted a comment from miroslavaivanova Sep 10, 2018
@KristianDD KristianDD force-pushed the kddimitrov/add-platform-application-identifier-setting branch from 228893d to 663736e Compare September 10, 2018 15:16
@NativeScript NativeScript deleted a comment from miroslavaivanova Sep 11, 2018
@NativeScript NativeScript deleted a comment from miroslavaivanova Sep 11, 2018
@KristianDD KristianDD force-pushed the kddimitrov/add-platform-application-identifier-setting branch from ea73872 to 098d545 Compare September 17, 2018 09:44
@@ -792,6 +795,10 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
}
}

public emitLivesyncEvent (event: string, livesyncData: ILiveSyncEventData): boolean {
return this.emit(event, livesyncData);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can add some trace message before emitting the event.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will tracing the event name be enough or should we JSON.stringify the livesyncData?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use:

this.$logger.trace(`Will emit event ${event} with data`, livesyncData);

deviceIdentifier: string,
applicationIdentifier?: string,
projectDir: string,
syncedFiles?: Object
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this really an object?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad. It is a string[].

@KristianDD KristianDD force-pushed the kddimitrov/add-platform-application-identifier-setting branch from 098d545 to 64085d8 Compare September 18, 2018 15:00
@KristianDD
Copy link
Contributor Author

run ci

1 similar comment
@KristianDD
Copy link
Contributor Author

run ci

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
@KristianDD KristianDD force-pushed the kddimitrov/add-platform-application-identifier-setting branch from 64085d8 to 0576a20 Compare September 20, 2018 13:14
@KristianDD KristianDD changed the title DO NOT MERGE Kddimitrov/add platform application identifier setting Kddimitrov/add platform application identifier setting Sep 20, 2018
@KristianDD KristianDD merged commit 2be786c into master Sep 20, 2018
@KristianDD KristianDD deleted the kddimitrov/add-platform-application-identifier-setting branch September 20, 2018 14:31
@kspearrin
Copy link

Any idea what version this will land in?

@rosen-vladimirov
Copy link
Contributor

Hey @kspearrin ,
We'll release this in NativeScript 5.0.0, but you can try it even now by installing CLI's next version:

npm i -g nativescript@next

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants