\documentclass{article}
\usepackage{ulem}
\pagestyle{headings}
\begin{document}
\tableofcontents

No More Pear: Move to composerBugsPeopleDescriptionRuntime dependencieshorde-db-migrate and web migratorl10n/translation tools?Document .horde.yml format and how it relates to composer json and pear xmlInstallationGenerate composer json file from .horde.ymlComposer plugin: install apps below base rather than vendor/Composer plugin: copy, move or link js content from libraries to horde/jsPackagistAutoloading and fixed loadingExamining horde base bootstrapping:Examining nag bootstrapping:Issues with Horde\_Autoloader\_Default and Horde\_Autoloader\_CacheExamining git-tools as a composer-native app:PSR-0, db migrations, classmaps and packagesHorde\_TestProof of conceptcomponents and git-toolscomponents release commandKnown issuesCore, Base and AutoloaderTestOther librariesResources

\part{No More Pear: Move to composer}
Remove any hard runtime or installation dependency on pear and pearisms

\section{Bugs}
List any tickets on http://bugs.horde.org/\footnote{http://bugs.horde.org/} that cover this issue or are relevant to it.

\section{People}
Ralf Lang

\section{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.

\subsection{Runtime dependencies}
\subsubsection{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. \newline
https://github.com/horde/Core/pull/2\footnote{https://github.com/horde/Core/pull/2}

\subsubsection{l10n/translation tools?}
\subsection{Document .horde.yml format and how it relates to composer json and pear xml}
See Developer Doc on .horde.yml format\footnote{http://example.com/index.php?page=Doc/Dev/HordeYmlFormat} for both original format and proposed additions.

\subsection{Installation}
\subsubsection{Generate composer json file from .horde.yml}
[DONE] components/lib/Helper/Composer.php currently depends on conductor and gets its data from package.xml\newline
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\footnote{https://github.com/horde/components/pull/3}

Other resources\newline
Do we want to keep a whitelist of other channels/packages which should be pulled from packagist or github rather than pear?

\subsubsection{Composer plugin: install apps below base rather than vendor/}
(we don't want /vendor/ web-readable)\newline
[DONE] horde apps are type "horde-application" and get installed to /\$appname or base/appname\newline
Installing/updating an app should clear cache and autoloader cache\newline
[DONE] Check if the app provides a registry snippet in /doc/registry.d/\newline
[DONE] write horde.local.php if necessary\newline
[WONTDO SEE BELOW] installing base should provide some initialization\newline
[DONE] The installer allows the deployment/bundle to provide pre-made configs for horde and apps

\subsubsection{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\newline
[DONE] js/ dir content of horde-library packages and the horde base app are copied or linked to web/js/\newline
[DONE] automatically rewrite registry path of hordeJs fileroot and webroot to web/js/

\subsection{Packagist}
Add tool chain to create and update packages on packagist for easier consumption.

\subsection{Autoloading and fixed loading}
\subsubsection{Examining horde base bootstrapping:}
[NO TODO] horde/horde/index.php require\_once lib/Application\newline
[NO TODO]Horde/Application.php require\_once core.php\newline
[DONE] core.php checks for horde.local.php  -- composer installer will write necessary autoloading instructions there.\newline
[DONE] Either include\_once Horde/Autoloader/Cache.php or require\_once Horde/Autoloader/Default.php - fixed by adding a search path

\subsubsection{Examining nag bootstrapping:}
horde/nag/index.php and other client pages require\_once nag/lib/Application.php\newline
nag probes for horde\_dir (either info from horde.local.php or directory above nag dir)\newline
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

\subsubsection{Issues with Horde\_Autoloader\_Default and Horde\_Autoloader\_Cache}
Horde\_Autoloader\_Default has unconditional require\_onces\newline
Horde\_Autoloader\_Default registers unconditionally when loaded\newline
Horde\_Autoloader\_Cache requires/registers Horde\_Autoloader\_Default unconditionally

[DONE] Fixed by providing suitable search paths in horde.local.php

\subsubsection{Examining git-tools as a composer-native app:}
git-tools binary detects the composer autoloader entrypoint vendor/autoload.php and require\_once it.\newline
the composer autoloader is configured to provide a psr-4 autoloader for the \\\\Horde\\\\GitTools\footnote{http://example.com/index.php?page=GitTools} namespace to ./lib

\subsubsection{PSR-0, db migrations, classmaps and packages}
Most horde library packages are simple to map to the psr-0 autoloader.\newline
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\newline
Horde\_Core has Horde\_ErrorHandler \& friends\newline
Horde\_Form has multiple classes in one file\newline
Horde\_Util has Horde\_String

These either need to be scanned for additional mappings or need "classmap" style autoload hints.\newline
[UNSURE] Unit tests should be marked as autoload-dev (root package only autoloads)\newline
[DONE] migrations should be autodetected by the composer writer.\newline
[DONE] special case classmaps should be hinted by .horde.yml

\subsubsection{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\footnote{https://github.com/horde/Test/pull/1}\newline
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\footnote{http://example.com/index.php?page=AllTests} \& friends.

\section{Proof of concept}
There is a proof of concept in https://github.com/maintaina-com\footnote{https://github.com/maintaina-com}\newline
This proof of concept includes all software patches which are part of this effort

\subsection{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\newline
rather than package.xml

To generate a new composer.json file for an app, run

\begin{verbatim}

composer exec -v horde-components web/$app/ composer
\end{verbatim}

To generate a new composer.json file for a library, run

\begin{verbatim}

composer exec -v horde-components vendor/horde/$lib composer
\end{verbatim}

Mind providing a useful config for horde-components first

config options govern \newline
- if we want to build against dev-master dependencies or dependencies using the horde.yml version constraints\newline
- if we assume all packages live on packagist, in a shared satis repo or a per-library git location\newline
- how to translate non-horde pear dependencies into packagist dependencies (otherwise, pear channels will be used)

\subsubsection{components release command}
The components release command needs some additions to make this practical

\begin{itemize}
\item{[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}
\item{[TODO] There should be configureable hooks to either trigger a satis rewrite or a packagist upload}
\item{[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.}
\end{itemize}
\subsubsection{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.\newline
https://github.com/composer/composer/issues/5632\footnote{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 \ldots

\subsection{Core, Base and Autoloader}
Several patches were needed in places where horde just assumed files to always be in a certain location.\newline
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 \newline
 lib/Horde/Core/Controller/RequestMapper\footnote{http://example.com/index.php?page=RequestMapper}.php

\subsection{Test}
The Horde\_Test suite had some hardcoded requires which were made condidional.

\subsection{Other libraries}
Unmentioned libraries SHOULD only have been modified by replacing the master branch composer file

\subsection{}
\section{Resources}
https://getcomposer.org/doc/articles/custom-installers.md\footnote{https://getcomposer.org/doc/articles/custom-installers.md} composer notes on custom installers and plugins\newline
https://github.com/composer/installers\footnote{https://github.com/composer/installers} multi-framework collection of installers\newline
https://github.com/maglnet/ComposerRequireChecker\footnote{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)


\noindent\rule{\textwidth}{1pt}
Back to the Project List\footnote{http://example.com/index.php?page=Project}

\end{document}
