Snarl Notifications for Cruise Control

At work, we use Cruise Control.NET for our continuous integration system. I’ve had Snarl running for some time now, and I thought it would be nice if the CCTray balloons popped up in Snarl instead of their own balloon provider. I added an extra provider and rebuilt it to work with Snarl.

As usual, this software comes with the “It works on my box” warranty… which is none whatsoever.

You can download the binaries here. If anyone wants the source, just ask. I’ve got it sitting in svn, but not zipped up or anything.

Enjoy.

Posted by Scott Thu, 18 Sep 2008 22:49:00 GMT


Fun With Extend in IronRuby

Building on the implements idea from the last post, I’ve been playing around with extending CLR objects on the fly as I bring them at runtime. I wrote a quickie load_assemblies method that checks objects to see if they implement an interface, and extend them if they do.

I think this pattern will be very useful when importing existing .NET objects into IronRuby. For instance, if you wanted all of the objects governed by your ORM to take on ActiveRecord-like behavior, you could catch them and extend them like this:

class Class
  def implements? interface
    !to_clr_type.nil? && !to_clr_type.get_interface(interface).nil?
  end
end

def load_assemblies(assemblies)
  assemblies.each do |assembly| 
    require assembly
    System::Reflection::Assembly.load(assembly).get_types.each do |t|
      if t.to_class.implements? "IPersistence"
        t.to_class.extend ActsAsActiveRecord 
      end
    end
  end
  true
end

I’m sure there’s lots of other cool uses for the pattern… If anyone actually reads this shit and thinks of some, let me know. :)

Posted by Scott Mon, 30 Jun 2008 20:17:00 GMT


I'm in love with IronRuby

I’ve been playing with IronRuby a lot lately, and it’s turning out to be every bit as amazing as I’d hoped it would be. I’m constantly thinking about new stuff to do with it, but one of the easiest low hanging fruits is rewriting our existing unit tests in ruby.

I’ve been putting together a little library of IronRuby specific modules for tests. You’ve got to love being able to do things like this:

class Class
  def should_implement(interface)
    !to_clr_type.nil? && !to_clr_type.get_interface(interface).nil?
  end
end

>>> MyClass.should_implement "ISomething"
=> true

Bringing the power of Ruby to .NET is going to be incredible. It feels great clicking both the Ruby and .NET tags on a post. More on this to come…

Posted by Scott Sat, 21 Jun 2008 17:08:00 GMT


Restful Routing with ASP MVC Preview 2

There is still very little documentation available for ASP MVC 2, and I had a bit of trouble finding out how to put HTTP method constraints on routes. After a bit of poking around I found out that the Method value was changed to httpMethod. I generally follow the convention that my controller is named the same as my resource. For instance, a resource named “Rates” would have a Rates controller. I use this little utility method to map the REST routes for the Rates resource.

public class GlobalApplication : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        MapResource(routes, "Rates");
    }

    protected void Application_Start(object sender, EventArgs e)
    {
        RegisterRoutes(RouteTable.Routes);
    }

    protected static void MapResource(RouteCollection routes, string resourceName)
    {

        routes.Add(new Route(resourceName, new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(
                new { controller = resourceName, action = "List" }),
            Constraints = new RouteValueDictionary(
                new { httpMethod = "GET" }),
        });

        routes.Add(new Route(resourceName, new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(
                new { controller = resourceName, action = "Create" }),
            Constraints = new RouteValueDictionary(
                new { httpMethod = "PUT" }),
        });

        routes.Add(new Route(resourceName + "/{id}", new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(
                new { controller = resourceName, action = "Read" }),
            Constraints = new RouteValueDictionary(
                new { httpMethod = "GET" }),
        });

        routes.Add(new Route(resourceName + "/{id}", new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(
                new { controller = resourceName, action = "Update" }),
            Constraints = new RouteValueDictionary(
                new { httpMethod = "POST" }),
        });

        routes.Add(new Route(resourceName + "/{id}", new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(
                new { controller = resourceName, action = "Delete" }),
            Constraints = new RouteValueDictionary(
                new { httpMethod = "DELETE" }),
        });
    }
}

It’s pretty basic, but it keeps your code DRY and saves time if you’re doing simple REST routes for a few different models.

Posted by Scott Tue, 15 Apr 2008 21:30:00 GMT