Shiny happy people coding

Coding with smile

Manage Your Dependencies With Merb

| Comments

How i use merb in my personal time and in my new open source project, I study more deeply the depedency system of Merb.

Merb is a gem based framework. In this way, all dependency need to be a gem and only gem.

Using gem with Merb

To use gem with Merb, it's simply. You can use your local repository of gem or freeze another.

Using your local gem repository

If you use this technique, so no more simply. update the file /config/dependencies.rb to inform what gem you want load in your application. By exemple, the dependencies.rb file after a fresh merb installation.

# dependencies are generated using a strict version, don't forget to edit the dependency versions when upgrading. merb_gems_version = "1.0.7.1" dm_gems_version = "0.9.8" # For more information about each component, please read http://wiki.merbivore.com/faqs/merb_components dependency "merb-action-args", merb_gems_version dependency "merb-assets", merb_gems_version dependency "merb-cache", merb_gems_version dependency "merb-helpers", merb_gems_version dependency "merb-mailer", merb_gems_version dependency "merb-slices", merb_gems_version dependency "merb-auth-core", merb_gems_version dependency "merb-auth-more", merb_gems_version dependency "merb-auth-slice-password", merb_gems_version dependency "merb-param-protection", merb_gems_version dependency "merb-exceptions", merb_gems_version dependency "dm-core", dm_gems_version dependency "dm-aggregates", dm_gems_version dependency "dm-migrations", dm_gems_version dependency "dm-timestamps", dm_gems_version dependency "dm-types", dm_gems_version dependency "dm-validations", dm_gems_version dependency "merb_datamapper", merb_gems_version dependency "do_sqlite3" # If using another database, replace this

We can list all gems of Merb and Datamapper to want use it. If we want use new one. you can just update this list. You can delete it too, if you want less loading gem, because you don't use it.

Using a local gem repository in your application

It's a different point in comparaison to RubyOnRails. In my point of view, it's better than Rails system. The idea is simple. Rubygems can be define a directory where all gem are. So why don't put this directory in your application?

To using this technique, you need create the directory /gems in your application. After use the thor task to install your wanted gem in your new gem repository. You can install merb-core and datamapper with follow command:

$ thor merb:gem:install merb-core dm-core

Once all dependencies are install, you can freeze your application with all using gem.

If you want use a source manager, you just need add the directory /gems/cache. This directory contains all gem files using. The other directory can be generate after. So when you get some sources, you just need made the thor task of deployement:

$ thor merb:gem:redeploy

All gems in your cache directory to install in your gems directory. I found this system better than rails because, if you have some gem with C extension, you can freeze it in your merb application. All extension can be compiled in other system. You can't to do that with Rails.

But if I want use developpement version. How can I do ?

It's the weakly point of Merb in comparison with Rails. With Rails, it's easy. We put some sources in directory /vendor and all works. A simple git submodule allow to track the dependencies evolution. Merb can't allow that. Merb load only gem.

Core-team recommandation

This technique recommand by core-team is based on gem. You need generate gem on your developpement source. Add it on your directory gems/cache and after using it. there are some thor task to help you to do that. By exemple, you can install the developpment version with command :

$ thor merb:source:install dm-core

This task clone the dm-core repository in your directory /src/, generate the gem and install it in your directory /gem. You can made same thing with push source directly inside /src/ directory and use this name directory. it's launch the rake package and install the generated gem.

I thing that it's not really good, because you can't know what it's really this gem use it. The version number gem is fixe and we can't know how commit use it. I like know just after a clone of project what commit it's use on each gem.

My personnal technique avoid generated gem

This technique working, but it's not the better. In my file config/init.rb, I created a little method:

def load_from_source(src) $:.unshift File.join(Merb.root, "src/#{src}/lib") require "src/#{src}/init.rb" end

After in the before_app_loads callback, I can call this method.

Merb::BootLoader.before_app_loads do # This will get executed after dependencies have been loaded but before your app's classes have loaded. load_from_source('will_paginate') end

Now with a will_paginate clone repository in my directory /src/ will_paginate can be loaded before the application load and after all dependencies load.

BUt this technique has a big issue. I can't fixed it without some patch to Merb (I made it maybe, even Merb is a little dead in futur :'( ). So we can load from source only after all dependencies. If you want load some source in middle of dependency, you can't . Yo u need using gem system.

What not to do

I made it, so i say to you don't to do. You can't using require in your dependencies file. If you require in this file. your sources are loaded before all dependency. All dependency list on this file are loaded after. So you can to have problem with loading order.< /p>

Traduction Francaise