Seaside 2.8 Released!

Seaside

Seaside, my other favorite framework, released version 2.8 today. This release has been optimized and optimized some more, as it doubles the average page rendering speed, and now uses up to 4 times less memory. Plus it supports Gemstone, which is the feature that I'm most excited about playing with.

The official release page is here, and if you still haven't tried Squeak, a great new tutorial can be found here.

Congrats to the entire Squeak team on this one.

(Seriously though, who does a release on a Sunday? You guys are nuts.)

The Endless Parade of Firetrucks

I've been on vacation down in LA for the last week.

A couple of days ago, my friend James pointed to the horizon and said something along of lines of, "look at all of the smoke from the fires up North."

Well, I had no idea how bad things were until today, when I was driving back up I-5 and literally 10 minutes didn't go by where I didn't see a caravan of 5-10 firetrucks heading South. This was over the course of a 5 hour drive, so I figure that I saw about 200 firetrucks.

We also drove just East of the fires under two lines of helicopters, one that was flying in and dropping water on the blaze, and another that was returning to load up their water tanks again. The suburbs that we could see from the highway all had police cars stationed in front of them to keep people from trying to return to their homes.

It was more than a bit surreal.

Hopefully they get the fires out soon and everyone down there is safely evacuated.

Scary, scary stuff.

Unwind with Subversion

At the Codehaus and at JBoss.org, I’ve continually come across Subversion repositories that needed to be split apart or merged, perhaps after converting from CVS. One problem you continually hit, particularly if you’re merging repositories, is the “date order of revisions” bug. Simply stated, if you create a new repository loaded from two other repositories, you can end up with a situation where revision N does not necessarily occur before revision N+1, in terms of the commit time-stamp.

When you do a date-based operation using Subversion, it does a binary search through the revision sequence to find the revisions matching the specified dates. This binary search assumes the revisions are indeed date-ordered.

With the acquisition of Mobicents by JBoss, we’re in the situation of having to merge about a dozen repositories. Some are CVS, some are SVN. Good ol’ cvs2svn works well for the first step, of converting a CVS repository into a SVN repository. But now we have either oddly disjoint repositories, or conflicting paths overlaid one another.

I’ve always been a fan of mod_rewrite for Apache-httpd, and a SVN dumpfile has a lot of paths just ripe for rewriting. 1000 lines of Ruby code later, I’m able to announce Unwind. Unwind is a Ruby library, along with a command-line tool, for performing mind-numbing feats of repository surgery.

Since a massive conversion and rewriting is something that requires a bit of trial-and-error, the command-line utility is ultimately driven by a configuration file. Of course, with Ruby, it’s just a DSL created using instance_eval and blocks.

Picture 5.png

This configuration file will ultimate produce a single file (merged-repo.svndump) from multiple input dump files. Each source file can include()/exclude paths (based upon the original paths in that particular dumpfile). Each source can also use Rails-ish URL rewriting. The :something syntax matches 1 segment of a path, and is available as a substitution value in the output path for the rule.

The rewrite engine tracks all existing paths, and creates parent directories when necessary. SVN copy operations are fully adjusted both for the source and the destination paths.

Unwind automatically interleaves revisions to achieve total monotonically increasing time-ordering for the final repository.

Finally, before a revision is emitted to the output repository, addition include()/exclude() rules can be applied. For repositories converted from CVS, you may end up with a bundle of CVSROOT directories attempting to live in the same location. No reason to rewrite them to unique locations, as you can just exclude them before they get figured into the final output repository.

Unwind uses SQLite for organizing the meta-information about each repository and revision, while performing random-access seeks on the source dumpfiles to produce the final repository. While merging may be the common use-case, Unwind’s rewriting also makes it useful just for extracting bits out of a repository.

At this point, this blog entry is the complete documentation for Unwind. But feel free to browse the SVN repository.

Ruby NetBeans, Now With Haml and Better Rspec Support

Ever since I started writing Ruby code I've used Textmate as my editor. Recently, however, I've found myself using Netbeans more and more, to the point where I usually have Netbeans and Textmate open next to one another. Netbeans' refactoring support, ability to jump to method definitions, and ability to autocomplete code is just too good to ignore.

However, a couple of features have kept me from switching to Netbeans full time, namely its lack of Haml support and the fact that it couldn't run a focused Rspec example.

Well lo and behold, I just checked the Netbeans Ruby Recent Changes page and found the following:

  • October 12
    • Lots of bug fixes
    • RSpec module (not part of 6.0 but available in the continuous builds on deadlock)
      • TextMate RSpec snippets
      • "Run Focused Test" action which runs test under the caret. Locate the action in the Keybinding options (see the "Other" category) and bind to something convenient.
      • "Debug Focused Test", which starts the debugger on the test under the caret.
    • Preliminary support for HAML and SASS - see announcement

They solved both of my issues on the same day!

I did have to install the Haml plugin from here, but it looks like I no longer have a compelling reason not to switch to NetBeans fulltime.

And the obligatory screenshot:

Haml in NetBeans

Awesome!

Conventional Validations

As part of some other work I'm currently undertaking, I've just extracted a VERY new Rails plugin called, you guessed it, Conventional Validations.

As the README says, Conventional Validations is a plugin that attempts to apply validation based on the naming of column. Specifically, the plugin searches for validation methods such that a column named foo or ending in _foo would be validated using a method named validates_foo.

For example, by defining a class method as:

def self.validates_phone(*attr_names)
  validates_format_of attr_names, :with => /[0-9]+(\.[0-9]+)*/, :allow_nil => true 
end

Any columns named phone or ending in _phone would be automatically validated.

I've only just added it (it's only available in trunk) and the matching rules are VERY simplistic but if you have company-wide or even project-wide validation and you're strict about your naming conventions (as I am), consider extracting them into a module and mixing them into ActiveRecord::Base and letting the plugin apply them for you.

There are already some existing plugins such as (off the top of my head) "validates_email" that would most likely just work out of the box.

Enjoy.

Mint Programmers Need to Learn How to Do Math

A recent disturbing trend that I've noticed is that more and more programmers I run into seem to be really bad at math. At the very least, I'm starting to think that a few semesters of calculus in college wouldn't have hurt anyone.

Example 1:

Mint is a financial website that recently won first place at the Techcrunch 40 conference here in San Francisco. It aggregates your bank accounts and tells you how you can save money. While checking it out his evening I came across this, which, incidentally, is the same thing that it's been telling me since I signed up:

Savings!

Come on Mint, this is the core feature of your website. (I'm not counting the account sign in and aggregation piece, as they seem to contract with Yodlee to do that.) How hard is it to properly calculate the above value?

I hate it when a startup spends so long on design that they forget to write solid code. People aren't going to come back if you can't even get this right.

Furthermore, check out the account that they want me to switch over:

Account

Where did they even begin to pull these numbers from? They want me to switch an account with no money on it from a lower rate card to a higher rate card in order to save $278 a year.

At this point I've stopped thinking about math though, and starting thinking about all of the security holes that are probably in this site if they got something this fundamental wrong.

Unfortunately, there's no way in their interface to cancel my account. Wonderful:

Cancel

These just seem like basic, basic things to me. I don't even know how you say that you're in beta when things like this don't work.

Identity Matcher: Import social graphes

My favourite talk at the FOWA was Matt Biddulph talking about his experience with Dopplr which is a fantastic little service (and I was shown today that the colors change EVEN on the favicon.ico when you are in a different location!!!). Matt's talk was high level, but he managed to keep it interesting and it wasn't about pimping Dopplr. He also released identity matcher, a new open source project that allows you to import social graphs! Now we can all work together on this instead of reinventing the wheel: This code, extracted from the Rails codebase of dopplr.com, extends your User model with methods to pull in social network information from sites such as GMail, Twitter, Flickr, Facebook and any site supporting appropriate Microformats. This is an alpha-quality plugin. It was extracted from our codebase at the start of October 2007 and may still contain dopplr-specific code (although we tried to avoid that). The code is just one file with a few includes and you can now matches_identities in your Rails model. Of course, you can abstract out the Rails stuff and just have a library to do the matching. Very nice indeed. Now I just want the option to say "if someone shares their stuff with me on Dopplr, and they are friends with me via another service (e.g. Facebook, Twitter) just go ahead and share back automatically!" more on the FOWA.