Tag: programming

Vimgrep and Vim Project

Chris Hartjes today was on a quest for a "find in project" feature for Vim. "Find in Project" was a feature of Textmate that he'd grown accustomed to and was having trouble finding an equivalent for.

The funny thing is that Textmate is a newcomer, and, of course, vim has had such a feature for years. The thing to remember with vim, of course, is its unix roots; typically if you know the unix command for doing something, you can find what you need in vim. In this case, the key is the vimgrep plugin, which ships in the standard vim distribution.

Continue reading...

git-svn Tip: don't use core.autocrlf

I've been playing around with Git in the past couple months, and have been really enjoying it. Paired with subversion, I get the best of all worlds — distributed source control when I want it (working on new features or trying out performance tuning), and non-distributed source control for my public commits.

Github suggests that when working with remote repositories, you turn on the autocrlf option, which ensures that changes in line endings do not get accounted for when pushing to and pulling from the remote repo. However, when working with git-svn, this actually causes issues. After turning this option on, I started getting the error "Delta source ended unexpectedly" from git-svn. After a bunch of aimless tinkering, I finally asked myself the questions, "When did this start happening?" and, "Have I changed anything with Git lately?" Once I'd backed out the config change, all started working again.

In summary: don't use git config --global core.autocrlf true when using git-svn.

Continue reading...

Server Upgrades... lost entries...

My good friend, Rob, hosts my site for me, in return for helping with server maintenance. After being on Gentoo for the past three years, though, we decided it was time to switch to something a little easier to maintain, so last night we wiped the system partitions and installed Ubuntu server.

I'll say this: the setup is much faster! However, we had a few gotchas that surprised us — it didn't setup our RAID array out-of-the-box, which led to a good hour of frustration as we tried to verify that the install wouldn't wipe it, and then to verify that we could re-assemble it. (We succeeded.) Additionally, we second-guessed a few things we shouldn't have, which led to needing to back out and reconfigure. But what was over a 12 hour install with Gentoo we accomplished in a matter of a few hours with Ubuntu server — so it was a huge success that way.

Unfortunately, our mysqldump of all databases… wasn't, a fact we discovered only after importing it into the new system. I ended up losing my blog database and PEAR channel database. Fortunately, the PEAR channel has not changed at all in the past year, so we had an old backup that worked, and I had a snapshot of my blog database from three weeks ago I was able to use. As a result, there are a few missing entries, but for the most part, all works. If you commented on one of those missing entries, my apologies.

Now that the install is done, I'm also finalizing some design changes to my blog — it's time to leave the black and white for more colorful grounds. Look for a revamp in the coming weeks!

Continue reading...

Submitting Bug Reports

Full disclosure: I am employed by Zend to program Zend Framework. That said, the following is all my opinion, and is based on my experiences with Zend Framework, as well as answering questions on a variety of mailing lists and with other OSS projects (PEAR, Solar, and Cgiapp in particular).

One of my biggest pet peeves in the OSS world is vague bug/issue reports and feature requests. I cannot count the number of times I've seen a report similar to the following:

<Feature X> doesn't work; you need to fix it now!

If such a report comes in on an issue tracker, it's invariably marked critical and high priority.

What bothers me about it? Simply this: it gives those responsible for maintaining Feature X absolutely no information to work on: what result they received, what was expected, or how exactly they were using the feature. The reviewer now has to go into one or more cycles with the reporter fishing for that information — wasting everyone's time and energy.

Only slightly better are these reports:

<Feature X> doesn't work — I keep getting <Result X> from it, which is incorrect.

At least this tells the reviewers what they reporter is receiving… but it doesn't tell them how they got there, or what they're expecting.

So, the following should be your mantra when reporting issues or making feature requests:

  • What is the minimum code necessary to reproduce the issue or show the desired API?
  • What is the expected result?
  • What is the actual result?

Continue reading...

Backwards Compatibility

Ivo already pointed this out, but I want to point it out again: Boy Baukema writes a very nice entry regarding backwards compatibility on the ibuildings.nl corporate blog.

Backwards compatibility (BC) is a tricky thing to support, even when you strive hard to, as Boy puts it, "think hard about your API" prior to release. Somebody will always come along and point out ways it could have been done better or ways it could be improved. I've had to wrestle with these issues a ton since joining the Zend Framework team, and while it often feels like the wrong thing to do to tell somebody, "too little, too late" when they have genuinely good feedback for you, its often in the best interest of the many users already using a component.

I had the pleasure of meeting Boy last year when visiting the ibuildings.nl offices, and he's got a good head on his shoulders. He does a nice job outlining the issues and a number of approaches to BC; if you develop a project for public consumption, you should definitely head over and read what he has to say.

Continue reading...

Apache HOSTNAME on Clusters

In an effort to debug issues on a cluster, I was trying to determine which machine on the cluster was causing the issue. My idea was that I could insert a header token identifying the server.

My first idea was to add the directive Header add X-Server-Ip "%{SERVER\_ADDR}e in my httpd.conf. However, due to the nature of our load balancer, Apache was somehow resolving this to the load balancer IP address on all machines of the cluster — which was really, really not useful.

I finally stumbled on a good solution, however: you can set environment variables in apachectl, and then pass them into the Apache environment using the PassEnv directive from mod_env; once that's done, you can use the environment variable anywhere.

In my apachectl, I added the line export HOSTNAME=\hostname`. Then, in myhttpd.conf, I added first the linePassEnv HOSTNAME, followed by the directiveHeader add X-Server-Name "%{HOSTNAME}e"`. Voilá! I now had the hostname in the header, which gave me the information I needed for debugging.

Continue reading...

2007 Retrospective

2007 was a busy year, both personally and professionally. I won't go into the personal too much, because, well, it's personal, and some of the details are simply inappropriate for blogging material.

Here's the short version:

  • One trip to Belgium and The Netherlands.
  • Two trips to Israel.
  • Two trips to Atlanta, GA (not counting the return trip from Europe, when I was stranded for a day due to storms in the Northeast).
  • Three different user groups attended, with three presentations.
  • One major Zend Framework release
  • One PEAR release.
  • One podcast.
  • One webinar.
  • One book published.
  • One conference attended.

What follows is my month-by-month breakdown:

Continue reading...


I was recently working with someone who was using Zend Framework in their project. To keep things stable and releasable, he was doing an export of framework into his repository and checking it in. Since files change so much in the ZF project currently, instead of doing an rsync from a checkout into his own repository, he decided instead to delete the directory from the repository and re-add it everytime he was updating framework.

This seemed really inefficient to me, especially considering that it made it incredibly difficult to merge changes from his development branch into his production branch (deleting and re-adding directories breaks the merge process considerably). I knew there had to be a better way.

I'd heard of the svn:externals property before, but never really played with it. As it turns out, it exists for just this very type of situation. The problem is that the documentation of svn:externals in the SVN book doesn't indicate at all how the property should be set, and most howto's I've read omit one or more very important details. I finally figured things out through some trial and error of my own, so I'm going to share the process so others hopefully can learn from the experience as well.

It's actually pretty easy. This assumes that your project layout looks something like this:

  • In the top of your project trunk, execute the following:

    $ svn propedit svn:externals .
  • This will open an editor session. In the file opened by your editor, each line indicates a different external svn repo to pull. The first segment of the line is the directory where you want the pull to exist. The last segment is the svn repo URL to pull. You can have an optional middle argument indicating the revision to use. Some examples:

    • Pull framework repo from head:

      framework http://framework.zend.com/svn/framework/trunk
      • Pull framework repo from revision 2616:
      framework -r2616 http://framework.zend.com/svn/framework/trunk
  • After saving and exiting, update the repo:

    $ svn up
  • Commit changes:

    $ svn commit

One thing to note: any directory you specify for an svn:externals checkout should not already exist in your repository. If it does, you will get an error like the following:

svn: Working copy 'sharedproject' locked
svn: run 'svn cleanup' to remove locks

I show using revisions above; you could also pin to tags by simply checkout the external repository from a given tag. Either way works well.

Then, when moving from one branch to another, or from the trunk to a branch, you simply set a different svn:externals for each branch. For instance, your current production might check from one particular revision, but your trunk might simply track head; you then simply determine what the current revision being used is on your trunk, and update svn:externals in your production branch when you're ready to push changes in.

Hope this helps some of you out there!

Continue reading...

Vim 7 code completion

I may work at Zend, but I've never been a fan of IDEs. They simply don't suit my programming style. I can usually keep track of file locations in my head pretty easily, and what I really need is a blank slate on which I can write, and one that doesn't consume resource that can better be used running web servers and other programs. Syntax highlighting, good indentation — these are important, but you can get these from good, minimal text editors very easily. Vim is my editor of choice.

I will admit, though, that one area where I have had IDE-envy is the area of code completion. I often find myself doing quick lookups to php.net or perldoc to determine the order of arguments to a function or method call, or checking for the expected return value. Most of the time, this doesn't take much time, however, so I just live with it.

Today, however, cruising through the blogosphere, I came across an article showcasing some new features of Vim 7.0, and discovered Vim 7's code completion.

Basically, while in insert mode, you can type <C-x> <C-o> to have vim attempt to autocomplete the current keyword. If more than one possibility exists, it shows a dropdown, and you can use your arrow keys to highlight the keyword that you wish to use.

But it gets better! Not only does it do this kind of autocompletion, but it also opens a small 'scratch preview' pane showing the function/method signature — i.e., the expected arguments and return value!

I thought I had little need for IDEs before… now I have even less! Bram and the rest of the Vim team, my hat's off to you for more fine work!

Continue reading...

Serendipity upgrade

I upgraded Serendipity today, due to the recent announcement of the 1.0 release, as well as to combat some rampant issues with trackback spam.

I've been very happy with Serendipity so far; it just runs, and the default install gives just what you need to get a blog up and running, and nothing more; any extra functionality comes via plugins which you, the blogger, get to decide upon.

Additionally, it's incredibly easy to upgrade. Unpack the tarball, rsync it over your existing install (I rsync it, because I don't use 'serendipity' as my directory name), visit the admin, boom, you're done. I've upgraded several times, and never lost data, nor configuration settings.

My primary reason for the upgrade was, as noted earlier, to combat trackback spam. As of this morning, I had 15,000 pending trackbacks, none of which appeared to be valid (if any of them were, and you're not seeing yours, I'm very sorry; I deleted them en masse). These had accumulated in less than a month — that's an average of about one every 3 minutes.

Since upgrading, and using the Akismet service, I've received not a single spam trackback. Needless to say, I'm happy I performed the upgrade!

If you're a Serendipity user, and haven't upgraded to 1.0.0 yet (or one of it's reportedly very stable release candidates), do it today — you have nothing to lose, and a lot of lost time to gain!

Continue reading...