Cover photo for post A look at package2.xml and how to create a PEAR 1.4 package.

A look at package2.xml and how to create a PEAR 1.4 package.

I recently gave an overview on what will be new in PEAR 1.4, this time I'd like to start publishing some more detailed info on PEAR 1.4 news. Today's topic is package.xml version 2 and how to create a PEAR 1.4 package.

Update, 2005-02-26, 02:32:

I updated the little tutorial regarding Gregs comment. Sadly his XML input has been stripped by S9Y. I'll contact him to clear that up.

Update, 2005-02-26, 02:46:

Greg replied very quickly. Another update. :)

This little article covers the creation of a package2.xml (package.xml version 2.0) and packaging a package with it. Best ways of learning are a) looking at exmaples and b) trial and error. I hope this little example will help you to move your package.xml to package2.xml a bit more smooth.

Basically the conversion is pretty simple. The pear convert command (run the directory where your old package.xml lies) does a great job and converts all data for you. But in most cases, there will still be some work to be done. So, let's take a walk through the package2.xml of Net_FTP and look, what's in there.

<?xml version="1.0"?> <package packagerversion="1.4.0a1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">

This references to the package2.xml schema files are auto generated by the pear convert command.

<name>Net_FTP</name> <channel>pear.php.net</channel>

The first new tag is <channel />, which describes, in which channel your package is available. For PEAR packages, this is of course correct, as it is. For a PECL package pecl.php.net should be sufficient.

<summary>Net_FTP provides...</summary> <description>Net_FTP allows you to communicate with FTP servers...</description> <lead> <name>Tobias Schlitt</name> <user>toby</user> <email>toby@php.net</email> <active>yes</active> </lead>

The <maintainers /> and <maintainer /> tags have been dropped. Package maintainers are now listed directly inside the main tag, using tags to cover the user data that directly correspond to the PEAR development roles (e.g. lead, developer,...). A new subtag for a maintainer is the <active /> flag, which enables you to have retired maintainers still listed to give them credit (switching active to "no").

<date>2005-02-24</date> <time>16:06:49</time>

The <time /> tag is also new, AFAIK. Not much to tell about it.

<version> <release>1.3.0</release> <api>1.3.0</api> </version>

The usage of the <release /> tag has been refined completly. The currently release is now described through the <version /> tag, which contains a <release /> version and an <api /> version number. Pretty usefull, to indicate, that the API of a package has changed.

<stability> <release>stable</release> <api>stable</api> </stability>

The definition of the old tag <state /> has also been refined. The <stablility /> of a package is now determined through 2 values, one for the release and one for the API version.

<license uri="http://www.php.net/license/3_0.txt">PHP License</license>

The <license /> tag can now contain a link to the text of a license.

<notes>Another month of testing did not bring any more critical bugs to daylight...</notes>

The <notes /> tag stays as it was.

<contents> <dir name="/"> <dir name="example"> <file baseinstalldir="" md5sum="0aeb3b3be1fdfe7fccbe704581d36f3f" name="extensions.ini" role="doc" /> </dir> <!-- /example --> </dir> <!-- / --> </contents> So far, the structure of the new <cotents /> section should be clear. The content of the package is described similar to the old fashioned <filelist /> section. Instead of using abstruse name constructs, one creates the directory structure as an XML tree. Much better handling. The list itself is converted nicely from the old structure. Attention: The toplevel dirtag is required!

A variation is the following (which you have to change manually):

<file baseinstalldir="" md5sum="e980d7c1ed73f336c0ba08494d253657" name="index.php" role="doc"> <tasks:replace from="@package_version@" to="version" type="package-info" /> </file>

The <task /> part is a new invention of package2.xml. It defines a task to perform with the file after installation (a post install script). In this case, a replacement for the string @package_version@ is defined, to be replaced, with a package-info, concreter the version of the package. (This is neccessary for the use of the new docblock standard.)

<dependencies> <required> <code> <min>4.0.0</min> <max>6.0.0</max> </code> <pearinstaller> <min>1.4.0a1</min> </pearinstaller> <extension> <name>ftp</name> </extension> </required> </dependencies>

The dependency section has changed greatly. The <deps /> tag is replaced by <dependencies />. The data of this tag is grouped into a <required /> and an <optional /> section (we only have required here). Below this sections each dependency is identified by it's type (PHP release <php />, PEAR installer release <pearinstaller /> and <extension /> can be seen here). Those identifiers are mostly correspondant to the type attripute in the old <dep /> tags. Inside the single dependency sections the dependcies are defined (pretty self-explanatory). The conversion from old to new dependency style is done automatically by pear convert.

<phprelease /> As told by Greg in his comment to this entry, this tag determines the type of a package, e.g. this package contains PHP code, other possible values would be extsrcrelease for a release of PECL sources, extbinrelease for a binary PECL release or bundle.

Below this line, just the changelog follows, which is pretty uninteressting for the generation and automatically created when using pear convert.

And that's all folks.

Last to mention is how to build a package with the new package2.xml. Usually one would say, "upgrade to PEAR 1.4" and run "pear package". The first step is not that easy, currently, since PEAR 1.4 has not been released officially (when it one time is, just type "pear upgrade -f PEAR" and force the upgrade to a PEAR alpha version). For now, one has 2 options:

  1. Download a testing tarball and install

type pear upgrade -f http://pear.chiaraquartet.net/PEAR-1.4.0a1-test2.tgz

  1. Use the current CVS sources (recommended)

checkout the current CVS sources of pear-core enter the pear-core directory type pear upgrade -f package-PEAR.xml

Grabbing the CVS sources is of course recommended, to have the most up2date version of the PEAR core. Doing this you can easily help making the PEAR installer more stable. Enter the test/ directory below pear-core and type pear run-tests -rlq and send the created results to pear-qa.

If you have installed the new PEAR version you can do pear convert to create a new package2.xml from your old package.xml. After your have performed any necessary optimizations you can check if everything is correct using pear package-validate package2.xml (if the output is not that clear, try pear config-set verbose 3 to raise the verbosity.

Now that everything is correct, we can package the new release. The current packaging command for using package2.xml is a bit confusing. Normaly one would expect to do pear package package2.xml and it should work (or even just pear package and if a package2.xml is available, use it). This does not work. If a package.xml is available, the pear installer automatically uses this one instead of package2.xml (with both commands!). To package using the new version of package.xml, you have to type

pear package package.xml package2.xml.

The so created package contains both files (package.xml and package2.xml) so that your package is still installable with older PEAR versions.

Next time: How to set up a PEAR 1.4 server. :)

Comments

package.xml 1.0 did not differentiate between different kinds of releases. In order to tell whether a package provided a PHP extension or just a PHP script, you had to dig in very un-computerlike fashion through the filelist and check out the roles of individual files to see if there were any src or php files.

package.xml 2.0 makes this explicit.

<phprelease /> says "This is a PHP script release" <extsrcrelease /> says "This is a PHP extension source release" <extbinrelease /> says "This is a PHP extension binary release" <bundle /> says "This is a collection of other pre-packaged releases in one bundle"

The tag is also there to define different release sets based on the client's system configuration. PEAR, for instance, installs itself differently on windows and on linux, so there are two install sets.

package.xml used to do this with some hackish attributes in the <file> section like "platform" and "install-as" which only led to unreadability and more importantly, much greater difficulty debugging complex situations.

Since this is a comment, I will leave the major detail to an upcoming blog post on my blog.

In general, Toby's insight is right on. Notice that the convert command will put the baseinstalldir attribute into every file - this is a quirk of how the conversion happens. You can still put baseinstalldir into <dir> tags, and they will cascade down like in package.xml 1.0.

Also note that a top-level <dir> tag is required in package.xml 2.0 so we have

<contents><dir name="/"><file name="blah.php" role="php"></dir></contents>

for the simplest possible contents tag.

Greg Beaver at 2005-02-25

package.xml used to do this with some hackish attributes in the <file> section like "platform" and "install-as" which only led to unreadability and more importantly, much greater difficulty debugging complex situations.

keith opinion at 2012-08-06