@aiot-toolkit/emulator 2.0.2-beta.1 → 2.0.2-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/lib/avd/index.d.ts +12 -0
- package/lib/avd/index.js +26 -7
- package/lib/index.d.ts +3 -1
- package/lib/index.js +4 -1
- package/lib/instance/common.d.ts +15 -11
- package/lib/instance/common.js +98 -151
- package/lib/instance/dev.d.ts +35 -5
- package/lib/instance/dev.js +188 -69
- package/lib/instance/index.d.ts +10 -2
- package/lib/instance/index.js +15 -3
- package/lib/instance/miwear.d.ts +59 -10
- package/lib/instance/miwear.js +237 -170
- package/lib/instance/pre.d.ts +8 -0
- package/lib/instance/pre.js +19 -0
- package/lib/instance/preDev.d.ts +34 -6
- package/lib/instance/preDev.js +95 -86
- package/lib/static/advancedFeatures.ini +1 -0
- package/lib/static/constants.d.ts +10 -5
- package/lib/static/constants.js +20 -8
- package/lib/typing/Instance.d.ts +12 -2
- package/lib/utils/index.d.ts +21 -0
- package/lib/utils/index.js +66 -8
- package/package.json +8 -4
package/lib/instance/preDev.js
CHANGED
|
@@ -35,8 +35,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
const
|
|
39
|
-
const FileUtil_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/utils/FileUtil"));
|
|
38
|
+
const shared_utils_1 = require("@aiot-toolkit/shared-utils");
|
|
40
39
|
const adbMiwt = __importStar(require("@miwt/adb"));
|
|
41
40
|
const child_process_1 = require("child_process");
|
|
42
41
|
const find_process_1 = __importDefault(require("find-process"));
|
|
@@ -46,25 +45,40 @@ const path_1 = __importDefault(require("path"));
|
|
|
46
45
|
const portfinder_1 = __importDefault(require("portfinder"));
|
|
47
46
|
const constants_1 = require("../static/constants");
|
|
48
47
|
const common_1 = __importDefault(require("./common"));
|
|
48
|
+
/**
|
|
49
|
+
* OldGoldfishInstance
|
|
50
|
+
* 针对 Vela开发版(dev, 0.0.2)的镜像
|
|
51
|
+
*/
|
|
49
52
|
class OldGoldfishInstance extends common_1.default {
|
|
50
53
|
constructor(params) {
|
|
51
54
|
super(params);
|
|
52
55
|
this.host9pPort = 7878;
|
|
53
56
|
}
|
|
54
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* 1. 启动9p server
|
|
59
|
+
* 2. 将打包好的rpk推到host的挂载目录
|
|
60
|
+
* 3. 启动模拟器
|
|
61
|
+
* 4. 模拟器启动成功后,adb连接模拟器
|
|
62
|
+
* 5. 连接成功后,在模拟器中启动快应用
|
|
63
|
+
*/
|
|
55
64
|
start(options) {
|
|
56
65
|
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
this.startOptions = options;
|
|
67
|
+
this.sn = `127.0.0.1:${this.startOptions.adbPort}`;
|
|
57
68
|
// host启动9p server
|
|
58
69
|
yield this.ensure9pServerRunnning();
|
|
59
|
-
this.startOptions = options;
|
|
60
70
|
// 将rpk推到host的./export/qa/app目录
|
|
61
|
-
const buildedFilesPath = this.isRpk
|
|
71
|
+
const buildedFilesPath = this.isRpk
|
|
72
|
+
? this.projectPath
|
|
73
|
+
: path_1.default.resolve(this.projectPath, './build');
|
|
62
74
|
this.pushRpk(buildedFilesPath);
|
|
63
75
|
// 启动模拟器
|
|
64
76
|
yield this.startGoldfish(options);
|
|
77
|
+
// adb连接快应用
|
|
65
78
|
const connected = yield this.connectGoldfish();
|
|
66
79
|
if (connected) {
|
|
67
|
-
|
|
80
|
+
shared_utils_1.ColorConsole.log('### Emulator ### Goldfish emulator connected successfully');
|
|
81
|
+
// 如果是首次启动,创建server端监听事件
|
|
68
82
|
if (this.isFirstStart && this.startOptions.serverPort) {
|
|
69
83
|
yield this.createWebsockeServer();
|
|
70
84
|
}
|
|
@@ -73,41 +87,49 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
73
87
|
this.isFirstStart = false;
|
|
74
88
|
}
|
|
75
89
|
else {
|
|
76
|
-
|
|
90
|
+
shared_utils_1.ColorConsole.throw('### Emulator ### Failed to connect emulator, please check whether the adb is normal');
|
|
77
91
|
}
|
|
78
92
|
});
|
|
79
93
|
}
|
|
80
|
-
/**
|
|
94
|
+
/**
|
|
95
|
+
* 在模拟器中启动快应用(快应用都在模拟器的/data/app目录下)
|
|
96
|
+
* 1. 是否为调试模式
|
|
97
|
+
* 若是,在模拟器终端执行vapp app/${packageName} &
|
|
98
|
+
* 若否,在模拟器终端执行vapp --jsdebugger=10.0.2.15:101 app/${packageName} &
|
|
99
|
+
*/
|
|
81
100
|
startupQuickApp(options) {
|
|
82
101
|
try {
|
|
83
102
|
const { package: packageName } = this.projectInfo;
|
|
84
103
|
const appMountDir = path_1.default.resolve(this.sdkHome, 'qa');
|
|
85
|
-
const mountCmd = `adb -s 127.0.0.1:${
|
|
86
|
-
|
|
104
|
+
const mountCmd = `adb -s 127.0.0.1:${options.adbPort} shell mount -t v9fs -o tag=10.0.2.2,port=${this.host9pPort},aname=${appMountDir} /data`;
|
|
105
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${mountCmd}`);
|
|
87
106
|
adbMiwt.execAdbCmdSync(mountCmd);
|
|
88
|
-
let vappCmd = `adb -s 127.0.0.1:${
|
|
107
|
+
let vappCmd = `adb -s 127.0.0.1:${options.adbPort} shell vapp app/${packageName} &`;
|
|
108
|
+
// 调试情况下,需要加--jsdebugger=10.0.2.15:101
|
|
89
109
|
if (options.devtool) {
|
|
90
|
-
vappCmd = `adb -s 127.0.0.1:${
|
|
110
|
+
vappCmd = `adb -s 127.0.0.1:${options.adbPort} shell vapp --jsdebugger=10.0.2.15:101 app/${packageName} &`;
|
|
91
111
|
}
|
|
92
|
-
|
|
112
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Excuting adb cmd: ${vappCmd}`);
|
|
93
113
|
// vapp进程会一直pending,不会退出。这里必须加stdio: 'ignore',否则快应用无法运行成功
|
|
94
114
|
adbMiwt.execAdbCmdAsync(vappCmd, { stdio: 'ignore', encoding: 'utf-8' });
|
|
95
115
|
}
|
|
96
116
|
catch (e) {
|
|
97
|
-
|
|
117
|
+
shared_utils_1.ColorConsole.error(`### Emulator ### Failed to startup quickapp: ${e.message}`);
|
|
98
118
|
}
|
|
99
119
|
}
|
|
100
|
-
/** host启动9pServer
|
|
120
|
+
/** host启动9pServer
|
|
121
|
+
* 作用是将本地的quickappMountDir目录挂载到模拟器的/data目录
|
|
122
|
+
*/
|
|
101
123
|
ensure9pServerRunnning() {
|
|
102
124
|
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
103
125
|
var _a;
|
|
104
126
|
const yaFileName = os_1.default.platform() === 'win32' ? 'ya-vm-file-server.exe' : 'ya-vm-file-server';
|
|
105
127
|
const pidList = yield (0, find_process_1.default)('name', yaFileName);
|
|
106
128
|
if (pidList.length > 0) {
|
|
107
|
-
|
|
129
|
+
shared_utils_1.ColorConsole.log('### Emulator ### 9p server started in host');
|
|
108
130
|
return resolve();
|
|
109
131
|
}
|
|
110
|
-
|
|
132
|
+
shared_utils_1.ColorConsole.log('### Emulator ### Starting 9p server in host');
|
|
111
133
|
const quickappMountDir = path_1.default.resolve(this.sdkHome, 'qa');
|
|
112
134
|
const toolsHome = path_1.default.resolve(this.sdkHome, 'tools');
|
|
113
135
|
const serverBinPath = path_1.default.resolve(toolsHome, yaFileName);
|
|
@@ -121,49 +143,60 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
121
143
|
address,
|
|
122
144
|
'--debug'
|
|
123
145
|
]);
|
|
146
|
+
// 监听stderr,判断9p server是否启动成功了
|
|
124
147
|
(_a = this.v9fsProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
125
148
|
const output = data.toString();
|
|
126
149
|
if (output.match(/Server started, listening on: 127.0.0.1:(\d+)/)) {
|
|
127
|
-
|
|
128
|
-
|
|
150
|
+
shared_utils_1.ColorConsole.log(output);
|
|
151
|
+
shared_utils_1.ColorConsole.log('### Emulator ### 9p server starts successfully');
|
|
129
152
|
return resolve();
|
|
130
153
|
}
|
|
131
154
|
});
|
|
155
|
+
// 监听exit事件,判断9p server是否退出了
|
|
132
156
|
this.v9fsProcess.on('exit', (code) => {
|
|
133
|
-
|
|
157
|
+
shared_utils_1.ColorConsole.error(`### Emulator ### ya-vm-file-server exited with code ${code}`);
|
|
134
158
|
return reject();
|
|
135
159
|
});
|
|
136
160
|
}));
|
|
137
161
|
}
|
|
138
|
-
/**
|
|
162
|
+
/**
|
|
163
|
+
* 启动模拟器
|
|
164
|
+
* 1. 通过options生成模拟器的启动命令
|
|
165
|
+
* 2. 执行启动命令
|
|
166
|
+
* 3. 判断模拟器是否启动成功
|
|
167
|
+
* 3.1 若disableNSH=true,输出流中匹配到/quickapp_rpk_installer_init|rpk installer init done/,认为模拟器启动成功了
|
|
168
|
+
* 3.2 若disableNSH=false,认为8s过后模拟器启动成功了
|
|
169
|
+
* @param options
|
|
170
|
+
* @returns
|
|
171
|
+
*/
|
|
139
172
|
startGoldfish(options) {
|
|
140
173
|
return __awaiter(this, void 0, void 0, function* () {
|
|
141
|
-
const { avdName, devtool } = options;
|
|
174
|
+
const { avdName, devtool, origin = 'terminal' } = options;
|
|
175
|
+
// 获取emulator bin的绝对路径
|
|
142
176
|
const emulatorBin = this.getEmulatorBinPath();
|
|
143
|
-
|
|
177
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### emulator path: ${emulatorBin}`);
|
|
178
|
+
// 获取vela镜像的绝对路径
|
|
144
179
|
const avdInfo = this.velaAvdCls.getVelaAvdInfo(avdName);
|
|
145
180
|
const { avdArch, avdImagePath } = avdInfo;
|
|
146
|
-
|
|
147
|
-
ColorConsole_1.default.log(`### Emulator ### adb port: ${this.adbPort}`);
|
|
181
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### adb port: ${options.adbPort}`);
|
|
148
182
|
if (!avdImagePath) {
|
|
149
|
-
return
|
|
183
|
+
return shared_utils_1.ColorConsole.throw(`### Emulator ### Unable to find vela image via avd`);
|
|
150
184
|
}
|
|
151
185
|
const nuttxBinPath = path_1.default.resolve(avdImagePath, 'nuttx');
|
|
152
|
-
|
|
153
|
-
|
|
186
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### nuttx path: ${nuttxBinPath}`);
|
|
187
|
+
// 端口映射,adb端口和debug端口
|
|
188
|
+
let portMappingStr = `user,id=u1,hostfwd=tcp:127.0.0.1:${options.adbPort}-10.0.2.15:5555`;
|
|
154
189
|
if (devtool) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
portMappingStr += `,hostfwd=tcp:127.0.0.1:${this.debugPort}-10.0.2.15:101`;
|
|
190
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### debug port: ${options.debugPort}`);
|
|
191
|
+
portMappingStr += `,hostfwd=tcp:127.0.0.1:${options.debugPort}-10.0.2.15:101`;
|
|
158
192
|
}
|
|
159
|
-
|
|
160
|
-
const stdioType = options.disableNSH ? 'pipe' : 'inherit';
|
|
193
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Start qemu with TCP: ${portMappingStr}`);
|
|
161
194
|
// vnc配置
|
|
162
195
|
let noWindow = false;
|
|
163
196
|
let vncStr = '';
|
|
164
|
-
if (options.
|
|
197
|
+
if (options.grpcPort) {
|
|
165
198
|
noWindow = true;
|
|
166
|
-
const portSuffix = options.
|
|
199
|
+
const portSuffix = options.grpcPort - constants_1.defaultVncPort;
|
|
167
200
|
vncStr = `-vnc :${portSuffix}`;
|
|
168
201
|
}
|
|
169
202
|
// 启动goldfish的命令和参数
|
|
@@ -185,77 +218,53 @@ class OldGoldfishInstance extends common_1.default {
|
|
|
185
218
|
'-device',
|
|
186
219
|
'virtio-net-device,netdev=u1,bus=virtio-mmio-bus.3'
|
|
187
220
|
];
|
|
188
|
-
|
|
221
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Start CMD: ${spawnBin} ${spawnArgs.join(' ')}`);
|
|
189
222
|
return new Promise((resolve) => {
|
|
190
|
-
var _a;
|
|
191
|
-
this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio:
|
|
223
|
+
var _a, _b, _c, _d;
|
|
224
|
+
this.goldfishProcess = (0, child_process_1.spawn)(spawnBin, spawnArgs, { stdio: 'pipe', shell: true });
|
|
225
|
+
// 监听错误流
|
|
192
226
|
(_a = this.goldfishProcess.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
193
227
|
const stderrCb = options.stderrCallback || console.log;
|
|
194
228
|
stderrCb(data.toString());
|
|
195
229
|
});
|
|
230
|
+
if (origin === 'terminal') {
|
|
231
|
+
process.stdout.pipe(this.goldfishProcess.stdin);
|
|
232
|
+
(_b = this.goldfishProcess.stdout) === null || _b === void 0 ? void 0 : _b.pipe(process.stdout);
|
|
233
|
+
}
|
|
234
|
+
// 监听模拟器的退出事件
|
|
196
235
|
this.goldfishProcess.on('exit', (code) => {
|
|
197
|
-
|
|
236
|
+
shared_utils_1.ColorConsole.error(`### Emulator ### Goldfish emulator exited with code ${code}`);
|
|
198
237
|
if (options.exitCallback) {
|
|
199
238
|
options.exitCallback(code);
|
|
200
239
|
}
|
|
201
240
|
});
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
241
|
+
// 监听输出流。输出了'(NSH)'标识后则认为模拟器启动成功
|
|
242
|
+
(_d = (_c = this.goldfishProcess) === null || _c === void 0 ? void 0 : _c.stdout) === null || _d === void 0 ? void 0 : _d.on('data', (data) => {
|
|
243
|
+
const msg = data.toString();
|
|
244
|
+
if (origin === 'ide') {
|
|
205
245
|
const stdoutCb = options.stdoutCallback || console.log;
|
|
206
|
-
stdoutCb(
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
246
|
+
stdoutCb(msg);
|
|
247
|
+
}
|
|
248
|
+
if (msg.includes('(NSH)')) {
|
|
249
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Goldfish emulator starts successfully`);
|
|
250
|
+
resolve();
|
|
251
|
+
}
|
|
212
252
|
});
|
|
213
|
-
const p2 = setTimeout(() => {
|
|
214
|
-
ColorConsole_1.default.log(`### Emulator ### Goldfish emulator starts successfully`);
|
|
215
|
-
resolve();
|
|
216
|
-
}, 2000);
|
|
217
|
-
return Promise.race([p1, p2]);
|
|
218
253
|
});
|
|
219
254
|
});
|
|
220
255
|
}
|
|
221
|
-
/**
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const connectFn = () => __awaiter(this, void 0, void 0, function* () {
|
|
226
|
-
const sn = `127.0.0.1:${this.adbPort}`;
|
|
227
|
-
while (!adbConnected) {
|
|
228
|
-
const adbKillCmd = `adb kill-server`;
|
|
229
|
-
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${adbKillCmd}`);
|
|
230
|
-
adbMiwt.execAdbCmdSync(adbKillCmd);
|
|
231
|
-
const adbConnectCmd = `adb connect ${sn}`;
|
|
232
|
-
ColorConsole_1.default.log(`### Emulator ### Excuting adb cmd: ${adbConnectCmd}`);
|
|
233
|
-
const str = adbMiwt.execAdbCmdSync(adbConnectCmd);
|
|
234
|
-
ColorConsole_1.default.log(`### Emulator ### ${str}`);
|
|
235
|
-
const devices = yield adbMiwt.getAdbDevices();
|
|
236
|
-
ColorConsole_1.default.log(`### Emulator ### adb devices: ${JSON.stringify(devices)}`);
|
|
237
|
-
adbConnected =
|
|
238
|
-
devices.filter((item) => item.sn === sn && item.status === 'device').length > 0;
|
|
239
|
-
}
|
|
240
|
-
Promise.resolve(adbConnected);
|
|
241
|
-
});
|
|
242
|
-
yield Promise.race([
|
|
243
|
-
connectFn(),
|
|
244
|
-
new Promise((resolve) => {
|
|
245
|
-
setTimeout(() => resolve(false), 600 * 1000);
|
|
246
|
-
})
|
|
247
|
-
]);
|
|
248
|
-
return adbConnected;
|
|
249
|
-
});
|
|
250
|
-
}
|
|
256
|
+
/**
|
|
257
|
+
* 推送文件到本地的${sdkHome}/qa/app/${packageName}目录
|
|
258
|
+
* @param sourceRoot 源目录
|
|
259
|
+
*/
|
|
251
260
|
pushRpk(sourceRoot) {
|
|
252
261
|
return __awaiter(this, void 0, void 0, function* () {
|
|
253
262
|
const { package: appPackageName } = this.projectInfo;
|
|
254
263
|
const appRunDir = path_1.default.resolve(this.sdkHome, 'qa/app', appPackageName);
|
|
255
|
-
|
|
264
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Pushing ${appPackageName} to ${appRunDir}`);
|
|
256
265
|
fs_1.default.rmSync(appRunDir, { recursive: true, force: true });
|
|
257
|
-
|
|
258
|
-
|
|
266
|
+
shared_utils_1.FileUtil.copyFiles(sourceRoot, appRunDir);
|
|
267
|
+
shared_utils_1.ColorConsole.log(`### Emulator ### Push ${appPackageName} to ${appRunDir} successfully`);
|
|
259
268
|
});
|
|
260
269
|
}
|
|
261
270
|
/** 停止模拟器并释放相关资源 */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ModemSimulator = on
|
|
@@ -6,14 +6,19 @@ export declare const defaultSkinHome: string;
|
|
|
6
6
|
export declare const defaultQuickappHome: string;
|
|
7
7
|
export declare const defaultToolsHome: string;
|
|
8
8
|
export declare const defaultVncPort = 5900;
|
|
9
|
-
export declare const
|
|
9
|
+
export declare const defaultAdbPort = 5555;
|
|
10
|
+
export declare const defaultDebugPort = 10055;
|
|
11
|
+
export declare const VelaImageVersionList: {
|
|
12
|
+
label: string;
|
|
13
|
+
value: string;
|
|
14
|
+
time: string;
|
|
15
|
+
}[];
|
|
16
|
+
export declare const EmulatorEnvVersion: {
|
|
10
17
|
name: string;
|
|
11
18
|
emulator: string;
|
|
12
19
|
qa: string;
|
|
13
20
|
skins: string;
|
|
14
|
-
'system-images':
|
|
15
|
-
release: string;
|
|
16
|
-
dev: string;
|
|
17
|
-
};
|
|
21
|
+
'system-images': string;
|
|
18
22
|
tools: string;
|
|
23
|
+
modem_simulator: string;
|
|
19
24
|
};
|
package/lib/static/constants.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.EmulatorEnvVersion = exports.VelaImageVersionList = exports.defaultDebugPort = exports.defaultAdbPort = exports.defaultVncPort = exports.defaultToolsHome = exports.defaultQuickappHome = exports.defaultSkinHome = exports.defaultEmulatorHome = exports.defaultImageHome = exports.defaultAvdHome = exports.defaultSDKHome = void 0;
|
|
7
7
|
const os_1 = __importDefault(require("os"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
exports.defaultSDKHome = path_1.default.resolve(os_1.default.homedir(), '.export');
|
|
@@ -14,14 +14,26 @@ exports.defaultSkinHome = path_1.default.resolve(exports.defaultSDKHome, 'skins'
|
|
|
14
14
|
exports.defaultQuickappHome = path_1.default.resolve(exports.defaultSDKHome, 'qa');
|
|
15
15
|
exports.defaultToolsHome = path_1.default.resolve(exports.defaultSDKHome, 'tools');
|
|
16
16
|
exports.defaultVncPort = 5900;
|
|
17
|
-
exports.
|
|
17
|
+
exports.defaultAdbPort = 5555;
|
|
18
|
+
exports.defaultDebugPort = 10055;
|
|
19
|
+
exports.VelaImageVersionList = [
|
|
20
|
+
{
|
|
21
|
+
label: 'vela正式版(4.0)',
|
|
22
|
+
value: 'vela-release-4.0',
|
|
23
|
+
time: '2024-04-10T04:10:00'
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: 'vela开发版(dev, 0.0.2)',
|
|
27
|
+
value: 'vela-dev-0.0.2',
|
|
28
|
+
time: '2023-12-04T16:31:00'
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
exports.EmulatorEnvVersion = {
|
|
18
32
|
name: '模拟器资源版本管理',
|
|
19
|
-
emulator: '0.0.
|
|
33
|
+
emulator: '0.0.3',
|
|
20
34
|
qa: '0.0.1',
|
|
21
35
|
skins: '0.0.1',
|
|
22
|
-
'system-images':
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
},
|
|
26
|
-
tools: '0.0.2'
|
|
36
|
+
'system-images': exports.VelaImageVersionList[0].value,
|
|
37
|
+
tools: '0.0.2',
|
|
38
|
+
modem_simulator: '0.0.1'
|
|
27
39
|
};
|
package/lib/typing/Instance.d.ts
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import {
|
|
2
|
+
import { IJavascriptCompileOption } from '@aiot-toolkit/aiotpack';
|
|
3
|
+
import { IAvdResourcePaths } from './Avd';
|
|
3
4
|
export interface INewGoldfishInstanceParams extends IAvdResourcePaths {
|
|
4
5
|
projectPath: string;
|
|
5
6
|
sourceRoot?: string;
|
|
7
|
+
compilerOption?: Partial<IJavascriptCompileOption>;
|
|
6
8
|
}
|
|
7
9
|
export interface IStartOptions {
|
|
8
10
|
avdName: string;
|
|
9
11
|
devtool?: string;
|
|
12
|
+
/** @deprecated */
|
|
10
13
|
disableNSH?: boolean;
|
|
14
|
+
origin?: 'ide' | 'terminal';
|
|
11
15
|
serverPort?: number;
|
|
12
|
-
|
|
16
|
+
grpcPort?: number;
|
|
17
|
+
adbPort: number;
|
|
18
|
+
debugPort?: number;
|
|
13
19
|
stdoutCallback?: (buffer: Buffer) => void;
|
|
14
20
|
stderrCallback?: (buffer: Buffer) => void;
|
|
15
21
|
exitCallback?: (code: number | null) => void;
|
|
22
|
+
/** 要推送的目录路径 */
|
|
23
|
+
dist?: string;
|
|
24
|
+
/** 要推送到的目的路径 */
|
|
25
|
+
tar?: string;
|
|
16
26
|
}
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -9,4 +9,25 @@ export declare function killProcessByPid(pid: string): void;
|
|
|
9
9
|
* 根据命令杀死进程
|
|
10
10
|
*/
|
|
11
11
|
export declare function killProcessByCmd(cmd: string): Promise<void>;
|
|
12
|
+
/** 延迟函数 */
|
|
12
13
|
export declare function sleep(time: number): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* 重复执行某个任务直到成功,或者超过最大次数
|
|
16
|
+
* @param task 任务,需要返回 bool 值表示是否执行成功
|
|
17
|
+
* @param {Number=} maxCount 最大重试次数
|
|
18
|
+
* @param {number=} duration 每次重试的间隔
|
|
19
|
+
*/
|
|
20
|
+
export declare function tryRun(task: (...args: any[]) => Promise<any>, maxCount?: number, duration?: number, currentCount?: number): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* 延迟执行某个任务
|
|
23
|
+
* @param task
|
|
24
|
+
* @param duration
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
export declare function delayRun<T = any>(task: (...args: any[]) => Promise<T> | T, duration?: number): Promise<T>;
|
|
28
|
+
/**
|
|
29
|
+
* 为avdPort寻找一个不被占用的端口
|
|
30
|
+
* 端口号必须是偶数且在5555和5585之间
|
|
31
|
+
* @returns {number}
|
|
32
|
+
*/
|
|
33
|
+
export declare function getEvenPort(): Promise<number | false | undefined>;
|
package/lib/utils/index.js
CHANGED
|
@@ -12,17 +12,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.sleep = exports.killProcessByCmd = exports.killProcessByPid = exports.getSystemArch = void 0;
|
|
16
|
-
const
|
|
15
|
+
exports.getEvenPort = exports.delayRun = exports.tryRun = exports.sleep = exports.killProcessByCmd = exports.killProcessByPid = exports.getSystemArch = void 0;
|
|
16
|
+
const shared_utils_1 = require("@aiot-toolkit/shared-utils");
|
|
17
17
|
const child_process_1 = require("child_process");
|
|
18
18
|
const find_process_1 = __importDefault(require("find-process"));
|
|
19
19
|
const os_1 = __importDefault(require("os"));
|
|
20
20
|
const semver_1 = __importDefault(require("semver"));
|
|
21
|
+
const portfinder_1 = __importDefault(require("portfinder"));
|
|
21
22
|
const cpuArch = {
|
|
22
23
|
arm64: 'aarch64',
|
|
23
24
|
aarch64: 'aarch64',
|
|
24
25
|
x64: 'x86_64',
|
|
25
|
-
x86_64: 'x86_64'
|
|
26
|
+
x86_64: 'x86_64'
|
|
26
27
|
};
|
|
27
28
|
/** 获取mac电脑的CPU架构
|
|
28
29
|
* node 15.0.0之后,m1芯片的mac的os.arch()才是arm64,在这之前都是x86
|
|
@@ -42,7 +43,7 @@ function getSystemArch() {
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
if (osArch !== 'arm64' && osArch !== 'x64') {
|
|
45
|
-
return
|
|
46
|
+
return shared_utils_1.ColorConsole.throw(`unsupport system`);
|
|
46
47
|
}
|
|
47
48
|
return cpuArch[osArch];
|
|
48
49
|
}
|
|
@@ -50,9 +51,7 @@ exports.getSystemArch = getSystemArch;
|
|
|
50
51
|
/** 根据PID杀死进程 */
|
|
51
52
|
function killProcessByPid(pid) {
|
|
52
53
|
try {
|
|
53
|
-
const cmd = os_1.default.platform() ===
|
|
54
|
-
? `taskkill /pid ${pid} /T /F`
|
|
55
|
-
: `kill -9 ${pid}`;
|
|
54
|
+
const cmd = os_1.default.platform() === 'win32' ? `taskkill /pid ${pid} /T /F` : `kill -9 ${pid}`;
|
|
56
55
|
(0, child_process_1.execSync)(cmd);
|
|
57
56
|
}
|
|
58
57
|
catch (e) {
|
|
@@ -79,9 +78,68 @@ function killProcessByCmd(cmd) {
|
|
|
79
78
|
});
|
|
80
79
|
}
|
|
81
80
|
exports.killProcessByCmd = killProcessByCmd;
|
|
81
|
+
/** 延迟函数 */
|
|
82
82
|
function sleep(time) {
|
|
83
83
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
-
return new Promise(resolve => setTimeout(resolve, time));
|
|
84
|
+
return new Promise((resolve) => setTimeout(resolve, time));
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
87
|
exports.sleep = sleep;
|
|
88
|
+
/**
|
|
89
|
+
* 重复执行某个任务直到成功,或者超过最大次数
|
|
90
|
+
* @param task 任务,需要返回 bool 值表示是否执行成功
|
|
91
|
+
* @param {Number=} maxCount 最大重试次数
|
|
92
|
+
* @param {number=} duration 每次重试的间隔
|
|
93
|
+
*/
|
|
94
|
+
function tryRun(task, maxCount = 5, duration = 1000, currentCount = 0) {
|
|
95
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
if (currentCount > maxCount)
|
|
97
|
+
return false;
|
|
98
|
+
return (Boolean(yield task()) ||
|
|
99
|
+
(yield delayRun(() => tryRun(task, maxCount, duration, currentCount + 1), duration)));
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
exports.tryRun = tryRun;
|
|
103
|
+
/**
|
|
104
|
+
* 延迟执行某个任务
|
|
105
|
+
* @param task
|
|
106
|
+
* @param duration
|
|
107
|
+
* @returns
|
|
108
|
+
*/
|
|
109
|
+
function delayRun(task, duration = 1000) {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
return new Promise((resolve) => {
|
|
112
|
+
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
return resolve(task());
|
|
114
|
+
}), duration);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
exports.delayRun = delayRun;
|
|
119
|
+
/**
|
|
120
|
+
* 为avdPort寻找一个不被占用的端口
|
|
121
|
+
* 端口号必须是偶数且在5555和5585之间
|
|
122
|
+
* @returns {number}
|
|
123
|
+
*/
|
|
124
|
+
function getEvenPort() {
|
|
125
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
const startPort = 5555;
|
|
127
|
+
const stopPort = 5585;
|
|
128
|
+
let index = 1;
|
|
129
|
+
let port = yield portfinder_1.default.getPortPromise({
|
|
130
|
+
port: startPort,
|
|
131
|
+
stopPort
|
|
132
|
+
});
|
|
133
|
+
while (port % 2 !== 0) {
|
|
134
|
+
if (index > 30)
|
|
135
|
+
return false;
|
|
136
|
+
port = yield portfinder_1.default.getPortPromise({
|
|
137
|
+
port: startPort + index,
|
|
138
|
+
stopPort
|
|
139
|
+
});
|
|
140
|
+
index++;
|
|
141
|
+
return port;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
exports.getEvenPort = getEvenPort;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiot-toolkit/emulator",
|
|
3
|
-
"version": "2.0.2-beta.
|
|
3
|
+
"version": "2.0.2-beta.11",
|
|
4
4
|
"description": "vela emulator tool.",
|
|
5
5
|
"homepage": "",
|
|
6
6
|
"license": "ISC",
|
|
@@ -35,10 +35,14 @@
|
|
|
35
35
|
"emulator"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@aiot-toolkit/aiotpack": "2.0.2-beta.
|
|
39
|
-
"@aiot-toolkit/shared-utils": "2.0.2-beta.
|
|
38
|
+
"@aiot-toolkit/aiotpack": "2.0.2-beta.11",
|
|
39
|
+
"@aiot-toolkit/shared-utils": "2.0.2-beta.11",
|
|
40
40
|
"find-process": "^1.4.7",
|
|
41
41
|
"portfinder": "^1.0.32"
|
|
42
42
|
},
|
|
43
|
-
"
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/fs-extra": "^11.0.4",
|
|
45
|
+
"fs-extra": "^11.2.0"
|
|
46
|
+
},
|
|
47
|
+
"gitHead": "07c38dd12ba0d932c6dc1fd16fe25aaf15ab9fbb"
|
|
44
48
|
}
|