Skip to content

What's wrong with composer and your .travis.yml?

I'm a huge advocate of CI and one service in particular called Travis-Ci.

Travis-CI runs a continuous integration platform for both open source and commercial products. In a nutshell: Travis-CI listens for a commit to a Github repository and runs your test suite. Simple as that, no Jenkins required.

At Imagine Easy we happily take advantage of both. :)

So what's wrong?

For some reason, every other open source project (and probably a lot of closed source projects), use Travis-CI wrong in a way, that it will eventually break your builds.

When exactly? Whenever Travis-CI promotes composer to be a first-class citizen on the platform and attempts to run composer install automatically for you.

There may be breakage, but there may also be slowdown because by then you may end up with not one, but two composer install runs before your tests actually run.

Here's what needs fixing

A lot of projects use composer like so:

language: php
before_script: composer install --dev
script: phpunit

Here's what you have to adjust

language: php
install: composer install --dev
script: phpunit

install vs. before_script

I had never seen the install target either. Not consciously at least. And since I don't do a lot of CI for Ruby projects, I wasn't exposed to it either. On a Ruby build, Travis-CI will automatically run bundler for you, using said install target.

order of execution

In a nutshell, here are the relevant targets and how the execute:

  1. before_install
  2. install
  3. before_script
  4. script

The future

The future is that Travis-CI will do the following:

  1. before_install will self-update the composer(.phar)
  2. install will run composer install
  3. There is also the rumour of a composer_opts (or similar) setting so you can provide something like --prefer-source to the install target, without having to add an install target

Fin

Is any of this your fault? I don't think so, since the documentation leaves a lot to be desired. Scanning it while writing this blog post, I can't find a mention of install target on the pages related to building PHP products.

Long story short: go update your configurations now! ;)

I've started with doctrine/cache and doctrine/dbal, and will make it a habit to send a PR each time I see a configuration which is not what it should be.

Wordpress and disqus and post loops

First off — I don't have too much experience with disqus on Wordpress but when I looked at the code(-quality), disqus is one of the best plugins for Wordpress to date. I looked only very briefly, but I found it to be very clean, well documented and well architected. Good job, disqus!

In case you happen to dive into Wordpress plugins in 2012, you will see that this is unfortunately not a given. Even (or maybe especially) the commercially available plugins to extend Wordpress are a source for PHP worst practices and contain all kinds of examples how not to write PHP. Part of it, is the platform, the rest is unexperienced developers or general lazyness.

Anyhow! Enough the rant!

Disqus and the loop

In Wordpress, almost everything is a loop. If you'd like to display a list of posts somewhere (for whatever reason), a loop is executed. The advantage (vs. a straight SQL query) range from all kinds all things like caching to convenience. When said hook is used different actions (plugin hooks) and filters are run. So even when the objective is to just collect data (and not even display it) — for example for an Ajax request/response — all these things happen in the back.

So in this case, whenever a loop is used, disqus will attempt to add their JavaScript to it. Usually, to display a comment form, counts and what not.

Problem?

The problem is, that the JavaScript code is then added all over and especially with Ajax you end up with the same code multiple times but add to that the cost of transport.

Solution!

Here's a simple workaround to prevent that.

Stick the following code into your template when you do not want the code to appear:

<?php
if (has_action('loop_end', 'dsq_loop_end')) {
    remove_action('loop_end', 'dsq_loop_end');
}

Yay! Happyness!

Fin

Filters and hooks are really what make Wordpress worth while. Period. In case you happen to do development for it, I urge you to take a look at them. I have a couple more ideas for small posts — stay tuned.

Contributing to PEAR: Taking over packages

One of the more frequent questions I see on the mailing lists and IRC is, "How do I take over a package?".

Very often people start to use a PEAR package and then at some point encounter either a bug or they miss a certain feature. The package's state however is inactive or flat unmaintained.

Offer help

The first step is to offer your help. And the easiest way to help is to report bugs or open feature requests.

A great bug report or feature request includes:

  1. Accurate problem description.
  2. A proposed solution.
  3. A patch (unified diff, aka diff -up or svn diff)
  4. A PHPUnit test case so this bug stays fixed.

I realize that these are a lot of requirements, but I also said a great bug report and no one said it was easy.

Getting fixes in

Often people persued these first steps and went the whole nine yards. But the bugs are still not fixed, the feature isn't implemented either and no release was pushed out.

How do you move forward now?

  1. Email the maintainer and cc [email protected].
  2. Ping PEAR QA again after reasonable period of time passed (e.g. 1 or 2 weeks tops)

If the package is generally unmaintained or the maintainer did not respond, PEAR QA will be happy to apply patches for you and do a new release. If the maintainer replied, work with them to get the issues fixed and a new release shipped.

Do you want to maintain?

To become the maintainer of any package we need to see your contributions first.

Contributions include:

  • patches for bugs and features
  • tests
  • bug reports
  • (maybe) helping people on the IRC channel

The fastest way to take over an orphaned package is to provide patches to any open issues so the QA team can push out a new release.

Contributing code is not just the preferred way but a hard requirement. It's the only viable way for others to assess your skills.

Another way to maintainership is of course when the current maintainer asked you if you want to contribute more since you showed them an interest through your work.

Find a package

Here's a list of currently unmaintained PEAR packages: http://pear.php.net/qa/packages_orphan.php.

Fin

I hope I summarized the process a little to make it more transparent. In the end it's pretty simple and straight forward to contribute to PEAR — and lots of people will be tankful for your contributions too.

A case for PEAR and PHP4 (Or, why BC is important!)

Every once in someone likes to argue that PEAR is all fugly PHP4 code and why you should not use it, and instead go and use another framework or component library. Most of those people also say that they looked at or used PEAR x years ago and then act all surprised when someone else disagrees.

In related (BC) news, most people probably read my blog because of Zend Framework, and I remember that one of the reasons I sold my clients on Zend Framework was a supposedly backward compatibility and clean API. Well, a couple years later one knows it's not all that and since another BC break was argued today on one of the mailing lists and the project lead said I spread fud, I felt l needed to write something on the topic.

Facts first.

A small history of PEAR.

I don't know how old exactly PEAR is, but the manual is copyrighted since 2001 and none of the other current frameworks have been around eight — almost nine — years.

Because PEAR has been around much longer, we also have more older code than any of those PHP5-only frameworks. In comparison, Zend Framework's first stable was release in June, 2007, almost six years later.

Major versus minor releases.

A package' version consists of x.y.z.

The rules are as follow:

  • A BC break (see below) — increment x, and set y and z to 0.
  • Adding a new feature — keep x, increment y and set z to 0.
  • Fixing a bug — keep x and y, but increment z.

When someone refers to a major release in PEAR's context (and a lot of other projects such as Zend Framework, Solar and ezComponents follow this), it's one with a change in x. :-)

What is backward compatibility?

Backward compatibility, or BC, describes that a component, package or library preserves compatibility with an older versions.

Because programming itself and developers tend to evolve, PEAR tries to keep BC in all minor versions, but allows you to break compatibility to an earlier version with a new major release.

The exception to the rule is that you may break BC during alpha and beta releases before the package reaches a stable 1.0.0. Once a 1.0.0 is reached, BC may not be broken — for whatever reason.

PHP4?

Because PEAR aims to provide BC all the way, BC includes the PHP version when the package was first released. Which in turn means that of course you may make the code compatible to a later PHP release, but not without breaking compatibility to the initial release.

If you followed the above, you understand the reason why for example there is a Mail_Queue and (a soon to be) Mail_Queue2, or more importantly: why the Mail_Queue release in 2009 is still compatible to PHP4. Even though PHP4 EOL'd a while ago.

The first Mail_Queue package was released in September of 2002, the 1.0.0 stable release followed in December of the same year. Because its 1.0.0 was compatible with PHP4, we keep it backwards compatible with PHP4 until we release Mail_Queue2-0.1.0.

A principal

A lot of people argue that with the official end of life of PHP4, one should break BC anyway. But here is why you should not.

  • Even though we all love to use PHP5, there is still a lot of PHP4 in the enterprise. And like it or not, many of those apps use PEAR, and not your funky PHP5 framework.

  • How do you keep so-called necessary and unnecessary BC breaks apart? From another point of you (which is not your own), there is always a necessary BC break to fix implement something else.

  • Because there is no such thing as small or acceptable BC breaks. There are BC breaks or there are none, it's one of those things that is black and white.

BC in other frameworks

I know for a fact that ezComponents is very strict on BC. I cannot comment on Solar or Symfony, but at least in Solar's case, I'm assuming that adhere to BC as well since a some former PEAR developers are active and they also follow the PEAR Coding Standard in many respects.

Zend Framework?

A friend of mine said that if Zend Framework really kept BC, we would at 10.0.0 and not on 1.9.3.

Reasons why Zend Framework likes to break BC, even though it advertises full BC:

  • No versioning per components but per framework.

  • Missing peer review and QA leads to unstable code in a so-called stable release. (Which in turn also fakes the stability of the entire framework since it suggests that a component that was added a couple weeks ago is as stable as a component added in 2007.)

  • Because it fixes an "issue". (Biggest WTF of them all.)

The issue in question, I'm not even sure what they were trying to fix. Supposedly some developers found it too hard or did not understand how to write an adapter for Zend_Db and someone committed a fix in the 1.9 tree/branch and apparently it was OK to break BC because it was the easier way out.

I haven't updated some projects since late 1.8.x because of these BC breaks because no one can tell me what the issue is and I don't have a day to debug my application to figure out where and how it breaks. This is annoying as hell, especially since they are supposed to be tailored to the business.

On a side-note, I know of a couple components (e.g. Zend_Session) which really deserve (!) a BC break and don't get one until 2.0. And I totally get why, but why is it OK in some cases? All BC breaks fix issues!

(Btw, as I finish this post, I see an email to zf-contributor@ in my inbox where someone considers pulling the 1.9.3 release (because it obviously breaks BC). Guess I didn't spread that much FUD after all.)

BEPHPUG: Debugging mit Eclipse und Xdebug

Mostly German content ahead!

Die Berliner PHP Usergroup trifft sich am 5. August, ab 20:30 Uhr, in der Z-Bar.

Thema: Debugging mit Eclipse und Xdebug (Vortragender: Marthin Rothenberger)

Adresse:


View Larger Map

Teilnahme: kostenlos

( In English: The next meetup of the Berlin PHP Usergroup will take place on the 5th August, 2009. We'll meet at Z-Bar, at around 8:30 PM. This meetup's topic is Debugging with Eclipse and Xdebug. Feel free to join. The admission is free! (Free, as in free Beer, or something)! )