@lazycatcloud/lzc-cli 2.0.0-pre.3 → 2.0.0-pre.5
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 +17 -0
- package/lib/app/lpk_build.js +51 -20
- package/lib/app/lpk_create.js +8 -7
- package/lib/app/lpk_create_generator.js +26 -10
- package/lib/app/project_sync.js +1 -4
- package/package.json +1 -1
- package/template/blank/lzc-build.dev.yml +5 -2
- package/template/golang/lzc-build.dev.yml +5 -2
- package/template/gui-vnc/lzc-build.dev.yml +5 -2
- package/template/python/lzc-build.dev.yml +5 -2
- package/template/springboot/lzc-build.dev.yml +5 -2
- package/template/vue/lzc-build.dev.yml +5 -2
- package/template/vue-minidb/lzc-build.dev.yml +5 -2
package/changelog.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.0.0-pre.5](https://gitee.com/linakesi/lzc-cli/compare/v2.0.0-pre.4...v2.0.0-pre.5) (2026-03-19)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- remove dozzle and use LPK v2
|
|
8
|
+
- read debug bridge version from package metadata
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
- keep `.lzcdevignore` semantics consistent during `project sync --watch`
|
|
13
|
+
|
|
14
|
+
## [2.0.0-pre.4](https://gitee.com/linakesi/lzc-cli/compare/v2.0.0-pre.3...v2.0.0-pre.4) (2026-03-14)
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
- support build package metadata overrides
|
|
19
|
+
|
|
3
20
|
## [2.0.0-pre.3](https://gitee.com/linakesi/lzc-cli/compare/v2.0.0-pre.2...v2.0.0-pre.3) (2026-03-12)
|
|
4
21
|
|
|
5
22
|
### Features
|
package/lib/app/lpk_build.js
CHANGED
|
@@ -303,16 +303,39 @@ function mergeBuildOptions(baseOptions, topOptions) {
|
|
|
303
303
|
};
|
|
304
304
|
}
|
|
305
305
|
|
|
306
|
-
function
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (!normalizedSuffix) {
|
|
310
|
-
return normalizedPackageId;
|
|
306
|
+
function normalizePackageMetadataOverride(options, fieldName) {
|
|
307
|
+
if (!Object.prototype.hasOwnProperty.call(options ?? {}, fieldName)) {
|
|
308
|
+
return '';
|
|
311
309
|
}
|
|
312
|
-
|
|
313
|
-
|
|
310
|
+
const normalizedValue = String(options[fieldName] ?? '').trim();
|
|
311
|
+
if (!normalizedValue) {
|
|
312
|
+
throw new Error(`${fieldName} cannot be empty when specified`);
|
|
314
313
|
}
|
|
315
|
-
return
|
|
314
|
+
return normalizedValue;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function applyPackageMetadataOverrides(manifest, packageInfo, options) {
|
|
318
|
+
const pkgId = normalizePackageMetadataOverride(options, 'pkg_id');
|
|
319
|
+
const pkgName = normalizePackageMetadataOverride(options, 'pkg_name');
|
|
320
|
+
const hasPackageMetadataOverrides = !!pkgId || !!pkgName;
|
|
321
|
+
let nextManifest = { ...(manifest ?? {}) };
|
|
322
|
+
let nextPackageInfo = packageInfo;
|
|
323
|
+
|
|
324
|
+
if (pkgId) {
|
|
325
|
+
nextManifest = { ...nextManifest, package: pkgId };
|
|
326
|
+
nextPackageInfo = { ...(nextPackageInfo ?? {}), package: pkgId };
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (pkgName) {
|
|
330
|
+
nextManifest = { ...nextManifest, name: pkgName };
|
|
331
|
+
nextPackageInfo = { ...(nextPackageInfo ?? {}), name: pkgName };
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return {
|
|
335
|
+
manifest: nextManifest,
|
|
336
|
+
packageInfo: nextPackageInfo,
|
|
337
|
+
hasPackageMetadataOverrides,
|
|
338
|
+
};
|
|
316
339
|
}
|
|
317
340
|
|
|
318
341
|
export function validatePackageFileForArchiveFormat(hasPackageFile, archiveFormat) {
|
|
@@ -328,8 +351,8 @@ function hasBuildEnvEntries(envEntries) {
|
|
|
328
351
|
return Array.isArray(envEntries) && envEntries.length > 0;
|
|
329
352
|
}
|
|
330
353
|
|
|
331
|
-
export function shouldUseV2PackageLayout({ forceV2 = false, hasPackageFile = false, hasImagesConfig = false, buildEnvEntries = [] } = {}) {
|
|
332
|
-
return !!forceV2 || !!hasPackageFile || !!hasImagesConfig || hasBuildEnvEntries(buildEnvEntries);
|
|
354
|
+
export function shouldUseV2PackageLayout({ forceV2 = false, hasPackageFile = false, hasImagesConfig = false, buildEnvEntries = [], hasPackageMetadataOverrides = false } = {}) {
|
|
355
|
+
return !!forceV2 || !!hasPackageFile || !!hasImagesConfig || hasBuildEnvEntries(buildEnvEntries) || !!hasPackageMetadataOverrides;
|
|
333
356
|
}
|
|
334
357
|
|
|
335
358
|
function logDeprecatedStaticFieldWarning(manifestPath, fields) {
|
|
@@ -347,6 +370,16 @@ function normalizeBuildOptions(options) {
|
|
|
347
370
|
return normalized;
|
|
348
371
|
}
|
|
349
372
|
|
|
373
|
+
function normalizeContentDir(contentdir) {
|
|
374
|
+
if (contentdir === undefined || contentdir === null) {
|
|
375
|
+
return '';
|
|
376
|
+
}
|
|
377
|
+
if (typeof contentdir === 'string') {
|
|
378
|
+
return contentdir.trim();
|
|
379
|
+
}
|
|
380
|
+
return contentdir;
|
|
381
|
+
}
|
|
382
|
+
|
|
350
383
|
function loadYamlIfExists(filePath) {
|
|
351
384
|
if (!filePath || !isFileExist(filePath)) {
|
|
352
385
|
return {};
|
|
@@ -396,6 +429,7 @@ export class LpkBuild {
|
|
|
396
429
|
this.sourceManifest = null;
|
|
397
430
|
this.packageInfo = null;
|
|
398
431
|
this.hasPackageFile = false;
|
|
432
|
+
this.hasPackageMetadataOverrides = false;
|
|
399
433
|
this.buildVars = null;
|
|
400
434
|
this.preprocessedManifestText = '';
|
|
401
435
|
|
|
@@ -424,6 +458,7 @@ export class LpkBuild {
|
|
|
424
458
|
this.sourceManifest = null;
|
|
425
459
|
this.packageInfo = null;
|
|
426
460
|
this.hasPackageFile = false;
|
|
461
|
+
this.hasPackageMetadataOverrides = false;
|
|
427
462
|
this.buildVars = buildVarsFromEnvEntries(this.options['envs']);
|
|
428
463
|
this.preprocessedManifestText = '';
|
|
429
464
|
return this;
|
|
@@ -476,15 +511,10 @@ export class LpkBuild {
|
|
|
476
511
|
this.sourceManifest = loaded.sourceManifest;
|
|
477
512
|
this.packageInfo = loaded.packageInfo;
|
|
478
513
|
this.hasPackageFile = loaded.hasPackageFile;
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
this.manifest = { ...this.manifest, package: packageWithSuffix };
|
|
484
|
-
if (this.hasPackageFile) {
|
|
485
|
-
this.packageInfo = { ...(this.packageInfo ?? {}), package: packageWithSuffix };
|
|
486
|
-
}
|
|
487
|
-
}
|
|
514
|
+
const packageMetadata = applyPackageMetadataOverrides(loaded.manifest, loaded.packageInfo, this.options);
|
|
515
|
+
this.manifest = packageMetadata.manifest;
|
|
516
|
+
this.packageInfo = packageMetadata.packageInfo;
|
|
517
|
+
this.hasPackageMetadataOverrides = packageMetadata.hasPackageMetadataOverrides;
|
|
488
518
|
|
|
489
519
|
if (!isValidPackageName(this.manifest['package'])) {
|
|
490
520
|
throw t('lzc_cli.lib.app.lpk_build.get_manifest_package_name_fail', `{{ package }} 含有非法字符,请使用正确的包名格式(java的包名格式),如:cloud.lazycat.apps.video`, {
|
|
@@ -538,7 +568,7 @@ export class LpkBuild {
|
|
|
538
568
|
}
|
|
539
569
|
|
|
540
570
|
const tempDir = fs.mkdtempSync('.lzc-cli-build');
|
|
541
|
-
let contentdir = this.options['contentdir'];
|
|
571
|
+
let contentdir = normalizeContentDir(this.options['contentdir']);
|
|
542
572
|
let browserExtension = this.options['browser-extension'];
|
|
543
573
|
let aiPodService = this.options['ai-pod-service'];
|
|
544
574
|
try {
|
|
@@ -649,6 +679,7 @@ export class LpkBuild {
|
|
|
649
679
|
hasPackageFile: this.hasPackageFile,
|
|
650
680
|
hasImagesConfig,
|
|
651
681
|
buildEnvEntries: this.options['envs'],
|
|
682
|
+
hasPackageMetadataOverrides: this.hasPackageMetadataOverrides,
|
|
652
683
|
});
|
|
653
684
|
if (useV2PackageLayout) {
|
|
654
685
|
logDeprecatedStaticFieldWarning(this.manifestFilePath, findManifestStaticFields(this.sourceManifest));
|
package/lib/app/lpk_create.js
CHANGED
|
@@ -212,17 +212,18 @@ export class TemplateInit {
|
|
|
212
212
|
this.type = normalizeTemplateType(type);
|
|
213
213
|
this.lpkManifest = new LpkManifest(name);
|
|
214
214
|
this.lpkPackageFile = new LpkPackageFile(name);
|
|
215
|
+
this.templateVars = null;
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
async init() {
|
|
218
219
|
this.type = await chooseTemplate(this.type);
|
|
219
220
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
221
|
+
const templateRoot = path.join(contextDirname(import.meta.url), '..', '..', 'template', '_lpk');
|
|
222
|
+
const typeTemplatePath = path.join(templateRoot, `${this.type}.manifest.yml.in`);
|
|
223
|
+
const manifestTemplatePath = isFileExist(typeTemplatePath) ? typeTemplatePath : path.join(templateRoot, 'manifest.yml.in');
|
|
224
|
+
const packageTemplatePath = path.join(templateRoot, 'package.yml.in');
|
|
225
|
+
this.templateVars = await this.lpkManifest.init(manifestTemplatePath, true);
|
|
226
|
+
await this.lpkPackageFile.init(packageTemplatePath, true, this.templateVars);
|
|
226
227
|
}
|
|
227
228
|
|
|
228
229
|
async create() {
|
|
@@ -286,7 +287,7 @@ class LpkCreate {
|
|
|
286
287
|
),
|
|
287
288
|
);
|
|
288
289
|
}
|
|
289
|
-
|
|
290
|
+
await TemplateConfig[type].build(path.resolve(this.cwd, this.name), { templateVars: template.templateVars });
|
|
290
291
|
|
|
291
292
|
console.log(chalk.green(t('lzc_cli.lib.app.lpk_create.exec_init_project_success_tips', `✨ 初始化懒猫云应用`)));
|
|
292
293
|
await TemplateConfig[type].after(this.name, this.cwd);
|
|
@@ -8,8 +8,23 @@ import logger from 'loglevel';
|
|
|
8
8
|
import { t } from '../i18n/index.js';
|
|
9
9
|
|
|
10
10
|
const __dirname = contextDirname(import.meta.url);
|
|
11
|
+
const PROJECT_CREATE_PACKAGE_DEV_PLACEHOLDER = '__PROJECT_CREATE_PACKAGE_DEV__';
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
function renderProjectCreateFileContent(filePath, content, opts = {}) {
|
|
14
|
+
if (typeof content !== 'string' || path.basename(filePath) !== 'lzc-build.dev.yml') {
|
|
15
|
+
return content;
|
|
16
|
+
}
|
|
17
|
+
if (!content.includes(PROJECT_CREATE_PACKAGE_DEV_PLACEHOLDER)) {
|
|
18
|
+
return content;
|
|
19
|
+
}
|
|
20
|
+
const packageId = String(opts.templateVars?.package ?? '').trim();
|
|
21
|
+
if (!packageId) {
|
|
22
|
+
throw new Error(`templateVars.package is required for ${filePath}`);
|
|
23
|
+
}
|
|
24
|
+
return content.replaceAll(PROJECT_CREATE_PACKAGE_DEV_PLACEHOLDER, `${packageId}.dev`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function loadFiles(dirPath, prefix = '', opts = {}) {
|
|
13
28
|
const templateRoot = path.join(__dirname, '..', '..', 'template');
|
|
14
29
|
const templateDir = path.join(templateRoot, dirPath);
|
|
15
30
|
|
|
@@ -26,15 +41,16 @@ async function loadFiles(dirPath, prefix = '') {
|
|
|
26
41
|
} else {
|
|
27
42
|
content = fs.readFileSync(sourcePath, 'utf8');
|
|
28
43
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
44
|
+
if (p.startsWith('_')) {
|
|
45
|
+
p = p.replace('_', '.');
|
|
46
|
+
}
|
|
32
47
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
48
|
+
const outputPath = path.join(prefix, p);
|
|
49
|
+
files[outputPath] = {
|
|
50
|
+
content: renderProjectCreateFileContent(outputPath, content, opts),
|
|
51
|
+
mode,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
38
54
|
return files;
|
|
39
55
|
}
|
|
40
56
|
|
|
@@ -50,7 +66,7 @@ function writeFileTree(target, files) {
|
|
|
50
66
|
}
|
|
51
67
|
|
|
52
68
|
export async function generate(type, to, opts = {}) {
|
|
53
|
-
const files = await loadFiles(type, opts.prefix);
|
|
69
|
+
const files = await loadFiles(type, opts.prefix, opts);
|
|
54
70
|
writeFileTree(to, files);
|
|
55
71
|
}
|
|
56
72
|
|
package/lib/app/project_sync.js
CHANGED
|
@@ -64,7 +64,7 @@ function createIgnoreMatcher(rootDir) {
|
|
|
64
64
|
return ig;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
function createWatchIgnored(rootDir) {
|
|
67
|
+
export function createWatchIgnored(rootDir) {
|
|
68
68
|
const ig = createIgnoreMatcher(rootDir);
|
|
69
69
|
return (candidatePath) => {
|
|
70
70
|
const relPath = normalizePosixPath(path.relative(rootDir, candidatePath));
|
|
@@ -162,9 +162,6 @@ export function buildRsyncArgs(runtime, uid, host, rootDir, targetDir, sourceDir
|
|
|
162
162
|
const ignoreFile = path.join(rootDir, LZCDEVIGNORE_FILE);
|
|
163
163
|
if (fs.existsSync(ignoreFile)) {
|
|
164
164
|
args.push(`--exclude-from=${ignoreFile}`);
|
|
165
|
-
if (deleteMode) {
|
|
166
|
-
args.push('--delete-excluded');
|
|
167
|
-
}
|
|
168
165
|
}
|
|
169
166
|
if (sourceDir) {
|
|
170
167
|
args.push('--relative');
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# 开发态覆盖配置
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
|
|
3
|
+
# 覆盖开发态包名,避免覆盖 release 安装包
|
|
4
|
+
pkg_id: __PROJECT_CREATE_PACKAGE_DEV__
|
|
5
|
+
|
|
6
|
+
# 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
|
|
7
|
+
contentdir:
|
|
5
8
|
|
|
6
9
|
envs:
|
|
7
10
|
- DEV_MODE=1
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# 开发态覆盖配置
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
|
|
3
|
+
# 覆盖开发态包名,避免覆盖 release 安装包
|
|
4
|
+
pkg_id: __PROJECT_CREATE_PACKAGE_DEV__
|
|
5
|
+
|
|
6
|
+
# 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
|
|
7
|
+
contentdir:
|
|
5
8
|
|
|
6
9
|
envs:
|
|
7
10
|
- DEV_MODE=1
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# 开发态覆盖配置
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
|
|
3
|
+
# 覆盖开发态包名,避免覆盖 release 安装包
|
|
4
|
+
pkg_id: __PROJECT_CREATE_PACKAGE_DEV__
|
|
5
|
+
|
|
6
|
+
# 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
|
|
7
|
+
contentdir:
|
|
5
8
|
|
|
6
9
|
envs:
|
|
7
10
|
- DEV_MODE=1
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# 开发态覆盖配置
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
|
|
3
|
+
# 覆盖开发态包名,避免覆盖 release 安装包
|
|
4
|
+
pkg_id: __PROJECT_CREATE_PACKAGE_DEV__
|
|
5
|
+
|
|
6
|
+
# 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
|
|
7
|
+
contentdir:
|
|
5
8
|
|
|
6
9
|
envs:
|
|
7
10
|
- DEV_MODE=1
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# 开发态覆盖配置
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
|
|
3
|
+
# 覆盖开发态包名,避免覆盖 release 安装包
|
|
4
|
+
pkg_id: __PROJECT_CREATE_PACKAGE_DEV__
|
|
5
|
+
|
|
6
|
+
# 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
|
|
7
|
+
contentdir:
|
|
5
8
|
|
|
6
9
|
envs:
|
|
7
10
|
- DEV_MODE=1
|