Public Access
135 lines
3.6 KiB
PHP
135 lines
3.6 KiB
PHP
|
|
#!/usr/bin/env php
|
||
|
|
<?php
|
||
|
|
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||
|
|
*
|
||
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||
|
|
*
|
||
|
|
* FILE INFORMATION
|
||
|
|
* DEFGROUP: moko-platform.CLI
|
||
|
|
* INGROUP: moko-platform
|
||
|
|
* REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
|
||
|
|
* PATH: /cli/changelog_prune.php
|
||
|
|
* BRIEF: Prune old CHANGELOG.md entries — keeps [Unreleased] + last N releases
|
||
|
|
*
|
||
|
|
* Usage:
|
||
|
|
* php changelog_prune.php --path /repo --keep 5
|
||
|
|
* php changelog_prune.php --path /repo --keep 3 --dry-run
|
||
|
|
*/
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
$path = '.';
|
||
|
|
$keep = 5;
|
||
|
|
$dryRun = false;
|
||
|
|
|
||
|
|
foreach ($argv as $i => $arg) {
|
||
|
|
if ($arg === '--path' && isset($argv[$i + 1])) $path = $argv[$i + 1];
|
||
|
|
if ($arg === '--keep' && isset($argv[$i + 1])) $keep = (int)$argv[$i + 1];
|
||
|
|
if ($arg === '--dry-run') $dryRun = true;
|
||
|
|
if ($arg === '--help') {
|
||
|
|
echo "changelog_prune — Keep [Unreleased] + last N versioned entries\n\n";
|
||
|
|
echo "Usage: php changelog_prune.php --path . --keep 5 [--dry-run]\n\n";
|
||
|
|
echo "Options:\n";
|
||
|
|
echo " --path Repository path (default: .)\n";
|
||
|
|
echo " --keep Number of versioned releases to keep (default: 5)\n";
|
||
|
|
echo " --dry-run Preview without writing\n";
|
||
|
|
exit(0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$changelog = realpath($path) . '/CHANGELOG.md';
|
||
|
|
if (!file_exists($changelog)) {
|
||
|
|
fwrite(STDERR, "No CHANGELOG.md found at {$path}\n");
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
|
||
|
|
$content = file_get_contents($changelog);
|
||
|
|
$lines = explode("\n", $content);
|
||
|
|
|
||
|
|
// Split into sections by ## headings
|
||
|
|
$sections = [];
|
||
|
|
$current = [];
|
||
|
|
$currentHeading = null;
|
||
|
|
|
||
|
|
foreach ($lines as $line) {
|
||
|
|
if (preg_match('/^## /', $line)) {
|
||
|
|
if ($currentHeading !== null) {
|
||
|
|
$sections[] = ['heading' => $currentHeading, 'lines' => $current];
|
||
|
|
}
|
||
|
|
$currentHeading = $line;
|
||
|
|
$current = [$line];
|
||
|
|
} else {
|
||
|
|
$current[] = $line;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if ($currentHeading !== null) {
|
||
|
|
$sections[] = ['heading' => $currentHeading, 'lines' => $current];
|
||
|
|
}
|
||
|
|
|
||
|
|
// Find the header (everything before the first ## section)
|
||
|
|
$header = [];
|
||
|
|
$contentLines = explode("\n", $content);
|
||
|
|
foreach ($contentLines as $line) {
|
||
|
|
if (preg_match('/^## /', $line)) {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
$header[] = $line;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Separate [Unreleased] from versioned sections
|
||
|
|
$unreleased = null;
|
||
|
|
$versioned = [];
|
||
|
|
|
||
|
|
foreach ($sections as $section) {
|
||
|
|
if (preg_match('/\[Unreleased\]/i', $section['heading'])) {
|
||
|
|
$unreleased = $section;
|
||
|
|
} else {
|
||
|
|
$versioned[] = $section;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$totalVersioned = count($versioned);
|
||
|
|
$pruned = $totalVersioned - $keep;
|
||
|
|
|
||
|
|
if ($pruned <= 0) {
|
||
|
|
echo "CHANGELOG has {$totalVersioned} versioned entries — nothing to prune (keeping {$keep})\n";
|
||
|
|
exit(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Keep only the first N versioned sections
|
||
|
|
$keptVersioned = array_slice($versioned, 0, $keep);
|
||
|
|
$droppedVersioned = array_slice($versioned, $keep);
|
||
|
|
|
||
|
|
// Report
|
||
|
|
echo "CHANGELOG: {$totalVersioned} versioned entries found\n";
|
||
|
|
echo " Keeping: {$keep} most recent\n";
|
||
|
|
echo " Pruning: {$pruned} old entries\n";
|
||
|
|
|
||
|
|
foreach ($droppedVersioned as $section) {
|
||
|
|
$heading = trim($section['heading']);
|
||
|
|
echo " - {$heading}\n";
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($dryRun) {
|
||
|
|
echo "\n(dry-run) No changes written\n";
|
||
|
|
exit(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Rebuild the file
|
||
|
|
$output = implode("\n", $header);
|
||
|
|
|
||
|
|
if ($unreleased !== null) {
|
||
|
|
$output .= implode("\n", $unreleased['lines']) . "\n";
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach ($keptVersioned as $section) {
|
||
|
|
$output .= implode("\n", $section['lines']) . "\n";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Clean up excessive blank lines at end
|
||
|
|
$output = rtrim($output) . "\n";
|
||
|
|
|
||
|
|
file_put_contents($changelog, $output);
|
||
|
|
echo "\nCHANGELOG pruned: removed {$pruned} old entries\n";
|
||
|
|
exit(0);
|