hdw2
Version:
鸿蒙前端hdc调试工具
203 lines (193 loc) • 9.16 kB
JavaScript
/*
* @Author: tankunpeng
* @Date: 2024-08-29 17:21:16
* @LastEditTime: 2024-11-20 19:17:17
* @LastEditors: tankunpeng
* @Description: 推送文件
* Come on, worker!
*/
const path = require('path');
const shell = require('shelljs');
const chalk = require('chalk');
const { getHdc, getHdwConfig } = require('./util');
function printTitle(text = '=====>推送文件结束<=====') {
shell.echo(chalk.italic(chalk.bold(chalk.blue(text))));
}
function sandbox(options = {}, command = {}) {
const args = command.args || [];
const hdc = getHdc();
const local = args[0];
if (!options.local && !local) {
shell.echo();
shell.echo(`${chalk.cyan('执行结果: ')}${chalk.red('失败')}`);
shell.echo(
`${chalk.cyan('处理建议: ')}${chalk.yellow(
'缺少本地文件路径或文件名,只传文件名时,默认为当前目录\n命令示例:' +
chalk.green(`hdw push -l ./vue2-common.zip -r /data/storage/el2/base/cache/sirius/common -b com.xxx.xxx -a xxx`) +
' 或 ' +
chalk.green(`hdw push vue2-common.zip -c -b com.xxx.xxx -a xxx`)
)}`
);
shell.echo();
shell.exit(1);
}
// 获取目标应用
const bundleName = options.bundle || getHdwConfig('bundleName');
const abilityName = options.ability || getHdwConfig('abilityName');
if (!bundleName || !abilityName) {
shell.echo();
shell.echo(`${chalk.cyan('执行结果: ')}${chalk.red('失败')}`);
shell.echo(
`${chalk.cyan('处理建议: ')}${chalk.yellow(
'缺少手机应用bundle或ability传参\n命令示例:' +
chalk.green(`hdw push -l ./vue2-common.zip -r /data/storage/el2/base/cache/sirius/common`) +
' 或 ' +
chalk.green(`hdw push vue2-common.zip -c`) +
'\n\n' +
'提示: 也可以通过全局config设置,不传bundle或ability时默认从全局config获取\n' +
'1. 全局设置bundleName: ' +
chalk.green(`hdw config bundleName com.xxx.xxx`) +
'\n' +
'2. 全局设置abilityName: ' +
chalk.green(`hdw config abilityName xxx`) +
'\n'
)}`
);
shell.echo();
shell.exit(1);
}
const rootDir = getHdwConfig('sandboxRootPath') || '/data/storage/el2/base/cache';
printTitle('=====>推送文件开始<=====');
if (options.common) {
options.remote = `${rootDir}/sirius/common`;
} else if (options.miniapp) {
options.remote = `${rootDir}/sirius/app`;
}
if (!options.remote) {
shell.echo();
shell.echo(`${chalk.cyan('执行结果: ')}${chalk.red('失败')}`);
shell.echo(
`${chalk.cyan('处理建议: ')}${chalk.yellow(
'缺少手机端沙箱路径,只传文件名时,默认为当前目录\n命令示例:' +
chalk.green(`hdw push -l ./vue2-common.zip -r /data/storage/el2/base/cache/sirius/common`) +
' 或 ' +
chalk.green(`hdw push vue2-common.zip -c`)
)}`
);
shell.echo();
shell.exit(1);
}
if (!options.local) {
options.local = './';
}
const localPath = path.resolve(options.local, local || '');
const localOpsPath = options.local ? options.local.replace(/\\/g, '/') : '';
const localTempPath = local ? local.replace(/\\/g, '/') : '';
const remotePath = path.posix.resolve(options.remote, localOpsPath, localTempPath);
const tempPath = '/data/local/tmp/';
const processTempPath = path.posix.resolve(tempPath, localOpsPath, localTempPath);
shell.echo();
shell.echo(`${chalk.cyan('本地路径: ')}${chalk.green(localPath)}`);
shell.echo(`${chalk.cyan('临时路径: ')}${chalk.yellow(processTempPath)}`);
shell.echo(`${chalk.cyan('沙箱路径: ')}${chalk.yellow(remotePath)}`);
shell.echo(`${chalk.cyan('目标bundle: ')}${chalk.yellow(bundleName)}`);
shell.echo(`${chalk.cyan('目标ability: ')}${chalk.yellow(abilityName)}`);
shell.echo();
// 推送文件到临时路径
shell.echo(`${chalk.cyan('* 推送到临时路径: ')}${tempPath}\n`);
const hdcCmd = `${hdc} file send ${localPath} ${tempPath}`;
const hdcCmdExec = shell.exec(hdcCmd, { silent: true, async: true });
let hdcStdout = '';
hdcCmdExec.stdout.on('data', (data) => {
hdcStdout += data;
console.log(`${data}`);
});
hdcCmdExec.stderr.on('data', (data) => {
if (args.includes('-h')) {
console.log(`${data}`);
} else {
console.error(`${data}`);
}
});
hdcCmdExec.on('error', () => {
shell.echo(`${chalk.cyan('命令执行结果: ')}${chalk.red('失败')}`);
shell.echo(`${chalk.cyan('处理建议: ')}${chalk.yellow('命令执行失败,请手动执行命令尝试\n命令:' + chalk.green(hdcCmd))}`);
shell.echo();
printTitle();
shell.exit(1);
});
hdcCmdExec.on('close', () => {
const isSuccess = hdcStdout.includes('finish');
if (!isSuccess) {
shell.echo(`${chalk.cyan('文件发送临时路径结果: ')}${chalk.red('失败')}`);
printTitle();
shell.exit(1);
}
// 查询端口映射
// shell.echo(`${chalk.cyan('* 查询端口映射: ')}\n`);
const fportPsCmd = `${hdc} shell "ps -ef | grep bftpd"`;
const fportPsExec = shell.exec(fportPsCmd, { silent: true });
if (fportPsExec.code !== 0) {
shell.echo(`${chalk.cyan('查询端口映射结果: ')}${chalk.red('失败')}`);
shell.echo(`${chalk.cyan('处理建议: ')}${chalk.yellow('查询端口映射列表命令执行失败,请手动执行命令尝试\n命令:' + chalk.green(fportPsCmd))}`);
printTitle();
shell.exit(1);
}
const fportPsStdout = fportPsExec.stdout;
// shell.echo(fportPsStdout);
const matchArr = Array.from(fportPsStdout.matchAll(/bftpd(?:\s+[-\w]+)*\s+-p\s+(\d+)/g));
const portArr = matchArr.map((match) => Number(match[1])).filter((port) => port);
const maxPort = portArr.length ? Math.max(...portArr) : 9200;
const curPort = maxPort + 1;
// 端口映射
shell.echo(`${chalk.cyan('* 端口映射: ')}${curPort}\n`);
const fportAACmd = `${hdc} shell aa process -b ${bundleName} -a ${abilityName} -p "/system/bin/bftpd -D -p ${curPort}" -S`;
const fportAAExec = shell.exec(fportAACmd, { silent: true });
if (fportAAExec.code !== 0) {
shell.echo(`${chalk.cyan('端口映射结果: ')}${chalk.red('失败')}`);
shell.echo(`${chalk.cyan('处理建议: ')}${chalk.yellow('端口映射列表命令执行失败,请手动执行命令尝试\n命令:' + chalk.green(fportAACmd))}`);
printTitle();
shell.exit(1);
}
const fportAAExecStdout = fportAAExec.stdout;
shell.echo(fportAAExecStdout);
const isProcessSuccess = fportAAExec.stdout.includes('successfully');
if (!isProcessSuccess) {
shell.echo(`${chalk.cyan('端口映射结果: ')}${chalk.red('失败')}`);
shell.echo(`${chalk.cyan('处理建议: ')}${chalk.yellow('端口映射列表命令执行失败,请手动执行命令尝试\n命令:' + chalk.green(fportAACmd))}`);
printTitle();
shell.exit(1);
}
// ftp转发
const remoteTempPath = path.posix.resolve(tempPath, localOpsPath, localTempPath);
shell.echo(`${chalk.cyan('* ftp转发: ')}${chalk.yellow(remoteTempPath)} ==> ${chalk.green(remotePath)}\n`);
const hdcFtpCmd = `${hdc} shell ftpget -p ${curPort} -P guest -u anonymous localhost -s ${remoteTempPath} ${remotePath}`;
const hdcFtpExec = shell.exec(hdcFtpCmd, { silent: true, async: true });
let hdcFtpStdout = '';
hdcFtpExec.stdout.on('data', (data) => {
hdcFtpStdout += data;
console.log(`${data}`);
});
hdcFtpExec.stderr.on('data', (data) => {
if (args.includes('-h')) {
console.log(`${data}`);
} else {
console.error(`${data}`);
}
});
hdcFtpExec.on('error', () => {
shell.echo(`${chalk.cyan('命令执行结果: ')}${chalk.red('失败')}`);
shell.echo(`${chalk.cyan('处理建议: ')}${chalk.yellow('命令执行失败,请手动执行命令尝试\n命令:' + chalk.green(hdcFtpCmd))}`);
shell.echo();
printTitle();
shell.exit(1);
});
hdcFtpExec.on('close', () => {
const isSuccess = hdcFtpStdout.trim().length === 0;
shell.echo(`${chalk.cyan('文件发送结果: ')}${isSuccess ? chalk.green('成功') : chalk.red('失败')}`);
shell.echo();
printTitle();
});
});
}
exports.sandbox = sandbox;