dev-playbooks-cn 2.0.0 → 2.1.0
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/bin/devbooks.js +195 -0
- package/package.json +1 -1
package/bin/devbooks.js
CHANGED
|
@@ -380,6 +380,195 @@ async function performNpmUpdate() {
|
|
|
380
380
|
});
|
|
381
381
|
}
|
|
382
382
|
|
|
383
|
+
/**
|
|
384
|
+
* 显示版本变更摘要
|
|
385
|
+
* @param {string} fromVersion - 当前版本
|
|
386
|
+
* @param {string} toVersion - 目标版本
|
|
387
|
+
*/
|
|
388
|
+
async function displayVersionChangelog(fromVersion, toVersion) {
|
|
389
|
+
try {
|
|
390
|
+
// 尝试从 npm 获取 CHANGELOG
|
|
391
|
+
const { execSync } = await import('child_process');
|
|
392
|
+
const changelogUrl = `https://raw.githubusercontent.com/Darkbluelr/dev-playbooks-cn/master/CHANGELOG.md`;
|
|
393
|
+
|
|
394
|
+
// 使用 curl 获取 CHANGELOG(如果可用)
|
|
395
|
+
let changelog = '';
|
|
396
|
+
try {
|
|
397
|
+
changelog = execSync(`curl -s -m 5 "${changelogUrl}"`, {
|
|
398
|
+
encoding: 'utf-8',
|
|
399
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
400
|
+
});
|
|
401
|
+
} catch {
|
|
402
|
+
// 如果获取失败,显示简化信息
|
|
403
|
+
console.log(chalk.cyan('📋 版本变更摘要'));
|
|
404
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
405
|
+
console.log(chalk.yellow('⚠ 无法获取详细变更日志,请访问:'));
|
|
406
|
+
console.log(chalk.blue(` https://github.com/Darkbluelr/dev-playbooks-cn/releases/tag/v${toVersion}`));
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// 解析 CHANGELOG,提取相关版本的变更
|
|
411
|
+
const changes = parseChangelog(changelog, fromVersion, toVersion);
|
|
412
|
+
|
|
413
|
+
if (changes.length === 0) {
|
|
414
|
+
console.log(chalk.cyan('📋 版本变更摘要'));
|
|
415
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
416
|
+
console.log(chalk.yellow('⚠ 未找到详细变更信息,请访问:'));
|
|
417
|
+
console.log(chalk.blue(` https://github.com/Darkbluelr/dev-playbooks-cn/releases/tag/v${toVersion}`));
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// 显示变更摘要
|
|
422
|
+
console.log(chalk.cyan('📋 版本变更摘要'));
|
|
423
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
424
|
+
|
|
425
|
+
for (const change of changes) {
|
|
426
|
+
console.log();
|
|
427
|
+
console.log(chalk.bold.green(`## ${change.version}`));
|
|
428
|
+
if (change.date) {
|
|
429
|
+
console.log(chalk.gray(` 发布日期: ${change.date}`));
|
|
430
|
+
}
|
|
431
|
+
console.log();
|
|
432
|
+
|
|
433
|
+
// 显示主要变更(限制显示前10条)
|
|
434
|
+
const highlights = change.content.split('\n')
|
|
435
|
+
.filter(line => line.trim().length > 0)
|
|
436
|
+
.slice(0, 10);
|
|
437
|
+
|
|
438
|
+
for (const line of highlights) {
|
|
439
|
+
if (line.startsWith('###')) {
|
|
440
|
+
console.log(chalk.bold.yellow(line));
|
|
441
|
+
} else if (line.startsWith('####')) {
|
|
442
|
+
console.log(chalk.bold(line));
|
|
443
|
+
} else if (line.startsWith('- ✅') || line.startsWith('- ✓')) {
|
|
444
|
+
console.log(chalk.green(line));
|
|
445
|
+
} else if (line.startsWith('- ⚠️') || line.startsWith('- ❌')) {
|
|
446
|
+
console.log(chalk.yellow(line));
|
|
447
|
+
} else if (line.startsWith('- ')) {
|
|
448
|
+
console.log(chalk.white(line));
|
|
449
|
+
} else {
|
|
450
|
+
console.log(chalk.gray(line));
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
if (change.content.split('\n').length > 10) {
|
|
455
|
+
console.log(chalk.gray(' ... (更多变更请查看完整日志)'));
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
console.log();
|
|
460
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
461
|
+
console.log(chalk.blue('📖 完整变更日志: ') + chalk.underline(`https://github.com/Darkbluelr/dev-playbooks-cn/blob/master/CHANGELOG.md`));
|
|
462
|
+
|
|
463
|
+
} catch (error) {
|
|
464
|
+
// 静默失败,不影响更新流程
|
|
465
|
+
console.log(chalk.gray('提示: 无法显示变更摘要'));
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* 解析 CHANGELOG 内容,提取指定版本范围的变更
|
|
471
|
+
* @param {string} changelog - CHANGELOG 内容
|
|
472
|
+
* @param {string} fromVersion - 起始版本
|
|
473
|
+
* @param {string} toVersion - 目标版本
|
|
474
|
+
* @returns {Array} - 变更列表
|
|
475
|
+
*/
|
|
476
|
+
function parseChangelog(changelog, fromVersion, toVersion) {
|
|
477
|
+
const changes = [];
|
|
478
|
+
const lines = changelog.split('\n');
|
|
479
|
+
|
|
480
|
+
let currentVersion = null;
|
|
481
|
+
let currentDate = null;
|
|
482
|
+
let currentContent = [];
|
|
483
|
+
let inVersionBlock = false;
|
|
484
|
+
let shouldCapture = false;
|
|
485
|
+
|
|
486
|
+
// 解析版本号(移除 'v' 前缀)
|
|
487
|
+
const from = fromVersion.replace(/^v/, '');
|
|
488
|
+
const to = toVersion.replace(/^v/, '');
|
|
489
|
+
|
|
490
|
+
for (let i = 0; i < lines.length; i++) {
|
|
491
|
+
const line = lines[i];
|
|
492
|
+
|
|
493
|
+
// 匹配版本标题:## [2.0.0] - 2026-01-19
|
|
494
|
+
const versionMatch = line.match(/^##\s+\[?(\d+\.\d+\.\d+)\]?\s*(?:-\s*(\d{4}-\d{2}-\d{2}))?/);
|
|
495
|
+
|
|
496
|
+
if (versionMatch) {
|
|
497
|
+
// 保存上一个版本的内容
|
|
498
|
+
if (inVersionBlock && shouldCapture && currentVersion) {
|
|
499
|
+
changes.push({
|
|
500
|
+
version: currentVersion,
|
|
501
|
+
date: currentDate,
|
|
502
|
+
content: currentContent.join('\n').trim()
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// 开始新版本
|
|
507
|
+
currentVersion = versionMatch[1];
|
|
508
|
+
currentDate = versionMatch[2] || null;
|
|
509
|
+
currentContent = [];
|
|
510
|
+
inVersionBlock = true;
|
|
511
|
+
|
|
512
|
+
// 判断是否应该捕获这个版本
|
|
513
|
+
// 捕获从 fromVersion 到 toVersion 之间的所有版本
|
|
514
|
+
const versionNum = currentVersion.split('.').map(Number);
|
|
515
|
+
const fromNum = from.split('.').map(Number);
|
|
516
|
+
const toNum = to.split('.').map(Number);
|
|
517
|
+
|
|
518
|
+
const isAfterFrom = compareVersions(versionNum, fromNum) > 0;
|
|
519
|
+
const isBeforeOrEqualTo = compareVersions(versionNum, toNum) <= 0;
|
|
520
|
+
|
|
521
|
+
shouldCapture = isAfterFrom && isBeforeOrEqualTo;
|
|
522
|
+
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// 如果遇到下一个版本标题或分隔线,结束当前版本
|
|
527
|
+
if (line.startsWith('---') && inVersionBlock) {
|
|
528
|
+
if (shouldCapture && currentVersion) {
|
|
529
|
+
changes.push({
|
|
530
|
+
version: currentVersion,
|
|
531
|
+
date: currentDate,
|
|
532
|
+
content: currentContent.join('\n').trim()
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
inVersionBlock = false;
|
|
536
|
+
shouldCapture = false;
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// 收集内容
|
|
541
|
+
if (inVersionBlock && shouldCapture) {
|
|
542
|
+
currentContent.push(line);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// 保存最后一个版本
|
|
547
|
+
if (inVersionBlock && shouldCapture && currentVersion) {
|
|
548
|
+
changes.push({
|
|
549
|
+
version: currentVersion,
|
|
550
|
+
date: currentDate,
|
|
551
|
+
content: currentContent.join('\n').trim()
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return changes;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* 比较两个版本号
|
|
560
|
+
* @param {number[]} v1 - 版本1 [major, minor, patch]
|
|
561
|
+
* @param {number[]} v2 - 版本2 [major, minor, patch]
|
|
562
|
+
* @returns {number} - 1 if v1 > v2, -1 if v1 < v2, 0 if equal
|
|
563
|
+
*/
|
|
564
|
+
function compareVersions(v1, v2) {
|
|
565
|
+
for (let i = 0; i < 3; i++) {
|
|
566
|
+
if (v1[i] > v2[i]) return 1;
|
|
567
|
+
if (v1[i] < v2[i]) return -1;
|
|
568
|
+
}
|
|
569
|
+
return 0;
|
|
570
|
+
}
|
|
571
|
+
|
|
383
572
|
// ============================================================================
|
|
384
573
|
// 自动更新 .gitignore 和 .npmignore
|
|
385
574
|
// ============================================================================
|
|
@@ -1373,6 +1562,12 @@ async function updateCommand(projectDir) {
|
|
|
1373
1562
|
|
|
1374
1563
|
if (hasUpdate) {
|
|
1375
1564
|
spinner.info(`发现新版本: ${currentVersion} → ${latestVersion}`);
|
|
1565
|
+
|
|
1566
|
+
// 显示版本变更摘要
|
|
1567
|
+
console.log();
|
|
1568
|
+
await displayVersionChangelog(currentVersion, latestVersion);
|
|
1569
|
+
console.log();
|
|
1570
|
+
|
|
1376
1571
|
const shouldUpdate = await confirm({
|
|
1377
1572
|
message: `是否更新 ${CLI_COMMAND} 到 ${latestVersion}?`,
|
|
1378
1573
|
default: true
|