Imagine yourself and a posse of like-minded Ruby hackers on a country retreat with zero internet for a weekend of fun. You’ll laugh, hack, learn, cry (well, you probably wonâ€™t cryâ€¦ but you knowâ€¦ it felt poetic) and most likely play a crap-load of guitar hero. [manifesto]
In chronological order, the first RailsCamps in Australia were in the states: New South Wales, Victoria, New South Wales, and South Australia.
This time, between May 15th and 18th, it’s in Queensland. God’s Country. The Sunshine State. Home of Steve Irwin (deceased), Sir Joh Bjelke-Petersen (deceased), Greg Norman (expat), Keith Urban (expat), and Kristy Hinze (marrying ex-Silicon Graphics/ex-Netscape billionaire Jim Clark; expat). So its a pretty famous and popular place to come from.
Book your tickets now for RailsCamp #5.
Its almost Christmas time and that means presents.
It also means that sometime between today and December 25th you need to go out and buy other people some presents because you haven’t done it yet.
But there’s someone else special in your life that deserves an Xmas gift this year. That special someone is your open source projects.
You might think, “But, Dr Nic, what do I get for the open source project that already has everything? What gift would my open source projects possible appreciate?”
Its true – this year has been a boon for open source. You probably migrated your projects from SVN to Git this year. Specifically, you probably clicked the “create a new one” link on your GitHub home page a lot this year: either to migrate your old projects to github or start new ones. Lots of new ones.
And now that your code is on github, your README file is rendered beautifully on the home page, so you were more inclined to rename it to README.markdown or README.textile and thusforthly fill it full of education information about your projects.
More people would then instantaneously figure out what the f@#$ your project actually does, thus more people used it, thus more people wrote patches or forked your code and sent Pull Requests.
All round, in 2008, I bet your open source projects had a sweet year.
Nonetheless, it is Christmas time and you should now get them a present. Something they wouldn’t get for themselves. Something you wouldn’t have done for them except for the free loving spirit of Christmas.
The Gift for all Open Source projects
Oh sure, github renders your README.markdown file. Yeah, yeah, github gives you a wiki for your project. Sure, sure, Google Groups let you communicate with your co-developers and users. Certainly, you don’t need a website for your project.
That’s why its a Christmas gift. You’re going to do it because you care.
Websites sell your project. READMEs and Wikis educate. The project website will sell it and make people want to use your stuff.
A website could have a blog with an RSS/atom feed. Then you could post updates about your project. People could subscribe and also leave comments. Oh the novelty.
And if it only took 5 minutes to get all this setup – the website code, the blog engine, the RSS feed, the comments, and published to its own hosted server – then that would just be oh so sweet.
So we’re going to do some craft for our Xmas present. A little DIY project, if you will. You’ll need a few things that you’ll find around your house, a command-line interface, and a beer or perhaps some port or sherry. Christmas cake is good too.
And on the iPhone there is this nifty object called
UIWebView. Otherwise known as WebKit. Otherwise known as an embedded browser in your iPhone app.
And if you want a sexily awesome looking UI view, like the Today view of the Surf Report app (see right or free on AppStore) that was released on the AppStore recently, then the WebKit is just the best thing since the electric bread slicer for speed of development.
Holy grail of iPhone development?
Well, that’s what we thought. When I chatted with Dan Grigsby last week I mentioned there were good and bad things about the WebKit within an iPhone app.
This article is about good and bad things. The pros and cons. How we managed the integration of the two code-bases. And the answer to the big question: Would we do it again?
Its probably wonderfully useful stuff to know.
The New Gem Generator (newgem) was exciting, moderately revolutionary, and definitely helpful two years ago when I created it. Of late it seems to attract a chunk of criticism:
- making a new gem, but newgem seems broken… hoe hoe
- NewGem has the “hoe” virus. Much prefer Mr. Bones.
- the newgem site is begging for someone to put the word fuck on its front page
- Almost two days fighting with newgem, but today i won! The secret is hoe 1.7.0 and rubygem 1.2.0.
- unfortunately for the one project I went with newgem, will give Mr. Bones a try on the next gem I throw out there.
- sow or newgem, neither, Mr. Bones
- egads, the website newgem sets up for you looks awful
- newgem seems to be failed to generate package if AUTHOR is an array of authors.
On the positive side of the spectrum is the following list:
- newgem? really? you rock drnic!
Comparatively, the two lists are awfully different in length. And not in a good way. No, not at all.
I know about these criticisms and platitude(s) because they appear publicly on newgem’s website within a live Twitter search of ‘newgem’. So that the twitter messages on the project’s own homepage are more positive, it was time for a new direction. A new beginning. It was time for a change.
So I fixed it. All of it. As of release 1.0.3 it is perfect .
To help you realise how wonderful newgem now is, I shall use the time-proven medium for proving awesomeness: a list. The bullet points are for free.
- newgem now finally gone 1.0.0. It made it all the way to 0.29.0, but I think 1.0.0 was needed to transfer the message of a new beginning. This is the Obama of Gem Generators.
- Generated gems are 50% smaller. No more config/hoe.rb. No more website folder (by default). No more tasks folder. No more license file. No more version.rb file.
- Very little config required before releasing your gem. Just a few fields in the
- You can use rspec or test/unit for unit testing (option:
- You can use cucumber for functional testing (option:
-i cucumber or run
- Generated gems are future-proofed. They will automatically benefit from future newgem releases.
- Executable apps within gems now have a
lib/appname/cli.rb file for the code base, and a lightweight
-b appname or run
script/generate executable appname)
- Your README file can be called
README.rdoc so it appears nicely formatted on github. No more hoe warning messages about “README.txt is missing” (see feature)
- GitHub RubyGem support.
rake gemspec generates a clean
my_project.gemspec file that will work with GitHub
- RubyForge support. As before,
rake release VERSION=X.Y.Z releases your project to RubyForge (see ‘preparing for releases to rubyforge’ help page)
- newgem’s website is a different colour. Its a nice peppermint green colour. The default website template is now this theme too.
- You can raise bugs or suggest improvements via Lighthouse tracker
sudo gem install newgem
To create your RubyGem scaffold:
newgem mygem -b myapp # create a CLI executable
newgem mygem -T rspec -i cucumber # use rspec and cucumber for gem tests
newgem mygem -w # create a simple website
newgem -h # get help
Now your code goes in
lib folder, and your tests go in
features as appropriate.
There are a bunch of rails-esque generators (like
migration) that you can use to help your development:
script/generate executable myapp # create your own command-line interface (CLI)
script/generate extconf mylib # starting point for C-extensions, plus TDD framework
script/generate component_generator mygenerator scope # create your own generators for Rails, Merb, RubyGems
script/generate application_generator myapp # create a CLI that is a generator for something
script/generate -h # get help
Bugs and suggestions
You can raise bugs or suggest improvements via Lighthouse tracker
Thanks goes to… Cucumber
Aside from several days of my time refactoring it, reducing it, and doubling the amount of awesomeness within it, all its wondefulness is thanks to Cucumber.
Cucumber is the successor to Rspec Story Runner. I never found time to play with Story Runner, but Cucumber is blowing my mind with awesomeness. My attention-span is short so I may be forgetting something but I think Cucumber could be the most important piece of software released in 2008 for Ruby-based developers.
Cucumber gave me a framework to specify newgem’s expected behaviour; its features. First I wrote feature descriptions for known, expected behaviour. Then I refactored the crap out of newgem until it was in tip-top shape.
There are over 90 feature steps defining newgem’s current features. To run them:
gem unpack newgem
sudo gem install cucumber
And watch the awesomeness of Cucumber unfold before your eyes. What you are seeing isn’t just newgem’s generators being executed, but also the generated code is being executed, rake tasks executed, and generated test files tested.
I can now setup continuous integration for newgem. I have a framework to know that newgem, or any other RubyGem, is doing what it should do.
UPDATE: I want to thank David Chelimsky for our time hanging out in Brazil during RailsSummit. I saw him using Cucumber, and talking about it on stage and then help helped me whilst I integrated it into newgem as a generator and then using it internally itself. For a day and a half we hung out in the hotel foyer. He’s so wonderful.
Cucumber makes me so happy.
Use newgem. Write gems.
Use mrbones. Write gems.
Use sow. Write gems.
Use gemhub. Write gems.
And write cucumber feature descriptions first. Then unit tests. Then code. Then release. Then profit.
 All claims of perfection are for the express purpose of making you try the product enough to use it, share it with your friends, and wrap it up and give it as a gift to family on Xmas day. Gift boxes are available upon request.
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
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 email@example.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.
Now, check that your sake tasks are installed:
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.
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
To install new tasks or reinstall modified tasks, just run the rake task (
rake install or
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.
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.