xref: /web-php/bin/news2html (revision acd86a16)
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