Add debug method to the public API - #2677
Conversation
e9548d6 to
6ca7280
Compare
| protected $platformsData: IPlatformsData) { | ||
| this.$projectData.initializeProjectData(); | ||
| } | ||
| this.$projectData.initializeProjectData(this.$options.path); |
There was a problem hiding this comment.
You can skip passing this.$options.path here - it'll default to it anyways
| } | ||
|
|
||
| private getPathToAppPackage(debugService: IPlatformDebugService, options: IOptions, buildConfig: IBuildConfig): string { | ||
| if (debugService.platform === this.$devicePlatformsConstants.Android) { |
There was a problem hiding this comment.
I think it'd be better to use $mobileHelper.isAndroidPlatform here in case the casing differs
| } else { | ||
| return null; | ||
| } | ||
| } else if (debugService.platform === this.$devicePlatformsConstants.iOS) { |
There was a problem hiding this comment.
Same here $mobileHelper.isiOSPlatform
| import { EventEmitter } from "events"; | ||
|
|
||
| export abstract class DebugServiceBase extends EventEmitter implements IPlatformDebugService { | ||
| constructor() { |
There was a problem hiding this comment.
Isn't such a constructor gratuitous?
| // TODO: Check if app is running. | ||
| const isAppRunning = true; | ||
| let result: string[]; | ||
| if (device.deviceInfo.platform === this.$devicePlatformsConstants.iOS) { |
There was a problem hiding this comment.
Same remark about $mobileHelper.isiOSPlatform
| } | ||
|
|
||
| result = await debugService.debug(debugData, debugOptions); | ||
| } else if (device.deviceInfo.platform === this.$devicePlatformsConstants.Android) { |
| this.$devicesService.execute(async (device: Mobile.IiOSDevice) => await device.isEmulator ? this.emulatorDebugBrk(projectData, buildConfig) : this.debugBrkCore(device, projectData)); | ||
| public async debugStart(debugData: IDebugData, debugOptions: IDebugOptions): Promise<void> { | ||
| await this.$devicesService.initialize({ platform: this.platform, deviceId: debugData.deviceIdentifier }); | ||
| const action = async (device: Mobile.IiOSDevice) => await device.isEmulator ? this.emulatorDebugBrk(debugData, false, debugOptions) : this.debugBrkCore(device, debugData, debugOptions); |
There was a problem hiding this comment.
The await operator here seems misplaced
|
|
||
| if (this.$options.debugBrk) { | ||
| await this.getDebugService(platform).debug(projectData, buildConfig); | ||
| const debugService = this.getDebugService(platform); const deployOptions: IDeployPlatformOptions = { |
There was a problem hiding this comment.
deployOptions can be declared above the if statement in order to avoid repetition
There was a problem hiding this comment.
That's why they've been declared there so far 😃
| testInjector.register("xmlValidator", {}); | ||
| testInjector.register("npm", {}); | ||
| testInjector.register("debugDataService", { | ||
| createDebugData: () => { return {}; } |
There was a problem hiding this comment.
You can use the short-hand syntax here:
createDebugData: () => ({})
| } | ||
|
|
||
| port = candidatePort; | ||
| port = await getAvailablePort(40000); |
There was a problem hiding this comment.
why do we start from 40000?
There was a problem hiding this comment.
Because we want to start chrome devtools on port 40000 each time we start debugging. That's why we don't get random free port. If we get random free port, the users should copy the url each time tns debug is executed.
| const platformData = this.getPlatformData(debugService); | ||
|
|
||
| return this.$platformService.getLatestApplicationPackageForDevice(platformData, buildConfig).packageName; | ||
| } else { |
There was a problem hiding this comment.
do we really need the else? Can't you place the return null at the end of the method?
| } | ||
| } | ||
|
|
||
| protected getPlatformData(debugService: IPlatformDebugService): IPlatformData { |
There was a problem hiding this comment.
why is this method protected and not private?
| import { EventEmitter } from "events"; | ||
| import { CONNECTION_ERROR_EVENT_NAME } from "../constants"; | ||
|
|
||
| class DebugService extends EventEmitter { |
There was a problem hiding this comment.
shouldn't you implement IDebugService as well ?
There was a problem hiding this comment.
This debug service has different debug method. In ios/android debug service the debug method returns array of the chrome devtools urls. In this service we want to start debugging only on one device and return the url only for it.
| const device = this.$devicesService.getDeviceByIdentifier(debugData.deviceIdentifier); | ||
| const debugService = this.getDebugService(device); | ||
|
|
||
| debugService.on(CONNECTION_ERROR_EVENT_NAME, (e: Error) => this.emit(CONNECTION_ERROR_EVENT_NAME, e)); |
There was a problem hiding this comment.
who will remove this handler? In case you call debug method three times, you'll have three handlers for the error event. So in case an error is raised, the one who listens for DebugService's CONNECTION_ERROR_EVENT_NAME event will receive three errors.
There was a problem hiding this comment.
Also why the handler is attached before the if (!device) statement. It looks like the handler has meaning only when we have a device.
|
|
||
| result = await debugService.debug(debugData, debugOptions); | ||
| } else if (device.deviceInfo.platform === this.$devicePlatformsConstants.Android) { | ||
| debugOptions.client = true; |
There was a problem hiding this comment.
shouldn't this be valid for iOS instead of Android?
There was a problem hiding this comment.
debugOptions.client in the android debug service is the same as debugOptions.chrome in ios debug service. I changed the android debug service to use debugOptions.chrome.
| private async deviceDebugBrk(projectData: IProjectData, buildConfig: IBuildConfig, shouldBreak?: boolean): Promise<void> { | ||
| await this.$devicesService.initialize({ platform: this.platform, deviceId: this.$options.device }); | ||
| this.$devicesService.execute(async (device: iOSDevice.IOSDevice) => { | ||
| private async deviceDebugBrk(debugData: IDebugData, shouldBreak: boolean, debugOptions: IDebugOptions): Promise<string[]> { |
There was a problem hiding this comment.
isn't shouldBreak a debug option? Can't we place it in debugOptions object?
P.S. I do not like passing boolean arguments.
| return result; | ||
| }; | ||
|
|
||
| const result = await this.$devicesService.execute(action, this.getCanExecuteAction(debugData.deviceIdentifier)); |
There was a problem hiding this comment.
results sounds better
| private async deviceStart(debugData: IDebugData, debugOptions: IDebugOptions): Promise<string[]> { | ||
| await this.$devicesService.initialize({ platform: this.platform, deviceId: debugData.deviceIdentifier }); | ||
| const action = async (device: Mobile.IiOSDevice) => device.isEmulator ? await this.emulatorStart(debugData, debugOptions) : await this.deviceStartCore(device, debugData, debugOptions); | ||
| const result = await this.$devicesService.execute(action, this.getCanExecuteAction(debugData.deviceIdentifier)); |
|
|
||
| if (this.$options.debugBrk) { | ||
| await this.getDebugService(platform).debug(projectData, buildConfig); | ||
| const debugService = this.getDebugService(platform); const deployOptions: IDeployPlatformOptions = { |
There was a problem hiding this comment.
That's why they've been declared there so far 😃
61bf525 to
6bd76ad
Compare
6bd76ad to
1cd6874
Compare
1cd6874 to
3d9c6b1
Compare
3d9c6b1 to
8f79755
Compare
We need to add debug service to the public API of the {N} CLI. This service should have method which starts debugging and returns the chrome devtools url. With this service it will be possible to use the CLI as a library and start debugging.
This PR includes:
Common lib reference: telerik/mobile-cli-lib#927