UNPKG

cadb

Version:

安卓/鸿蒙系统截图/录屏工具

259 lines (239 loc) 7.55 kB
/** * Created by Niki on 2025/2/10 14:12. * Email: m13296644326@163.com */ const path = require('path'); const program = require('commander'); const fs = require('fs'); const _ = require('lodash'); const {execFileSync} = require('child_process'); const { maybeParseXTaroName, getValueIgnoreCase, ls2Array, } = require('../common/utils/crnBundleUtil'); const { getCurrModuleInfo, adbPath, rcPath, deletePath, } = require('../common/utils'); const {logRed, logGreen, shellConfigs} = require('../common/constants'); const qrcode = require('qrcode-terminal'); const bundleParentDir = path.join(process.cwd(), 'bundle_output'); const businessBundleName = 'rn_business.jsbundle'; const commonBundleName = 'common_android.hbc'; const bundlePublishPath = path.join( bundleParentDir, 'publish', businessBundleName, ); const rnCommonBundlePath = path.join( bundleParentDir, 'publish', commonBundleName, ); let finalBundlePath = ''; const adbRootPath = '/data/data/'; const deviceBundleDir = 'app_ctripwebapp5'; let outerFilePath = ''; program // 使用中括号表示可选参数, 尖括号表示必选参数 .arguments('[filePath]') // 如果加了 -c 参数, 则不会使用rcConfig的缓存了 .option('-pn --productName', 'Specify a product name') .option('-c --isCtrip', 'insert to ctrip app') .option('-z --isZhixing', 'insert to zhixing app') .option('-zl --isZhixingLight', 'insert to zhixing travel app') // 智行旅行 // .option('-usejs --useJsBundleMode', 'use .jsbundle instead of .hbc') // 后续使用jsbundle模式 .action((filePath, arg) => { outerFilePath = filePath; run(arg); }) .parse(process.argv); function run(arg) { const packName = parsePackName(arg); const moduleName = arg.productName || readModuleName(); checkBundle(moduleName); // const destPath = assembleAndCheckDestPath(packName, moduleName); doAdbPush(packName, moduleName); createQrCode(moduleName); // adbPush(bundlePublishPath, path.join(destPath, 'rn_business.jsbundle')); // deleteHermesConfigFile(arg, destPath); // logGreen('crn bundle插入成功, 请重启app'); } function checkBundle(moduleName) { const isRnCommon = moduleName === 'rn_common'; // todo rn_common特殊处理 let tPath; if (outerFilePath) { tPath = path.join(outerFilePath, businessBundleName); if (isRnCommon) { tPath = path.join(outerFilePath, commonBundleName); } } else { tPath = bundlePublishPath; if (isRnCommon) { tPath = rnCommonBundlePath; } } if (!fs.existsSync(tPath)) { logRed(`bundle文件不存在: ${bundlePublishPath}`); process.exit(); } else if (isRnCommon) { // 删除publish目录下除common_android.hbc和common_android.js以外的所有文件 const publishDir = path.dirname(tPath); const files = fs.readdirSync(publishDir); files.forEach(file => { if (file !== commonBundleName && file !== 'common_android.js') { const filePath = path.join(publishDir, file); // fs.unlinkSync(filePath); deletePath(filePath); } }); console.log( `已删除publish目录下除${commonBundleName}和common_android.js以外的所有文件`, ); } if (!outerFilePath) { const finalPath = path.join(bundleParentDir, moduleName); if (fs.existsSync(finalPath)) { deletePath(finalPath); } fs.renameSync(path.join(bundleParentDir, 'publish'), finalPath); finalBundlePath = finalPath; } } function parsePackName(arg) { const {isCtrip, isZhixing, isZhixingLight} = arg; if (isCtrip) { return 'ctrip.android.view'; } else if (isZhixing) { return 'com.yipiao'; } else if (isZhixingLight) { return 'cn.suanya.zhixing'; } // 默认返回智行 return 'com.yipiao'; } /* * 解析拿到productName * */ function readModuleName() { if (outerFilePath) { return path.basename(outerFilePath); } let rcConfig = {}; if (!fs.existsSync(rcPath)) { fs.writeFileSync(rcPath, JSON.stringify({})); } else { rcConfig = JSON.parse(fs.readFileSync(rcPath, 'utf-8')); } let {moduleName = ''} = getCurrModuleInfo(); // 如果是xTaro项目的moduleName, 则转换为crn频道名 moduleName = maybeParseXTaroName(moduleName); console.log('moduleName', moduleName); if (!moduleName.startsWith('rn_')) { const moduleMaps = require('../config/module_map.json'); let prdName = getValueIgnoreCase(moduleMaps, moduleName); const {exModuleMap = {}} = rcConfig; if (!prdName) { prdName = getValueIgnoreCase(exModuleMap, moduleName); } if (!prdName) { // 如果仍找不到, 则怀疑是xTaro项目 prdName = maybeParseXTaroName('', true); } if (!prdName) { logRed('未找到对应的crn频道名'); process.exit(); } return prdName; } else { return moduleName; } } // /data/data/com.yipiao/app_ctripwebapp5/rn_order function assembleAndCheckDestPath(packName, moduleName) { const destPath = path.join( adbRootPath, packName, deviceBundleDir, moduleName, ); console.log(`destPath: ${destPath}`); const lsResult = ls2Array(destPath, true); if (!lsResult) { logRed( `crn目录不存在: ${deviceBundleDir}/${moduleName}, 请至少进入一次相关crn页面`, ); process.exit(); } if (_.isEmpty(lsResult)) { logRed( `crn目录不存在任何文件: ${deviceBundleDir}/${moduleName}, 请至少进入一次相关crn页面`, ); process.exit(); } return destPath; } // push到设备上app的cache目录 function doAdbPush(packName, moduleName) { const destPath = path.join('/sdcard/Android/data', packName, 'cache'); const modulePath = path.join(destPath, moduleName); // const cmd = ['push', localBundlePath, destPath]; const exist = ls2Array(modulePath, true); if (exist) { const cmd = ['shell', 'rm', '-r', modulePath]; console.log('execute:', `adb ${cmd.join(' ')}`); const result = execFileSync(adbPath, cmd, shellConfigs); console.log(result); } if (!outerFilePath) { const mkDirCmd = ['shell', 'mkdir', '-p', modulePath]; console.log('execute:', `adb ${mkDirCmd.join(' ')}`); const result = execFileSync(adbPath, mkDirCmd, shellConfigs); console.log(result); adbPush(finalBundlePath, destPath); } else { adbPush(outerFilePath, modulePath); } } function adbPush(localBundlePath, destPath) { const cmd = ['push', localBundlePath, destPath]; console.log('execute:', `adb ${cmd.join(' ')}`); const result = execFileSync(adbPath, cmd, shellConfigs); console.log(result); } function createQrCode(moduleName) { // 在终端输出二维码 const qrText = `_copyRnBundle_://${JSON.stringify({ op: 'copy', name: moduleName, })}`; qrcode.generate(qrText, {small: true}, qrBinary => { console.log(qrBinary); }); logGreen('请使用安卓手机扫码, 将bundle复制到work目录'); } function deleteHermesConfigFile(arg, destPath) { const {useJsBundleMode} = arg; const cmdRmHbc = [ 'shell', 'rm', path.join(destPath, 'rn_business.hbcbundle'), ]; const hbcResult = execFileSync(adbPath, cmdRmHbc, shellConfigs); console.log(hbcResult); if (!useJsBundleMode) { const cmdRmConfigV6 = [ 'shell', 'rm', path.join(destPath, '_crn_config_v6'), ]; const configV6Result = execFileSync(adbPath, cmdRmConfigV6, shellConfigs); console.log(configV6Result); } else { console.log('由于设置了-usejs, 不删除_crn_config_v6文件'); } }