@lazycatcloud/lzc-cli 1.2.27 → 1.2.28
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/lib/app/apkshell.js +37 -0
- package/lib/app/index.js +74 -74
- package/lib/app/lpk_build.js +113 -117
- package/lib/app/lpk_create.js +78 -148
- package/lib/app/lpk_create_generator.js +101 -74
- package/lib/app/lpk_debug_bridge.js +65 -62
- package/lib/app/lpk_devshell.js +227 -228
- package/lib/app/lpk_devshell_docker.js +28 -28
- package/lib/app/lpk_installer.js +59 -49
- package/lib/appstore/index.js +29 -29
- package/lib/appstore/login.js +64 -64
- package/lib/appstore/prePublish.js +68 -68
- package/lib/appstore/publish.js +55 -55
- package/lib/box/index.js +25 -25
- package/lib/env.js +18 -18
- package/lib/shellapi.js +55 -58
- package/lib/utils.js +217 -164
- package/package.json +7 -1
- package/scripts/cli.js +56 -56
- package/template/_lpk/manifest.yml.in +8 -8
- package/template/vue/README.md +29 -0
- package/template/vue/index.html +13 -0
- package/template/vue/lzc-build.yml +59 -0
- package/template/vue/lzc-icon.png +0 -0
- package/template/vue/package.json +20 -0
- package/template/vue/public/vite.svg +1 -0
- package/template/vue/src/App.vue +30 -0
- package/template/vue/src/assets/vue.svg +1 -0
- package/template/vue/src/components/HelloWorld.vue +41 -0
- package/template/vue/src/main.ts +5 -0
- package/template/vue/src/style.css +79 -0
- package/template/vue/src/vite-env.d.ts +1 -0
- package/template/vue/tsconfig.app.json +24 -0
- package/template/vue/tsconfig.json +7 -0
- package/template/vue/tsconfig.node.json +22 -0
- package/template/vue/vite.config.ts +7 -0
- package/template/ionic_vue3/package-lock.json +0 -8100
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import fs from "node:fs"
|
|
2
|
+
import fetch from "node-fetch"
|
|
3
|
+
import logger from "loglevel"
|
|
4
|
+
|
|
5
|
+
export async function triggerApk(id, name, iconPath) {
|
|
6
|
+
if (!id) {
|
|
7
|
+
logger.error("Appid 为必填项!")
|
|
8
|
+
return
|
|
9
|
+
}
|
|
10
|
+
name = name || "懒猫应用"
|
|
11
|
+
try {
|
|
12
|
+
const form = new FormData()
|
|
13
|
+
form.append("app_id", id)
|
|
14
|
+
form.append("app_name", name)
|
|
15
|
+
if (iconPath) {
|
|
16
|
+
form.append("app_icon", new Blob([fs.readFileSync(iconPath)]))
|
|
17
|
+
}
|
|
18
|
+
const resp = await fetch(
|
|
19
|
+
"https://appstore.lazycat.cloud/api/trigger_latest_for_app",
|
|
20
|
+
{
|
|
21
|
+
method: "POST",
|
|
22
|
+
body: form
|
|
23
|
+
}
|
|
24
|
+
)
|
|
25
|
+
if (resp.status == 304) {
|
|
26
|
+
// 没有修改
|
|
27
|
+
logger.info(`APK构建任务已创建成功,如需使用安卓端,请耐心等待1分钟左右`)
|
|
28
|
+
} else if (resp.status == 201) {
|
|
29
|
+
logger.info(`APK构建任务已创建成功,如需使用安卓端,请耐心等待1分钟左右`)
|
|
30
|
+
} else if (resp.status >= 400) {
|
|
31
|
+
logger.debug("请求按钮应用出错:", resp)
|
|
32
|
+
throw "请求生成应用出错!"
|
|
33
|
+
}
|
|
34
|
+
} catch (error) {
|
|
35
|
+
logger.error(error)
|
|
36
|
+
}
|
|
37
|
+
}
|
package/lib/app/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import path from "node:path"
|
|
2
|
-
import lpkCreate from "./lpk_create.js"
|
|
3
|
-
import { LpkBuild } from "./lpk_build.js"
|
|
4
|
-
import { AppDevShell } from "./lpk_devshell.js"
|
|
5
|
-
import { LpkInstaller } from "./lpk_installer.js"
|
|
6
|
-
import logger from "loglevel"
|
|
7
|
-
import { sleep } from "../utils.js"
|
|
8
|
-
import { DebugBridge } from "./lpk_debug_bridge.js"
|
|
9
|
-
import shellApi from "../shellapi.js"
|
|
1
|
+
import path from "node:path"
|
|
2
|
+
import lpkCreate from "./lpk_create.js"
|
|
3
|
+
import { LpkBuild } from "./lpk_build.js"
|
|
4
|
+
import { AppDevShell } from "./lpk_devshell.js"
|
|
5
|
+
import { LpkInstaller } from "./lpk_installer.js"
|
|
6
|
+
import logger from "loglevel"
|
|
7
|
+
import { sleep } from "../utils.js"
|
|
8
|
+
import { DebugBridge } from "./lpk_debug_bridge.js"
|
|
9
|
+
import shellApi from "../shellapi.js"
|
|
10
10
|
|
|
11
11
|
export function lpkProjectCommand(program) {
|
|
12
12
|
let subCommands = [
|
|
@@ -14,10 +14,10 @@ export function lpkProjectCommand(program) {
|
|
|
14
14
|
command: "create <name>",
|
|
15
15
|
desc: "创建懒猫云应用",
|
|
16
16
|
handler: async ({ name }) => {
|
|
17
|
-
await shellApi.init()
|
|
17
|
+
await shellApi.init()
|
|
18
18
|
|
|
19
|
-
await lpkCreate(name)
|
|
20
|
-
}
|
|
19
|
+
await lpkCreate(name)
|
|
20
|
+
}
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
command: "build [context]",
|
|
@@ -26,28 +26,28 @@ export function lpkProjectCommand(program) {
|
|
|
26
26
|
args.option("o", {
|
|
27
27
|
alias: "output",
|
|
28
28
|
describe: "输出文件",
|
|
29
|
-
type: "string"
|
|
30
|
-
})
|
|
29
|
+
type: "string"
|
|
30
|
+
})
|
|
31
31
|
args.option("f", {
|
|
32
32
|
alias: "file",
|
|
33
33
|
describe: "指定构建的lzc-build.yml文件",
|
|
34
34
|
default: "lzc-build.yml",
|
|
35
|
-
type: "string"
|
|
36
|
-
})
|
|
35
|
+
type: "string"
|
|
36
|
+
})
|
|
37
37
|
},
|
|
38
38
|
handler: async ({ context, output, file }) => {
|
|
39
|
-
const lpk = await new LpkBuild(context, file).init()
|
|
39
|
+
const lpk = await new LpkBuild(context, file).init()
|
|
40
40
|
// 正常的打包逻辑不需要 devshell
|
|
41
41
|
lpk.onBeforeBuildPackage(async (options) => {
|
|
42
|
-
delete options["devshell"]
|
|
42
|
+
delete options["devshell"]
|
|
43
43
|
|
|
44
44
|
if (output) {
|
|
45
|
-
options["lpkPath"] = output
|
|
45
|
+
options["lpkPath"] = output
|
|
46
46
|
}
|
|
47
|
-
return options
|
|
48
|
-
})
|
|
49
|
-
await lpk.exec()
|
|
50
|
-
}
|
|
47
|
+
return options
|
|
48
|
+
})
|
|
49
|
+
await lpk.exec()
|
|
50
|
+
}
|
|
51
51
|
},
|
|
52
52
|
{
|
|
53
53
|
command: "devshell [context]",
|
|
@@ -56,50 +56,50 @@ export function lpkProjectCommand(program) {
|
|
|
56
56
|
args.option("f", {
|
|
57
57
|
alias: "force",
|
|
58
58
|
describe: "强制重新构建",
|
|
59
|
-
type: "boolean"
|
|
60
|
-
})
|
|
59
|
+
type: "boolean"
|
|
60
|
+
})
|
|
61
61
|
args.option("c", {
|
|
62
62
|
alias: "config",
|
|
63
63
|
describe: "devshell配置文件",
|
|
64
64
|
type: "string",
|
|
65
|
-
default: "lzc-build.yml"
|
|
66
|
-
})
|
|
65
|
+
default: "lzc-build.yml"
|
|
66
|
+
})
|
|
67
67
|
args.option("contentdir", {
|
|
68
68
|
describe: "同时打包 lzc-build.yml 中指定的 contentdir 目录",
|
|
69
|
-
type: "boolean"
|
|
70
|
-
})
|
|
69
|
+
type: "boolean"
|
|
70
|
+
})
|
|
71
71
|
},
|
|
72
72
|
handler: async ({ context, force, config, contentdir }) => {
|
|
73
|
-
await shellApi.init()
|
|
73
|
+
await shellApi.init()
|
|
74
74
|
|
|
75
|
-
const cwd = context ? path.resolve(context) : process.cwd()
|
|
76
|
-
const lpkBuild = await new LpkBuild(cwd, config).init()
|
|
75
|
+
const cwd = context ? path.resolve(context) : process.cwd()
|
|
76
|
+
const lpkBuild = await new LpkBuild(cwd, config).init()
|
|
77
77
|
lpkBuild.onBeforeBuildPackage(async (options) => {
|
|
78
78
|
// devshell 正常情况下,不需要执行 buildscript 和 contentdir 字段
|
|
79
|
-
logger.debug("devshell delete 'buildscript' field")
|
|
80
|
-
delete options["buildscript"]
|
|
79
|
+
logger.debug("devshell delete 'buildscript' field")
|
|
80
|
+
delete options["buildscript"]
|
|
81
81
|
|
|
82
82
|
if (!contentdir) {
|
|
83
|
-
logger.debug("devshell delete 'contentdir' field")
|
|
84
|
-
delete options["contentdir"]
|
|
83
|
+
logger.debug("devshell delete 'contentdir' field")
|
|
84
|
+
delete options["contentdir"]
|
|
85
85
|
}
|
|
86
|
-
return options
|
|
87
|
-
})
|
|
88
|
-
const app = new AppDevShell(cwd, lpkBuild, force, config)
|
|
89
|
-
await app.init()
|
|
90
|
-
await app.build()
|
|
91
|
-
await sleep(2000)
|
|
92
|
-
await app.rsyncShell()
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
]
|
|
86
|
+
return options
|
|
87
|
+
})
|
|
88
|
+
const app = new AppDevShell(cwd, lpkBuild, force, config)
|
|
89
|
+
await app.init()
|
|
90
|
+
await app.build()
|
|
91
|
+
await sleep(2000)
|
|
92
|
+
await app.rsyncShell()
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
96
|
program.command({
|
|
97
97
|
command: "project",
|
|
98
98
|
desc: "项目管理",
|
|
99
99
|
builder: (args) => {
|
|
100
|
-
args.command(subCommands)
|
|
101
|
-
}
|
|
102
|
-
})
|
|
100
|
+
args.command(subCommands)
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
export function lpkAppCommand(program) {
|
|
@@ -108,34 +108,34 @@ export function lpkAppCommand(program) {
|
|
|
108
108
|
command: "install [pkgPath]",
|
|
109
109
|
desc: "部署应用至设备, pkgPath 可以为路径,或者https://,http://请求地址, 如果不填写,将默认为当前目录下的lpk",
|
|
110
110
|
handler: async ({ pkgPath }) => {
|
|
111
|
-
await shellApi.init()
|
|
111
|
+
await shellApi.init()
|
|
112
112
|
|
|
113
|
-
pkgPath = pkgPath ?? process.cwd()
|
|
114
|
-
const installer = new LpkInstaller()
|
|
115
|
-
await installer.init()
|
|
116
|
-
await installer.install(pkgPath)
|
|
117
|
-
}
|
|
113
|
+
pkgPath = pkgPath ?? process.cwd()
|
|
114
|
+
const installer = new LpkInstaller()
|
|
115
|
+
await installer.init()
|
|
116
|
+
await installer.install(pkgPath)
|
|
117
|
+
}
|
|
118
118
|
},
|
|
119
119
|
{
|
|
120
120
|
command: "uninstall <pkgId>",
|
|
121
121
|
desc: "从设备中卸载某一个应用",
|
|
122
122
|
handler: async ({ pkgId }) => {
|
|
123
|
-
await shellApi.init()
|
|
123
|
+
await shellApi.init()
|
|
124
124
|
|
|
125
|
-
const bridge = new DebugBridge()
|
|
126
|
-
await bridge.uninstall(pkgId)
|
|
127
|
-
}
|
|
125
|
+
const bridge = new DebugBridge()
|
|
126
|
+
await bridge.uninstall(pkgId)
|
|
127
|
+
}
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
130
|
command: "status <pkgId>",
|
|
131
131
|
desc: "获取某一个应用的状态",
|
|
132
132
|
handler: async ({ pkgId }) => {
|
|
133
|
-
await shellApi.init()
|
|
133
|
+
await shellApi.init()
|
|
134
134
|
|
|
135
|
-
const bridge = new DebugBridge()
|
|
136
|
-
const status = await bridge.status(pkgId)
|
|
137
|
-
console.log(status)
|
|
138
|
-
}
|
|
135
|
+
const bridge = new DebugBridge()
|
|
136
|
+
const status = await bridge.status(pkgId)
|
|
137
|
+
console.log(status)
|
|
138
|
+
}
|
|
139
139
|
},
|
|
140
140
|
{
|
|
141
141
|
command: "log <pkgId>",
|
|
@@ -145,21 +145,21 @@ export function lpkAppCommand(program) {
|
|
|
145
145
|
alias: "follow",
|
|
146
146
|
describe: "持续输出",
|
|
147
147
|
type: "boolean",
|
|
148
|
-
default: false
|
|
149
|
-
})
|
|
148
|
+
default: false
|
|
149
|
+
})
|
|
150
150
|
},
|
|
151
151
|
handler: async () => {
|
|
152
|
-
await shellApi.init()
|
|
152
|
+
await shellApi.init()
|
|
153
153
|
|
|
154
|
-
throw "还没有实现"
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
]
|
|
154
|
+
throw "还没有实现"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
158
|
program.command({
|
|
159
159
|
command: "app",
|
|
160
160
|
desc: "应用管理",
|
|
161
161
|
builder: async (args) => {
|
|
162
|
-
args.command(subCommands)
|
|
163
|
-
}
|
|
164
|
-
})
|
|
162
|
+
args.command(subCommands)
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
165
|
}
|
package/lib/app/lpk_build.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import path from "node:path"
|
|
2
|
-
import fs from "node:fs"
|
|
3
|
-
import logger from "loglevel"
|
|
1
|
+
import path from "node:path"
|
|
2
|
+
import fs from "node:fs"
|
|
3
|
+
import logger from "loglevel"
|
|
4
4
|
import {
|
|
5
5
|
loadFromYaml,
|
|
6
6
|
isDirExist,
|
|
@@ -9,280 +9,276 @@ import {
|
|
|
9
9
|
envTemplateFile,
|
|
10
10
|
isValidPackageName,
|
|
11
11
|
tarContentDir,
|
|
12
|
-
isPngWithFile
|
|
13
|
-
} from "../utils.js"
|
|
14
|
-
import { spawnSync } from "child_process"
|
|
15
|
-
import { LpkManifest } from "./lpk_create.js"
|
|
16
|
-
import archiver from "archiver"
|
|
17
|
-
import yaml from "js-yaml"
|
|
12
|
+
isPngWithFile
|
|
13
|
+
} from "../utils.js"
|
|
14
|
+
import { spawnSync } from "child_process"
|
|
15
|
+
import { LpkManifest } from "./lpk_create.js"
|
|
16
|
+
import archiver from "archiver"
|
|
17
|
+
import yaml from "js-yaml"
|
|
18
18
|
|
|
19
|
-
const isMacos = process.platform == "darwin"
|
|
19
|
+
const isMacos = process.platform == "darwin"
|
|
20
20
|
|
|
21
21
|
async function archiveFolderTo(appDir, out, format = "zip") {
|
|
22
22
|
return new Promise(async (resolve, reject) => {
|
|
23
23
|
if (!fs.existsSync(appDir)) {
|
|
24
|
-
reject(new Error(`${appDir} 文件夹不存在`))
|
|
25
|
-
return
|
|
24
|
+
reject(new Error(`${appDir} 文件夹不存在`))
|
|
25
|
+
return
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
logger.debug("start archive app ...")
|
|
29
|
-
const output = fs.createWriteStream(out)
|
|
30
|
-
const archive = archiver(format)
|
|
28
|
+
logger.debug("start archive app ...")
|
|
29
|
+
const output = fs.createWriteStream(out)
|
|
30
|
+
const archive = archiver(format)
|
|
31
31
|
|
|
32
32
|
archive.on("error", (e) => {
|
|
33
|
-
reject(e)
|
|
34
|
-
logger.error(e)
|
|
35
|
-
})
|
|
33
|
+
reject(e)
|
|
34
|
+
logger.error(e)
|
|
35
|
+
})
|
|
36
36
|
archive.on("end", () => {
|
|
37
|
-
resolve(output)
|
|
38
|
-
})
|
|
39
|
-
archive.pipe(output)
|
|
37
|
+
resolve(output)
|
|
38
|
+
})
|
|
39
|
+
archive.pipe(output)
|
|
40
40
|
|
|
41
|
-
archive.directory(appDir, false)
|
|
42
|
-
archive.finalize()
|
|
43
|
-
})
|
|
41
|
+
archive.directory(appDir, false)
|
|
42
|
+
archive.finalize()
|
|
43
|
+
})
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
async function fetchIconTo(options, cwd, destDir) {
|
|
47
47
|
if (!options["icon"]) {
|
|
48
|
-
logger.warn("图标icon 没有指定")
|
|
49
|
-
return
|
|
48
|
+
logger.warn("图标icon 没有指定")
|
|
49
|
+
return
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
let iconPath = options["icon"]
|
|
52
|
+
let iconPath = options["icon"]
|
|
53
53
|
if (path.extname(iconPath) !== ".png") {
|
|
54
|
-
logger.warn("图标icon 不是一个 .png 文件")
|
|
55
|
-
return
|
|
54
|
+
logger.warn("图标icon 不是一个 .png 文件")
|
|
55
|
+
return
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
if (!path.isAbsolute(iconPath)) {
|
|
59
|
-
iconPath = path.resolve(cwd, iconPath)
|
|
59
|
+
iconPath = path.resolve(cwd, iconPath)
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
if (!isFileExist(iconPath)) {
|
|
63
|
-
logger.warn(`图标icon ${iconPath} 不存在`)
|
|
64
|
-
return
|
|
63
|
+
logger.warn(`图标icon ${iconPath} 不存在`)
|
|
64
|
+
return
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
if (!isPngWithFile(iconPath)) {
|
|
68
|
-
logger.warn(`图标icon ${iconPath} 验证失败(不是一个png格式)`)
|
|
69
|
-
return
|
|
68
|
+
logger.warn(`图标icon ${iconPath} 验证失败(不是一个png格式)`)
|
|
69
|
+
return
|
|
70
70
|
} else {
|
|
71
|
-
logger.debug(`图标icon ${iconPath} 验证成功(png格式)`)
|
|
71
|
+
logger.debug(`图标icon ${iconPath} 验证成功(png格式)`)
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
fs.copyFileSync(iconPath, path.join(destDir, "icon.png"))
|
|
75
|
-
return
|
|
74
|
+
fs.copyFileSync(iconPath, path.join(destDir, "icon.png"))
|
|
75
|
+
return
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
// 提供一些方便的环境变量,可以在 lzc-build.yml 中直接使用
|
|
79
79
|
// - LocalIP 本地局域网ip
|
|
80
80
|
function localIp() {
|
|
81
|
-
const regex = /inet6 (fc03:1136:[0-9a-fA-F:]+)[?:\/ ]
|
|
81
|
+
const regex = /inet6 (fc03:1136:[0-9a-fA-F:]+)[?:\/ ]/
|
|
82
82
|
|
|
83
|
-
let output = ""
|
|
83
|
+
let output = ""
|
|
84
84
|
if (isMacos) {
|
|
85
85
|
const result = spawnSync("sh", ["-c", "ifconfig"], {
|
|
86
|
-
encoding: "utf-8"
|
|
87
|
-
})
|
|
86
|
+
encoding: "utf-8"
|
|
87
|
+
})
|
|
88
88
|
if (result.status != 0 || result.error) {
|
|
89
|
-
logger.debug("macos get current ip is error", result.error)
|
|
90
|
-
return ""
|
|
89
|
+
logger.debug("macos get current ip is error", result.error)
|
|
90
|
+
return ""
|
|
91
91
|
}
|
|
92
|
-
output = result.stdout
|
|
92
|
+
output = result.stdout
|
|
93
93
|
} else {
|
|
94
94
|
const result = spawnSync("ip", ["addr", "show", "heiyu-0"], {
|
|
95
|
-
encoding: "utf-8"
|
|
96
|
-
})
|
|
95
|
+
encoding: "utf-8"
|
|
96
|
+
})
|
|
97
97
|
if (result.status !== 0 || result.error) {
|
|
98
|
-
logger.debug("run ip addr show heiyu-0 failed", result.error)
|
|
99
|
-
return ""
|
|
98
|
+
logger.debug("run ip addr show heiyu-0 failed", result.error)
|
|
99
|
+
return ""
|
|
100
100
|
}
|
|
101
|
-
output = result.stdout
|
|
101
|
+
output = result.stdout
|
|
102
102
|
}
|
|
103
|
-
const match = output.match(regex)
|
|
103
|
+
const match = output.match(regex)
|
|
104
104
|
if (match) {
|
|
105
|
-
return `[${match[1]}]
|
|
105
|
+
return `[${match[1]}]`
|
|
106
106
|
} else {
|
|
107
|
-
logger.debug("get LocalIP environment error", output.stderr)
|
|
108
|
-
return ""
|
|
107
|
+
logger.debug("get LocalIP environment error", output.stderr)
|
|
108
|
+
return ""
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
function convenientEnv() {
|
|
112
112
|
return Object.assign(
|
|
113
113
|
{},
|
|
114
114
|
{
|
|
115
|
-
LocalIP: localIp()
|
|
115
|
+
LocalIP: localIp()
|
|
116
116
|
},
|
|
117
117
|
process.env
|
|
118
|
-
)
|
|
118
|
+
)
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
export class LpkBuild {
|
|
122
122
|
constructor(cwd, buildConfigFile) {
|
|
123
|
-
this.pwd = cwd ?? process.cwd()
|
|
123
|
+
this.pwd = cwd ?? process.cwd()
|
|
124
124
|
|
|
125
|
-
this.optionsFilePath = path.join(this.pwd, buildConfigFile)
|
|
126
|
-
this.options = loadFromYaml(this.optionsFilePath)
|
|
125
|
+
this.optionsFilePath = path.join(this.pwd, buildConfigFile)
|
|
126
|
+
this.options = loadFromYaml(this.optionsFilePath)
|
|
127
127
|
|
|
128
128
|
this.manifestFilePath = this.options["manifest"]
|
|
129
129
|
? path.join(this.pwd, this.options["manifest"])
|
|
130
|
-
: path.join(this.pwd, "lzc-manifest.yml")
|
|
131
|
-
this.manifest = null
|
|
130
|
+
: path.join(this.pwd, "lzc-manifest.yml")
|
|
131
|
+
this.manifest = null
|
|
132
132
|
|
|
133
|
-
this.beforeBuildPackageFn = []
|
|
134
|
-
this.beforeDumpYamlFn = []
|
|
135
|
-
this.beforeTarContentFn = []
|
|
136
|
-
this.beforeDumpLpkFn = [fetchIconTo]
|
|
133
|
+
this.beforeBuildPackageFn = []
|
|
134
|
+
this.beforeDumpYamlFn = []
|
|
135
|
+
this.beforeTarContentFn = []
|
|
136
|
+
this.beforeDumpLpkFn = [fetchIconTo]
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
// init 时替换 lzc-build.yml 中的模板字段
|
|
140
140
|
async init() {
|
|
141
|
-
const manifest = await this.getManifest()
|
|
142
|
-
const primitive = convenientEnv()
|
|
141
|
+
const manifest = await this.getManifest()
|
|
142
|
+
const primitive = convenientEnv()
|
|
143
143
|
this.options = yaml.load(
|
|
144
144
|
await envTemplateFile(
|
|
145
145
|
this.optionsFilePath,
|
|
146
146
|
Object.assign({}, primitive, manifest)
|
|
147
147
|
)
|
|
148
|
-
)
|
|
149
|
-
return this
|
|
148
|
+
)
|
|
149
|
+
return this
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
// onBeforeDumpYaml
|
|
153
153
|
// fn: function(manifest, options) => manifest
|
|
154
154
|
onBeforeDumpYaml(fn) {
|
|
155
|
-
this.beforeDumpYamlFn.push(fn)
|
|
155
|
+
this.beforeDumpYamlFn.push(fn)
|
|
156
156
|
}
|
|
157
157
|
// onBeforeTarContent
|
|
158
158
|
// fn: function(contentdir, options) => void
|
|
159
159
|
onBeforeTarContent(fn) {
|
|
160
|
-
this.beforeTarContentFn.push(fn)
|
|
160
|
+
this.beforeTarContentFn.push(fn)
|
|
161
161
|
}
|
|
162
162
|
// onBeforeBuildPackage
|
|
163
163
|
// fn: function(options) => options
|
|
164
164
|
onBeforeBuildPackage(fn) {
|
|
165
|
-
this.beforeBuildPackageFn.push(fn)
|
|
165
|
+
this.beforeBuildPackageFn.push(fn)
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
// onBeforeDumpLpk
|
|
169
169
|
// fn: function(options, cwd, dir) => void
|
|
170
170
|
onBeforeDumpLpk(fn) {
|
|
171
|
-
this.beforeDumpLpkFn.push(fn)
|
|
171
|
+
this.beforeDumpLpkFn.push(fn)
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
async getManifest() {
|
|
175
175
|
if (this.manifest) {
|
|
176
|
-
return this.manifest
|
|
176
|
+
return this.manifest
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
let lpkM = new LpkManifest()
|
|
180
|
-
await lpkM.init(this.manifestFilePath)
|
|
181
|
-
this.manifest = lpkM.manifest
|
|
179
|
+
let lpkM = new LpkManifest()
|
|
180
|
+
await lpkM.init(this.manifestFilePath)
|
|
181
|
+
this.manifest = lpkM.manifest
|
|
182
182
|
|
|
183
183
|
if (!isValidPackageName(this.manifest["package"])) {
|
|
184
|
-
throw `${this.manifest["package"]} 含有非法字符,请使用正确的包名格式(java的包名格式),如:cloud.lazycat.apps.video
|
|
184
|
+
throw `${this.manifest["package"]} 含有非法字符,请使用正确的包名格式(java的包名格式),如:cloud.lazycat.apps.video`
|
|
185
185
|
}
|
|
186
|
-
return this.manifest
|
|
186
|
+
return this.manifest
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
async exec() {
|
|
190
190
|
if (this.beforeBuildPackageFn.length > 0) {
|
|
191
191
|
this.options = await this.beforeBuildPackageFn.reduce(
|
|
192
192
|
async (prev, curr) => {
|
|
193
|
-
return await curr(await prev)
|
|
193
|
+
return await curr(await prev)
|
|
194
194
|
},
|
|
195
195
|
this.options
|
|
196
|
-
)
|
|
196
|
+
)
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
if (this.options["buildscript"]) {
|
|
200
200
|
let p = spawnSync("sh", ["-c", this.options["buildscript"]], {
|
|
201
201
|
cwd: this.pwd,
|
|
202
|
-
stdio: "inherit"
|
|
203
|
-
})
|
|
202
|
+
stdio: "inherit"
|
|
203
|
+
})
|
|
204
204
|
if (p.status != 0) {
|
|
205
|
-
throw
|
|
205
|
+
throw `构建失败`
|
|
206
206
|
}
|
|
207
207
|
} else {
|
|
208
|
-
logger.warn("跳过执行 buildscript")
|
|
208
|
+
logger.warn("跳过执行 buildscript")
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
// 输出路径
|
|
212
|
-
let packName = this.options["lpkPath"]
|
|
213
|
-
const pkgout = path.resolve(this.pwd, this.options["pkgout"])
|
|
212
|
+
let packName = this.options["lpkPath"]
|
|
213
|
+
const pkgout = path.resolve(this.pwd, this.options["pkgout"])
|
|
214
214
|
if (!packName && !isDirExist(pkgout)) {
|
|
215
|
-
throw `${pkgout}
|
|
215
|
+
throw `${pkgout} 不存在`
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
const tempDir = fs.mkdtempSync(".lzc-cli-build")
|
|
219
|
-
let contentdir = this.options["contentdir"]
|
|
218
|
+
const tempDir = fs.mkdtempSync(".lzc-cli-build")
|
|
219
|
+
let contentdir = this.options["contentdir"]
|
|
220
220
|
try {
|
|
221
221
|
if (contentdir) {
|
|
222
|
-
contentdir = path.resolve(this.pwd, contentdir)
|
|
222
|
+
contentdir = path.resolve(this.pwd, contentdir)
|
|
223
223
|
if (!isDirExist(contentdir)) {
|
|
224
|
-
throw `${contentdir}
|
|
224
|
+
throw `${contentdir} 不存在`
|
|
225
225
|
}
|
|
226
226
|
} else {
|
|
227
|
-
logger.warn("跳过拷贝 contentdir 内容")
|
|
227
|
+
logger.warn("跳过拷贝 contentdir 内容")
|
|
228
228
|
// 当没有指定的 contentdir 的时候,也生成一个空的文件夹
|
|
229
229
|
// 原因是:可能其他地方会复制内容进来,像 devshell 中的会在打包的时候,将ssh key拷贝进来
|
|
230
|
-
contentdir = fs.mkdtempSync(path.join(tempDir, "fake-contentdir"))
|
|
230
|
+
contentdir = fs.mkdtempSync(path.join(tempDir, "fake-contentdir"))
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
// 开始打包 contentdir
|
|
234
234
|
if (this.beforeTarContentFn.length > 0) {
|
|
235
235
|
await this.beforeTarContentFn.reduce(async (prev, curr) => {
|
|
236
|
-
let _prev = await prev
|
|
237
|
-
await curr(_prev, this.options)
|
|
238
|
-
return _prev
|
|
239
|
-
}, contentdir)
|
|
236
|
+
let _prev = await prev
|
|
237
|
+
await curr(_prev, this.options)
|
|
238
|
+
return _prev
|
|
239
|
+
}, contentdir)
|
|
240
240
|
}
|
|
241
|
-
await tarContentDir(
|
|
242
|
-
["./"],
|
|
243
|
-
path.join(tempDir, "content.tar"),
|
|
244
|
-
contentdir
|
|
245
|
-
);
|
|
241
|
+
await tarContentDir(["./"], path.join(tempDir, "content.tar"), contentdir)
|
|
246
242
|
|
|
247
243
|
// 如果是临时的 contentdir, 目录在打包完成后删除
|
|
248
244
|
if (!this.options["contentdir"]) {
|
|
249
|
-
fs.rmSync(contentdir, { recursive: true })
|
|
245
|
+
fs.rmSync(contentdir, { recursive: true })
|
|
250
246
|
}
|
|
251
247
|
|
|
252
248
|
// 开始生成 manifest.yml
|
|
253
|
-
let manifest = await this.getManifest()
|
|
249
|
+
let manifest = await this.getManifest()
|
|
254
250
|
if (process.env.LZC_VERSION) {
|
|
255
|
-
manifest.version = process.env.LZC_VERSION
|
|
251
|
+
manifest.version = process.env.LZC_VERSION
|
|
256
252
|
}
|
|
257
253
|
if (this.beforeDumpYamlFn.length > 0) {
|
|
258
254
|
manifest = await this.beforeDumpYamlFn.reduce(async (prev, curr) => {
|
|
259
|
-
return await curr(await prev, this.options)
|
|
260
|
-
}, manifest)
|
|
255
|
+
return await curr(await prev, this.options)
|
|
256
|
+
}, manifest)
|
|
261
257
|
}
|
|
262
|
-
logger.debug("manifest\n", manifest)
|
|
263
|
-
dumpToYaml(manifest, path.join(tempDir, "manifest.yml"))
|
|
258
|
+
logger.debug("manifest\n", manifest)
|
|
259
|
+
dumpToYaml(manifest, path.join(tempDir, "manifest.yml"))
|
|
264
260
|
|
|
265
261
|
// 打包 lpk
|
|
266
262
|
if (this.beforeDumpLpkFn.length > 0) {
|
|
267
263
|
await this.beforeDumpLpkFn.reduce(async (prev, curr) => {
|
|
268
|
-
await curr(this.options, this.pwd, tempDir)
|
|
269
|
-
return prev
|
|
270
|
-
}, {})
|
|
264
|
+
await curr(this.options, this.pwd, tempDir)
|
|
265
|
+
return prev
|
|
266
|
+
}, {})
|
|
271
267
|
}
|
|
272
268
|
|
|
273
269
|
if (!packName) {
|
|
274
270
|
packName = path.resolve(
|
|
275
271
|
pkgout,
|
|
276
272
|
`${manifest.package}-v${manifest.version}.lpk`
|
|
277
|
-
)
|
|
273
|
+
)
|
|
278
274
|
}
|
|
279
275
|
|
|
280
|
-
const lpkPath = await archiveFolderTo(tempDir, packName)
|
|
281
|
-
logger.info(`输出lpk包 ${lpkPath.path}`)
|
|
276
|
+
const lpkPath = await archiveFolderTo(tempDir, packName)
|
|
277
|
+
logger.info(`输出lpk包 ${lpkPath.path}`)
|
|
282
278
|
|
|
283
|
-
return lpkPath.path
|
|
279
|
+
return lpkPath.path
|
|
284
280
|
} finally {
|
|
285
|
-
fs.rmSync(tempDir, { recursive: true })
|
|
281
|
+
fs.rmSync(tempDir, { recursive: true })
|
|
286
282
|
}
|
|
287
283
|
}
|
|
288
284
|
}
|