|
| 1 | +#!/usr/bin/env php |
| 2 | +<?php |
| 3 | + |
| 4 | +declare(strict_types=1); |
| 5 | + |
| 6 | +/** |
| 7 | + * This file is part of CodeIgniter 4 framework. |
| 8 | + * |
| 9 | + * (c) CodeIgniter Foundation <[email protected]> |
| 10 | + * |
| 11 | + * For the full copyright and license information, please view |
| 12 | + * the LICENSE file that was distributed with this source code. |
| 13 | + */ |
| 14 | + |
| 15 | +use CodeIgniter\CLI\CLI; |
| 16 | +use Translations\Tests\AbstractTranslationTestCase; |
| 17 | + |
| 18 | +require __DIR__ . '/../vendor/codeigniter4/codeigniter4/system/Test/bootstrap.php'; |
| 19 | + |
| 20 | +if (! isset($argv[1]) || ! in_array($argv[1], ['--major', '--minor', '--patch'], true)) { |
| 21 | + CLI::error( |
| 22 | + 'Please provide the tagging strategy for this release: --major, --minor, --patch.', |
| 23 | + 'light_gray', |
| 24 | + 'red' |
| 25 | + ); |
| 26 | + |
| 27 | + exit(1); |
| 28 | +} |
| 29 | + |
| 30 | +if (! function_usable('exec')) { |
| 31 | + CLI::error('The `exec()` function is needed but is disabled.', 'light_gray', 'red'); |
| 32 | + |
| 33 | + exit(1); |
| 34 | +} |
| 35 | + |
| 36 | +$resultCode = 0; |
| 37 | +/** @var list<string> $output */ |
| 38 | +$output = []; |
| 39 | + |
| 40 | +exec('git describe --tags --abbrev=0 2>/dev/null', $output, $resultCode); |
| 41 | + |
| 42 | +if ($resultCode !== 0) { |
| 43 | + CLI::error('Failed getting the latest tag.', 'light_gray', 'red'); |
| 44 | + |
| 45 | + exit($resultCode); |
| 46 | +} |
| 47 | + |
| 48 | +$latestTag = $output[0]; |
| 49 | +/** @var list<string> $changelog */ |
| 50 | +$changelog = []; |
| 51 | + |
| 52 | +exec(sprintf('git log --format=%%s %s...HEAD --reverse 2>/dev/null', $latestTag), $changelog, $resultCode); |
| 53 | + |
| 54 | +if ($resultCode !== 0) { |
| 55 | + CLI::error('Failed getting the changelog from git.', 'light_gray', 'red'); |
| 56 | + |
| 57 | + exit($resultCode); |
| 58 | +} |
| 59 | + |
| 60 | +$localeChanges = []; |
| 61 | +$otherChanges = []; |
| 62 | + |
| 63 | +$nextTag = preg_replace_callback( |
| 64 | + '/^v(\d+)\.(\d+)\.(\d+)$/', |
| 65 | + static function (array $matches) use ($argv): string { |
| 66 | + switch ($argv[1]) { |
| 67 | + case '--patch': |
| 68 | + return sprintf('v%d.%d.%d', $matches[1], $matches[2], ++$matches[3]); |
| 69 | + |
| 70 | + case '--minor': |
| 71 | + return sprintf('v%d.%d.0', $matches[1], ++$matches[2]); |
| 72 | + |
| 73 | + case '--major': |
| 74 | + return sprintf('v%d.0.0', ++$matches[1]); |
| 75 | + } |
| 76 | + }, |
| 77 | + $latestTag |
| 78 | +); |
| 79 | + |
| 80 | +CLI::write(sprintf('Generating changelog for %s...', $nextTag), 'green'); |
| 81 | + |
| 82 | +sleep(1); // for cinematic effect |
| 83 | + |
| 84 | +foreach ($changelog as $log) { |
| 85 | + if (preg_match('/^\[([a-zA-Z-]+)\].+/', $log, $match) === 1) { |
| 86 | + $locale = $match[1]; |
| 87 | + |
| 88 | + if (array_key_exists($locale, $localeChanges)) { |
| 89 | + continue; |
| 90 | + } |
| 91 | + |
| 92 | + if (in_array($locale, AbstractTranslationTestCase::$locales, true)) { |
| 93 | + $class = array_search($locale, AbstractTranslationTestCase::$locales, true); |
| 94 | + |
| 95 | + if (! is_string($class)) { |
| 96 | + continue; |
| 97 | + } |
| 98 | + |
| 99 | + $localeChanges[$locale] = preg_replace_callback( |
| 100 | + '/\ATranslations\\\\Tests\\\\(\S+)TranslationTest\z/', |
| 101 | + static fn (array $matches): string => preg_replace( |
| 102 | + '/(?<!^)((?=[\p{Lu}][^\p{Lu}])|(?<![\p{Lu}])(?=[\p{Lu}]))/u', |
| 103 | + ' ', |
| 104 | + $matches[1] |
| 105 | + ), |
| 106 | + $class |
| 107 | + ); |
| 108 | + |
| 109 | + continue; |
| 110 | + } |
| 111 | + } |
| 112 | + |
| 113 | + $otherChanges[] = $log; |
| 114 | +} |
| 115 | + |
| 116 | +ksort($localeChanges); |
| 117 | + |
| 118 | +CLI::write('Copy the following to the CHANGELOG.md file and edit the subheadings:', 'yellow'); |
| 119 | +CLI::newLine(); |
| 120 | +CLI::write(sprintf( |
| 121 | + <<<'CHANGELOG' |
| 122 | + ## [%1$s](https://github.com/codeigniter4/translations/compare/%2$s...%1$s) - %3$s |
| 123 | +
|
| 124 | + ### Changed |
| 125 | +
|
| 126 | + %4$s |
| 127 | +
|
| 128 | + ### Others |
| 129 | +
|
| 130 | + - %5$s |
| 131 | + CHANGELOG, |
| 132 | + $nextTag, |
| 133 | + $latestTag, |
| 134 | + (new DateTimeImmutable('now', new DateTimeZone('UTC')))->format('Y-m-d'), |
| 135 | + implode("\n", array_map( |
| 136 | + static fn (string $value, string $key): string => sprintf('- %s (%s)', $key, $value), |
| 137 | + array_values($localeChanges), |
| 138 | + array_keys($localeChanges) |
| 139 | + )) ?: '- <none>', |
| 140 | + implode("\n- ", $otherChanges) ?: '<none>' |
| 141 | +)); |
| 142 | + |
| 143 | +sleep(1); // for cinematic effect |
| 144 | + |
| 145 | +CLI::newLine(); |
| 146 | +CLI::write('For reference, here is the complete changelog:', 'yellow'); |
| 147 | +CLI::write(sprintf('- %s', implode("\n- ", $changelog) ?: '<none>')); |
| 148 | + |
| 149 | +sleep(1); // for cinematic effect |
| 150 | + |
| 151 | +CLI::newLine(); |
| 152 | +CLI::write('After editing the CHANGELOG.md file, execute the following commands.', 'green'); |
| 153 | +CLI::write(implode("\n", [ |
| 154 | + 'git add CHANGELOG.md', |
| 155 | + sprintf('git commit -S -m "Prepare changelog for %s"', $nextTag), |
| 156 | + 'git push upstream develop', |
| 157 | + 'git switch master', |
| 158 | + 'git merge --ff develop', |
| 159 | + 'git push upstream master', |
| 160 | + sprintf('git tag -s %1$s -m "CodeIgniter %1$s Translations"', $nextTag), |
| 161 | + 'git push upstream --tags', |
| 162 | +])); |
0 commit comments