Last Modified 2007-01-10 by Jan Schneider

Horde 3 Development Guidelines

These guidelines apply right now to Horde itself, the framework packages, IMP, Ingo, Chora, Nag, Mnemo, and Kronolith - all of the applications that have FRAMEWORK_3 branches and were just released. They will apply, in the future, to any application released to work with Horde 3.0 in a FRAMEWORK_3 branch.

  • All applications that work with Horde 3.0 are tagged with H3 in their version numbers. This is for ease of identifying what Horde version you need to run a particular application. No more remembering that RELENG_3 of IMP goes with RELENG_1 of Turba and RELENG_2 of Horde. If you see H3 in the version string, you need Horde 3.x to run it. If you see H4, then you'll need a whole new (at this point completely theoretical) Horde 4.x install.
    • Avoid breaking backwards compatibility like the plague. If you need a change in an API, do it by introducing a new framework package. If that won't work, then we'll talk on the lists about what the change gets us and what the cost is. If it justifies making a move towards Horde 4.0 (which is the next version in which BC will be allowed to be broken), then we'll do it. But we want to keep developing with this set of APIs and apps as long as possible to polish them, making quicker feature releases, upgrading packages as needed.
    • All bugfixes /must/ be merged into the FRAMEWORK_3 branches. bugfixes will go into the point releases - Horde 3.0.1, IMP 4.0.1, Kronolith 2.1.1 (eventually), etc.
    • All new features get committed to HEAD (again, not breaking backwards compatibility). New releases will be minor version changes - IMP 4.1, Horde 3.1, etc. All of these releases should work with a base Horde 3.0 install, with the exception that if you only require newer versions of some framework packages, which are otherwise BC-compatible (only new features or bugfixes), that change is allowed.
    • Once we release a new minor version of an application, the FRAMEWORK_3 branch of that application will be updated to that release from HEAD (essentially re-branching by merging), and the point (bugfix) releases will still be made from the FRAMEWORK_3 branch. This is for consistency - the stable code that works with Horde 3 will always be in a FRAMEWORK_3 branch - and to avoid FRAMEWORK_3_0, FRAMEWORK_3_1, etc. as branch names, since that gets confusing as to what the version number is referring to.

Nothing here is set in stone; it's what's been worked out among the core developers for how we want to handle development. The core goals are to make Horde 3 a stable base for a long time, on which we can do frequent releases and speed up development of new features that don't require breaking backwards compatibility. Suggestions and comments are welcome.

Horde's Version Numbering

Text adapted from http://apr.apache.org/versioning.html.

Conventions: Libraries are the classes of the Horde Framework packages. Applications are the different Horde applications. Modules are libraries, application, and the Horde application itself. APIs are the class interfaces of the libraries and methods of the applications' public APIs.

This document covers how the Horde modules are versioned. Since the Horde modules provide APIs to other applications, it is very important to define a stable API for users of the modules. However, we also need to move the modules forward, technologically. To balance these two needs, a strict policy of versioning is required, which users can rely upon to understand the limitations, restrictions, and the changes that can occur from one release of a Horde module to the next.

The Basics

Versions are denoted using a standard triplet of integers: MAJOR.MINOR.PATCH. The basic intent is that MAJOR versions are incompatible, large-scale upgrades of the API. MINOR versions retain compatibility with older minor versions, and changes in the PATCH level are perfectly compatible, forwards and backwards.

It is important to note that an application that has not reached 1.0.0 is not subject to the guidelines described in this document. Before a 1.0 release (version 0.x.y), the API can and will be changing freely, without regard to the restrictions detailed below.


We define "compatible" to mean that an application can be used with other modules and will continue to function properly.

Applications that write against a particular version of another module will remain compatible against later versions, until the major number changes. However, if a application uses an API which has become available in a particular minor version, it (obviously) will no longer operate against previous minor versions.


Here are some examples to demonstrate the compatibility:

Original Version New Version Compatible?
2.2.3 2.2.4 Yes; Compatibility across patch versions is guaranteed.
2.2.3 2.2.1 Yes; Compatibility across patch versions is guaranteed.
2.2.3 2.3.1 Yes; Compatibility with later minor versions is guaranteed.
2.2.3 2.1.7 No; Compatibility with prior minor versions is not guaranteed.
2.2.3 3.0.0 No; Compatibility with different major versions is not guaranteed.
2.2.3 1.4.7 No; Compatibility with different major versions is not guaranteed.

Note: while some of the cells say "no", it is possible that the versions may be compatible, depending very precisely upon the particular APIs used by the applications.


This section details how we will build the code to meet the above requirements and guidelines.

Patch Version

To retain perfect compatibility, a patch release can only change function implementations. Changes to the API, to the signatures of public functions, or to the interpretation of function parameters is not allowed. Effectively, these releases are pure bug fix releases.

Minor Versions

Minor releases can introduce new functions and deprecate existing functions.

New functions

An application coded against an older minor release will still have all of its functions available with their original signatures. Once an application begins to use a new function, however, they will be unable to work against older minor versions.

It is tempting to say that introducing new functions might create incompatibility across minor releases. If an application takes advantage of an API that was introduced in version 2.3 of a module, then it is not going to work against version 2.2. However, we have stated that an application created against version 2.2 will continue to work for all 2.x releases. Thus, an application that states "requires 2.3 or later" is perfectly acceptable -- the administrator simply upgrades the installed prerequisite to 2.3. This is a safe operation and will not break any other application that was using the 2.2 version.

In other words, yes an incompatibility arises by mandating that a specific version needs to be installed. But in practice, this will not be a problem since upgrading to newer versions is always safe.

Replacing functions

This gets a bit trickier. The original function must remain available at the API level so that an application created against a minor version will continue to work with later minor versions. Further, if a application is designed to work with an earlier minor version, then we don't want to suddenly change the requirements for that application.

The new, alternate function can be made available in the API and applications can choose to use it (and become dependent upon the minor release where the function appears).

Deprecating functions

Since a function must remain available for applications coded against a previous minor release, it is only possible to "deprecate" a function. It cannot be removed from the APIs (so that compatibility is retained).

If you deprecate a function in a module, please mark it as such in the function documentation, using the phpdoc "@deprecated" tag. Deprecated functions can only be removed in major releases.

Finally, if you are deprecating a function so that you can change the name of the function, please use the method described above under "Replacing functions", so that projects which use a module can retain compatibility.

Note that all deprecated functions will be removed at the next major version bump.

Major Versions

Any kind of change can be made during a major version release. Particular types of changes that might occur:

  • remove (deprecated) functions
  • require newer PHP versions