@lazycatcloud/lzc-cli 1.2.45 → 1.2.47
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/changelog.md +8 -0
- package/lib/app/apkshell.js +1 -1
- package/lib/app/index.js +4 -1
- package/lib/app/lpk_debug_bridge.js +24 -3
- package/lib/app/lpk_devshell.js +8 -15
- package/lib/utils.js +60 -0
- package/package.json +1 -1
- package/scripts/cli.js +1 -4
- package/template/_lpk/init_debug_bridge.sh +4 -0
- package/template/ionic_vue3/package-lock.json +8100 -0
package/changelog.md
CHANGED
package/lib/app/apkshell.js
CHANGED
|
@@ -16,7 +16,7 @@ export async function triggerApk(id, name, iconPath) {
|
|
|
16
16
|
form.append("app_icon", new Blob([fs.readFileSync(iconPath)]))
|
|
17
17
|
}
|
|
18
18
|
const resp = await api.post(
|
|
19
|
-
"https://appstore.lazycat.cloud/api/trigger_latest_for_app",
|
|
19
|
+
"https://appstore.api.lazycat.cloud/api/trigger_latest_for_app",
|
|
20
20
|
form,
|
|
21
21
|
{ timeout: 5000 }
|
|
22
22
|
)
|
package/lib/app/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { LpkBuild } from "./lpk_build.js"
|
|
|
4
4
|
import { AppDevShell } from "./lpk_devshell.js"
|
|
5
5
|
import { LpkInstaller, installConfig } from "./lpk_installer.js"
|
|
6
6
|
import logger from "loglevel"
|
|
7
|
-
import { sleep } from "../utils.js"
|
|
7
|
+
import { sleep, checkRsync } from "../utils.js"
|
|
8
8
|
import { DebugBridge } from "./lpk_debug_bridge.js"
|
|
9
9
|
import shellApi from "../shellapi.js"
|
|
10
10
|
import { generate } from "./lpk_create_generator.js"
|
|
@@ -84,6 +84,9 @@ export function lpkProjectCommand(program) {
|
|
|
84
84
|
},
|
|
85
85
|
handler: async ({ context, force, config, contentdir, apk }) => {
|
|
86
86
|
await shellApi.init()
|
|
87
|
+
// 检测 rsync 满足
|
|
88
|
+
await checkRsync()
|
|
89
|
+
|
|
87
90
|
installConfig.apk = apk == "y"
|
|
88
91
|
const cwd = context ? path.resolve(context) : process.cwd()
|
|
89
92
|
const lpkBuild = await new LpkBuild(cwd, config).init()
|
|
@@ -8,7 +8,8 @@ import {
|
|
|
8
8
|
sleep,
|
|
9
9
|
findSshPublicKey,
|
|
10
10
|
isWindows,
|
|
11
|
-
contextDirname
|
|
11
|
+
contextDirname,
|
|
12
|
+
compareVersions
|
|
12
13
|
} from "../utils.js"
|
|
13
14
|
import logger from "loglevel"
|
|
14
15
|
import commandExists from "command-exists"
|
|
@@ -142,6 +143,20 @@ export class DebugBridge {
|
|
|
142
143
|
])
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
async version() {
|
|
147
|
+
const output = await this.common(sshBinary(), [
|
|
148
|
+
...sshCmdArgs(`box@${this.domain}`),
|
|
149
|
+
`version`
|
|
150
|
+
])
|
|
151
|
+
logger.debug(`backend version:\n${output}`)
|
|
152
|
+
try {
|
|
153
|
+
const data = JSON.parse(output)
|
|
154
|
+
return data.version
|
|
155
|
+
} catch {
|
|
156
|
+
return "0.0.0"
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
145
160
|
async uninstall(appId) {
|
|
146
161
|
return this.common(sshBinary(), [
|
|
147
162
|
...sshCmdArgs(`box@${this.domain}`),
|
|
@@ -193,6 +208,8 @@ export class DebugBridge {
|
|
|
193
208
|
}
|
|
194
209
|
|
|
195
210
|
async buildImage(label, contextTar) {
|
|
211
|
+
const backendVersion = await this.version()
|
|
212
|
+
|
|
196
213
|
const tag = `debug.bridge/${label}`
|
|
197
214
|
const resolvedIp = await resolveDomain(this.domain)
|
|
198
215
|
const stream = fs.createReadStream(contextTar)
|
|
@@ -209,8 +226,12 @@ export class DebugBridge {
|
|
|
209
226
|
return new Promise((resolve, reject) => {
|
|
210
227
|
buildStream.on("close", (code) => {
|
|
211
228
|
code == 0
|
|
212
|
-
? resolve(
|
|
213
|
-
|
|
229
|
+
? resolve(
|
|
230
|
+
compareVersions("0.1.12", backendVersion) >= 0
|
|
231
|
+
? `localhost:5000/${tag}`
|
|
232
|
+
: `dev.${this.boxname}.heiyu.space/${tag}`
|
|
233
|
+
)
|
|
234
|
+
: reject(`在盒子中构建 image 失败`)
|
|
214
235
|
})
|
|
215
236
|
}).finally(() => {
|
|
216
237
|
fs.rmSync(contextTar)
|
package/lib/app/lpk_devshell.js
CHANGED
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
isLinux
|
|
25
25
|
} from "../utils.js"
|
|
26
26
|
import os from "node:os"
|
|
27
|
-
import commandExists from "command-exists"
|
|
28
27
|
import chokidar from "chokidar"
|
|
29
28
|
import _ from "lodash"
|
|
30
29
|
import { DebugBridge } from "./lpk_debug_bridge.js"
|
|
@@ -425,10 +424,14 @@ export class AppDevShell {
|
|
|
425
424
|
}
|
|
426
425
|
|
|
427
426
|
const devshell = new DevShell(pkgId, this.isUserApp)
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
427
|
+
try {
|
|
428
|
+
if (isSync) {
|
|
429
|
+
await devshell.shell()
|
|
430
|
+
} else {
|
|
431
|
+
await devshell.connectShell()
|
|
432
|
+
}
|
|
433
|
+
} catch (e) {
|
|
434
|
+
logger.error(`devshell 错误: ${e}`)
|
|
432
435
|
}
|
|
433
436
|
logger.debug("exit shell")
|
|
434
437
|
// TODO: shell 在正常情况下,按 Ctrl-D 就会退出,回到原来的本地的 shell ,但
|
|
@@ -444,15 +447,6 @@ class DevShell {
|
|
|
444
447
|
}
|
|
445
448
|
|
|
446
449
|
async syncProject(appId) {
|
|
447
|
-
if (isLinux || isMacOs) {
|
|
448
|
-
// 检查rsync工具是否存在:提示用户
|
|
449
|
-
const rsyncExisted = commandExists.sync("rsync")
|
|
450
|
-
if (!rsyncExisted) {
|
|
451
|
-
logger.error("请检查 rsync 是否安装,路径是否正确!")
|
|
452
|
-
process.exit(1)
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
450
|
const resolvedIp = await resolveDomain(
|
|
457
451
|
`dev.${shellApi.boxname}.heiyu.space`
|
|
458
452
|
)
|
|
@@ -562,7 +556,6 @@ class DevShell {
|
|
|
562
556
|
await this.syncProject(this.appId)
|
|
563
557
|
})
|
|
564
558
|
} catch (e) {
|
|
565
|
-
console.log(e)
|
|
566
559
|
return Promise.reject(e)
|
|
567
560
|
}
|
|
568
561
|
}
|
package/lib/utils.js
CHANGED
|
@@ -18,6 +18,14 @@ import * as tar from "tar"
|
|
|
18
18
|
import dns from "node:dns/promises"
|
|
19
19
|
import axios from "axios"
|
|
20
20
|
import AdmZip from "adm-zip"
|
|
21
|
+
import commandExists from "command-exists"
|
|
22
|
+
|
|
23
|
+
// lzc-cli 包的 pkgInfo 信息
|
|
24
|
+
export const pkgInfo = JSON.parse(
|
|
25
|
+
fs.readFileSync(
|
|
26
|
+
path.join(contextDirname(import.meta.url), "..", "package.json")
|
|
27
|
+
)
|
|
28
|
+
)
|
|
21
29
|
|
|
22
30
|
// 创建 Axios 实例
|
|
23
31
|
export const api = axios.create()
|
|
@@ -42,6 +50,27 @@ export const envsubstr = async (templateContents, args) => {
|
|
|
42
50
|
return parse(templateContents, args)
|
|
43
51
|
}
|
|
44
52
|
|
|
53
|
+
// 比较当前的版本和want的大小,如果
|
|
54
|
+
// - 当前版本大于指定的版本 => 1
|
|
55
|
+
// - 当前版本等于指定的版本 => 0
|
|
56
|
+
// - 当前版本小于指定的版本 => -1
|
|
57
|
+
export function compareVersions(want, current = pkgInfo.version) {
|
|
58
|
+
const wantArrs = want.split(".")
|
|
59
|
+
const currArrs = current.split(".")
|
|
60
|
+
|
|
61
|
+
// Compare each part
|
|
62
|
+
for (let i = 0; i < Math.max(wantArrs.length, currArrs.length); i++) {
|
|
63
|
+
// Convert to integers, default to 0 if part doesn't exist
|
|
64
|
+
const w = parseInt(wantArrs[i] || 0)
|
|
65
|
+
const c = parseInt(currArrs[i] || 0)
|
|
66
|
+
|
|
67
|
+
if (c > w) return 1
|
|
68
|
+
if (c < w) return -1
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return 0 // Versions are equal
|
|
72
|
+
}
|
|
73
|
+
|
|
45
74
|
/**
|
|
46
75
|
* 确保文件夹存在
|
|
47
76
|
* @param filePath {string} 如果为文件路径 确保其文件夹存在; 如果为文件夹, 则确保该文件夹存在
|
|
@@ -588,3 +617,34 @@ export function findSshPublicKey() {
|
|
|
588
617
|
throw error
|
|
589
618
|
}
|
|
590
619
|
}
|
|
620
|
+
|
|
621
|
+
export function checkRsync() {
|
|
622
|
+
return new Promise((resolve, reject) => {
|
|
623
|
+
if (isLinux || isMacOs) {
|
|
624
|
+
// 检查rsync工具是否存在:提示用户
|
|
625
|
+
const rsyncExisted = commandExists.sync("rsync")
|
|
626
|
+
if (!rsyncExisted) {
|
|
627
|
+
reject("请检查 rsync 是否安装,路径是否正确!")
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
const check = spawn.sync("rsync", ["--version"], {
|
|
631
|
+
shell: true,
|
|
632
|
+
encoding: "utf-8",
|
|
633
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
634
|
+
})
|
|
635
|
+
logger.debug(`执行命令 rsync --version`)
|
|
636
|
+
if (check.status == 0) {
|
|
637
|
+
const versionMatch = check.stdout.match(
|
|
638
|
+
/rsync\s+version\s+(\d+\.\d+\.\d+)/i
|
|
639
|
+
)
|
|
640
|
+
if (!versionMatch || compareVersions("3.2.0", versionMatch[1]) < 0) {
|
|
641
|
+
reject(`当前rsync版本为:${versionMatch[1]}, 要求rsync版本为: 3.2.0+`)
|
|
642
|
+
}
|
|
643
|
+
logger.debug(`当前rsync版本为:${versionMatch[1]}`)
|
|
644
|
+
} else {
|
|
645
|
+
reject("请检查 rsync 安装是否正确,指定 rsync --version 错误")
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
resolve()
|
|
649
|
+
})
|
|
650
|
+
}
|
package/package.json
CHANGED
package/scripts/cli.js
CHANGED
|
@@ -7,13 +7,10 @@ import yargs from "yargs"
|
|
|
7
7
|
import { hideBin } from "yargs/helpers"
|
|
8
8
|
import chalk from "chalk"
|
|
9
9
|
|
|
10
|
-
import { contextDirname } from "../lib/utils.js"
|
|
10
|
+
import { contextDirname, pkgInfo } from "../lib/utils.js"
|
|
11
11
|
import { boxCommand } from "../lib/box/index.js"
|
|
12
12
|
import { appstoreCommand } from "../lib/appstore/index.js"
|
|
13
13
|
import { lpkAppCommand, lpkProjectCommand } from "../lib/app/index.js"
|
|
14
|
-
const pkgInfo = JSON.parse(
|
|
15
|
-
fs.readFileSync(path.join(contextDirname(import.meta.url), "../package.json"))
|
|
16
|
-
)
|
|
17
14
|
import env from "../lib/env.js"
|
|
18
15
|
|
|
19
16
|
// logger level middleware
|
|
@@ -33,6 +33,10 @@ if ${LZCBUSYBOX} netstat -tln | grep ':22222' >/dev/null; then
|
|
|
33
33
|
else
|
|
34
34
|
echo "启动 rsync daemon."
|
|
35
35
|
rsync --daemon --no-detach --config=/lzcapp/pkg/content/devshell/rsyncd.conf &
|
|
36
|
+
while ! nc -z localhost 873; do
|
|
37
|
+
sleep 1
|
|
38
|
+
done
|
|
39
|
+
echo "rsync daemon 已成功监听 873 端口"
|
|
36
40
|
|
|
37
41
|
mkdir -p /etc/dropbear
|
|
38
42
|
exec dropbearmulti dropbear -R -F -E -B -p 22222
|