\documentclass{article}
\usepackage{ulem}
\pagestyle{headings}
\begin{document}
\part{ The .horde.yml file format}
\section{ Basic format }
This format has been used by Horde Framework 5.2 since roughly the time of the git split.

Document .horde.yml format and how it relates to composer json and pear xml

TODO: beautify

\subsection{ Meta data head}
id: string, mandatory, uppercase and minus Horde\_ for libs, lowercase for apps (horde, turba, Autoloader, Exception)\newline
name: string, mandatory, Uppercase (Horde, Turba, Autoloader, Exception)\newline
full: string, mandatory, a one-line description\newline
description: string, mandatory, a multi-line description\newline
list: string, mandatory, may be empty: a hint on the mailing list appropriate for the component\newline
type: string, mandatory, classic: either "application" or "library", modern: horde-application, horde-library, horde-theme\newline
homepage: string, mandatory, a related informational url\newline
authors: list, each element has string attributes name, user, email, active (true/false), role (lead, developer)\newline
version: has sub keys api and release each with a version string (1.0.0 format)\newline
state: has sub keys api and release, each with a stabilitiy string (stable, beta, alpha)\newline
license: has subkeys identifier and uri\newline
license: identifier: An SPDX license identifier string\newline
license: uri: a link to a fulltext license

Example:

\begin{verbatim}

---
id: Db
name: Db
full: Database abstraction library
description: Database access and SQL abstraction layer.
list: dev
type: library
homepage: https://www.horde.org/libraries/Horde_Db
authors:
  -
    name: Jan Schneider
    user: jan
    email: jan@horde.org
    active: true
    role: lead
  -
    name: Mike Naberezny
    user: mnaberez
    email: mike@naberezny.com
    active: false
    role: lead
  -
    name: Chuck Hagenbuch
    user: chuck
    email: chuck@horde.org
    active: false
    role: lead
version:
  release: 2.4.1
  api: 2.4.0
state:
  release: stable
  api: stable
license:
  identifier: BSD-2-Clause
  uri: http://www.horde.org/licenses/bsd
\end{verbatim}

\subsection{ PHP and Pear Dependencies}
This covers PHP itself, php binary modules and PEAR dependencies both inside horde and external. \newline
For composer, pear dependencies on parts of horde get translated. External dependencies get included as pear unless they are defined in a conversion list in the components tool's config. \newline
See below for composer-only dependencies.

dependencies: top level structure for several optional keys\newline
dependencies: required: multilevel list of mandatory dependencies (php, pear, ext) - The key and all sub keys are optional\newline
dependencies: required: php: optional key. The value should be a version constraint string\newline
dependencies: required: pear: optional key. This is a list of channel/package keys and version constraint values. For pecl extensions, there may be additional sub keys instead of a version string\newline
dependencies: required: ext: optional key. This is a list of php binary extensions (hash, pdo, \ldots) as keys and version constraint strings as values.\newline
dependencies: optional: multilevel list of optional, suggested collaborators (pear, ext) - The key and all sub keys are optional\newline
dependencies: required: pear: optional key. This is a list of channel/package keys and version constraint values. For pecl extensions, there may be\newline
dependencies: dev: composer: optional key. This is a list of vendor/package keys and version constraint values. This generates the composer require-dev section.

\begin{verbatim}

dependencies:
  required:
    php: ^5.3 || ^7
    pear:
      pear.horde.org/Horde_Date: ^2
      pear.horde.org/Horde_Exception: ^2
      pear.horde.org/Horde_Support: ^2
      pear.horde.org/Horde_Util: ^2
  optional:
    pear:
      pear.horde.org/Horde_Autoloader: ^2
      pear.horde.org/Horde_Cache: ^2
      pear.horde.org/Horde_Log: ^2
      pear.horde.org/Horde_Test: ^2.1
    ext:
      mysql: '*'
      mysqli: '*'
      oci8: '*'
      PDO: '*'
  dev:
    composer:
      horde/test: '*'
\end{verbatim}

\section{ Additions for transitioning to composer based installs}
optional top level key "autoload", inspired by corresponding composer.yml structure\newline
It hints how autoloaders should expect to find php classes from the package.

Structure:\newline
autoload: psr-0: list of "Class\_Prefix" : "dir"\newline
autoload: psr-4: list of "\\\\Prefix" : "dir"

autoload: classmap: list of directories to recursively scan for php files containing classes

\begin{verbatim}

autoload:
  classmap: ['lib/']
\end{verbatim}

The default if absent would be autosensing.

If the directory has a /lib/ dir, it will derive a PSR-0 rule from the package name.\newline
If the directory has a /src/ dir, it will derive a PSR-4 rule from the package name.

If an autoload-dev section is present in the .horde.yml file, it will work exactly like the autoload section.

If a test dir is present, a PSR-4 rule will be generated from the package name, appending "\\Test\\" to the namespace

\begin{verbatim}

    "autoload": {
        "psr-0": {
            "Horde_Http": "lib/"
        },
        "psr-4": {
            "Horde\\Http\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Horde\\Http\\Test\\": "test/"
        }
    }
\end{verbatim}

\subsection{ Composer native dependency definitions}
Example: https://github.com/maintaina-com/Dav/commit/71dd9714a8d49c28b5cfe1b0bcd089eb6fa93226\footnote{https://github.com/maintaina-com/Dav/commit/71dd9714a8d49c28b5cfe1b0bcd089eb6fa93226}\newline
components version: https://github.com/maintaina-com/components/commit/3ffe6013081287bb02260e2d55291f98b93f6e15\footnote{https://github.com/maintaina-com/components/commit/3ffe6013081287bb02260e2d55291f98b93f6e15}

It is now possible in horde.yml to define dependencies for the composer.json file which are not derived from pear dependencies.\newline
This allows unbundling composer libraries like sabre dav from wrapping horde libraries like horde/dav.\newline
New libraries which do not intend to support pear installations at all could easily just define their dependencies here

\begin{verbatim}

dependencies:
  required:
    php: ^5.4.1 || ^7
    composer: 
        sabre/dav: ~2.0.0
\end{verbatim}

\subsection{ Composer vendor-bin}
By default, the composer.json writer will treat all executable files living directly under package/bin as vendor binaries.\newline
This can be overridden:\newline
commands: optional: List of paths relative to package root which should be offered as vendor binaries. If you provide commands, no automatic search in bin/ will happen.\newline
nocommands: optional: List of paths relative to package root which should not be offered as vendor binaries. nocommands wins over commands list or implicitly found bin/

\begin{verbatim}

nocommands:
  - 'bin/horde-bootstrap'
  - 'bin/foobar'
\end{verbatim}

\subsection{ Conflicts}
The conflicts: block in .horde.yml is optional. It is literally transformed into a "conflict:" block in composer.json. There are no "composer:" or "pear:" sub keys. This is different from requires: or optional: blocks.\newline
\begin{verbatim}

conflicts:
  horde/base: <= 5.9.9
  horde/horde: <= 5.9.9
\end{verbatim}

conflicts blocks are sometimes necessary to prevent versions from coexisting when constraints of already released packages were too liberal.

\subsection{ Provides}
The provides: block in .horde.yml is optional. It is literally transformed into a "provide:" block in composer.json. There are no "composer:" or "pear:" sub keys. This is different from requires: or optional: blocks.\newline
\begin{verbatim}

provides:
  horde/base: 6.1.1
  horde/user-management-api-implementation: 1.0
\end{verbatim}

This is useful if multiple packages provide a capability as packages can depend on these capabilities as if they were packages. It is also useful if one package changes name or is the successor to another package. Think ingo is the successor to forwards and vacation modules, imp 6 is the successor to dimp and mimp. Both turba and hermes may provide an addressbook/customer API.

\end{document}
