Skip to content

Commit

Permalink
feat: v2 APPDevTool 安卓部分 功能
Browse files Browse the repository at this point in the history
v2 APPDevTool 安卓部分 功能
  • Loading branch information
hewx815 committed Oct 23, 2023
1 parent e353bc8 commit 0543309
Show file tree
Hide file tree
Showing 78 changed files with 2,439 additions and 73 deletions.
Binary file added .DS_Store
Binary file not shown.
22 changes: 20 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
# node_modules
node_modules/

# editor
.vscode/

# website
website/

# dist
for-vue2/dist
for-vue3/dist

website/
dist

# cli storage
cli/storage/index.json

# vitepress cache
.vitepress/cache

# yarn error log
yarn-error.log

# APPDevTool
android/
ios/

# APPDevTool template
!for-vue2/src/packages/plugins/APPDevTool/template/android/
!for-vue2/src/packages/plugins/APPDevTool/template/ios/
9 changes: 9 additions & 0 deletions APPDevTool.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"resourceDir": "./for-vue2/dist/dev/app-plus",
"android": {
// "AndroidSdkPath": "C:\\Users\\admin\\AppData\\Local\\Android\\Sdk",
// "JavaPath": "C:\\Program Files\\Eclipse Adoptium\\jdk-8.0.382.5-hotspot"
"AndroidSdkPath": "/Users/hewx/Library/Android/sdk",
"JavaPath": "/Users/hewx/Library/Java/JavaVirtualMachines/corretto-1.8.0_382/Contents/Home"
}
}
19 changes: 19 additions & 0 deletions bin/argvs/APPDevTool.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { spawnSync } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';

export default {
description: 'App 开发工具',
fn: () => {
const { argv, env } = process;
const argvs = argv.slice(3).join(' ');

if (env.NODE_ENV === 'development') {
const APPDevTool = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../for-vue2/src/packages/plugins/APPDevTool/index.ts');
spawnSync(`ts-node ${APPDevTool} ${argvs}`, { shell: true, stdio: 'inherit' });
} else {
const APPDevTool = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../dist/for-vue2/plugins/APPDevTool/index.js');
spawnSync(`node ${APPDevTool} ${argvs}`, { shell: true, stdio: 'inherit' });
}
},
};
2 changes: 1 addition & 1 deletion bin/argvs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@

export { default as initHUniBuild } from './init-h-uni-build.js';
export { default as version } from './version.js';
export { default as V } from './version.js';
export { default as v } from './version.js';
export { default as APPDevTool } from './APPDevTool.js';
6 changes: 5 additions & 1 deletion bin/argvs/version.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export default {

const nowVersion = packageJson.version;

console.log(`[h-uni]:当前版本:${nowVersion}`);
console.log(`
[h-uni]:
当前版本:${nowVersion}
`);
},
};
5 changes: 3 additions & 2 deletions bin/h-uni.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ const argv = process.argv[2];
// 输入可用命令参数
const help = () => {
const columns = Object.keys(argvs).map((key) => ({
Parameter: key,
命令: key,
// eslint-disable-next-line import/namespace
Description: argvs[key].description,
描述: argvs[key].description,
}));

const content = columnify(columns, { minWidth: 30 });
Expand All @@ -29,6 +29,7 @@ const help = () => {
// eslint-disable-next-line no-console
console.log(`
[h-uni]:可用命令如下:
${content}
更多信息:${homeUrl}
Expand Down
2 changes: 1 addition & 1 deletion for-vue2/src/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "",
"appid": "",
"appid": "__UNI__CA5CB1E",
"description": "",
"versionName": "1.0.0",
"versionCode": "100",
Expand Down
8 changes: 8 additions & 0 deletions for-vue2/src/packages/plugins/APPDevTool/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"root": true,
"extends": ["eslint-config-hewx/node-typescript"],
"rules": {
"import/extensions": "off",
"node/no-extraneous-import": "off"
}
}
Empty file.
23 changes: 23 additions & 0 deletions for-vue2/src/packages/plugins/APPDevTool/androidServer/buildAPK.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { spawn } from 'child_process';

const COMMAND = process.platform === 'win32' ? 'gradlew.bat' : './gradlew';

export default function buildAPK(
projectPath: string,
): Promise<number | null> {
return new Promise((resolve, reject) => {
const gradlewPs = spawn(COMMAND, ['assembleDebug'], { cwd: projectPath, shell: true, stdio: 'inherit' });

gradlewPs.on('error', (err) => {
reject(err);
});

gradlewPs.on('exit', (code) => {
if (code === 0) {
resolve(code);
} else {
reject(code);
}
});
});
}
185 changes: 185 additions & 0 deletions for-vue2/src/packages/plugins/APPDevTool/androidServer/choiceDevice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import { spawn } from 'child_process';
import inquirer from 'inquirer';
import {
log, err,
} from '../utils.js';
import { listenKeyPress, clearAllListenKeyPress } from '../common/keyPress.js';
import type { KeypressCallBack } from '../common/keyPress.js';

export type DeviceOptions = {
deviceName: string;
description: string;
name: string;
type: 'emulator' | 'usb' | 'unknown';
};

export default async function choiceDevice(abdPath: string) {
const ADB_COMMAND = process.platform === 'win32' ? 'adb' : './adb';

const LF = process.platform === 'win32' ? '\r\n' : '\n';

const DEVICE_TYPES = [
{
name: '模拟器设备',
str: 'product',
type: 'emulator',
},
{
name: 'USB设备',
str: 'product',
type: 'usb',
},
];

const HELP_TEXT = '使用 R 键刷新';

let devicesGetting: boolean = false;

let device = {} as DeviceOptions;

// 获取设备列表
function getDevices(): Promise<Array<DeviceOptions>> {
return new Promise((resolve, reject) => {
devicesGetting = true;

const adbPs = spawn(ADB_COMMAND, ['devices', '-l'], { cwd: abdPath });

adbPs.on('error', (error) => {
reject(error);
});

adbPs.stdout.on('data', (data) => {
const devices = String(data)
.split(LF)

.filter((item) => item !== '' && item !== 'List of devices attached')

.map((item) => {
const deviceInfoList = item.split(' ').filter((itemItem) => itemItem !== '');

const deviceName = deviceInfoList[0];

const deviceStr = deviceInfoList[2].slice(0, deviceInfoList[2].indexOf(':'));

const deviceType = DEVICE_TYPES.find((itemItem) => itemItem.str === deviceStr);

const name = deviceType ? deviceType.name : '未知设备';

const description = `${deviceName}(${name})
${deviceInfoList.splice(2, deviceInfoList.length - 2).join(' ')}`;

const type = deviceType ? deviceType.type : 'unknown';

return {
description, name, type, deviceName,
} as DeviceOptions;
});

setTimeout(() => {
resolve(devices);
devicesGetting = false;
}, 1000);
});
});
}

// 用户选择设备
function userChoice(
devices: Array<DeviceOptions>,
): Promise<DeviceOptions> {
return new Promise((resolve, reject) => {
inquirer.prompt([{
type: 'list',
name: 'device',
message: '[APPDevTool]:请选择设备\n',
choices: devices.map((item) => item.description),
}])

.then(({ device: _device }) => resolve(devices.find((item) => item.description === _device) as DeviceOptions))

.catch((error) => reject(error));
});
}

// 重新加载设备列表
function reLoadDevices(
str: Parameters<KeypressCallBack>[0],
key: Parameters<KeypressCallBack>[1],
) {
if (key.name === 'r') {
if (!devicesGetting) {
// eslint-disable-next-line no-use-before-define, @typescript-eslint/no-floating-promises
main();
}
}
}

// 清除 inquirer 键盘 监听器
function clearInquirerKeyListners() {
const listeners = process.stdin.listeners('keypress');

const onKeyPressListeners = listeners.filter((listener) => listener.name === 'onkeypress');

listeners.forEach((listener) => {
if (listener.name !== 'onkeypress' && listener.name !== 'hUniAPPDevToolKeyPress') {
process.stdin.removeListener('keypress', listener as (...args: unknown[]) => void);
}
});

onKeyPressListeners.forEach((listener, index) => {
if (index !== onKeyPressListeners.length - 1) {
process.stdin.removeListener('keypress', listener as (...args: unknown[]) => void);
}
});
}

async function main() {
// eslint-disable-next-line no-console
console.clear();
log(`
正在搜索设备中...`);

clearInquirerKeyListners();
clearAllListenKeyPress();

listenKeyPress(reLoadDevices);

let devices: Array<DeviceOptions> = [];

try {
devices = await getDevices();
} catch (error) {
err('获取ADB设备出错', error, 'android');
}

// eslint-disable-next-line no-console
console.clear();
if (devices.length === 0) {
log(`${HELP_TEXT}
未搜索到任何设备`);
} else {
log(`${HELP_TEXT}
搜索设备成功, 共搜索到 ${devices.length} 个设备`);

try {
device = await userChoice(devices);
} catch (error) {
err('选择ADB设备出错', error);
}
}
}

await main();

while (!device.name) {
// 选择设备中...
// eslint-disable-next-line no-await-in-loop, no-promise-executor-return
await new Promise((resolve) => setTimeout(resolve, 0));
}

clearAllListenKeyPress();
return device;
}

0 comments on commit 0543309

Please sign in to comment.