nativescript
Version:
Command-line interface for building NativeScript projects
147 lines • 7.13 kB
JavaScript
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
;