UNPKG

nativescript

Version:

Command-line interface for building NativeScript projects

147 lines • 7.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AndroidDeviceFileSystem = void 0; const path = require("path"); const _ = require("lodash"); const semver = require("semver"); const android_device_hash_service_1 = require("./android-device-hash-service"); const helpers_1 = require("../../helpers"); const constants_1 = require("../../constants"); class AndroidDeviceFileSystem { constructor(adb, $fs, $logger, $mobileHelper, $tempService, $injector) { this.adb = adb; this.$fs = $fs; this.$logger = $logger; this.$mobileHelper = $mobileHelper; this.$tempService = $tempService; this.$injector = $injector; this._deviceHashServices = Object.create(null); } async listFiles(devicePath, appIdentifier) { let listCommandArgs = ["ls", "-a", devicePath]; if (appIdentifier) { listCommandArgs = ["run-as", appIdentifier].concat(listCommandArgs); } return this.adb.executeShellCommand(listCommandArgs); } async getFile(deviceFilePath, appIdentifier, outputPath) { const stdout = !outputPath; if (stdout) { outputPath = await this.$tempService.path({ prefix: "sync", suffix: ".tmp", }); } await this.adb.executeCommand(["pull", deviceFilePath, outputPath]); if (stdout) { await new Promise((resolve, reject) => { const readStream = this.$fs.createReadStream(outputPath); readStream.pipe(process.stdout); readStream.on("end", () => { resolve(); }); readStream.on("error", (err) => { reject(err); }); }); } } async getFileContent(deviceFilePath, appIdentifier) { const result = await this.adb.executeShellCommand(["cat", deviceFilePath]); return result; } async putFile(localFilePath, deviceFilePath, appIdentifier) { await this.adb.pushFile(localFilePath, deviceFilePath); } async transferFiles(deviceAppData, localToDevicePaths) { const directoriesToChmod = []; const transferredFiles = []; const action = async (localToDevicePathData) => { const fstat = this.$fs.getFsStats(localToDevicePathData.getLocalPath()); if (fstat.isFile()) { const devicePath = localToDevicePathData.getDevicePath(); await this.adb.pushFile(localToDevicePathData.getLocalPath(), devicePath); transferredFiles.push(localToDevicePathData); } else if (fstat.isDirectory()) { const dirToChmod = localToDevicePathData.getDevicePath(); directoriesToChmod.push(dirToChmod); } }; await (0, helpers_1.executeActionByChunks)(localToDevicePaths, constants_1.DEFAULT_CHUNK_SIZE, action); const dirsChmodAction = (directoryToChmod) => this.adb.executeShellCommand(["chmod", "0777", directoryToChmod]); await (0, helpers_1.executeActionByChunks)(_.uniq(directoriesToChmod), constants_1.DEFAULT_CHUNK_SIZE, dirsChmodAction); return transferredFiles; } async transferDirectory(deviceAppData, localToDevicePaths, projectFilesPath) { // starting from Android 9, adb push is throwing an exception when there are subfolders // the check could be removed when we start supporting only runtime versions with sockets const minAndroidWithoutAdbPushDir = "9.0.0"; const isAdbPushDirSupported = semver.lt(semver.coerce(deviceAppData.device.deviceInfo.version), minAndroidWithoutAdbPushDir); const deviceProjectDir = await deviceAppData.getDeviceProjectRootPath(); let transferredLocalToDevicePaths = []; if (isAdbPushDirSupported) { await this.adb.pushFile(projectFilesPath, deviceProjectDir); transferredLocalToDevicePaths = localToDevicePaths; } else { transferredLocalToDevicePaths = await this.pushFiles(localToDevicePaths); } if (transferredLocalToDevicePaths.length) { const filesToChmodOnDevice = transferredLocalToDevicePaths.map((localToDevicePath) => localToDevicePath.getDevicePath()); await this.chmodFiles(deviceProjectDir, filesToChmodOnDevice); } return transferredLocalToDevicePaths; } async chmodFiles(deviceProjectRoot, filesToChmodOnDevice) { const commandsDeviceFilePath = this.$mobileHelper.buildDevicePath(deviceProjectRoot, "nativescript.commands.sh"); await this.createFileOnDevice(commandsDeviceFilePath, `chmod 0777 ${filesToChmodOnDevice.join(" ")}`); await this.adb.executeShellCommand([commandsDeviceFilePath]); } async pushFiles(localToDevicePaths) { this.$logger.trace("Changed hashes are:", localToDevicePaths); const transferredFiles = []; const transferFileAction = async (localToDevicePathData) => { transferredFiles.push(localToDevicePathData); await this.transferFile(localToDevicePathData.getLocalPath(), localToDevicePathData.getDevicePath()); }; await (0, helpers_1.executeActionByChunks)(localToDevicePaths, constants_1.DEFAULT_CHUNK_SIZE, transferFileAction); return transferredFiles; } async transferFile(localPath, devicePath) { this.$logger.trace(`Transfering ${localPath} to ${devicePath}`); const stats = this.$fs.getFsStats(localPath); if (stats.isDirectory()) { await this.adb.executeShellCommand(["mkdir", path.dirname(devicePath)]); } else { await this.adb.pushFile(localPath, devicePath); } } async createFileOnDevice(deviceFilePath, fileContent) { const hostTmpDir = await this.$tempService.mkdirSync("application-"); const commandsFileHostPath = path.join(hostTmpDir, "temp.commands.file"); this.$fs.writeFile(commandsFileHostPath, fileContent); // copy it to the device await this.transferFile(commandsFileHostPath, deviceFilePath); await this.adb.executeShellCommand(["chmod", "0777", deviceFilePath]); } async deleteFile(deviceFilePath, appIdentifier) { await this.adb.executeShellCommand(["rm", "-rf", deviceFilePath]); } async updateHashesOnDevice(hashes, appIdentifier) { const deviceHashService = this.getDeviceHashService(appIdentifier); await deviceHashService.uploadHashFileToDevice(hashes); } getDeviceHashService(appIdentifier) { if (!this._deviceHashServices[appIdentifier]) { this._deviceHashServices[appIdentifier] = this.$injector.resolve(android_device_hash_service_1.AndroidDeviceHashService, { adb: this.adb, appIdentifier, }); } return this._deviceHashServices[appIdentifier]; } } exports.AndroidDeviceFileSystem = AndroidDeviceFileSystem; //# sourceMappingURL=android-device-file-system.js.map