1#!/usr/bin/env php 2<?php 3PHP_SAPI == 'cli' or die("Please run this script using the cli sapi"); 4 5// get args 6$cmd = array_shift($_SERVER['argv']); 7 8if (count($_SERVER['argv']) < 2) { 9 echo "Use: $cmd /path/to/php-5.4.16/NEWS 5.4.16 [path/to/ChangeLog.php]\n"; 10 exit(1); 11} 12$news_file = array_shift($_SERVER['argv']); 13$version = array_shift($_SERVER['argv']); 14$changelog = @array_shift($_SERVER['argv']); 15 16// find NEWS entry 17$fp = fopen($news_file, "r"); 18if(!$fp) { 19 die("Can not open {$news_file}\n"); 20} 21 22$inside = false; 23$entries = []; 24while(($ln = fgets($fp)) !== false) { 25 if (preg_match("/(.. ... ....),? PHP $version/", $ln, $m)) { 26 // got entry start 27 $inside = true; 28 $date = strtr($m[1], " ", "-"); 29 continue; 30 } 31 if (!$inside) { continue; } 32 33 if (preg_match('/, PHP \d+.\d+.\d+/', $ln)) { 34 // next entry - we're done 35 break; 36 } 37 38 if ($ln == "\n") { 39 $module = 'Core'; 40 continue; 41 } 42 if ($ln[0] == '-') { 43 // module 44 $module = trim(substr($ln, 1), " \t\n:"); 45 } elseif (preg_match('/^\s+\.\s/',$ln)) { 46 $entries[$module][] = trim(preg_replace('/^\s+\.\s+/', '', $ln)); 47 } else { 48 // continued line 49 $c = count($entries[$module])-1; 50 $entries[$module][$c] = trim($entries[$module][$c] )." ".trim($ln); 51 } 52} 53 54if ($changelog) { ob_start(); } 55 56echo <<<HEAD 57<section class="version" id="$version"><!-- {{{ $version --> 58<h3>Version $version</h3> 59<b><?php release_date('$date'); ?></b> 60<ul> 61HEAD; 62 63$bug_map = [ 64 '/Fixed bug #([0-9]+)/' => '<?php bugfix(\1); ?'.'>', 65 '/Fixed PECL bug #([0-9]+)/' => '<?php peclbugfix(\1); ?'.'>', 66 '/Implemented FR #([0-9]+)/' => '<?php implemented(\1); ?'.'>', 67 '/GitHub PR #([0-9]+)/' => '<?php githubissuel(\'php/php-src\', \1); ?'.'>', 68 '/GH-([0-9]+)/' => '<?php githubissuel(\'php/php-src\', \1); ?'.'>', 69 '/GHSA-([0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4})/' 70 => '<?php githubsecurityl(\'php/php-src\', \'\1\'); ?'.'>', 71]; 72 73foreach($entries as $module => $items) { 74 echo "<li>$module:\n<ul>\n"; 75 foreach($items as $item) { 76 // strip author 77 $item = preg_replace('/(\.(\s+\(CVE-\d+-\d+\))?)\s+\(.+?\)\s*$/', '\\1', $item); 78 // encode HTML 79 $item = htmlspecialchars($item, ENT_NOQUOTES); 80 // convert bug numbers 81 $item = preg_replace(array_keys($bug_map), array_values($bug_map), $item); 82 echo " <li>$item</li>\n"; 83 } 84 echo "</ul></li>\n"; 85} 86echo "</ul>\n<!-- }}} --></section>\n\n"; 87 88if ($changelog) { 89 $contents = ob_get_clean(); 90 91 $log = file_get_contents($changelog); 92 if (empty($log)) { 93 fprintf(STDERR, "Unable to read $changelog\n"); 94 exit(1); 95 } 96 97 $parts = explode('.', $version, 3); 98 if (count($parts) < 2) { 99 fprintf(STDERR, "Unable to parse branch from $version\n"); 100 exit(1); 101 } 102 103 $tag = "<a id=\"PHP_{$parts[0]}_{$parts[1]}\"></a>"; 104 if (strpos($log, $tag) === false) { 105 fprintf(STDERR, "Unable to find branch tag in ChangeLog\n"); 106 exit(1); 107 } 108 109 $log = str_replace($tag, "$tag\n\n$contents", $log); 110 file_put_contents($changelog, $log); 111} 112