Skip to content

Commit 12e8f6a

Browse files
committed
fix: fix native change during livesync
Currently when a native file is changed during livesync on android, NativeScript CLI doesn't show the "Successfully synced application" message. This is due to the reason that NativeScript CLI tries to transfer native file on device (for example AndroidManifest.xml). After timeout of 30seconds, the socket on android device throws "Socket connection timeout" error but CLI doesn't show it as the parsing of received errors is not correct. This PR fixes the followings: * the behavior when native file is changed during liveSync * the parsing of errors during livesync * stops livesync process when an error occurs during livesync
1 parent fb5f155 commit 12e8f6a

File tree

3 files changed

+49
-63
lines changed

3 files changed

+49
-63
lines changed

lib/controllers/run-controller.ts

Lines changed: 47 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,16 @@ export class RunController extends EventEmitter implements IRunController {
124124
await this.refreshApplicationWithDebug(projectData, liveSyncResultInfo, filesChangeEventData, deviceDescriptor, settings) :
125125
await this.refreshApplicationWithoutDebug(projectData, liveSyncResultInfo, filesChangeEventData, deviceDescriptor, settings);
126126

127+
const device = liveSyncResultInfo.deviceAppData.device;
128+
129+
this.emitCore(RunOnDeviceEvents.runOnDeviceExecuted, {
130+
projectDir: projectData.projectDir,
131+
deviceIdentifier: device.deviceInfo.identifier,
132+
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
133+
syncedFiles: liveSyncResultInfo.modifiedFilesData.map(m => m.getLocalPath()),
134+
isFullSync: liveSyncResultInfo.isFullSync
135+
});
136+
127137
return result;
128138
}
129139

@@ -282,14 +292,6 @@ export class RunController extends EventEmitter implements IRunController {
282292

283293
await this.refreshApplication(projectData, liveSyncResultInfo, null, deviceDescriptor);
284294

285-
this.emitCore(RunOnDeviceEvents.runOnDeviceExecuted, {
286-
projectDir: projectData.projectDir,
287-
deviceIdentifier: device.deviceInfo.identifier,
288-
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
289-
syncedFiles: liveSyncResultInfo.modifiedFilesData.map(m => m.getLocalPath()),
290-
isFullSync: liveSyncResultInfo.isFullSync
291-
});
292-
293295
this.$logger.info(`Successfully synced application ${liveSyncResultInfo.deviceAppData.appIdentifier} on device ${liveSyncResultInfo.deviceAppData.device.deviceInfo.identifier}.`);
294296

295297
this.emitCore(RunOnDeviceEvents.runOnDeviceStarted, {
@@ -327,22 +329,6 @@ export class RunController extends EventEmitter implements IRunController {
327329
});
328330

329331
try {
330-
if (data.hasNativeChanges) {
331-
const rebuiltInfo = this.rebuiltInformation[platformData.platformNameLowerCase] && (this.$mobileHelper.isAndroidPlatform(platformData.platformNameLowerCase) || this.rebuiltInformation[platformData.platformNameLowerCase].isEmulator === device.isEmulator);
332-
if (!rebuiltInfo) {
333-
await this.$prepareNativePlatformService.prepareNativePlatform(platformData, projectData, prepareData);
334-
await deviceDescriptor.buildAction();
335-
this.rebuiltInformation[platformData.platformNameLowerCase] = { isEmulator: device.isEmulator, platform: platformData.platformNameLowerCase, packageFilePath: null };
336-
}
337-
338-
await this.$deviceInstallAppService.installOnDevice(device, deviceDescriptor.buildData, this.rebuiltInformation[platformData.platformNameLowerCase].packageFilePath);
339-
}
340-
341-
const isInHMRMode = liveSyncInfo.useHotModuleReload && data.hmrData && data.hmrData.hash;
342-
if (isInHMRMode) {
343-
this.$hmrStatusService.watchHmrStatus(device.deviceInfo.identifier, data.hmrData.hash);
344-
}
345-
346332
const platformLiveSyncService = this.$liveSyncServiceResolver.resolveLiveSyncService(device.deviceInfo.platform);
347333
const watchInfo = {
348334
liveSyncDeviceData: deviceDescriptor,
@@ -355,53 +341,52 @@ export class RunController extends EventEmitter implements IRunController {
355341
force: liveSyncInfo.force,
356342
connectTimeout: 1000
357343
};
358-
let liveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
344+
const deviceAppData = await platformLiveSyncService.getAppData(_.merge({ device, watch: true }, watchInfo));
359345

360-
await this.refreshApplication(projectData, liveSyncResultInfo, data, deviceDescriptor);
346+
if (data.hasNativeChanges) {
347+
const rebuiltInfo = this.rebuiltInformation[platformData.platformNameLowerCase] && (this.$mobileHelper.isAndroidPlatform(platformData.platformNameLowerCase) || this.rebuiltInformation[platformData.platformNameLowerCase].isEmulator === device.isEmulator);
348+
if (!rebuiltInfo) {
349+
await this.$prepareNativePlatformService.prepareNativePlatform(platformData, projectData, prepareData);
350+
await deviceDescriptor.buildAction();
351+
this.rebuiltInformation[platformData.platformNameLowerCase] = { isEmulator: device.isEmulator, platform: platformData.platformNameLowerCase, packageFilePath: null };
352+
}
361353

362-
this.emitCore(RunOnDeviceEvents.runOnDeviceExecuted, {
363-
projectDir: projectData.projectDir,
364-
deviceIdentifier: device.deviceInfo.identifier,
365-
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
366-
syncedFiles: liveSyncResultInfo.modifiedFilesData.map(m => m.getLocalPath()),
367-
isFullSync: liveSyncResultInfo.isFullSync
368-
});
354+
await this.$deviceInstallAppService.installOnDevice(device, deviceDescriptor.buildData, this.rebuiltInformation[platformData.platformNameLowerCase].packageFilePath);
355+
await platformLiveSyncService.restartApplication(projectData, { deviceAppData, modifiedFilesData: [], isFullSync: false, useHotModuleReload: liveSyncInfo.useHotModuleReload });
356+
} else {
357+
const isInHMRMode = liveSyncInfo.useHotModuleReload && data.hmrData && data.hmrData.hash;
358+
if (isInHMRMode) {
359+
this.$hmrStatusService.watchHmrStatus(device.deviceInfo.identifier, data.hmrData.hash);
360+
}
369361

370-
if (!liveSyncResultInfo.didRecover && isInHMRMode) {
371-
const status = await this.$hmrStatusService.getHmrStatus(device.deviceInfo.identifier, data.hmrData.hash);
372-
if (status === HmrConstants.HMR_ERROR_STATUS) {
373-
watchInfo.filesToSync = data.hmrData.fallbackFiles;
374-
liveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
375-
// We want to force a restart of the application.
376-
liveSyncResultInfo.isFullSync = true;
377-
await this.refreshApplication(projectData, liveSyncResultInfo, data, deviceDescriptor);
378-
379-
this.emitCore(RunOnDeviceEvents.runOnDeviceExecuted, {
380-
projectDir: projectData.projectDir,
381-
deviceIdentifier: device.deviceInfo.identifier,
382-
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
383-
syncedFiles: liveSyncResultInfo.modifiedFilesData.map(m => m.getLocalPath()),
384-
isFullSync: liveSyncResultInfo.isFullSync
385-
});
362+
let liveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
363+
364+
if (!liveSyncResultInfo.didRecover && isInHMRMode) {
365+
const status = await this.$hmrStatusService.getHmrStatus(device.deviceInfo.identifier, data.hmrData.hash);
366+
if (status === HmrConstants.HMR_ERROR_STATUS) {
367+
watchInfo.filesToSync = data.hmrData.fallbackFiles;
368+
liveSyncResultInfo = await platformLiveSyncService.liveSyncWatchAction(device, watchInfo);
369+
// We want to force a restart of the application.
370+
liveSyncResultInfo.isFullSync = true;
371+
await this.refreshApplication(projectData, liveSyncResultInfo, data, deviceDescriptor);
372+
}
386373
}
374+
375+
await this.refreshApplication(projectData, liveSyncResultInfo, data, deviceDescriptor);
387376
}
388377

389-
this.$logger.info(`Successfully synced application ${liveSyncResultInfo.deviceAppData.appIdentifier} on device ${liveSyncResultInfo.deviceAppData.device.deviceInfo.identifier}.`);
378+
this.$logger.info(`Successfully synced application ${deviceAppData.appIdentifier} on device ${device.deviceInfo.identifier}.`);
390379
} catch (err) {
391-
const allErrors = (<Mobile.IDevicesOperationError>err).allErrors;
380+
this.$logger.warn(`Unable to apply changes for device: ${device.deviceInfo.identifier}. Error is: ${err && err.message}.`);
392381

393-
if (allErrors && _.isArray(allErrors)) {
394-
for (const deviceError of allErrors) {
395-
this.$logger.warn(`Unable to apply changes for device: ${deviceError.deviceIdentifier}. Error is: ${deviceError.message}.`);
382+
this.emitCore(RunOnDeviceEvents.runOnDeviceError, {
383+
projectDir: projectData.projectDir,
384+
deviceIdentifier: device.deviceInfo.identifier,
385+
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
386+
error: err,
387+
});
396388

397-
this.emitCore(RunOnDeviceEvents.runOnDeviceError, {
398-
projectDir: projectData.projectDir,
399-
deviceIdentifier: device.deviceInfo.identifier,
400-
applicationIdentifier: projectData.projectIdentifiers[device.deviceInfo.platform.toLowerCase()],
401-
error: err,
402-
});
403-
}
404-
}
389+
await this.stop({ projectDir: projectData.projectDir, deviceIdentifiers: [device.deviceInfo.identifier] });
405390
}
406391
};
407392

lib/definitions/livesync.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ declare global {
250250
restartApplication(projectData: IProjectData, liveSyncInfo: ILiveSyncResultInfo): Promise<void>;
251251
shouldRestart(projectData: IProjectData, liveSyncInfo: ILiveSyncResultInfo): Promise<boolean>;
252252
getDeviceLiveSyncService(device: Mobile.IDevice, projectData: IProjectData): INativeScriptDeviceLiveSyncService;
253+
getAppData(syncInfo: IFullSyncInfo): Promise<Mobile.IDeviceAppData>;
253254
}
254255

255256
interface IRestartApplicationInfo {

lib/services/livesync/platform-livesync-service-base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export abstract class PlatformLiveSyncServiceBase {
141141
return transferredFiles;
142142
}
143143

144-
protected async getAppData(syncInfo: IFullSyncInfo): Promise<Mobile.IDeviceAppData> {
144+
public async getAppData(syncInfo: IFullSyncInfo): Promise<Mobile.IDeviceAppData> {
145145
const platform = syncInfo.device.deviceInfo.platform.toLowerCase();
146146
const appIdentifier = syncInfo.projectData.projectIdentifiers[platform];
147147
const deviceProjectRootOptions: IDeviceProjectRootOptions = _.assign({ appIdentifier }, syncInfo);

0 commit comments

Comments
 (0)