My attempt at sake task management
I’ve used sake intermittently in my workflow. It competes against me writing helper/admin scripts in my ~/ruby/bin folder. Normally, executable Ruby scripts have won. But I think I have a new solution that could make sake a permanent winner for me.
Ruby scripts are easy to create and execute. You just open new file, change the TextMate grammar to ‘Ruby’, type ‘rb’ and press TAB and you’re off and running (the ‘rb’ snippet generates #!/usr/bin/env ruby or a variation of that). You then make the file executable and BAM! you can run the script from any folder in your environment.
Sake tasks are more annoying to write. After creating a new file, you need to create the namespace and task wrappers for your functionality, such as:
namespace 'foo' do
namespace 'bar' do
desc "This task ..."
task :baz do
end
end
end
Your task isn’t instantly executable either. After each change, you need to uninstall the task (sake -u foo:bar:baz) and then reinstall the sake file (sake -i foo/bar/baz.sake) and then run it (sake foo:bar:baz). Perhaps there’s a way to inline edit a sake task, but I can’t see it from the help options.
But once you’ve got your script installed in sake, you get all the wonders that sake provides: a named list (with summary) of tasks (sake -T) and the ability to run those tasks anywhere. Ok, that’s really only one advantage over standard Ruby scripts. But I like it. Oh, namespacing. The baz task exists in a namespace foo:bar. That’s nice too.
So to make me happy, I need a solution to the dubious “create-install-execute” process above. I also want the raw source for all my sake tasks in one place so I can fix/add/change them, reinstall them and move on with my life. I want simple.
So I’ve forked Chris Wanstrath’s empty sake-tasks repo (mine) and added some infrastructure for managing sake tasks. Of course the repo itself is the repository for my sake tasks (which includes a lot from Luke Melia), but most importantly it has a single rake task to reinstall all the tasks without any manual fuss.
The rest of this article assumes you want to have your own repository for your own sake tasks hosted on github. This paragraph is probably unnecessary, but I don’t want to be accused of not being mildly thorough.
Fork the sake-tasks repo
For thoroughness and a chance to demonstrate some gold-medal git-fu, I’ll show two ways: fork my repo and forking the original repo from Chris and pulling my stuff into yours. It’s git, it’s distributed, you can do anything.
If you want to fork my repo and skip a nifty git lesson, go to my sake-tasks repo and click “fork”. Then follow the clone instructions as you normally do when you are blatantly, systematically duplicating someone else’s hard work, using a command that will look something like:
git clone git@github.com:your-github-username/sake-tasks.git
Now, lazy man, you can skip to the next step.
If you want to flex your git-fu, then go and fork Chris’ repo instead. Again, follow the clone instructions.

Now take a moment to reflect on just how empty your repository is. A fine moment in open-source where you’ve essentially cloned an empty repository. Hardly worth the effort, but since Chris is a creator of github then if he creates an empty repository then who am I to disagree. Empty it shall start.
Now let’s pull in the code and tasks from my repo. My repo could be any git repo anywhere on the tubes.
One way you could pull my code into your local repository is to add my repo as a remote and then pull in the goodness:
git remote add drnic git://github.com/drnic/sake-tasks.git git pull drnic master
This is useful if you ever plan on re-pulling from a target repo again in the future.
If you just want to pull from someone’s repo one time only, then you can merge these two lines together:
git pull git://github.com/drnic/sake-tasks.git master
If you get occasional pull requests for your projects, then the latter option is handy to know.
Your local repo is now different to your remote repo (your fork on github) so push it back to your remote:
git push origin master
Installing the sake tasks
I originally created my sake-tasks fork so I could store a git:manpages:install task. I’ve just upgraded to git 1.6 (note to self: I want an ‘upgrade to latest git version via src’ task; UPDATE the repository now includes a git:src:install task to do this) and found some instructions for installing the pre-built manpages. Then I got over excited and refactored all of Luke Melia’s git+mysql+ssh tasks in to my repo so it looked like I’d done a lot of work.
To install all the tasks, first install sake:
sudo gem install sake
Then run the install task (check below for the list of tasks to be installed):
WARNING: This will uninstall any tasks you already have by the same name.
rake install
Now, check that your sake tasks are installed:
sake -T
Gives you:
sake git:analyze:commits:flog_frequent # Flog the most commonly revised files in the git history sake git:close # Delete the current branch and switch back to master sake git:manpages:install # Install man pages for current git version sake git:open # Create a new branch off master sake git:pull # Pull new commits from the repository sake git:push # Push all changes to the repository sake git:status # Show the current status of the checkout sake git:topic # Create a new topic branch sake git:update # Pull new commits from the repository sake mysql:dump # Dump the database to FILE (depends on mysql:params) sake mysql:load # Load the database from FILE (depends on mysql:params) sake ssh:install_public_key # Install your public key on a remote server.
Sexy.
Adding new recipes/tasks
The installer rake task rake install works by assuming that each .sake file contains one sake task. This allows the rake task to uninstall the tasks from sake first, and then re-install it (sake barfs if you attempt to reinstall an existing task). Without the one-task-per-file rule, the solution would be to load all the sake tasks as rake tasks into memory. But I like one-task-per-file; it seems clean.
So, to create a task foo:bar:baz, you’ll need to add a folder foo/bar and create a file baz.sake inside it. Within that file you would then specify your task using namespace and task method calls:
namespace 'foo' do
namespace 'bar' do
desc "This task ..."
task :baz do
end
end
end
To install new tasks or reinstall modified tasks, just run the rake task (rake install or rake).
TextMate users
The latest Ruby.tmbundle on github includes a task command that generates the above namespace/task snippet based on the path + file name. That is, inside the foo/bar/baz.sake file, make sure your grammar is ‘Ruby’ or ‘Ruby on Rails’ and then type “task” and press TAB. The above snippet will be generated ready for you to specify your task.
Summary
So now I have a single place for all my original sake source and a simple rake task to re-install the tasks if I add or modify them. And because its all in one git repo, if other people fork it and add their own tasks then I can steal them.
Unit Testing iPhone apps with Ruby: rbiphonetest

Everything to love about Ruby: the concise, powerful language; the sexy testing frameworks; and finally, the people.
Everything to love about Objective-C: hmmm; well…; and finally, its the only high-level language you can use to write iPhone apps.
On iPhone 2.0, to arrive on the 11th of July, you cannot run RubyCocoa. But you can run it on your Mac, so let’s use it to unit test your Objective-C classes. This tutorial shows you how to get started using a new project rbiphonetest [GitHub | Lighthouse | Google Group]
If you followed some of my recent tweets, this project was previously called “iphoneruby”. And alas, the screencast also calls it “iphoneruby” but that was a crap name. People thought it was a way to run Ruby on the iphone. I can’t do that yet. So, a far better name is ‘rbiphonetest’. [track on summize]
Even if you’ve never touched Objective-C, Cocoa, the iPhone SDK, nor RubyCocoa I recommend watching the video anyway. It should give you hope that if you make the transition to iPhone development you don’t have to go alone without Ruby: your trusty swiss army knife of language/libraries/tools.
The screencast is also available in high-def video (55Mb QuickTime)
Unit Testing iPhone apps using Ruby from Dr Nic on Vimeo.
Installation and Usage
To summarize the video, but change ‘iphoneruby’ to ‘rbiphonetest’, you install the framework via RubyGems:
sudo gem install rbiphonetest
Then change to your project’s folder and install the test framework:
rbiphonetest .
Finally, for each generic, non-UIKit-framework-using class you want to test:
script/generate model WidgetModel
Then write your tests in test/test_widget_model.rb
Supported Cocoa & iPhone frameworks
The mysterious, magical premise upon which rbiphonetest depends is possibly erroneous: that your Objective-C class can be compiled and tested against your OS X/Intel frameworks, and if your tests pass you assume you can then compile and include your class with the the iPhone/ARM frameworks.
I’m willing to go with this assumption until its proven dangerously flawed by some angry 20-year veteran of NextStep/Cocoa/iPhone. But really, how different could NSString be on the iPhone versus your Mac?
Fortunately there is one way to check for significant differences between your available Mac-based frameworks, such as Cocoa, and the iPhone-based frameworks, such as UIKit. We need to compare the framework names, header files and method signatures.
So for example, you cannot currently unit test any class that depends on/includes the UIKit framework. Why? It doesn’t exist on your Mac, so the Mac/Intel compiler cannot link it in. We’re compiling and running our tests with RubyCocoa, which itself is built against the Mac/Intel frameworks, not the iPhone frameworks. Hell, Laurent doesn’t even own an iPhone
[Laurent is the Apple-employee maintainer of RubyCocoa and the newer MacRuby]
Similarly, its no use including/linking the Cocoa framework into your Objective-C class. Why? It doesn’t exist on the iPhone. It has its own UI frameworks, collectively called ‘UIKit’.
So for the moment we cannot test UI-related, iPhone-API-specific code. But we can test generic Objective-C. That’s better than a kick in the teeth. Surely. I mean, in the teeth… that’d friggin’ hurt.
“Fair enough Dr Nic, so which frameworks can my code use and yet still unit test it with your oh-so-special test library thingy?” Keep your pants on, I’m getting there. [ref]
To the best of my ability, I’ve compared the two sets of frameworks and listed the available Frameworks that are available on both the iPhone and your Mac. There are about a dozen. The most important is called ‘Foundation’. It holds gold nuggets like ‘NSString’.
The list of platform differences is on the wiki as a reference.
Note, this list doesn’t guarantee that any two framework classes - the iPhone and matching Mac framework - will behave the same. This list is compiled by finding the set of Frameworks with the same name on both platforms, e.g. Foundation.
Then it compares the set of public header files (Foundation.framework/Headers/*.h files) This comparison is by method signature. It pulls all lines from each header that start with + or - (+ is a class method and - is an instance method in Objective-C) and compares the two lists. If there is a single difference in the method signatures of the header files in the two platforms it is marked on the wiki page. You’ll need to look at the two header files yourself to see the differences. Some header files are ugly. C-based anything starts ugly and goes down from there, I think.
Python testing of iPhone Objective-C?
In the Python world there is PyObjC, a bridge-based twin to RubyCocoa. If you are a Python developer you could easily port this project to use PyObjC I would think. Ping me if you are attempting this and need any help.
Summary
I think this project can give Ruby developers a happy place to work from as they write their Objective-C/iPhone code. You still need to wire up your UI views and controller classes manually, but if you push all the “oooh that code really needs some tests” classes away from the UI-dependent frameworks then you can hook it up to rbiphonetest and write your tests in Ruby.
Currently the generator creates test/unit test stubs. I personally then add the Shoulda gem into my test_helper.rb for my apps. If an rspec and/or test/spec developer can help with adding support to the generators I’m certain the large rspec user-base would be happy campers.
Similarly, someone might like to investigate using MacRuby to run the tests instead of RubyCocoa. Fast tests vs slow tests. You choose.
What the?
Sometimes I re-read what I’ve written and notice things that don’t seem to make sense, but are in my vocabulary nonetheless. Yep, the things you learn living in Australia.
“Keep your pants on” - this seems to imply that until I mentioned otherwise you were about to take your pants off. Hardly relevant at any stage during this article, we’d both agree. Most code-based blog articles are “pants on”. This phrase means “don’t get upset”. You can try to figure out how you go from “don’t get upset” to “keep your pants on”. I have no idea.
Composite Primary Keys goes 1.0.0 for Rails 2.1
Two years ago Dave Thomas did a keynote at the first RailsConf in 2006 and outlined a few things missing in Rails. One was the seeming unnecessary un-DRYness of duplicating associations and validations in Active Record models since the same information is in the DB schema. Another was support for Composite Primary Keys on Active Record models.
A few weeks later I created my first RubyGems as an attempt to solve these problems: Dr Nic’s Magic Models and Composite Primary Keys. The former was funny and an entertaining way to use const_missing? and Class.new. The latter was not funny. It started at the heights of “mildly entertaining,” dropped down from there and then over the subsequent months it never again rose above the humour-scale heights of “please shoot me in the foot.”
There were entire months that I hated ever having created the Composite Primary Keys project
Why? It sits precariously atop of ActiveRecord::Base, and a half dozen other ActiveRecord classes. It overrides methods, recreates entire blocks of SQL, and must work on all the different database adapters. That is, it is very sensitive to many changes in edge Rails. And refactoring ActiveRecord is a favourite pastime of the Rails Core team.
Unlike the Magic Models project which is perfectly useful for party tricks but probably partially pointless elsewhere, the CPK project just seemed to be so damned useful to some people.
Many people kept using it, several people contributed patches for adapter support and new features, and finally the Prophet arrived. The man that would lead the faithful forward to the Promised Land.
His name is Darrin “Champion” Holst.
Today, CPK was given the golden release number 1.0.0 and officially supports Rails 2.1 (but no longer supports 2.0.2 afaik).
CPK users might remember that we went 0.9.90 back in January, and its now June. This led Darrin to comment in his release email to the mailing list:
I’d like to name this release the “we’re running out of 0.9.x numbers, so it has to go to 1.0 sooner or later” release.
Maintaining CPK is like being on the team that paints the Sydney Harbour Bridge - it takes then 12 mths to paint it from one end to the other, which is just in time to restart painting the bloody thing again.
So in every way that I (tried to) abandon the project, I am proud of Darrin for looking after it and all its users.
TextMate bundles for Merb
If you are using TextMate (OS X) or E Text Editor (Windows) then you’ll be dead keen to know there is a TextMate bundle for Merb, and another one for Datamapper.
[This is cross-posted on the new Merbunity community site for Merb]
Currently, you can access the bundles via git:
cd "~/Library/Application Support/TextMate/Bundles" git clone git://github.com/drnic/datamapper-tmbundle.git Datamapper.tmbundle git clone git://github.com/drnic/merb-tmbundle.git Merb.tmbundle
Now “Reload Bundles” or restart TextMate.
You can now select from three Merb syntax/scopes. Press Shift+Alt+Cmd+M to see the options (below)
- If you select Merb (Datamapper) you will have access to the Merb bundle AND the Datamapper bundle.
- If you select Merb (ActiveRecord) you have access to the Merb bundle AND the Ruby on Rails bundle.
- If you select Merb (Sequel) then nothing special happens as there isn’t a Sequel bundle yet. Want to create one?
Currently there is no separation in the Rails bundle for ActiveRecord and non-ActiveRecord snippets and commands, so if you use Merb (ActiveRecord) there will be some snippets + commands that you don’t want from Rails. In future, there may be more separation to help the Merb bundle. Also, TextMate 2 may help this cause.
As always, to learn what snippets are available at any given cursor position, use Ctrl+Cmd+T.
If you have new snippets for any of the bundles, I suggest forking the git repositories, pushing up the changes to github and sending Pull Requests to me (drnic).
Sponsored by Engine Yard
The initial development of this bundle was sponsored by Engine Yard because they care.
Rails bundle
There is also the hughly popular Ruby on Rails bundle for TextMate that you can use. Download from http://railsbundle.com/ or via github.
If you want to learn everything about the new Ruby on Rails bundle for TextMate and daily life with TextMate (short cuts, editing bundles) then I highly recommend the new TextMate for Rails 2 Peepcode:
This recommendation comes from inside information on the quality of the Peepcode… it was written by me, and incorporates the vocal skills of the operatic Geoffrey Grosenbach.
GitHub Badge for your Blog with 100% guarantee of more coolness
The killer app for JavaScript in the 90s was to take a perfectly readable sequence of words - aka “a sentence” - and turn every single character a different colour. You did that, then you went back to doing normal work.
The killer app for JavaScript in the 00s is widgets/badges. Taking perfectly useful stuff from one website - aka “data” - and re-posting it on your blog sidebar.
In both circumstances, across two decades, you did this to look cool. Sure, it never works but you do it anyway.
Thusly, riding high on the world-dominating success of GitHub there seems to be a vacancy in the department of “JavaScript badge for my blog to make me look cool” projects, in the sub-category of “GitHub”.
The first entrant and thus market leader of the “Blog Badges for GitHub” micro-industry is the “GitHub Badge” It is beautifully demonstrated in static image form above, or if you click the image through to the website (or here to my blog and its aesthetically appealing enhancement with said GitHub Badge) you’ll see it live and interactive.
Touch it. Feel it. Press the “Show more” link for hours of entertainment.
Installation
Then get it for yourself. Read the GitHub Badge website or just…
Slap the following into your blog sidebar:
<div id="github-badge"></div> <script type="text/javascript" charset="utf-8"> GITHUB_USERNAME="drnic"; GITHUB_LIST_LENGTH=10; GITHUB_HEAD="div"; // e.g. change to "h2" for wordpress sidebars </script> <script src="http://drnicjavascript.rubyforge.org/github_badge/dist/github-badge-launcher.js" type="text/javascript"></script>
Only GITHUB_USERNAME is a required pre-set variable. The others above show the defaults, and can be changed by being specified.
For my WordPress sidebar, which uses <li> and <h2> for sections and headers, I use the following:
<li id="github-badge"></li> <script type="text/javascript" charset="utf-8"> GITHUB_USERNAME="drnic"; GITHUB_HEAD="h2"; </script> <script src="http://drnicjavascript.rubyforge.org/github_badge/dist/github-badge-launcher.js" type="text/javascript"></script>
Thus the badge is inserted in the <li> element, and the “My projects (drnic)” header is an <h2> instead of a <div>.
Source and tests on github
You can fetch the source from github - http://github.com/drnic/github_badges/tree/master - using:
git clone git://github.com/drnic/github_badges.git
You might want to add an option to turn off the auto-CSS generator so you can theme it yourself.
The JavaScript tests are in test/ folder. Either run them with rake test, or individually open the files in your browser.
Future cool things the badge could do…
Ultimately, when Chris Wanstrath (harass him on twitter) adds more fields and APIs to the GitHub API then the badge can do more. Currently it orders the projects in reverse order - that is, newest projects first. If I can get the network/watching counters then I can order the list using those values, etc.
Any other cool ideas for what the badge could do?
I’d like to be able to show project version numbers (e.g. gem version numbers) and other project meta-information. This would require GitHub to offer a CRUD UI for generic key/values and for the fields to be returned via their API.
If you know Chris and can throw heavy objects at him with moderate certainty of hitting him and not damaging any expensive equipment, please do so til he gives me this stuff.









