-
-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathplatform-livesync-service-base.ts
139 lines (115 loc) · 6.58 KB
/
platform-livesync-service-base.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import * as path from "path";
import * as util from "util";
import { APP_FOLDER_NAME } from "../../constants";
export abstract class PlatformLiveSyncServiceBase {
private _deviceLiveSyncServicesCache: IDictionary<INativeScriptDeviceLiveSyncService> = {};
constructor(protected $fs: IFileSystem,
protected $logger: ILogger,
protected $platformsData: IPlatformsData,
protected $projectFilesManager: IProjectFilesManager,
private $devicePathProvider: IDevicePathProvider,
private $projectFilesProvider: IProjectFilesProvider) { }
public getDeviceLiveSyncService(device: Mobile.IDevice, applicationIdentifier: string): INativeScriptDeviceLiveSyncService {
const key = device.deviceInfo.identifier + applicationIdentifier;
if (!this._deviceLiveSyncServicesCache[key]) {
this._deviceLiveSyncServicesCache[key] = this._getDeviceLiveSyncService(device);
}
return this._deviceLiveSyncServicesCache[key];
}
protected abstract _getDeviceLiveSyncService(device: Mobile.IDevice): INativeScriptDeviceLiveSyncService;
public async refreshApplication(projectData: IProjectData, liveSyncInfo: ILiveSyncResultInfo): Promise<void> {
if (liveSyncInfo.isFullSync || liveSyncInfo.modifiedFilesData.length) {
const deviceLiveSyncService = this.getDeviceLiveSyncService(liveSyncInfo.deviceAppData.device, projectData.projectId);
this.$logger.info("Refreshing application...");
await deviceLiveSyncService.refreshApplication(projectData, liveSyncInfo);
}
}
public async fullSync(syncInfo: IFullSyncInfo): Promise<ILiveSyncResultInfo> {
const projectData = syncInfo.projectData;
const device = syncInfo.device;
const deviceLiveSyncService = this.getDeviceLiveSyncService(device, syncInfo.projectData.projectId);
const platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform, projectData);
const deviceAppData = await this.getAppData(syncInfo);
if (deviceLiveSyncService.beforeLiveSyncAction) {
await deviceLiveSyncService.beforeLiveSyncAction(deviceAppData);
}
const projectFilesPath = path.join(platformData.appDestinationDirectoryPath, APP_FOLDER_NAME);
const localToDevicePaths = await this.$projectFilesManager.createLocalToDevicePaths(deviceAppData, projectFilesPath, null, []);
const modifiedFilesData = await this.transferFiles(deviceAppData, localToDevicePaths, projectFilesPath, true);
return {
modifiedFilesData,
isFullSync: true,
deviceAppData
};
}
public async liveSyncWatchAction(device: Mobile.IDevice, liveSyncInfo: ILiveSyncWatchInfo): Promise<ILiveSyncResultInfo> {
const projectData = liveSyncInfo.projectData;
const syncInfo = _.merge<IFullSyncInfo>({ device, watch: true }, liveSyncInfo);
const deviceAppData = await this.getAppData(syncInfo);
let modifiedLocalToDevicePaths: Mobile.ILocalToDevicePathData[] = [];
if (liveSyncInfo.filesToSync.length) {
const filesToSync = liveSyncInfo.filesToSync;
const mappedFiles = _.map(filesToSync, filePath => this.$projectFilesProvider.mapFilePath(filePath, device.deviceInfo.platform, projectData));
// Some plugins modify platforms dir on afterPrepare (check nativescript-dev-sass) - we want to sync only existing file.
const existingFiles = mappedFiles.filter(m => this.$fs.exists(m));
this.$logger.trace("Will execute livesync for files: ", existingFiles);
const skippedFiles = _.difference(mappedFiles, existingFiles);
if (skippedFiles.length) {
this.$logger.trace("The following files will not be synced as they do not exist:", skippedFiles);
}
if (existingFiles.length) {
const platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform, projectData);
const projectFilesPath = path.join(platformData.appDestinationDirectoryPath, APP_FOLDER_NAME);
const localToDevicePaths = await this.$projectFilesManager.createLocalToDevicePaths(deviceAppData,
projectFilesPath, mappedFiles, []);
modifiedLocalToDevicePaths.push(...localToDevicePaths);
await this.transferFiles(deviceAppData, localToDevicePaths, projectFilesPath, false);
}
}
if (liveSyncInfo.filesToRemove.length) {
const filePaths = liveSyncInfo.filesToRemove;
const platformData = this.$platformsData.getPlatformData(device.deviceInfo.platform, projectData);
const mappedFiles = _.map(filePaths, filePath => this.$projectFilesProvider.mapFilePath(filePath, device.deviceInfo.platform, projectData));
const projectFilesPath = path.join(platformData.appDestinationDirectoryPath, APP_FOLDER_NAME);
const localToDevicePaths = await this.$projectFilesManager.createLocalToDevicePaths(deviceAppData, projectFilesPath, mappedFiles, []);
modifiedLocalToDevicePaths.push(...localToDevicePaths);
const deviceLiveSyncService = this.getDeviceLiveSyncService(device, projectData.projectId);
deviceLiveSyncService.removeFiles(deviceAppData, localToDevicePaths);
}
return {
modifiedFilesData: modifiedLocalToDevicePaths,
isFullSync: liveSyncInfo.isReinstalled,
deviceAppData
};
}
protected async transferFiles(deviceAppData: Mobile.IDeviceAppData, localToDevicePaths: Mobile.ILocalToDevicePathData[], projectFilesPath: string, isFullSync: boolean): Promise<Mobile.ILocalToDevicePathData[]> {
let transferredFiles = localToDevicePaths;
if (isFullSync) {
transferredFiles = await deviceAppData.device.fileSystem.transferDirectory(deviceAppData, localToDevicePaths, projectFilesPath);
} else {
await deviceAppData.device.fileSystem.transferFiles(deviceAppData, localToDevicePaths);
}
this.logFilesSyncInformation(transferredFiles, "Successfully transferred %s.", this.$logger.info);
return transferredFiles;
}
protected async getAppData(syncInfo: IFullSyncInfo): Promise<Mobile.IDeviceAppData> {
const deviceProjectRootOptions: IDeviceProjectRootOptions = _.assign({ appIdentifier: syncInfo.projectData.projectId }, syncInfo);
return {
appIdentifier: syncInfo.projectData.projectId,
device: syncInfo.device,
platform: syncInfo.device.deviceInfo.platform,
getDeviceProjectRootPath: () => this.$devicePathProvider.getDeviceProjectRootPath(syncInfo.device, deviceProjectRootOptions),
deviceSyncZipPath: this.$devicePathProvider.getDeviceSyncZipPath(syncInfo.device),
isLiveSyncSupported: async () => true
};
}
private logFilesSyncInformation(localToDevicePaths: Mobile.ILocalToDevicePathData[], message: string, action: Function): void {
if (localToDevicePaths && localToDevicePaths.length < 10) {
_.each(localToDevicePaths, (file: Mobile.ILocalToDevicePathData) => {
action.call(this.$logger, util.format(message, path.basename(file.getLocalPath()).yellow));
});
} else {
action.call(this.$logger, util.format(message, "all files"));
}
}
}