[[toc]] + No More Pear: Move to composer Remove any hard runtime or installation dependency on pear and pearisms ++ Bugs List any tickets on http://bugs.horde.org/ that cover this issue or are relevant to it. ++ People Ralf Lang ++ Description The PHP ecosystem has increasingly moved from pear to composer as the default installer. The changed paradigm (global versus local dependency management) attracts many users and developers. +++ Runtime dependencies ++++ horde-db-migrate and web migrator horde-db-migrate "forgets" to migrate or even acknowledge libraries in git checkouts where the pear channel is not present. https://github.com/horde/Core/pull/2 ++++ l10n/translation tools? +++ Document .horde.yml format and how it relates to composer json and pear xml See ((Doc/Dev/HordeYmlFormat|Developer Doc on .horde.yml format)) for both original format and proposed additions. +++ Installation ++++ Generate composer json file from .horde.yml [DONE] components/lib/Helper/Composer.php currently depends on conductor and gets its data from package.xml anything handling package.xml is broken without pear though. Always need to register the horde channel [DONE] rewrite all pear.horde.org dependencies to vcs type dependencies github/horde/ https://github.com/horde/components/pull/3 Other resources Do we want to keep a whitelist of other channels/packages which should be pulled from packagist or github rather than pear? ++++ Composer plugin: install apps below base rather than vendor/ (we don't want /vendor/ web-readable) [DONE] horde apps are type "horde-application" and get installed to /$appname or base/appname Installing/updating an app should clear cache and autoloader cache [DONE] Check if the app provides a registry snippet in /doc/registry.d/ [DONE] write horde.local.php if necessary [WONTDO SEE BELOW] installing base should provide some initialization [DONE] The installer allows the deployment/bundle to provide pre-made configs for horde and apps ++++ Composer plugin: copy, move or link js content from libraries to horde/js [DONE] horde libs are type "horde-library" and get installed to /vendor/Horde/Foo [DONE] js/ dir content of horde-library packages and the horde base app are copied or linked to web/js/ [DONE] automatically rewrite registry path of hordeJs fileroot and webroot to web/js/ +++ Packagist Add tool chain to create and update packages on packagist for easier consumption. +++ Autoloading and fixed loading ++++ Examining horde base bootstrapping: [NO TODO] horde/horde/index.php require_once lib/Application [NO TODO]Horde/Application.php require_once core.php [DONE] core.php checks for horde.local.php -- composer installer will write necessary autoloading instructions there. [DONE] Either include_once Horde/Autoloader/Cache.php or require_once Horde/Autoloader/Default.php - fixed by adding a search path ++++ Examining nag bootstrapping: horde/nag/index.php and other client pages require_once nag/lib/Application.php nag probes for horde_dir (either info from horde.local.php or directory above nag dir) finally load (hordedir)/lib/core.php -> both in base and apps, we can edit horde.local.php for hinting and autoloader ultimately comes from horde/lib/core.php ++++ Issues with Horde_Autoloader_Default and Horde_Autoloader_Cache Horde_Autoloader_Default has unconditional require_onces Horde_Autoloader_Default registers unconditionally when loaded Horde_Autoloader_Cache requires/registers Horde_Autoloader_Default unconditionally [DONE] Fixed by providing suitable search paths in horde.local.php ++++ Examining git-tools as a composer-native app: git-tools binary detects the composer autoloader entrypoint vendor/autoload.php and require_once it. the composer autoloader is configured to provide a psr-4 autoloader for the \\Horde\\GitTools namespace to ./lib ++++ PSR-0, db migrations, classmaps and packages Most horde library packages are simple to map to the psr-0 autoloader. Package Horde_Foo would have all its classes in lib/Horde/Foo. Some packages though have class names you would not expect from the package name Horde_Core has Horde_ErrorHandler & friends Horde_Form has multiple classes in one file Horde_Util has Horde_String These either need to be scanned for additional mappings or need "classmap" style autoload hints. [UNSURE] Unit tests should be marked as autoload-dev (root package only autoloads) [DONE] migrations should be autodetected by the composer writer. [DONE] special case classmaps should be hinted by .horde.yml ++++ Horde_Test Horde_Test bundles phpunit. A Horde Library uses a copy of boilerplate code from horde_test to initialize autoloading. This boilerplate makes some PEARish assumptions (universal include hierarchy) This pull request offers a new template and fixes other unconditional require_once instances https://github.com/horde/Test/pull/1 This should hopefully work for PEAR installs, composer installs and full git checkouts just the same. [DONE] Running the unit tests via the components app, when installed into a composer deployment, is also possible without fixing AllTests & friends. ++ Proof of concept There is a proof of concept in https://github.com/maintaina-com This proof of concept includes all software patches which are part of this effort +++ components and git-tools In this project, the components tool is used via git-tools as a frontend or as an installed app via composer exec horde-components. Various patches have been applied. Most relevant is a rewrite of the Components_Helper_Composer class. This class now writes a thoroughly different composer file than before and it takes its data from .horde.yml rather than package.xml To generate a new composer.json file for an app, run <code> composer exec -v horde-components web/$app/ composer </code> To generate a new composer.json file for a library, run <code> composer exec -v horde-components vendor/horde/$lib composer </code> Mind providing a useful config for horde-components first config options govern - if we want to build against dev-master dependencies or dependencies using the horde.yml version constraints - if we assume all packages live on packagist, in a shared satis repo or a per-library git location - how to translate non-horde pear dependencies into packagist dependencies (otherwise, pear channels will be used) ++++ components release command The components release command needs some additions to make this practical * [TODO] The composer file needs to be written with different options twice: It should use dev-master requirements in the master branch, but use versioned requirements as stated in the composer yaml file when writing a tagges release * [TODO] There should be configureable hooks to either trigger a satis rewrite or a packagist upload * [TODO] An easy way to perform downstream/inhouse releases omitting PEAR related stuff or upstream horde specific steps like updating the bug tracker. This should not involve lenghty command lines. ++++ Known issues There is currently a problem with discerning commandline options (-X and --something) for the composer exec command from those for the components cli. https://github.com/composer/composer/issues/5632 If your use case depends on using these switches (most notoriously, --depend), run the command instead using ./vendor/bin/horde-components ... +++ Core, Base and Autoloader Several patches were needed in places where horde just assumed files to always be in a certain location. Most of these patches SHOULD NOT break git dev installs or pear installs - testing was very limited Other relevant changes were detection of migration files in Horde_Core_Db_Migration and handling of Horde_Controller routes in lib/Horde/Core/Controller/RequestMapper.php +++ Test The Horde_Test suite had some hardcoded requires which were made condidional. +++ Other libraries Unmentioned libraries SHOULD only have been modified by replacing the master branch composer file +++ ++ Resources https://getcomposer.org/doc/articles/custom-installers.md composer notes on custom installers and plugins https://github.com/composer/installers multi-framework collection of installers https://github.com/maglnet/ComposerRequireChecker Tool to find direct usage of indirect dependencies (Ensure you directly require all dependencies whose classes are referenced in own code) ---- Back to the ((Project|Project List))