Re: [RFC_v3] Handling Backwards Compatibility in PEAR

From: Date: Thu, 25 Sep 2003 01:38:26 +0000
Subject: Re: [RFC_v3] Handling Backwards Compatibility in PEAR
References: 1 2 3 4  Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-21954@lists.php.net to get a copy of this message
Hi, If a package requires a rewrite to take advantage of new language features, it should have a major version upgrade. If it simply adds one minor thing that doesn't affect API, it should simply add a dependency on the new PHP version - I think the current RFC handles situations like this. PHPUnit is a rewrite, so the major version should bump, and they did actually, since it was beta and < 1.0, API breaks are perfectly legal. Of course, I'd like to see PHPUnit 1.x not be installed by default with new PEAR installs when 1.0 stable comes out, maybe this also requires a new package? I'm not sure what the best solution is. Greg Matthias Nothhaft wrote:
Greg Beaver wrote:
I think it is enough to simply put on the package page: "This package is no longer supported. Use at your own risk. The current version of this package is found in Foo_v2"
Ok, but maybe you should add a "Note that Foo can be replaced by Foo_v2 some time!" to make clear what could happen.
when the lead(s) decide it is time to move on. In this way, there is no need to ever remove the package.
Great. Well, I remembered another BC issue: What about PHP5/6/7/8... -> language/syntax changes ? Take the PHPUnit package for example! Versioning: ----------- [...] Developers should also consider bumping the major version number if they make a major rewrite that maintains BC because there might be hidden BC breaks as follows: 1. changes in performance behavior 2. changes in code maturity 3. compatibility to user patches additional: 4. language/syntax changes in/for newer php versions Or is it already point 3? Or is it no BC break? Regards, Matthias I know people who still have to code
for their customers in PHP 3 - it will often be a while before someone stops using a package. Usually, only after the code that uses it needs some feature or discovers a bug that won't be fixed. If these users never encounter a bug, they might happily use the package for years, not caring there is a new-fangled version out there. Incidentally, I'm working on the code for revert right now. When that is complete, I will work on the code that detects Foo_vX and displays the error message "use pear install Foo_vX" as shown in the example. Regards, Greg Matthias Nothhaft wrote:
Looks *very* nice (now). I only miss a "rule" how it is handled if Foo is eventually replaced by Foo_v2 some time. This should only be done after a *long* period of time so that you don't get a new BC problem... After replacing Foo, maybe Foo_v2 should also remain for another period of time so that "Foo_v2-people" can change their code... Anyway, I hope this will get more than a RFC, now ;-) Regards, Matthias Greg Beaver wrote:
[RFC3] Handling Backwards Compatibility in PEAR Sept. 24, 2003 Greg Beaver , Lukas Smith Alexey Borzov, contributor [Announcing API Changes] The Problem: ------------ PEAR does not have a system in place to handle backwards compatibility issues. definitions: BC: "Backwards Compatibility" means programs that rely upon a package will still work when the package is upgraded. It is assumed that the programs using the package only use elements of the API, and do not use any private elements. This obviously means that new functionality may be added as long as it doesn’t interfere with existing functionality. API: "Application Program Interface" is the connection between a package and the programs that use it. This includes class and method names, parameters that are passed to methods, and constant names, or any other publicly accessible area of a program. Elements explicitly marked as private data/methods are excluded from this definition. The Solution: ------------ The API of a PEAR package may only break BC if: 1) The packages is in the preparation phase to a new major version number 2) A new major stable release is made It is up to the lead developers to determine whether BC needs to be broken. It is highly encouraged to carefully select the API before version 1.0 so that changes to the API that break BC will not be necessary. Versioning: ----------- The first stable release of a package is version 1.0. If a package breaks BC at all, the version shall bump to the next whole number, 2.0. Developers should also consider bumping the major version number if they make a major rewrite that maintains BC because there might be hidden BC breaks as follows: 1. changes in performance behavior 2. changes in code maturity 3. compatibility to user patches When the major version is bumped a new package is created with the same name and a postfix with the new major version number in order to make it possible to have two different major versions of a package in use within a single script. This also means that all classes, functions, globals and defines (everything that is accessible through the global namespace) need to get this postfix. The new package will however will continue in the version progress of its predecessor. The postfix format shall be _vX where X is the major version number. The PEAR directory naming conventions shall remain the same, but files in newer versions will follow this format: Foo.vX.php contains class Foo_vX Foo/vX/support.php contains class Foo_vX_support Version 1.x of the Foo package will have this structure Foo.php contains class Foo Foo/support.php contains class Foo_support This naming convention allows the packages to co-exist while the Foo package is deprecated: Foo.php Foo.vX.php Foo/support.php Foo/vX/support.php Example: ------- Lifecycle of package Foo 1) release Foo-0.1 - devel (initial version) 2) release Foo-0.2 - devel (BC break allowed) .. 3) release Foo-0.9a - alpha (BC break allowed - but discouraged) 4) release Foo-1.0b1 - beta (BC break allowed - but heavily discouraged) 5) release Foo-1.0 - stable (BC break allowed - but heavily discouraged) 6) release Foo-1.0.1 - stable (BC is not allowed) 7) release Foo-1.1.0 - stable (BC is not allowed) ... 8) release Foo-1.1dev1 - devel (BC is not allowed) 8) release Foo-1.1b1 - beta (BC is not allowed) 9) release Foo-1.1 - stable (BC is not allowed) .. 10) release Foo-1.2 - stable (BC is not allowed) 11) release Foo_v2-2.0dev1 - devel (BC is allowed) 12) release Foo_v2-2.0a1 - alpha (BC is allowed - but discouraged) 13) release Foo_v2-2.0b1 - beta (BC is allowed - but heavily discouraged) 14) release Foo_v2-2.0 - stable (BC is allowed - but heavily discouraged) 15) release Foo_v2-2.0.1 - stable (BC is not allowed) With release 11) Foo becomes deprecated in favor of Foo_v2 and only bug fix releases will be made that will not increase the major version number. Announcing API changes: ----------------------- If there is a need to remove a public or protected method, then 1) If it is possible to implement the same functionality in other methods then such functionality should be added and the method should be marked deprecated in major release. This means that the method can be removed in any of the following major releases. 2) If it is not possible to implement the same functionality or if the method is removed due to API simplification then the package should enter beta stage before the next major release. Reasoning: API breaks will not happen without due warning. If you do not use deprecated methods and the next major version comes out, you can safely upgrade to it. If the package you depend upon enters alpha/beta stage, then you should test for compatibility before upgrading. Complete API change: -------------------- If a package is stable, and is rewritten with a completely different API that may need to temporarily co-exist with the older version, then the following solution should be used: Imagine package Foo version 1.6 is the latest stable release of Foo. The next release with a complete API rewrite shall be package Foo_v2 version 2.0. At this point, package Foo will automatically be considered a deprecated package. Foo_v2 will be intended to eventually replace Foo in all installations, and all development of new features on Foo will freeze permanently. New development will continue in package Foo_v2. In addition, the name of all paths and classes shall change to reflect this. file Foo.php: <?php class Foo { } ?> becomes file Foo.v2.php: class Foo_v2 { } Here's a scenario that may illustrate the need for specifying 1 package is the main package: Package FOO version 1.7 is out, package FOO_v2 version 2.0 is released. You want to maintain both packages. Say you decide to rewrite a large portion of the core of FOO. This would then suggest you bump the major version to 2.0. Now we have FOO version 2.0, and FOO_v2 version 2.0. This is unacceptable ambiguity. Once FOO_v2 is released, all major development on FOO 1.x is frozen - only bugfixes and minor feature enhancements will be allowed. So, FOO 1.5 or FOO 1.99 or FOO 1.999 is allowed, but never FOO 2.0 if the FOO_v2 package exists - it is expected that people will switch their code to FOO_v2 if the FOO package doesn't do what is needed in its current form. Changes to the PEAR Installer: ------------------------------ The PEAR Installer will not install a version of a package with a major version number greater than the current major version without the --force option. If a newer minor version of the current major version exists, that will be installed. Example: Package Foo's latest versions are 1.7 and 2.0 $ pear install Foo-1.6 Foo version 1.6 installed successfully $ pear upgrade Foo Foo version 1.7 installed successfully $ pear upgrade Foo-2.0 version 2.0 does not exist of package Foo, use pear install Foo_v2 for version 2.0 of package Foo $ pear install Foo_v2 Install of Foo_v2 version 2.0 successful The PEAR Installer will also add the revert command, which will restore a previous installation $ pear install Foo-1.6 Foo version 1.6 installed successfully $ php -q usesFoo.php Mmmmmmm, Foo :) $ pear upgrade Foo Foo version 1.7 installed successfully $ php -q usesFoo.php Error: something didn't work right $ pear revert Foo Reverting to version 1.6 of Foo $ php -q usesFoo.php Mmmmmmm, Foo :) $ The same changes apply to the automatic upgrading of dependencies through the --alldeps and --onlyreqdeps command-line switches. Infractions: ------------ If a package is released that breaks BC and isn't a major version number increase, the PEAR Group may at their discretion remove the release and require it to be a new major version number. A public announcement as well as a personal email to the lead maintainer(s) of the package shall be sent explaining the reasoning.


« previous php.pear.dev (#21954) next »