UNPKG

mobile-cli-lib

Version:
287 lines (286 loc) 17.5 kB
"use strict"; var fiberBootstrap = require("../fiber-bootstrap"); var syncBatchLib = require("./livesync/sync-batch"); var shell = require("shelljs"); var path = require("path"); var temp = require("temp"); var minimatch = require("minimatch"); var constants = require("../constants"); var util = require("util"); var gaze = require("gaze"); var LiveSyncServiceBase = (function () { function LiveSyncServiceBase($devicesService, $mobileHelper, $logger, $options, $deviceAppDataFactory, $fs, $injector, $hooksService, $projectFilesManager, $projectFilesProvider, $liveSyncProvider, $devicePlatformsConstants, $hostInfo, $dispatcher) { this.$devicesService = $devicesService; this.$mobileHelper = $mobileHelper; this.$logger = $logger; this.$options = $options; this.$deviceAppDataFactory = $deviceAppDataFactory; this.$fs = $fs; this.$injector = $injector; this.$hooksService = $hooksService; this.$projectFilesManager = $projectFilesManager; this.$projectFilesProvider = $projectFilesProvider; this.$liveSyncProvider = $liveSyncProvider; this.$devicePlatformsConstants = $devicePlatformsConstants; this.$hostInfo = $hostInfo; this.$dispatcher = $dispatcher; this.showFullLiveSyncInformation = false; this.batch = Object.create(null); this.livesyncData = Object.create(null); this.fileHashes = Object.create(null); } LiveSyncServiceBase.prototype.sync = function (data, filePaths) { var _this = this; return (function () { _this.syncCore(data, filePaths).wait(); if (_this.$options.watch) { _this.$hooksService.executeBeforeHooks('watch').wait(); _this.partialSync(data, data[0].syncWorkingDirectory); } }).future()(); }; LiveSyncServiceBase.prototype.isFileExcluded = function (filePath, excludedPatterns) { var isFileExcluded = false; _.each(excludedPatterns, function (pattern) { if (minimatch(filePath, pattern, { nocase: true })) { isFileExcluded = true; return false; } }); return isFileExcluded; }; LiveSyncServiceBase.prototype.partialSync = function (data, syncWorkingDirectory) { var that = this; this.showFullLiveSyncInformation = true; gaze("**/*", { cwd: syncWorkingDirectory }, function (err, watcher) { this.on('all', function (event, filePath) { fiberBootstrap.run(function () { that.$dispatcher.dispatch(function () { return (function () { try { if (filePath.indexOf(constants.APP_RESOURCES_FOLDER_NAME) !== -1) { that.$logger.warn(("Skipping livesync for changed file " + filePath + ". This change requires a full build to update your application. ").yellow.bold); return; } var fileHash = that.$fs.exists(filePath).wait() && that.$fs.getFsStats(filePath).wait().isFile() ? that.$fs.getFileShasum(filePath).wait() : ""; if (fileHash === that.fileHashes[filePath]) { that.$logger.trace("Skipping livesync for " + filePath + " file with " + fileHash + " hash."); return; } that.$logger.trace("Adding " + filePath + " file with " + fileHash + " hash."); that.fileHashes[filePath] = fileHash; for (var _i = 0, data_1 = data; _i < data_1.length; _i++) { var dataItem = data_1[_i]; if (that.isFileExcluded(filePath, dataItem.excludedProjectDirsAndFiles)) { that.$logger.trace("Skipping livesync for changed file " + filePath + " as it is excluded in the patterns: " + dataItem.excludedProjectDirsAndFiles.join(", ")); continue; } var mappedFilePath = that.$projectFilesProvider.mapFilePath(filePath, dataItem.platform); that.$logger.trace("Syncing filePath " + filePath + ", mappedFilePath is " + mappedFilePath); if (!mappedFilePath) { that.$logger.warn("Unable to sync " + filePath + "."); continue; } if (event === "added" || event === "changed" || event === "renamed") { that.batchSync(dataItem, mappedFilePath); } else if (event === "deleted") { that.fileHashes = (_.omit(that.fileHashes, filePath)); that.syncRemovedFile(dataItem, mappedFilePath).wait(); } } } catch (err) { that.$logger.info(("Unable to sync file " + filePath + ". Error is:" + err.message).red.bold); that.$logger.info("Try saving it again or restart the livesync operation."); } }).future()(); }); }); }); }); this.$dispatcher.run(); }; LiveSyncServiceBase.prototype.batchSync = function (data, filePath) { var _this = this; var platformBatch = this.batch[data.platform]; if (!platformBatch || !platformBatch.syncPending) { var done = function () { return (function () { setTimeout(function () { fiberBootstrap.run(function () { _this.$dispatcher.dispatch(function () { return (function () { try { var _loop_1 = function(platformName) { var batch = _this.batch[platformName]; var livesyncData = _this.livesyncData[platformName]; batch.syncFiles((function (filesToSync) { _this.$liveSyncProvider.preparePlatformForSync(platformName).wait(); _this.syncCore([livesyncData], filesToSync); }).future()).wait(); }; for (var platformName in _this.batch) { _loop_1(platformName); } } catch (err) { _this.$logger.warn("Unable to sync files. Error is:", err.message); } }).future()(); }); }); }, syncBatchLib.SYNC_WAIT_THRESHOLD); }).future()(); }; this.batch[data.platform] = this.$injector.resolve(syncBatchLib.SyncBatch, { done: done }); this.livesyncData[data.platform] = data; } this.batch[data.platform].addFile(filePath); }; LiveSyncServiceBase.prototype.syncRemovedFile = function (data, filePath) { var _this = this; return (function () { var filePathArray = [filePath], deviceFilesAction = _this.getSyncRemovedFilesAction(data); _this.syncCore([data], filePathArray, deviceFilesAction).wait(); }).future()(); }; LiveSyncServiceBase.prototype.getSyncRemovedFilesAction = function (data) { var _this = this; return function (deviceAppData, device, localToDevicePaths) { var platformLiveSyncService = _this.resolveDeviceLiveSyncService(data.platform, device); return platformLiveSyncService.removeFiles(deviceAppData.appIdentifier, localToDevicePaths); }; }; LiveSyncServiceBase.prototype.getSyncAction = function (data, filesToSync, deviceFilesAction, liveSyncOptions) { var _this = this; var appIdentifier = data.appIdentifier; var platform = data.platform; var projectFilesPath = data.projectFilesPath; var packageFilePath = null; var action = function (device) { return (function () { var shouldRefreshApplication = true; var deviceAppData = _this.$deviceAppDataFactory.create(appIdentifier, _this.$mobileHelper.normalizePlatformName(platform), device, liveSyncOptions); if (deviceAppData.isLiveSyncSupported().wait()) { var platformLiveSyncService = _this.resolveDeviceLiveSyncService(platform, device); if (platformLiveSyncService.beforeLiveSyncAction) { platformLiveSyncService.beforeLiveSyncAction(deviceAppData).wait(); } device.applicationManager.checkForApplicationUpdates().wait(); var wasInstalled = true; if (!device.applicationManager.isApplicationInstalled(appIdentifier).wait() && !_this.$options.companion) { _this.$logger.warn("The application with id \"" + appIdentifier + "\" is not installed on device with identifier " + device.deviceInfo.identifier + "."); if (!packageFilePath) { packageFilePath = _this.$liveSyncProvider.buildForDevice(device).wait(); } device.applicationManager.installApplication(packageFilePath).wait(); if (platformLiveSyncService.afterInstallApplicationAction) { var localToDevicePaths = _this.$projectFilesManager.createLocalToDevicePaths(deviceAppData, projectFilesPath, filesToSync, data.excludedProjectDirsAndFiles, liveSyncOptions); shouldRefreshApplication = platformLiveSyncService.afterInstallApplicationAction(deviceAppData, localToDevicePaths).wait(); } else { shouldRefreshApplication = false; } if (device.applicationManager.canStartApplication() && !shouldRefreshApplication) { device.applicationManager.startApplication(appIdentifier).wait(); } wasInstalled = false; } if (shouldRefreshApplication) { var localToDevicePaths = _this.$projectFilesManager.createLocalToDevicePaths(deviceAppData, projectFilesPath, filesToSync, data.excludedProjectDirsAndFiles, liveSyncOptions); if (deviceFilesAction) { deviceFilesAction(deviceAppData, device, localToDevicePaths).wait(); } else { _this.transferFiles(deviceAppData, localToDevicePaths, projectFilesPath, !filesToSync).wait(); } _this.$logger.info("Applying changes..."); platformLiveSyncService.refreshApplication(deviceAppData, localToDevicePaths, data.forceExecuteFullSync || !wasInstalled).wait(); _this.$logger.info("Successfully synced application " + data.appIdentifier + " on device " + device.deviceInfo.identifier + "."); } } else { _this.$logger.warn("LiveSync is not supported for application: " + deviceAppData.appIdentifier + " on device with identifier " + device.deviceInfo.identifier + "."); } }).future()(); }; return action; }; LiveSyncServiceBase.prototype.syncCore = function (data, filesToSync, deviceFilesAction) { var _this = this; return (function () { for (var _i = 0, data_2 = data; _i < data_2.length; _i++) { var dataItem = data_2[_i]; var appIdentifier = dataItem.appIdentifier; var platform = dataItem.platform; var canExecute = _this.getCanExecuteAction(platform, appIdentifier, dataItem.canExecute); var action = _this.getSyncAction(dataItem, filesToSync, deviceFilesAction, { isForCompanionApp: _this.$options.companion, additionalConfigurations: dataItem.additionalConfigurations, configuration: dataItem.configuration, isForDeletedFiles: false }); _this.$devicesService.execute(action, canExecute).wait(); } }).future()(); }; LiveSyncServiceBase.prototype.transferFiles = function (deviceAppData, localToDevicePaths, projectFilesPath, isFullSync) { var _this = this; return (function () { _this.$logger.info("Transferring project files..."); _this.logFilesSyncInformation(localToDevicePaths, "Transferring %s.", _this.$logger.trace); var canTransferDirectory = isFullSync && (_this.$devicesService.isAndroidDevice(deviceAppData.device) || _this.$devicesService.isiOSSimulator(deviceAppData.device)); if (canTransferDirectory) { var tempDir_1 = temp.mkdirSync("tempDir"); _.each(localToDevicePaths, function (localToDevicePath) { var fileDirname = path.join(tempDir_1, path.dirname(localToDevicePath.getRelativeToProjectBasePath())); shell.mkdir("-p", fileDirname); if (!_this.$fs.getFsStats(localToDevicePath.getLocalPath()).wait().isDirectory()) { shell.cp("-f", localToDevicePath.getLocalPath(), path.join(fileDirname, path.basename(localToDevicePath.getDevicePath()))); } }); deviceAppData.device.fileSystem.transferDirectory(deviceAppData, localToDevicePaths, tempDir_1).wait(); } else { _this.$liveSyncProvider.transferFiles(deviceAppData, localToDevicePaths, projectFilesPath, isFullSync).wait(); } _this.logFilesSyncInformation(localToDevicePaths, "Successfully transferred %s.", _this.$logger.info); }).future()(); }; LiveSyncServiceBase.prototype.logFilesSyncInformation = function (localToDevicePaths, message, action) { var _this = this; if (this.showFullLiveSyncInformation) { _.each(localToDevicePaths, function (file) { action.call(_this.$logger, util.format(message, path.basename(file.getLocalPath()).yellow)); }); } else { action.call(this.$logger, util.format(message, "all files")); } }; LiveSyncServiceBase.prototype.resolveDeviceLiveSyncService = function (platform, device) { return this.$injector.resolve(this.$liveSyncProvider.deviceSpecificLiveSyncServices[platform.toLowerCase()], { _device: device }); }; LiveSyncServiceBase.prototype.getCanExecuteAction = function (platform, appIdentifier, canExecute) { var _this = this; canExecute = canExecute || (function (dev) { return dev.deviceInfo.platform.toLowerCase() === platform.toLowerCase(); }); var finalCanExecute = canExecute; if (this.$options.device) { return function (device) { return canExecute(device) && device.deviceInfo.identifier === _this.$devicesService.getDeviceByDeviceOption().deviceInfo.identifier; }; } if (this.$mobileHelper.isiOSPlatform(platform)) { if (this.$options.emulator) { finalCanExecute = function (device) { return canExecute(device) && _this.$devicesService.isiOSSimulator(device); }; } else { var devices = this.$devicesService.getDevicesForPlatform(platform); var simulator_1 = _.find(devices, function (d) { return _this.$devicesService.isiOSSimulator(d); }); if (simulator_1) { var iOSDevices = _.filter(devices, function (d) { return d.deviceInfo.identifier !== simulator_1.deviceInfo.identifier; }); if (iOSDevices && iOSDevices.length) { var isApplicationInstalledOnSimulator = simulator_1.applicationManager.isApplicationInstalled(appIdentifier).wait(); var isApplicationInstalledOnAllDevices = _.intersection.apply(null, iOSDevices.map(function (device) { return device.applicationManager.isApplicationInstalled(appIdentifier).wait(); })); if (!isApplicationInstalledOnSimulator && !isApplicationInstalledOnAllDevices) { finalCanExecute = function (device) { return canExecute(device) && _this.$devicesService.isiOSDevice(device); }; } } } } } return finalCanExecute; }; return LiveSyncServiceBase; }()); $injector.register('liveSyncServiceBase', LiveSyncServiceBase);