It's been a while since I reported on any of my PHP activities, and this update is long overdue. I must apologize to Davey for not doing my 7 things, and to all of the facebook people for whom I didn't write 25 things. I am somehow not at all motivated to do this...
In any case, now that work on ext/phar has shifted primarily to maintenance mode, and namespaces are finally ancient history, I've shifted all of my coding energy to getting Pyrus, PEAR's next-generation installer, ready to ship. Pyrus is basically the PEAR installer completely redesigned for PHP 5.3, and it takes advantage of as many of PHP's new bells and whistles as makes sense. Some of the exciting features:
- Full support for .tar, .tgz, .tbz, .zip, and .phar archive formats out of the box, complete with signing via md5, sha1, sha256, sha512, or asymmetric true signature via openssl signature (all from ext/phar, which is built into PHP 5.3)
- primary registry is SQLite3-based, which is much more robust, and can be relocated very easily, plus support for XML file-based registry as well as PEAR 1.x's serialize-based registry
- redundant registries means ability to reconstruct a corrupted install
- configuration is stored with the installed files, no more hunting down errant config files, user preferences are stored in home directory or equivalent
- for developers: easy generation of package.xml straight from source code checkout
- also for developer: easy generation of channel REST files directly from release tarball, no need to install a package (like the old Chiara_PEAR_Server) or even run PHP on the channel web server.
There are many other great features for users who would like to extend Pyrus, including a seamless API for accessing package.xml which is identical regardless of whether the package.xml is from an .xml file, an archive, or an installed package's registry.
Of course, all of these features only matter if they work, and to move along that path, I've been spending my time unit testing up a storm. Using the run-tests command of the old PEAR installer, I'm writing and refining tests. With the addition of xdebug code coverage (pear run-tests -rx does the trick), it is possible to see where stuff is being executed. Unfortunately, I don't like the existing reporting tools (call me a snob), so I whipped up a very simple coverage analyzer and popped it into the subversion where all of PEAR2 is stored.
When I say simple, I mean here is the script for generating the source (svn link):
<?phpnamespace
{function __autoload
($c){ $c =
str_replace('PEAR2\Pyrus\Developer\CoverageAnalyzer\\',
'',
$c);
include __DIR__ .
'/' .
$c .
'.php';
}}namespace PEAR2\Pyrus\Developer\CoverageAnalyzer
{ $a =
new Aggregator
(realpath('../../../../../Pyrus/tests'),
realpath('../../../../../Pyrus/src'));
if (file_exists(__DIR__ .
'/test')) { foreach (new DirectoryIterator
(__DIR__ .
'/test') as $file) { if ($file->
isDot()) continue;
unlink($file->
getPathName());
} } else { mkdir(__DIR__ .
'/test');
} $a->
render(__DIR__ .
'/test');
}?> Highlighting is a little wonky because this is PHP 5.3+ code, but my blog is running 5.2.
The output is at http://pear.php.net/~greg/coverage/. This is a dumbed-down version of gcov.php.net, which I found extraordinarily helpful when writing the unit tests for ext/phar, but unlike gcov, there are some fantastically helpful features. The short list:
- summary of all executed files and their coverage
- project coverage (lines executed, lines covered, and the percentage of covered code)
- annotated source showing the lines covered with hyperlinks to lists of tests that cover each line
- this one excites me: per-test code coverage.
For instance,
this report shows the tests that execute line 660 of PackageFile/v2.php,
next this report shows the files that the PackageFile_v2/basic/file.phpt test actually executes with their proportional coverage, and
finally this report shows
the lines in PackageFile/v2.php that are executed by the file.phpt test.
This last part is extremely useful to me, I have already used it to determine when a test is not executing the lines I expect it should be, and to fix problems such as using isset() instead of array_key_exists(), which would otherwise be very difficult to track down.
As you can also see, only 30% of the source to Pyrus is covered by the current tests, and so there is a long ways to go to full coverage. If any of this work interests you, feel free to contribute, PEAR2 has a much lower barrier to entry than PEAR, and as you can see, we need all the help we can get to bring this baby off the ground.