Re: Extension changelogs
| From: | Hannes Magnusson | Date: | Tue, 05 Jun 2012 17:31:02 +0000 |
| Subject: | Re: Extension changelogs | ||
| References: | 1 2 3 4 5 | Groups: | php.doc |
| Request: | Send a blank email to phpdoc+get-969383848@lists.php.net to get a copy of this message | ||
On Wed, Feb 1, 2012 at 10:45 AM, Hannes Magnusson
<hannes.magnusson@gmail.com> wrote:
> On Wed, Feb 1, 2012 at 11:26, jpauli <jpauli@php.net> wrote:
>> On Wed, Feb 1, 2012 at 11:14 AM, Ulf Wendel <ulf.wendel@phpdoc.de> wrote:
>>>
>>>
>>> Am 01.02.2012 10:36, schrieb jpauli:
>>>>
>>>> Well, we already have some changelog inside an extension documentation,
>>>> think like php.net/manual/en/curl.constants.php
>>>> <http://php.net/manual/en/curl.constants.php>
>>>> for example.
>>>>
>>>> I admit its not centralized.
>>>> Do you mean we shall add a special central changelog section summing up
>>>> the changes for every extension ?
>>>
>>>
>>> Good morning Julien!
>>>
>>> Hannes has cited a commit of mine in which I update a "Change History"
>>> such as:
>>>
>>> http://de.php.net/manual/en/mysqlnd-ms.changes.php
>>> http://de.php.net/manual/en/mysqlnd-qc.changes.php
>>>
>>> These two "Change Histories"...
>>>
>>> ... are for a two PECL extensions
>>> ... try to be comprehensive summaries of changes
>>> ... link to the main sections for details
>>> ... accomplished by CHANGES files in the source tree
>>> ... increase visibility and awareness
>>> ... may not list all minor CHANGES file entries
>>>
>>> You are asking about, for example,
>>> http://php.net/manual/en/curl.constants.php . This also
>>> exists in the above
>>> named PECL extensions documentation for constants, configuration directives,
>>> functions and so forth. This is what I refer to as "... link to main
>>> sections for details" above. Naming changes in such constants, ... lists is
>>> good, is proven, is useful... - please let's continue with it.
>>>
>>> However, I felt that there was room for something in-between change
>>> details scattered in the main sections, a not so much visible
>>> CHANGES/NEWS/... file in the source tree and upgrade guidelines. I called
>>> this something "Change History" (I'm open to rename it).
>>>
>>> As I understand it, Hannes suggests to have a "Change History" or
>>> "Change
>>> Log" for every extension as the necessary change summary information is
>>> already in the central NEWS file. Similar to my PECL extension case.
>>>
>>> I do like that proposal. Though, one should be aware of the additional
>>> work. I would have had appreciated to find a template in the manual that I
>>> could have copied for my PECL extension case.
>>>
>>> Ulf
>>
>>
>> That makes things clearer to me :)
>>
>> So, yes Hannes, I do like the idea :) but like Ulf said, we should compute
>> the additional work needed to get those new chapters inside each supported
>> extension. We support *lots* of PECL extensions inside the main php-doc tree
>> (http://www.php.net/manual/en/extensions.alphabetical.php) , so that would
>> represent a lot of work.
>
>
> We already do some parts of the work in the form of changelogs on each
> function page, introducing this new page could aggregate that and
> provide more comprehensive information in the form of examples and
> longer human readable text.
> If we could do this for built-in exts first, and if it works out
> expand it to the rest of the pecl extensions.
>
> I think this will solve the docrot of the migration guides, as they
> almost never get updated with new info after the .0 releases, which
> gives the users the wrong impression of changes.
> And needing to navigate through every single damn function in the
> manual to see what has changed is very very annoying.
Soo... to start the process I patched PhD to aggregate all the exiting
changelog entries and spit them out in a new document.
It should be fairly easy to actually even spit out a complete
changelog page for every version of PHP automatically on
php.net/manual/changelog.php for example.
Attached is the PhD patch and trivial phpdoc patch.
Screenshots:
- http://prntscr.com/a5yml ("ext/strings")
- http://prntscr.com/a5yq2 (ext/mysql)
- http://prntscr.com/a5yrv ("ext/misc")
-Hannes
diff --git a/phpdotnet/phd/Format.php b/phpdotnet/phd/Format.php index 301a2ab..9fcaeb7 100644 --- a/phpdotnet/phd/Format.php +++ b/phpdotnet/phd/Format.php @@ -285,6 +285,19 @@ abstract class Format extends ObjectStorage public function addVarname($id, $var) { $this->vars[$var] = $id; } + public function getChangelogsForChildrenOf($bookid) { + $id = $this->sqlite->escapeString($bookid); + $results = $this->sqlite->query("SELECT * FROM changelogs WHERE parent_id='$id' ORDER BY version DESC"); + if (!$results) { + return array(); + } + + $changelogs = array(); + while ($row = $results->fetchArray()) { + $changelogs[] = $row; + } + return $changelogs; + } public function getRefs() { return $this->refs; } diff --git a/phpdotnet/phd/Index.php b/phpdotnet/phd/Index.php index 0a0f0d1..cf22ba8 100644 --- a/phpdotnet/phd/Index.php +++ b/phpdotnet/phd/Index.php @@ -63,6 +63,18 @@ class Index extends Format 'refname' => 'format_sdesc', 'titleabbrev' => 'format_sdesc', 'example' => 'format_example', + 'refsect1' => 'format_refsect1', + "row" => array( + /* DEFAULT */ null, + "tbody" => 'format_row', + ), + 'entry' => array( + /* DEFAULT */ null, + "row" => array( + /* DEFAULT */ null, + "tbody" => 'format_entry', + ), + ), ); private $mytextmap = array( @@ -74,6 +86,9 @@ class Index extends Format private $chunks = array(); private $isChunk = array(); private $previousId = ""; + private $inChangelog = false; + private $currentChangelog = array(); + private $changelog = array(); private $commit = array(); private $POST_REPLACEMENT_INDEXES = array(); private $POST_REPLACEMENT_VALUES = array(); @@ -155,6 +170,7 @@ class Index extends Format $db = new \SQLite3(Config::output_dir() . 'index.sqlite'); $db->exec('DROP TABLE IF EXISTS ids'); $db->exec('DROP TABLE IF EXISTS indexing'); + $db->exec('DROP TABLE IF EXISTS changelogs'); } $create = <<<SQL @@ -169,6 +185,12 @@ CREATE TABLE ids ( next TEXT, chunk INTEGER ); +CREATE TABLE changelogs ( + docbook_id TEXT, + parent_id TEXT, + version TEXT, + description TEXT +); CREATE TABLE indexing ( time INTEGER PRIMARY KEY ); @@ -385,6 +407,41 @@ SQL; $this->appendID(); return false; } + public function format_refsect1($open, $name, $attrs, $props) { + if ($open) { + if (isset($attrs[Reader::XMLNS_DOCBOOK]['role'])) { + if ($attrs[Reader::XMLNS_DOCBOOK]['role'] == "changelog") { + $this->inChangelog = true; + } + } + return; + } + $this->inChangelog = false; + } + + public function format_entry($open, $name, $attrs, $props) { + if ($open) { + if ($this->inChangelog) { + /* FIXME: How can I mark that node with "reparse" flag? */ + $this->currentChangelog[] = htmlentities(trim(ReaderKeeper::getReader()->readContent()), ENT_COMPAT, "UTF-8"); + } + } + } + public function format_row($open, $name, $attrs, $props) { + if ($open) { + if ($this->inChangelog) { + end($this->ids); prev($this->ids); + $this->currentChangelog = array(current($this->ids)); + } + return; + } + if ($this->inChangelog) { + $this->changelog[$this->currentid][] = $this->currentChangelog; + } + } + + + public function commit() { if (isset($this->commit) && $this->commit) { $search = $this->db->escapeString("POST-REPLACEMENT"); @@ -402,6 +459,20 @@ SQL; } $this->db->exec('BEGIN TRANSACTION; '.join("", $this->commit).' COMMIT'); + $log = ""; + foreach($this->changelog as $id => $arr) { + foreach($arr as $entry) { + $log .= sprintf( + "INSERT INTO changelogs (docbook_id, parent_id, version, description) VALUES('%s', '%s', '%s', '%s');\n", + $this->db->escapeString($id), + $this->db->escapeString($entry[0]), + $this->db->escapeString($entry[1]), + $this->db->escapeString($entry[2]) + ); + } + } + $this->db->exec('BEGIN TRANSACTION; ' . $log. ' COMMIT'); + $this->log = ""; $this->commit = array(); } } diff --git a/phpdotnet/phd/PI/PHPDOCHandler.php b/phpdotnet/phd/PI/PHPDOCHandler.php index 0f4842f..9a89adb 100644 --- a/phpdotnet/phd/PI/PHPDOCHandler.php +++ b/phpdotnet/phd/PI/PHPDOCHandler.php @@ -74,6 +74,17 @@ class PI_PHPDOCHandler extends PIHandler { } break; + case "generate-changelog-for": + $changelogs = $this->format->getChangelogsForChildrenOf($matches["value"]); + $ret = "<table class='doctable table'>"; + foreach($changelogs as $entry) { + $link = $this->format->createLink($entry["docbook_id"], $desc); + $ret .= sprintf("<tr><td>%s</td><td><a href='%s'>%s</a></td><td>%s</td></tr>", $entry["version"], $link, $desc, $entry["description"]); + } + return $ret . "</table>"; + + break; + default: trigger_error("Don't know how to handle {$matches["attr"]}", E_USER_WARNING); break; Index: en/reference/mysql/functions/mysql-fetch-row.xml =================================================================== --- en/reference/mysql/functions/mysql-fetch-row.xml (revision 325983) +++ en/reference/mysql/functions/mysql-fetch-row.xml (working copy) @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- $Revision$ --> -<refentry xml:id="function.mysql-fetch-row" xmlns="http://docbook.org/ns/docbook"> +<refentry xml:id="function.mysql-fetch-row" xmlns="http://docbook.org/ns/docbook" xmlns:phd="http://www.php.net/ns/phd"> <refnamediv> <refname>mysql_fetch_row</refname> <refpurpose>Get a result row as an enumerated array</refpurpose> @@ -11,7 +11,7 @@ &mysql.alternative.note; <simplelist role="alternatives"> <member><function>mysqli_fetch_row</function></member> - <member><methodname>PDOStatement::fetch</methodname> (<constant>PDO::FETCH_NUM</constant>)</member> + <member><methodname phd:arg1="PDO::FETCH_NUM" phd:arg3="$stuff" phd:arg2="$foobar">PDOStatement::fetch</methodname></member> </simplelist> </sidebar> </refsynopsisdiv> @@ -40,7 +40,7 @@ <refsect1 role="returnvalues"> &reftitle.returnvalues; <para> - Returns an numerical array of strings that corresponds to the fetched row, or + Returns an numerical array of strings that corresponds to the fetched row, or &false; if there are no more rows. </para> <para> Index: doc-base/docbook/docbook-xml/docbook.dtd =================================================================== --- doc-base/docbook/docbook-xml/docbook.dtd (revision 325983) +++ doc-base/docbook/docbook-xml/docbook.dtd (working copy) @@ -1052,6 +1052,11 @@ <!ATTLIST methodname xmlns CDATA #FIXED "http://docbook.org/ns/docbook" role CDATA #IMPLIED + phd:arg1 CDATA #IMPLIED + phd:arg2 CDATA #IMPLIED + phd:arg3 CDATA #IMPLIED + phd:arg4 CDATA #IMPLIED + phd:arg4 CDATA #IMPLIED %db.common.attributes; %db.common.linking.attributes; @@ -1902,6 +1907,11 @@ <!ATTLIST function xmlns CDATA #FIXED "http://docbook.org/ns/docbook" role CDATA #IMPLIED + phd:arg1 CDATA #IMPLIED + phd:arg2 CDATA #IMPLIED + phd:arg3 CDATA #IMPLIED + phd:arg4 CDATA #IMPLIED + phd:arg4 CDATA #IMPLIED %db.common.attributes; %db.common.linking.attributes;
diff --git a/phpdotnet/phd/Format.php b/phpdotnet/phd/Format.php index 301a2ab..9fcaeb7 100644 --- a/phpdotnet/phd/Format.php +++ b/phpdotnet/phd/Format.php @@ -285,6 +285,19 @@ abstract class Format extends ObjectStorage public function addVarname($id, $var) { $this->vars[$var] = $id; } + public function getChangelogsForChildrenOf($bookid) { + $id = $this->sqlite->escapeString($bookid); + $results = $this->sqlite->query("SELECT * FROM changelogs WHERE parent_id='$id' ORDER BY version DESC"); + if (!$results) { + return array(); + } + + $changelogs = array(); + while ($row = $results->fetchArray()) { + $changelogs[] = $row; + } + return $changelogs; + } public function getRefs() { return $this->refs; } diff --git a/phpdotnet/phd/Index.php b/phpdotnet/phd/Index.php index 0a0f0d1..cf22ba8 100644 --- a/phpdotnet/phd/Index.php +++ b/phpdotnet/phd/Index.php @@ -63,6 +63,18 @@ class Index extends Format 'refname' => 'format_sdesc', 'titleabbrev' => 'format_sdesc', 'example' => 'format_example', + 'refsect1' => 'format_refsect1', + "row" => array( + /* DEFAULT */ null, + "tbody" => 'format_row', + ), + 'entry' => array( + /* DEFAULT */ null, + "row" => array( + /* DEFAULT */ null, + "tbody" => 'format_entry', + ), + ), ); private $mytextmap = array( @@ -74,6 +86,9 @@ class Index extends Format private $chunks = array(); private $isChunk = array(); private $previousId = ""; + private $inChangelog = false; + private $currentChangelog = array(); + private $changelog = array(); private $commit = array(); private $POST_REPLACEMENT_INDEXES = array(); private $POST_REPLACEMENT_VALUES = array(); @@ -155,6 +170,7 @@ class Index extends Format $db = new \SQLite3(Config::output_dir() . 'index.sqlite'); $db->exec('DROP TABLE IF EXISTS ids'); $db->exec('DROP TABLE IF EXISTS indexing'); + $db->exec('DROP TABLE IF EXISTS changelogs'); } $create = <<<SQL @@ -169,6 +185,12 @@ CREATE TABLE ids ( next TEXT, chunk INTEGER ); +CREATE TABLE changelogs ( + docbook_id TEXT, + parent_id TEXT, + version TEXT, + description TEXT +); CREATE TABLE indexing ( time INTEGER PRIMARY KEY ); @@ -385,6 +407,41 @@ SQL; $this->appendID(); return false; } + public function format_refsect1($open, $name, $attrs, $props) { + if ($open) { + if (isset($attrs[Reader::XMLNS_DOCBOOK]['role'])) { + if ($attrs[Reader::XMLNS_DOCBOOK]['role'] == "changelog") { + $this->inChangelog = true; + } + } + return; + } + $this->inChangelog = false; + } + + public function format_entry($open, $name, $attrs, $props) { + if ($open) { + if ($this->inChangelog) { + /* FIXME: How can I mark that node with "reparse" flag? */ + $this->currentChangelog[] = htmlentities(trim(ReaderKeeper::getReader()->readContent()), ENT_COMPAT, "UTF-8"); + } + } + } + public function format_row($open, $name, $attrs, $props) { + if ($open) { + if ($this->inChangelog) { + end($this->ids); prev($this->ids); + $this->currentChangelog = array(current($this->ids)); + } + return; + } + if ($this->inChangelog) { + $this->changelog[$this->currentid][] = $this->currentChangelog; + } + } + + + public function commit() { if (isset($this->commit) && $this->commit) { $search = $this->db->escapeString("POST-REPLACEMENT"); @@ -402,6 +459,20 @@ SQL; } $this->db->exec('BEGIN TRANSACTION; '.join("", $this->commit).' COMMIT'); + $log = ""; + foreach($this->changelog as $id => $arr) { + foreach($arr as $entry) { + $log .= sprintf( + "INSERT INTO changelogs (docbook_id, parent_id, version, description) VALUES('%s', '%s', '%s', '%s');\n", + $this->db->escapeString($id), + $this->db->escapeString($entry[0]), + $this->db->escapeString($entry[1]), + $this->db->escapeString($entry[2]) + ); + } + } + $this->db->exec('BEGIN TRANSACTION; ' . $log. ' COMMIT'); + $this->log = ""; $this->commit = array(); } } diff --git a/phpdotnet/phd/PI/PHPDOCHandler.php b/phpdotnet/phd/PI/PHPDOCHandler.php index 0f4842f..9a89adb 100644 --- a/phpdotnet/phd/PI/PHPDOCHandler.php +++ b/phpdotnet/phd/PI/PHPDOCHandler.php @@ -74,6 +74,17 @@ class PI_PHPDOCHandler extends PIHandler { } break; + case "generate-changelog-for": + $changelogs = $this->format->getChangelogsForChildrenOf($matches["value"]); + $ret = "<table class='doctable table'>"; + foreach($changelogs as $entry) { + $link = $this->format->createLink($entry["docbook_id"], $desc); + $ret .= sprintf("<tr><td>%s</td><td><a href='%s'>%s</a></td><td>%s</td></tr>", $entry["version"], $link, $desc, $entry["description"]); + } + return $ret . "</table>"; + + break; + default: trigger_error("Don't know how to handle {$matches["attr"]}", E_USER_WARNING); break; Index: en/reference/mysql/functions/mysql-fetch-row.xml =================================================================== --- en/reference/mysql/functions/mysql-fetch-row.xml (revision 325983) +++ en/reference/mysql/functions/mysql-fetch-row.xml (working copy) @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- $Revision$ --> -<refentry xml:id="function.mysql-fetch-row" xmlns="http://docbook.org/ns/docbook"> +<refentry xml:id="function.mysql-fetch-row" xmlns="http://docbook.org/ns/docbook" xmlns:phd="http://www.php.net/ns/phd"> <refnamediv> <refname>mysql_fetch_row</refname> <refpurpose>Get a result row as an enumerated array</refpurpose> @@ -11,7 +11,7 @@ &mysql.alternative.note; <simplelist role="alternatives"> <member><function>mysqli_fetch_row</function></member> - <member><methodname>PDOStatement::fetch</methodname> (<constant>PDO::FETCH_NUM</constant>)</member> + <member><methodname phd:arg1="PDO::FETCH_NUM" phd:arg3="$stuff" phd:arg2="$foobar">PDOStatement::fetch</methodname></member> </simplelist> </sidebar> </refsynopsisdiv> @@ -40,7 +40,7 @@ <refsect1 role="returnvalues"> &reftitle.returnvalues; <para> - Returns an numerical array of strings that corresponds to the fetched row, or + Returns an numerical array of strings that corresponds to the fetched row, or &false; if there are no more rows. </para> <para> Index: doc-base/docbook/docbook-xml/docbook.dtd =================================================================== --- doc-base/docbook/docbook-xml/docbook.dtd (revision 325983) +++ doc-base/docbook/docbook-xml/docbook.dtd (working copy) @@ -1052,6 +1052,11 @@ <!ATTLIST methodname xmlns CDATA #FIXED "http://docbook.org/ns/docbook" role CDATA #IMPLIED + phd:arg1 CDATA #IMPLIED + phd:arg2 CDATA #IMPLIED + phd:arg3 CDATA #IMPLIED + phd:arg4 CDATA #IMPLIED + phd:arg4 CDATA #IMPLIED %db.common.attributes; %db.common.linking.attributes; @@ -1902,6 +1907,11 @@ <!ATTLIST function xmlns CDATA #FIXED "http://docbook.org/ns/docbook" role CDATA #IMPLIED + phd:arg1 CDATA #IMPLIED + phd:arg2 CDATA #IMPLIED + phd:arg3 CDATA #IMPLIED + phd:arg4 CDATA #IMPLIED + phd:arg4 CDATA #IMPLIED %db.common.attributes; %db.common.linking.attributes;