Packaging A HotCocoa Application

01 February 2010
← Home

HotCocoa is a thin, idiomatic Ruby layer that sits above Cocoa and other frameworks. HotCocoa used to be included in MacRuby but is now managed as a separate gem. Developing a HotCocoa application with TextMate and Terminal is a lightweight and expressive alternative to using Xcode and Interface Builder and I encourage everyone to give it a shot. Now that HotCocoa is hosted on GitHub forking and sending pull requests is probably the easiest way for a lot of people to contribute to the MacRuby ecosystem.

Getting Started

Getting started with HotCocoa from the Terminal is a breeze:

  sudo macgem install hotcocoa
  hotcocoa demo
  cd demo
  macrake

These commands will install HotCocoa, create a skeleton demo application and launch the application, which should look something like this:

Distribution

Packaging up a HotCocoa app for distribution is also dead simple:

  macrake deploy

This task will copy the entire MacRuby Framework, including the HotCocoa gem, into the application bundle ready for download as a self-contained app.

When I was packaging up Stopwatch for download I decided to not include the standard library and cut down the size of the app from around 150MB to 30MB. This turned out to be harder than I expected. Rubygems is part of the standard library and since HotCocoa is now a gem I had to embed HotCocoa into the app without requiring Rubygems. Here are the two rake tasks that unpack HotCocoa and embed MacRuby in the application without the standard library:

  task :unpack do
    `macgem unpack hotcocoa` unless File.directory? "hotcocoa-0.5.1"
  end

  task :embed => [:clean, :unpack, :build] do
    `macruby_deploy --no-stdlib --embed "#{AppConfig.name}.app"`
  end

We also need to make sure HotCocoa is added to the application bundle by adding it to the sources in config/build.yml

  name: Stopwatch
  load: lib/application.rb
  version: "1.0"
  resources:
    - resources/**/*.*
  sources: 
    - lib/**/*.rb
    - hotcocoa*/lib/**/*.rb
  agent: true

And finally, require HotCocoa at the top of lib/application.rb

  require File.join(File.dirname(__FILE__), '..', 'hotcocoa-0.5.1', 'lib', 'hotcocoa')

So now embedding MacRuby & HotCocoa without the standard library is as simple as running:

  macrake embed

All zipped up the entire application is around 10MB.

Building

I also made a small modification to the HotCocoa application builder so that Stopwatch could run as an agent in the background. When I was trying to build my forked version of the HotCocoa gem I got this nasty error:

  macgem build hotcocoa.gemspec 
  ERROR:  While executing gem ... (IOError)
      not opened for reading
  not opened for reading (IOError)

A workaround for this is to use the MRI gem command for building and then macgem for installing:

  gem build hotcocoa.gemspec && sudo macgem install hotcocoa-0.5.1.gem
blog comments powered by Disqus