hdw2
Version:
鸿蒙前端hdc调试工具
209 lines (197 loc) • 9.1 kB
JavaScript
/*
* @Author: tankunpeng
* @Date: 2024-08-29 17:21:16
* @LastEditTime: 2025-08-07 11:43:25
* @LastEditors: tankunpeng
* @Description: 推送文件
* Come on, worker!
*/
const path = require('path');
const shell = require('shelljs');
const chalk = require('chalk');
const { getHdc, getHdwConfig, printTitle, shellLog, shellError, CONFIG_BUNDLE_MAP } = require('./util');
function send(options = {}, command = {}, logOps = {}) {
const args = command.args || [];
const hdc = getHdc();
const arg0 = args[0];
options.local = /\.zip$/.test(arg0) ? arg0 : '';
if (!options.local) {
shellLog(`${chalk.cyan('执行结果: ')}${chalk.red('失败')}`, logOps, { hideLog: false });
shellLog(
`${chalk.cyan('处理建议: ')}${chalk.yellow(
'缺少本地压缩包路径,支持相对路径\n命令示例:' +
chalk.green(`hdw send ./vue2-common.zip -c -t sirius`) +
' 或 ' +
chalk.green(`hdw send ./vue2-common.zip -c -b com.xxx.xxx -a xxx`)
)}`,
logOps,
{ hideLog: false }
);
shell.exit(1);
}
// 获取目标应用
const targetApp = (options.target && CONFIG_BUNDLE_MAP[options.target]) || {};
const bundleName = options.bundle || targetApp.bundle || getHdwConfig('bundleName');
const abilityName = options.ability || targetApp.ability || getHdwConfig('abilityName') || 'EntryAbility';
if (!bundleName || !abilityName) {
shellLog(`${chalk.cyan('执行结果: ')}${chalk.red('失败')}`, logOps, { hideLog: false });
shellLog(
`${chalk.cyan('处理建议: ')}${chalk.yellow(
'缺少手机应用bundle或ability传参\n命令示例:' +
chalk.green(`hdw send ./vue2-common.zip -c -t sirius`) +
' 或 ' +
chalk.green(`hdw send ./vue2-common.zip -c -b com.xxx.xxx -a xxx`) +
'\n\n' +
'提示: 也可以通过全局config设置,不传bundle或ability时默认从全局config获取\n' +
'1. 全局设置bundleName: ' +
chalk.green(`hdw config set bundleName com.xxx.xxx`) +
'\n' +
'2. 全局设置abilityName: ' +
chalk.green(`hdw config set abilityName xxx`) +
'\n'
)}`,
logOps,
{ hideLog: false }
);
shell.exit(1);
}
const rootDir = getHdwConfig('sandboxRootPath') || '/data/storage/el2/base/cache';
printTitle('=====>推送压缩包<=====', logOps, { beforeLine: true, afterLine: true });
const isCommon = /-common\.zip$/.test(options.local);
if (isCommon) {
options.remote = `${rootDir}/sirius/common`;
} else {
options.remote = `${rootDir}/sirius/app`;
}
shellLog(`${chalk.cyan('推送包类型: ')}${chalk.green(isCommon ? '基础库' : '小程序')}`, logOps);
const localPath = path.resolve(options.local);
shellLog(`${chalk.cyan('本地路径: ')}${chalk.green(localPath)}`, logOps);
const localOpsPath = options.local.replace(/\\/g, '/');
const tempPath = '/data/local/tmp/';
const processTempPath = path.posix.resolve(tempPath, localOpsPath);
shellLog(`${chalk.cyan('临时路径: ')}${chalk.yellow(processTempPath)}`, logOps);
const remotePath = path.posix.resolve(options.remote, localOpsPath);
shellLog(`${chalk.cyan('沙箱路径: ')}${chalk.yellow(remotePath)}`, logOps);
shellLog(`${chalk.cyan('目标bundle: ')}${chalk.yellow(bundleName)}`, logOps);
shellLog(`${chalk.cyan('目标ability: ')}${chalk.yellow(abilityName)}`, logOps);
// 推送文件到临时路径
shellLog(`${chalk.cyan('* 推送到临时路径: ')}${tempPath}\n`, logOps);
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;
shellLog(`${data}`, logOps);
});
hdcCmdExec.stderr.on('data', (data) => {
if (args.includes('-h')) {
shellLog(`${data}`, logOps);
} else {
shellError(`${data}`, logOps, { hideLog: false });
}
});
hdcCmdExec.on('error', () => {
shellLog(`${chalk.cyan('命令执行结果: ')}${chalk.red('失败')}`, logOps, { hideLog: false });
shellLog(
`${chalk.cyan('处理建议: ')}${chalk.yellow(
'命令执行失败,请手动执行命令尝试\n命令:' + chalk.green(hdcCmd)
)}`,
logOps,
{ hideLog: false }
);
shell.exit(1);
});
hdcCmdExec.on('close', () => {
const isSuccess = hdcStdout.includes('finish');
if (!isSuccess) {
shellLog(`${chalk.cyan('文件发送临时路径结果: ')}${chalk.red('失败')}`, logOps, { hideLog: false });
shell.exit(1);
}
// 查询端口映射
// shellLog(`${chalk.cyan('* 查询端口映射: ')}\n`);
const fportPsCmd = `${hdc} shell "ps -ef | grep bftpd"`;
const fportPsExec = shell.exec(fportPsCmd, { silent: true });
if (fportPsExec.code !== 0) {
shellLog(`${chalk.cyan('查询端口映射结果: ')}${chalk.red('失败')}`, logOps, { hideLog: false });
shellLog(
`${chalk.cyan('处理建议: ')}${chalk.yellow(
'查询端口映射列表命令执行失败,请手动执行命令尝试\n命令:' + chalk.green(fportPsCmd)
)}`,
logOps,
{ hideLog: false }
);
shell.exit(1);
}
const fportPsStdout = fportPsExec.stdout;
// shellLog(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;
// 端口映射
shellLog(`${chalk.cyan('* 端口映射: ')}${curPort}\n`, logOps);
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) {
shellLog(`${chalk.cyan('端口映射结果: ')}${chalk.red('失败')}`, logOps, { hideLog: false });
shellLog(
`${chalk.cyan('处理建议: ')}${chalk.yellow(
'端口映射列表命令执行失败,请手动执行命令尝试\n命令:' + chalk.green(fportAACmd)
)}`,
logOps,
{ hideLog: false }
);
shell.exit(1);
}
const fportAAExecStdout = fportAAExec.stdout;
shellLog(fportAAExecStdout, logOps);
const isProcessSuccess = fportAAExec.stdout.includes('successfully');
if (!isProcessSuccess) {
shellLog(`${chalk.cyan('端口映射结果: ')}${chalk.red('失败')}`, logOps, { hideLog: false });
shellLog(
`${chalk.cyan('处理建议: ')}${chalk.yellow(
'端口映射列表命令执行失败,请手动执行命令尝试\n命令:' + chalk.green(fportAACmd)
)}`,
logOps,
{ hideLog: false }
);
shell.exit(1);
}
// ftp转发
const remoteTempPath = path.posix.resolve(tempPath, localOpsPath);
shellLog(
`${chalk.cyan('* ftp转发: ')}${chalk.yellow(remoteTempPath)} ==> ${chalk.green(remotePath)}\n`,
logOps
);
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;
shellLog(`${data}`, logOps);
});
hdcFtpExec.stderr.on('data', (data) => {
if (args.includes('-h')) {
shellLog(`${data}`, logOps);
} else {
shellError(`${data}`, logOps, { hideLog: false });
}
});
hdcFtpExec.on('error', () => {
shellLog(`${chalk.cyan('命令执行结果: ')}${chalk.red('失败')}`, logOps, { hideLog: false });
shellLog(
`${chalk.cyan('处理建议: ')}${chalk.yellow(
'命令执行失败,请手动执行命令尝试\n命令:' + chalk.green(hdcFtpCmd)
)}`,
logOps,
{ hideLog: false }
);
shell.exit(1);
});
hdcFtpExec.on('close', () => {
const isSuccess = hdcFtpStdout.trim().length === 0;
shellLog(`${chalk.cyan('文件发送结果: ')}${isSuccess ? chalk.green('成功') : chalk.red('失败')}`, logOps);
});
});
}
exports.send = send;