dev-playbooks 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
|
+
* Display version changelog summary
|
|
385
|
+
* @param {string} fromVersion - Current version
|
|
386
|
+
* @param {string} toVersion - Target version
|
|
387
|
+
*/
|
|
388
|
+
async function displayVersionChangelog(fromVersion, toVersion) {
|
|
389
|
+
try {
|
|
390
|
+
// Try to fetch CHANGELOG from GitHub
|
|
391
|
+
const { execSync } = await import('child_process');
|
|
392
|
+
const changelogUrl = `https://raw.githubusercontent.com/Darkbluelr/dev-playbooks/master/CHANGELOG.md`;
|
|
393
|
+
|
|
394
|
+
// Use curl to fetch CHANGELOG (if available)
|
|
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
|
+
// If fetch fails, show simplified info
|
|
403
|
+
console.log(chalk.cyan('📋 Version Changelog'));
|
|
404
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
405
|
+
console.log(chalk.yellow('⚠ Unable to fetch detailed changelog, please visit:'));
|
|
406
|
+
console.log(chalk.blue(` https://github.com/Darkbluelr/dev-playbooks/releases/tag/v${toVersion}`));
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Parse CHANGELOG, extract changes for relevant versions
|
|
411
|
+
const changes = parseChangelog(changelog, fromVersion, toVersion);
|
|
412
|
+
|
|
413
|
+
if (changes.length === 0) {
|
|
414
|
+
console.log(chalk.cyan('📋 Version Changelog'));
|
|
415
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
416
|
+
console.log(chalk.yellow('⚠ No detailed changelog found, please visit:'));
|
|
417
|
+
console.log(chalk.blue(` https://github.com/Darkbluelr/dev-playbooks/releases/tag/v${toVersion}`));
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Display changelog summary
|
|
422
|
+
console.log(chalk.cyan('📋 Version Changelog'));
|
|
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(` Release date: ${change.date}`));
|
|
430
|
+
}
|
|
431
|
+
console.log();
|
|
432
|
+
|
|
433
|
+
// Display main changes (limit to first 10 lines)
|
|
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(' ... (see full changelog for more)'));
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
console.log();
|
|
460
|
+
console.log(chalk.gray('─'.repeat(60)));
|
|
461
|
+
console.log(chalk.blue('📖 Full changelog: ') + chalk.underline(`https://github.com/Darkbluelr/dev-playbooks/blob/master/CHANGELOG.md`));
|
|
462
|
+
|
|
463
|
+
} catch (error) {
|
|
464
|
+
// Silent failure, don't affect update process
|
|
465
|
+
console.log(chalk.gray('Note: Unable to display changelog summary'));
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Parse CHANGELOG content, extract changes for specified version range
|
|
471
|
+
* @param {string} changelog - CHANGELOG content
|
|
472
|
+
* @param {string} fromVersion - Starting version
|
|
473
|
+
* @param {string} toVersion - Target version
|
|
474
|
+
* @returns {Array} - List of changes
|
|
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
|
+
// Parse version numbers (remove 'v' prefix)
|
|
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
|
+
// Match version header: ## [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
|
+
// Save previous version's content
|
|
498
|
+
if (inVersionBlock && shouldCapture && currentVersion) {
|
|
499
|
+
changes.push({
|
|
500
|
+
version: currentVersion,
|
|
501
|
+
date: currentDate,
|
|
502
|
+
content: currentContent.join('\n').trim()
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Start new version
|
|
507
|
+
currentVersion = versionMatch[1];
|
|
508
|
+
currentDate = versionMatch[2] || null;
|
|
509
|
+
currentContent = [];
|
|
510
|
+
inVersionBlock = true;
|
|
511
|
+
|
|
512
|
+
// Determine if this version should be captured
|
|
513
|
+
// Capture all versions between fromVersion and 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
|
+
// If we encounter next version header or separator, end current version
|
|
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
|
+
// Collect content
|
|
541
|
+
if (inVersionBlock && shouldCapture) {
|
|
542
|
+
currentContent.push(line);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// Save last version
|
|
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
|
+
* Compare two version numbers
|
|
560
|
+
* @param {number[]} v1 - Version 1 [major, minor, patch]
|
|
561
|
+
* @param {number[]} v2 - Version 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
|
// Auto-update .gitignore and .npmignore
|
|
385
574
|
// ============================================================================
|
|
@@ -1369,6 +1558,12 @@ async function updateCommand(projectDir) {
|
|
|
1369
1558
|
|
|
1370
1559
|
if (hasUpdate) {
|
|
1371
1560
|
spinner.info(`New version available: ${currentVersion} → ${latestVersion}`);
|
|
1561
|
+
|
|
1562
|
+
// Display version changelog summary
|
|
1563
|
+
console.log();
|
|
1564
|
+
await displayVersionChangelog(currentVersion, latestVersion);
|
|
1565
|
+
console.log();
|
|
1566
|
+
|
|
1372
1567
|
const shouldUpdate = await confirm({
|
|
1373
1568
|
message: `Update ${CLI_COMMAND} to ${latestVersion}?`,
|
|
1374
1569
|
default: true
|