Composer packaging

What is Composer?
Composer is a bundling dependency manager for PHP projects. It's similar to Bundler (for Ruby) or npm (for Javascript). It automates the process of downloading your project's dependencies. Recently it has become extremely popular and is used by major projects like PHPUnit and Drush.

The main repository for Composer packages is Packagist.

How does it work?
Each project that can be installed with Composer has a composer.json file that lists some information about it: the project name, its description, its dependencies, and so on. When you invoke Composer, it goes through that list of dependencies and downloads them all, storing them into your project's  directory. Afterwards, it generates a PHP class autoloader  that will automatically load any of the classes in your project or its dependencies.

Packaging hurdles
Most Composer packages use the autoloader (generated by Composer) to find and  their class files. As a result, the  statements typically used to include one PHP file into another are often missing. In that case, the package will not work out-of-the-box -- or in fact at all -- until an autoloader is created for it.

Composer's build system is incompatible with the way Gentoo's package managers work, so Composer cannot be used to generate the necessary autoloaders. For a long time, this obstacle prevented us from packaging anything that relied heavily on Composer. Fortunately, thanks to the hard work of other people, we now have decent workarounds for the problem.

Autoloading
The autoloaders that Composer generates support the PSR-0, PSR-4, and classmap formats. The generation of those autoloaders is the main obstacle to packaging Composer projects, and the creation of the Fedora Autoloader is the breakthrough that makes it possible.

The Fedora autoloader library provides a few functions --,  , and   -- that can generate class autoloaders for a directory tree. Moreover, it can build one big autoloader from a bunch of existing ones, allowing you to create an autoloader that works for an application and all of its dependencies (that's how Composer works). For example, the following file creates an autoloader for the package. The file is meant to be locates in the same directory as the library code, so we tell the autoloader to look in the current directory   and to prefix the class names therein with  :

Now, most people won't be using that package directly; instead, it will appear as a dependency of other PHP packages in the tree. In fact, it is used by itself. Here's a simplified version of the file that not only generates an autoloader for the   namespace, but also pulls in the   autoloader as well:

Ebuilds
Gentoo's naming conventions and the ones for Composer/Packagist don't quite agree. When choosing a Gentoo name for a Packagist project, you should try to choose the simplest name that is unambiguous and agrees with the Composer/Packagist names. Any slashes in the name must be converted to hyphens, and most packages should wind up in the  category, although that's not required. The idea is best illustrated with some examples.


 * 1) The psr/log package, once the slash is replaced by a hyphen, becomes . This closely matches what upstream uses, and what users will expect. A search for "psr" or "log" will turn up the correct package. The name   would not be appropriate because it is too general.
 * 2) The fedora/autoloader package becomes, because   is too general.
 * 3) The composer/composer package becomes simply, because there is no ambiguity in the name, and -- let's face it --   would be stupid.

Namespacing
Since we choose where to install everything, the resulting class namespaces are technically at our mercy. However, whenever possible, you should retain the upstream namespaces. As an example, consider the package. Symfony is a large framework that contains a number of components, and the Process component is merely one piece of the puzzle. As a result, the upstream namespace used for it is, which does not quite agree with the "symfony-process" name in the ebuild. Nevertheless, if a user wants to use directly, the upstream documentation will instruct him to use their namespaces:

We don't want to invalidate all of the existing documentation without a very good reason.

Tests
The test suites for Composer packages present another problem. Before a package is installed, it has no autoloader, but both the main class hierarchy and the test class hierarchy usually need autoloaders to be able to run.

Often you can fix this by copying the package's  file into both the current and test directories. This works because that autoloader is based on "the current directory," i.e. wherever you stick the file. Below you'll find an example from. (If this doesn't work, you may have to get clever.)