@lazycatcloud/lzc-cli 2.0.0-pre.0 → 2.0.0-pre.2
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 +46 -7
- package/changelog.md +56 -19
- package/lib/app/apkshell.js +7 -44
- package/lib/app/index.js +5 -1
- package/lib/app/lpk_build.js +266 -56
- package/lib/app/lpk_build_images.js +424 -229
- package/lib/app/lpk_build_images_local.js +425 -0
- package/lib/app/lpk_build_images_pack_local.js +409 -0
- package/lib/app/lpk_create.js +158 -83
- package/lib/app/lpk_create_generator.js +35 -42
- package/lib/app/lpk_devshell.js +6 -2
- package/lib/app/lpk_installer.js +4 -3
- package/lib/app/manifest_build.js +259 -0
- package/lib/app/project_cp.js +5 -10
- package/lib/app/project_deploy.js +80 -11
- package/lib/app/project_exec.js +48 -11
- package/lib/app/project_info.js +59 -59
- package/lib/app/project_log.js +5 -10
- package/lib/app/project_runtime.js +113 -18
- package/lib/app/project_start.js +6 -11
- package/lib/app/project_sync.js +499 -0
- package/lib/appstore/apkshell.js +50 -0
- package/lib/appstore/publish.js +54 -15
- package/lib/build_remote.js +0 -1
- package/lib/config/index.js +1 -1
- package/lib/debug_bridge.js +217 -47
- package/lib/i18n/locales/en/translation.json +262 -262
- package/lib/i18n/locales/zh/translation.json +262 -262
- package/lib/lpk/core.js +2 -1
- package/lib/migrate/index.js +52 -0
- package/lib/package_info.js +135 -0
- package/lib/shellapi.js +35 -1
- package/lib/sig/core.js +2 -2
- package/lib/utils.js +92 -15
- package/package.json +89 -89
- package/scripts/cli.js +2 -0
- package/scripts/smoke/frontend-dev-entry.mjs +104 -0
- package/scripts/smoke/template-project.mjs +311 -0
- package/template/_lpk/README.md +6 -3
- package/template/_lpk/gui-vnc.manifest.yml.in +0 -9
- package/template/_lpk/hello-vue.manifest.yml.in +38 -0
- package/template/_lpk/manifest.yml.in +0 -9
- package/template/_lpk/package.yml.in +7 -0
- package/template/_lpk/todolist-golang.manifest.yml.in +23 -9
- package/template/_lpk/todolist-java.manifest.yml.in +23 -9
- package/template/_lpk/todolist-python.manifest.yml.in +31 -9
- package/template/_lpk/todolist-serverless.manifest.yml.in +38 -0
- package/template/blank/lzc-build.dev.yml +4 -0
- package/template/blank/lzc-build.yml +0 -2
- package/template/blank/lzc-manifest.yml +3 -12
- package/template/blank/package.yml +7 -0
- package/template/golang/Dockerfile +1 -1
- package/template/golang/Dockerfile.dev +20 -0
- package/template/golang/README.md +22 -11
- package/template/golang/_lzcdevignore +21 -0
- package/template/golang/lzc-build.dev.yml +12 -0
- package/template/golang/lzc-build.yml +0 -5
- package/template/golang/main.go +1 -1
- package/template/golang/manifest.dev.page.js +24 -0
- package/template/golang/run.sh +7 -0
- package/template/gui-vnc/README.md +5 -1
- package/template/gui-vnc/lzc-build.dev.yml +4 -0
- package/template/gui-vnc/lzc-build.yml +0 -5
- package/template/python/Dockerfile +2 -2
- package/template/python/Dockerfile.dev +18 -0
- package/template/python/README.md +28 -11
- package/template/python/_lzcdevignore +21 -0
- package/template/python/app.py +1 -1
- package/template/python/lzc-build.dev.yml +12 -0
- package/template/python/lzc-build.yml +0 -5
- package/template/python/manifest.dev.page.js +25 -0
- package/template/python/run.sh +12 -1
- package/template/springboot/Dockerfile +1 -1
- package/template/springboot/Dockerfile.dev +20 -0
- package/template/springboot/README.md +22 -11
- package/template/springboot/_lzcdevignore +21 -0
- package/template/springboot/lzc-build.dev.yml +12 -0
- package/template/springboot/lzc-build.yml +0 -5
- package/template/springboot/manifest.dev.page.js +24 -0
- package/template/springboot/run.sh +7 -0
- package/template/vue/README.md +14 -27
- package/template/vue/_gitignore +0 -1
- package/template/vue/lzc-build.dev.yml +7 -0
- package/template/vue/lzc-build.yml +0 -2
- package/template/vue/manifest.dev.page.js +50 -0
- package/template/vue/src/App.vue +1 -1
- package/template/vue-minidb/README.md +11 -19
- package/template/vue-minidb/_gitignore +0 -1
- package/template/vue-minidb/lzc-build.dev.yml +7 -0
- package/template/vue-minidb/lzc-build.yml +0 -2
- package/template/vue-minidb/manifest.dev.page.js +50 -0
- package/template/blank/_gitignore +0 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import logger from 'loglevel';
|
|
4
|
+
import { LpkBuild } from '../app/lpk_build.js';
|
|
5
|
+
import { dumpToYaml, loadFromYaml } from '../utils.js';
|
|
6
|
+
import { PACKAGE_FILE_NAME, splitManifestAndPackageInfo } from '../package_info.js';
|
|
7
|
+
|
|
8
|
+
async function migrateHandler({ context, file }) {
|
|
9
|
+
const cwd = context ? path.resolve(context) : process.cwd();
|
|
10
|
+
const build = new LpkBuild(cwd, file || 'lzc-build.yml');
|
|
11
|
+
const manifestPath = build.manifestFilePath;
|
|
12
|
+
const packageFilePath = build.packageFilePath;
|
|
13
|
+
|
|
14
|
+
if (fs.existsSync(packageFilePath)) {
|
|
15
|
+
logger.info(`package metadata already exists at ${packageFilePath}`);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let manifest;
|
|
20
|
+
try {
|
|
21
|
+
manifest = loadFromYaml(manifestPath) ?? {};
|
|
22
|
+
} catch {
|
|
23
|
+
throw new Error(`Cannot auto-migrate templated manifest: ${manifestPath}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const split = splitManifestAndPackageInfo(manifest);
|
|
27
|
+
if (Object.keys(split.packageInfo).length === 0) {
|
|
28
|
+
throw new Error(`No static package fields found in ${manifestPath}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
dumpToYaml(split.packageInfo, packageFilePath);
|
|
32
|
+
dumpToYaml(split.manifest, manifestPath);
|
|
33
|
+
|
|
34
|
+
logger.info(`wrote ${PACKAGE_FILE_NAME}: ${packageFilePath}`);
|
|
35
|
+
logger.info(`updated manifest: ${manifestPath}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function migrateCommand(program) {
|
|
39
|
+
program.command({
|
|
40
|
+
command: 'migrate [context]',
|
|
41
|
+
desc: 'Migrate manifest package metadata to package.yml',
|
|
42
|
+
builder: (args) => {
|
|
43
|
+
args.option('f', {
|
|
44
|
+
alias: 'file',
|
|
45
|
+
describe: 'Build config file',
|
|
46
|
+
type: 'string',
|
|
47
|
+
default: 'lzc-build.yml',
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
handler: migrateHandler,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import yaml from 'js-yaml';
|
|
4
|
+
import { fakeLoadManifestText, fakeLoadManifestYml, loadFromYaml } from './utils.js';
|
|
5
|
+
|
|
6
|
+
export const PACKAGE_FILE_NAME = 'package.yml';
|
|
7
|
+
export const STATIC_PACKAGE_FIELDS = [
|
|
8
|
+
'package',
|
|
9
|
+
'version',
|
|
10
|
+
'name',
|
|
11
|
+
'description',
|
|
12
|
+
'author',
|
|
13
|
+
'license',
|
|
14
|
+
'homepage',
|
|
15
|
+
'min_os_version',
|
|
16
|
+
'unsupported_platforms',
|
|
17
|
+
'locales',
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
function hasOwn(obj, key) {
|
|
21
|
+
return Object.prototype.hasOwnProperty.call(obj ?? {}, key);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function readYamlIfExists(filePath) {
|
|
25
|
+
if (!filePath || !fs.existsSync(filePath)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return yaml.load(fs.readFileSync(filePath, 'utf-8')) ?? {};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function tryLoadManifestText(manifestText) {
|
|
32
|
+
const text = String(manifestText ?? '');
|
|
33
|
+
const hasGoTemplate = text.includes('{{') && text.includes('}}');
|
|
34
|
+
try {
|
|
35
|
+
return {
|
|
36
|
+
data: yaml.load(text) ?? {},
|
|
37
|
+
excp: hasGoTemplate,
|
|
38
|
+
};
|
|
39
|
+
} catch {
|
|
40
|
+
return {
|
|
41
|
+
data: fakeLoadManifestText(text) ?? {},
|
|
42
|
+
excp: true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function loadManifestFile(manifestPath) {
|
|
48
|
+
try {
|
|
49
|
+
return loadFromYaml(manifestPath) ?? {};
|
|
50
|
+
} catch {
|
|
51
|
+
return fakeLoadManifestYml(manifestPath) ?? {};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function loadManifestText(manifestText) {
|
|
56
|
+
return tryLoadManifestText(manifestText).data;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function loadPackageFile(packageFilePath) {
|
|
60
|
+
return readYamlIfExists(packageFilePath);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function defaultPackageFilePath(manifestPath) {
|
|
64
|
+
return path.join(path.dirname(manifestPath), PACKAGE_FILE_NAME);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function findManifestStaticFields(manifest) {
|
|
68
|
+
return STATIC_PACKAGE_FIELDS.filter((field) => hasOwn(manifest, field));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function ensureManifestStaticFieldsAbsent(manifest, manifestPath) {
|
|
72
|
+
const invalidFields = findManifestStaticFields(manifest);
|
|
73
|
+
if (invalidFields.length === 0) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
throw new Error(`Static package fields must be moved from ${manifestPath} to ${PACKAGE_FILE_NAME}: ${invalidFields.join(', ')}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function applyPackageFileToManifest(manifest, packageInfo) {
|
|
80
|
+
const nextManifest = { ...(manifest ?? {}) };
|
|
81
|
+
for (const field of STATIC_PACKAGE_FIELDS) {
|
|
82
|
+
delete nextManifest[field];
|
|
83
|
+
}
|
|
84
|
+
if (!packageInfo) {
|
|
85
|
+
return nextManifest;
|
|
86
|
+
}
|
|
87
|
+
for (const field of STATIC_PACKAGE_FIELDS) {
|
|
88
|
+
if (hasOwn(packageInfo, field)) {
|
|
89
|
+
nextManifest[field] = packageInfo[field];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return nextManifest;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function splitManifestAndPackageInfo(manifest, basePackageInfo = null) {
|
|
96
|
+
const manifestOnly = { ...(manifest ?? {}) };
|
|
97
|
+
const packageInfo = { ...(basePackageInfo ?? {}) };
|
|
98
|
+
for (const field of STATIC_PACKAGE_FIELDS) {
|
|
99
|
+
if (hasOwn(manifestOnly, field)) {
|
|
100
|
+
packageInfo[field] = manifestOnly[field];
|
|
101
|
+
delete manifestOnly[field];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
manifest: manifestOnly,
|
|
106
|
+
packageInfo,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function loadEffectiveManifest(manifestPath, options = {}) {
|
|
111
|
+
const hasInlineManifestText = Object.prototype.hasOwnProperty.call(options, 'manifestText');
|
|
112
|
+
const loadedManifest = hasInlineManifestText
|
|
113
|
+
? tryLoadManifestText(options.manifestText)
|
|
114
|
+
: { data: loadManifestFile(manifestPath), excp: false };
|
|
115
|
+
const sourceManifest = loadedManifest.data;
|
|
116
|
+
const packageFilePath = options.packageFilePath || defaultPackageFilePath(manifestPath);
|
|
117
|
+
const hasPackageFile = fs.existsSync(packageFilePath);
|
|
118
|
+
const packageInfo = hasPackageFile ? loadPackageFile(packageFilePath) ?? {} : null;
|
|
119
|
+
if (hasPackageFile && options.strictStaticFields) {
|
|
120
|
+
ensureManifestStaticFieldsAbsent(sourceManifest, manifestPath);
|
|
121
|
+
}
|
|
122
|
+
const manifest = hasPackageFile ? applyPackageFileToManifest(sourceManifest, packageInfo) : sourceManifest;
|
|
123
|
+
return {
|
|
124
|
+
manifest,
|
|
125
|
+
sourceManifest,
|
|
126
|
+
packageInfo,
|
|
127
|
+
hasPackageFile,
|
|
128
|
+
packageFilePath,
|
|
129
|
+
excpManifest: loadedManifest.excp,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function loadEffectiveManifestFromFiles(manifestPath, options = {}) {
|
|
134
|
+
return loadEffectiveManifest(manifestPath, options);
|
|
135
|
+
}
|
package/lib/shellapi.js
CHANGED
|
@@ -23,7 +23,9 @@ function getShellAPIConfigDir() {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
class ShellApi {
|
|
26
|
-
constructor() {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.clientId = '';
|
|
28
|
+
}
|
|
27
29
|
|
|
28
30
|
async init() {
|
|
29
31
|
// 检查当前 shell 环境上下文是否配置 HTTP_PROXY
|
|
@@ -109,6 +111,38 @@ NOTE:在指定环境变量的模式下,有些接口依旧不能访问,为
|
|
|
109
111
|
});
|
|
110
112
|
}
|
|
111
113
|
|
|
114
|
+
async queryShellCoreInfo() {
|
|
115
|
+
if (!this.client) {
|
|
116
|
+
return {};
|
|
117
|
+
}
|
|
118
|
+
return new Promise((resolve, reject) => {
|
|
119
|
+
this.client.queryShellCoreInfo({}, this.metadata, function (err, response) {
|
|
120
|
+
if (err) {
|
|
121
|
+
reject(err);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
resolve(response);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async resolveClientId() {
|
|
130
|
+
const cached = String(this.clientId ?? '').trim();
|
|
131
|
+
if (cached) {
|
|
132
|
+
return cached;
|
|
133
|
+
}
|
|
134
|
+
if (!this.client) {
|
|
135
|
+
return '';
|
|
136
|
+
}
|
|
137
|
+
const info = await this.queryShellCoreInfo();
|
|
138
|
+
const clientId = String(info?.id ?? '').trim();
|
|
139
|
+
if (!clientId) {
|
|
140
|
+
throw new Error('resolve client id failed: empty shell core id');
|
|
141
|
+
}
|
|
142
|
+
this.clientId = clientId;
|
|
143
|
+
return clientId;
|
|
144
|
+
}
|
|
145
|
+
|
|
112
146
|
async initBoxInfo() {
|
|
113
147
|
try {
|
|
114
148
|
const boxes = await this.boxList();
|
package/lib/sig/core.js
CHANGED
|
@@ -5,7 +5,7 @@ import crypto from 'node:crypto';
|
|
|
5
5
|
import archiver from 'archiver';
|
|
6
6
|
import AdmZip from 'adm-zip';
|
|
7
7
|
import * as tar from 'tar';
|
|
8
|
-
import
|
|
8
|
+
import { loadEffectiveManifestFromFiles } from '../package_info.js';
|
|
9
9
|
import { t } from '../i18n/index.js';
|
|
10
10
|
|
|
11
11
|
function toPosixPath(filePath) {
|
|
@@ -118,7 +118,7 @@ function loadManifestInfo(workDir) {
|
|
|
118
118
|
return { appid: '', version: '' };
|
|
119
119
|
}
|
|
120
120
|
try {
|
|
121
|
-
const manifest =
|
|
121
|
+
const manifest = loadEffectiveManifestFromFiles(manifestPath).manifest;
|
|
122
122
|
return {
|
|
123
123
|
appid: manifest?.package ?? '',
|
|
124
124
|
version: manifest?.version ? String(manifest.version) : '',
|
package/lib/utils.js
CHANGED
|
@@ -182,28 +182,38 @@ export function loadFromYaml(file) {
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
// lzc-manifest.yml 要支持模板,目前无法直接用yaml库解释,手动读出必要字段
|
|
185
|
-
|
|
186
|
-
const res = fs.readFileSync(file, 'utf8');
|
|
185
|
+
function fakeLoadManifestCore(text) {
|
|
187
186
|
let obj = {
|
|
188
187
|
application: {
|
|
189
188
|
subdomain: undefined,
|
|
190
189
|
},
|
|
191
190
|
};
|
|
192
191
|
|
|
193
|
-
|
|
192
|
+
const normalizeValue = (value) => {
|
|
193
|
+
const commentIndex = value.indexOf(' #');
|
|
194
|
+
if (commentIndex >= 0) {
|
|
195
|
+
value = value.slice(0, commentIndex);
|
|
196
|
+
}
|
|
197
|
+
return value.trim();
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
String(text ?? '').split('\n').forEach((v) => {
|
|
194
201
|
let line = v.trim();
|
|
195
202
|
const arr = line.split(':');
|
|
196
203
|
if (arr.length != 2) {
|
|
197
204
|
return;
|
|
198
205
|
}
|
|
199
206
|
let [key, value] = arr;
|
|
200
|
-
value = value
|
|
207
|
+
value = normalizeValue(value);
|
|
201
208
|
if (!obj.package && key == 'package') {
|
|
202
209
|
obj.package = value;
|
|
203
210
|
}
|
|
204
211
|
if (!obj.application.subdomain && key == 'subdomain') {
|
|
205
212
|
obj.application.subdomain = value;
|
|
206
213
|
}
|
|
214
|
+
if (!obj.name && key == 'name') {
|
|
215
|
+
obj.name = value;
|
|
216
|
+
}
|
|
207
217
|
if (!obj.version && key == 'version') {
|
|
208
218
|
obj.version = value;
|
|
209
219
|
}
|
|
@@ -211,6 +221,14 @@ export function fakeLoadManifestYml(file) {
|
|
|
211
221
|
return obj;
|
|
212
222
|
}
|
|
213
223
|
|
|
224
|
+
export function fakeLoadManifestText(text) {
|
|
225
|
+
return fakeLoadManifestCore(text);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export function fakeLoadManifestYml(file) {
|
|
229
|
+
return fakeLoadManifestCore(fs.readFileSync(file, 'utf8'));
|
|
230
|
+
}
|
|
231
|
+
|
|
214
232
|
export function dumpToYaml(template, target) {
|
|
215
233
|
fs.writeFileSync(
|
|
216
234
|
target,
|
|
@@ -526,16 +544,29 @@ export async function resolveDomain(domain, quiet = false) {
|
|
|
526
544
|
}
|
|
527
545
|
}
|
|
528
546
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
547
|
+
function detectLpkArchiveFormatSync(filePath) {
|
|
548
|
+
const fd = fs.openSync(filePath, 'r');
|
|
549
|
+
try {
|
|
550
|
+
const header = Buffer.alloc(512);
|
|
551
|
+
const bytesRead = fs.readSync(fd, header, 0, header.length, 0);
|
|
552
|
+
if (bytesRead >= 4 && header[0] === 0x50 && header[1] === 0x4b && header[2] === 0x03 && header[3] === 0x04) {
|
|
553
|
+
return 'zip';
|
|
554
|
+
}
|
|
555
|
+
if (bytesRead >= 265 && header.subarray(257, 262).toString() === 'ustar') {
|
|
556
|
+
return 'tar';
|
|
557
|
+
}
|
|
558
|
+
throw new Error(`Unsupported LPK archive format: ${filePath}`);
|
|
559
|
+
} finally {
|
|
560
|
+
fs.closeSync(fd);
|
|
532
561
|
}
|
|
562
|
+
}
|
|
533
563
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
const zip = new AdmZip(zipPath);
|
|
564
|
+
function normalizeArchiveEntryPath(entryPath) {
|
|
565
|
+
return String(entryPath ?? '').replace(/^\.\//, '').replace(/\\/g, '/');
|
|
566
|
+
}
|
|
538
567
|
|
|
568
|
+
function extractZipEntriesSync(zipPath, destPath, entries = []) {
|
|
569
|
+
const zip = new AdmZip(zipPath);
|
|
539
570
|
if (entries.length > 0) {
|
|
540
571
|
entries.forEach((entry) => {
|
|
541
572
|
try {
|
|
@@ -544,10 +575,56 @@ export function unzipSync(zipPath, destPath, entries = []) {
|
|
|
544
575
|
logger.debug(t('lzc_cli.lib.utils.unzip_sync_not_exist_file_log', `压缩包中没有找到 {{ entry }} 文件`, { entry, interpolation: { escapeValue: false } }));
|
|
545
576
|
}
|
|
546
577
|
});
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
zip.extractAllTo(destPath, true);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
function extractTarEntriesSync(tarPath, destPath, entries = []) {
|
|
584
|
+
const wanted = new Set((entries ?? []).map((entry) => normalizeArchiveEntryPath(entry)).filter(Boolean));
|
|
585
|
+
tar.x({
|
|
586
|
+
file: tarPath,
|
|
587
|
+
cwd: destPath,
|
|
588
|
+
sync: true,
|
|
589
|
+
filter: (entryPath) => {
|
|
590
|
+
if (wanted.size === 0) {
|
|
591
|
+
return true;
|
|
592
|
+
}
|
|
593
|
+
const normalized = normalizeArchiveEntryPath(entryPath);
|
|
594
|
+
return wanted.has(normalized);
|
|
595
|
+
},
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
if (wanted.size === 0) {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
for (const entry of wanted) {
|
|
602
|
+
if (!isFileExist(path.join(destPath, entry))) {
|
|
603
|
+
logger.debug(t('lzc_cli.lib.utils.unzip_sync_not_exist_file_log', `压缩包中没有找到 {{ entry }} 文件`, { entry, interpolation: { escapeValue: false } }));
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
export function extractLpkSync(lpkPath, destPath, entries = []) {
|
|
609
|
+
if (!isFileExist(lpkPath)) {
|
|
610
|
+
throw t('lzc_cli.lib.utils.unzip_sync_not_exist_fail', `{{ zipPath }} 找不到该文件`, { zipPath: lpkPath, interpolation: { escapeValue: false } });
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
fs.mkdirSync(destPath, { recursive: true });
|
|
614
|
+
const format = detectLpkArchiveFormatSync(lpkPath);
|
|
615
|
+
if (format === 'zip') {
|
|
616
|
+
extractZipEntriesSync(lpkPath, destPath, entries);
|
|
617
|
+
return;
|
|
550
618
|
}
|
|
619
|
+
if (format === 'tar') {
|
|
620
|
+
extractTarEntriesSync(lpkPath, destPath, entries);
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
throw new Error(`Unsupported LPK archive format: ${lpkPath}`);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
export function unzipSync(zipPath, destPath, entries = []) {
|
|
627
|
+
extractLpkSync(zipPath, destPath, entries);
|
|
551
628
|
}
|
|
552
629
|
|
|
553
630
|
export async function selectSshPublicKey(avaiableKeys) {
|
|
@@ -643,7 +720,7 @@ export function checkRsync() {
|
|
|
643
720
|
}
|
|
644
721
|
|
|
645
722
|
const check = spawn.sync('rsync', ['--version'], {
|
|
646
|
-
shell:
|
|
723
|
+
shell: false,
|
|
647
724
|
encoding: 'utf-8',
|
|
648
725
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
649
726
|
});
|
package/package.json
CHANGED
|
@@ -1,91 +1,91 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
2
|
+
"name": "@lazycatcloud/lzc-cli",
|
|
3
|
+
"version": "2.0.0-pre.2",
|
|
4
|
+
"description": "lazycat cloud developer kit",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"release": "release-it patch",
|
|
7
|
+
"prepublishOnly": "node check-changelog.js",
|
|
8
|
+
"i18n:parser": "i18next-cli extract -c i18next.config.js --sync-all && prettier -w ./lib/i18n/locales"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"template",
|
|
12
|
+
"scripts",
|
|
13
|
+
"lib",
|
|
14
|
+
"changelog.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"lzc-cli": "scripts/cli.js",
|
|
21
|
+
"lzc-docker": "scripts/lzc-docker.js",
|
|
22
|
+
"lzc-docker-compose": "scripts/lzc-docker-compose.js"
|
|
23
|
+
},
|
|
24
|
+
"type": "module",
|
|
25
|
+
"keywords": [
|
|
26
|
+
"lazycat cloud sdk"
|
|
27
|
+
],
|
|
28
|
+
"author": "zac zeng",
|
|
29
|
+
"license": "ISC",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@balena/dockerignore": "^1.0.2",
|
|
32
|
+
"@grpc/grpc-js": "^1.11.1",
|
|
33
|
+
"@grpc/proto-loader": "^0.7.13",
|
|
34
|
+
"@lazycatcloud/sdk": "^0.1.423",
|
|
35
|
+
"adm-zip": "^0.5.16",
|
|
36
|
+
"archiver": "^7.0.1",
|
|
37
|
+
"chalk": "^5.3.0",
|
|
38
|
+
"chokidar": "^3.6.0",
|
|
39
|
+
"command-exists": "^1.2.9",
|
|
40
|
+
"cross-spawn": "^7.0.3",
|
|
41
|
+
"dockerfile-ast": "^0.6.1",
|
|
42
|
+
"envsub": "^4.1.0",
|
|
43
|
+
"fast-glob": "^3.3.2",
|
|
44
|
+
"form-data": "^4.0.0",
|
|
45
|
+
"i18next": "^25.7.1",
|
|
46
|
+
"i18next-fs-backend": "^2.6.1",
|
|
47
|
+
"ignore": "^5.3.2",
|
|
48
|
+
"inquirer": "^10.1.8",
|
|
49
|
+
"isbinaryfile": "^5.0.2",
|
|
50
|
+
"js-yaml": "^4.1.0",
|
|
51
|
+
"lodash": "^4.17.23",
|
|
52
|
+
"lodash.debounce": "^4.0.8",
|
|
53
|
+
"lodash.merge": "^4.6.2",
|
|
54
|
+
"lodash.mergewith": "^4.6.2",
|
|
55
|
+
"loglevel": "^1.9.1",
|
|
56
|
+
"node-fetch": "^3.3.2",
|
|
57
|
+
"semver": "^7.6.3",
|
|
58
|
+
"tar": "^7.4.3",
|
|
59
|
+
"yargs": "^17.7.2"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@release-it/conventional-changelog": "^10.0.1",
|
|
63
|
+
"@types/command-exists": "^1.2.3",
|
|
64
|
+
"i18next-cli": "^1.32.0",
|
|
65
|
+
"prettier": "^3.3.3",
|
|
66
|
+
"release-it": "^19.0.4"
|
|
67
|
+
},
|
|
68
|
+
"release-it": {
|
|
69
|
+
"git": {
|
|
70
|
+
"requireCleanWorkingDir": false,
|
|
71
|
+
"commitMessage": "chore: release v${version}",
|
|
72
|
+
"commit": true,
|
|
73
|
+
"tag": true,
|
|
74
|
+
"push": false
|
|
75
|
+
},
|
|
76
|
+
"npm": {
|
|
77
|
+
"publish": false
|
|
78
|
+
},
|
|
79
|
+
"plugins": {
|
|
80
|
+
"@release-it/conventional-changelog": {
|
|
81
|
+
"preset": "angular",
|
|
82
|
+
"infile": "changelog.md"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
"publishConfig": {
|
|
87
|
+
"registry": "https://registry.npmjs.org",
|
|
88
|
+
"access": "public",
|
|
89
|
+
"tag": "lpkv2"
|
|
90
|
+
}
|
|
91
91
|
}
|
package/scripts/cli.js
CHANGED
|
@@ -15,6 +15,7 @@ import { lpkAppCommand, lpkProjectCommand } from '../lib/app/index.js';
|
|
|
15
15
|
import { configCommand } from '../lib/config/index.js';
|
|
16
16
|
import { lzcDockerCommand } from '../lib/docker/index.js';
|
|
17
17
|
import { lpkCommand } from '../lib/lpk/index.js';
|
|
18
|
+
import { migrateCommand } from '../lib/migrate/index.js';
|
|
18
19
|
|
|
19
20
|
function setLoggerLevel({ log }) {
|
|
20
21
|
logger.setLevel(log, false);
|
|
@@ -66,6 +67,7 @@ lpkProjectCommand(program);
|
|
|
66
67
|
appstoreCommand(program);
|
|
67
68
|
lzcDockerCommand(program);
|
|
68
69
|
lpkCommand(program);
|
|
70
|
+
migrateCommand(program);
|
|
69
71
|
|
|
70
72
|
// 当没有参数的时候,默认显示帮助。
|
|
71
73
|
(async () => {
|