Wednesday, December 19, 2007

Generate Merb Plugins and Generators

As part of my effort to port over restful_authentication I'm at the point where I want to start making a merb plugin gem out of it. This will of course include some generators for merb and datamapper. Later I'll add the Active Record generators. This is super simple thanx to Rubigen

Just today I went to start and found the merb plugin generator wasn't able to generate generators. Now just to move on from that fairly circular sentence, a quick call to DrNic and he had it sorted pretty quickly. The end result is, that as of today, you'll need to install merb from trunk to follow this. That or wait until merb 0.5.0 is released officially.

Generate a Merb Plugin

Merb comes with an option to build the skeleton of a plugin inside the merb command.
$ merb -P merbful_authentication
create lib/merbful_authentication
create spec
create Rakefile
create README
create LICENSE
create TODO
create spec/spec_helper.rb
create spec/merbful_authentication_spec.rb
create lib/merbful_authentication.rb
create lib/merbful_authentication/merbtasks.rb
dependency install_rubigen_scripts
create script
create script/generate
create script/destroy
As you can see it's very simple to generate a merb plugin. You could call rake gem in that directory and it will build the gem for you automatically.

From here it's just like any other gem. When you add new files, be sure to add them to the gemspec in the Rakefile.

For the specific case of merbful_authentication, I want to have a generator that is available for all merb projects, and also generators with the relevant code for datamapper, activerecord, and sequel. This is a pretty important way to help support merb's ORM agnosticness.

Merb makes use of rubigen scopes. All merb projects have the merb scope and in your app when you select which orm to use via use_orm the ORM scope is selected automatically. The available scopes in a merb application at the moment are

  • merb

  • merb_default - (used when no orm is selected)

  • datamapper

  • sequel

  • activerecord

  • rspec

  • test_unit

The merb scope is available in all merb projects, with the others available as selected. By default the rspec library is the testing scope that is available.

How to Use Scopes?

When you make your generators, you should apply a scope to them. What this does is allows your gem to behave itself according to the configuration the user has setup. The way I'll setup the generators structure in merbful_authentication will be:

  • merb_generators
    • authentication_generator

  • datamapper_generators
    • authentication_model_generator

  • activerecord_generators
    • authentication_model_generator

  • rspec_generators
    • authentication_testing_generator

  • test_unit_generators
    • authentication_testing_generator

The final names that I end up with might be different, but this is the general structure I will use.

Why this is useful, is that the merb generators are always available, so we can always call the authentication generator in a merb app. This in turn will have a dependency on the authentication_model generator. This is where the magic happens. So if the app has:

Scope : datamapper
The authentication_model generator defined in datamapper_generators will be active and therefore used.

Scope : activerecord
The authentication_model generator defined in activerecord_generators will be active and used instead

This is the way merb generators support the different syntaxes of models and controllers when you use script/generate resource or similar. The testing frameworks will work the same way.

How to Generate a Generator with Scope

To generate your generator with the required scope, it is really simple. In the root directory of your generated plugin:
$ ruby script/generate component_generator authentication merb
create merb_generators/authentication/templates
create test
create merb_generators/authentication/authentication_generator.rb
create test/test_authentication_generator.rb
create test/test_generator_helper.rb
create merb_generators/authentication/USAGE
There are also a whole heap of instructions on what to do next that are put up on the screen.

This will generate the authentication generator in the merb scope. See the documentation for rubigen to see how to use your shiny new generator. It's pretty much the same that you'd do for rails.

So then to make the datamapper generator
ruby script/generate component_generator authentication_model datamapper
I don't want this to show in the list of available generators when you run ruby script/generate so I will delete the USAGE file to prevent it showing up in that list.

Inside the merbful_authentication.rb (your_plugin.rb) file is the place to put your hook script. Similar to the init.rb file in rails plugins.

A note about plugins in general for merb. To mixin behavior to views and controllers you would include into and extend:

Views:- Merb::ViewContext (class)


  • All controllers - Merb::AbstractController

  • Just web controllers - Merb::Controller (or Application)

  • Just Part controllers - Merb::PartController

  • Just Mail controllers - Merb::MailController

Ok now get out there and make some cool plugins for Merb! :)

Thursday, December 13, 2007

Using Git with SVN

I've been setting up a git repository to help aid collaboration on the port of restful_authentication to merb as merbful_authentication.

This is such a good library and I use it in all my rails sites that need authentication. It just works and I like that. All credit to Rick Olson for such a great plugin. Hopefully we'll be able to to a good job porting it.

Initially I setup a git repo with this. I'm starting to do most of my work in git so this is a good opportunity to keep going learning it.

You can get the WIP on this plugin via
git clone
# OR
git clone git://
This is really just a blank Merb app that has the beginnings of a port in it. There were so many people working on a port of this plugin I figured we might as well work on it together.

To include everyone in the development I needed to have svn as well. Rubyforge have been generous in approving a project for me.

The issue was, how to bring the svn into my local git repo so that I can push changes up to svn. Heres how I did it.
git clone git://

cd merbful_authentication.git

mate .git/config
In this file I put the following
[svn-remote "rubyforge/trunk"]
url = svn+ssh://
fetch = :refs/remotes/rubyforge/trunk
Then to get the SVN linked into my local git
git-svn fetch rubyforge/trunk

git branch -a
* master
You can see that rubyforge/trunk is now present in my git remote branches. Next create a branch from rubyforge/trunk
git checkout -b local-svn/trunk rubyforge/trunk
This will create a local branch that you can use in git like any other branch. Now once you've made changes to your app. Merge them into the local-svn/trunk then update your svn repo with a lazy
git-svn dcommit
from within the local-svn/trunk branch.