source_composer
-s composer
package input
State: testing
Targets: deb, rpm, phar
The composer plugin can turn composer bundles into system packages (deb
/rpm
). They extract libraries under /usr/share/php/
then. Alternatively you can create local phars, or phars wrapped into system packages.
Normally you'd just use composer directly for joining libraries into projects. Syspackaging is meant to further fixate dependencies as globally shared libraries. Having php includes under system control can simplify deployment in a few settings.
System packages
Individual components
To package a dependency from within a composer-managed project directory use:
xpm -s composer -t deb,rpm gregwar/formidable
Note that fpm/xpm is meant for crafting one package at a time. So this will output exactly one
*.deb
/*.rpm
package. If you specified more than one composer bundle name as input, they'd end up intermingled otherwise. (→ A warning will occur, and fpm aborts.)Pack all the things
However it's quite trivial to convert all composer dependencies at once with a shell loop:
for P in vendor/*/*; do xpm -s composer -t deb $P done
This will create a whole bunch of
php-vnd-pkg_0.1.2_all.deb
system packages.Fetch afresh
If you're not within a composer checkout, then the -s composer hook will of course retrieve it directly via composer and from packagist. This way you could also predefine a version:
xpm -s composer -t deb --composer-ver 2.7 new/new
Again, this will just convert one individual package. It will have its system
Depends:
field populated. But its actual dependent packages must be crafted this way too/manually. (It's most practicaly to just create an empty directory, checkout a complete package list percomposer install
, and then use thefor
-loop method to package every component in one run.)
Pack'ging Phars
Local phars
Instead of system packages (
-t deb
and-t rpm
) you can also create Phar archives of "vnd-pkg.phar
". Simply use the existing-t phar
target:xpm -s composer -t phar vendor/vnd/pkg
Such phar archives of course won't contain absolute paths. In fact all source files are assembled without any ./vnd/pkg/ prefixes. → That would be redundant because it's already obvious from the phar basename (and its archive meta data).
Using phar packages within projects of course requires a modern autoloader. Be advised that it's a super negligible performance benefit by itself. Generally classmap-based autoloaders can be faster. But if class dependencies are dispersed across files within, then there's little gain over entirely file-by-file-tapping ones.
Phars in system packages
An interesting variation for the packaging process is to convert Composer packages into Phars wrapped in system packages. (This is labeled "matroska" mode in the plugin, btw). And it's simply available per
--composer-phar
flag:xpm -s composer --composer-phar -t deb,rpm new/new
This way you'll end up with a system
phar-vnd-pkg_0.1_all.deb
/.rpm
package. Which will install its containedVnd-Pkg.phar
directly under/usr/share/php/
.Again you'd need an autoloader that's designed for this. See shared.phar for a prototype. (A system trigger can keep the global map updated.)
Phar options
In both cases the -t phar module is used (internally) for generation. Currently and per default the composer source hook predefines the Phar format to be of the inspectable/compressed
ZIP+gz
variety. You could alternatively set the--phar-format=phar
for native/uncompressed Phars of course.
Notes
Dependencies
Composer package relations are transformed into
Depends:
/Requires:
fields, with package names remapped tophp-vnd-pkg (>= 1.0)
for example. Not all composer versioning internas are translated however, because RPM support for alternatives is mostly non-existent, and Debian has other guidelines as well.RPM
- Package names are
php-vnd-pkg_1.0.rpm
- Requires become
php-composer(vnd/pkg) >= 1.0
lists. - Version state appendices are cut out completely, as assumed from Fedora examples.
- Package names are
Debian
- Packages become
php-vnd-pkg-1.0.deb
- Dependencies are listed as
php-vnd-pkg
, but alternatively allowsphar-vnd-pkg
for any package, unless --composer-no-alt is used. - Versions are translated to contain orderable
~
and~~
suffixes for alpha/beta/rc/dev versions, which is what Debians php-pkg-tools does.
- Packages become
Phars
- Unprefixed package names
vnd-pkg.phar
- Depends:
vnd-pkg >= 1.0, two-lib >= 2.0
are basically local URNs. - Versions are only minimally adapted to be suitable for PHPs native
version_compare()
.
- Unprefixed package names
There's support for comparative, tilde and caret version expressions, some literals, also for conflicts and provides. Non-development releases should be preferred still. And in case of dependency hell, use fpms
--no-depends
flag.Autoloader building
The current version doesn't predefine any specific autoloader regeneration. This leaves room for a few options though.
- On Debian systems a package trigger watching for
/usr/share/php/
would certainly be the best option. This rebuilds any classloader after installations there. - Preferrably use phpab to build a common
autoload.phar
. It's both fast and language-compliant (case-insensitive lookups) per default. - When generating
phar
packages, using a --phar-stub for a concrete and built-in autoload registration is an option. A simpleinclude("vnd-pkg.phar");
could then initialize dependencies explicitly. - The aforementioned
shared.phar
prototype would also work. In fact implements the package/directory trigger. (The RPM trigger is untested still. Just recently transition to afpm
package build script.)
Obsolete: Formerly
composer.lock
information was retained in each packagescomposer.json
underextra[]→lock{}
. But composer itself doesn't support rebuildingcomposer.lock
or thus its autoloader. Both Debian and Fedora decided againstvendor/*/*
beneath/usr/share/php
, and composer folks never wanted it either. Therefore the current xpm composer plugin doesn't allow that anymore. (See the attachment for a prior rough implementation of composer.lock and autoloader/installed.json reconstruction; or the opensuse workaround: composer-add-package for this).- On Debian systems a package trigger watching for
Phar attributes
With --composer-phar or the -t phar target, each generated archive contains an archive meta data bag. It's intended for simple application-level feature/plugin management, similar to a pre-parsed
composer.json
even. The fieldsid:
andversion:
, as well astitle:
,description:
,author:
,url:
,category:
are available.Dependencies are translated into basename
depends:
lists. A copy of composer fields is retained in acomposer: {}
instead. (Redundant, as the composer.json is also packaged within. But may be more convenient in some cases.)built-in Classmap for Phars
The -t phar plugin meanwhile bakes a class map into the Phar meta array. It's obviously available for phar bundles and for phar-in-system packages.
- map
- class
vnd\dir\classname
=>src/dir/Classname.php
myiterator
=>src/MyIterator.php
- function
- const
- class
Most autoloaders would only consume the
class
attributes of course. Canonic_Autoloader is prepared toaddPhar()
this structure to the active classmap. Identifiers are already lowercased for language-compliant autoloading, of course.- map
Alternatives
See also pkg-php-tools
for the Debian build helper (translates package names and dependency lists). Or php-composer-rpms
for creating rpm
packages (seems to be a stub though).
If you're just looking for a way to bundle up all project dependencies at once, then instead check out github:clue/phar-composer. It was specifically designed for that, is implemented in PHP, and provides more targetted options.
Distinct -u composer update filter
Note that the -s composer
source plugin has a distinct purpose to the -u composer filter. The -update filter only generates a stub composer.json
and is intended for plain phar
archives generated from -s dir source files or -s src for meta-tagged scripts. -- Both plugin types are not yet aligned in any way; so you don't want to combine them.