Home > Software > Freezing compiled gems in merb

Freezing compiled gems in merb

Vendoring gems definitely makes deployment easier for both rails and merb. For merb, the solution is to create a local gem repository within your project.

gem install -i gems/ --no-ri --no-rdoc #{gem_to_install}

This works great, once you update your merb/config/init.rb to include the new gem repository.

Gem.clear_paths
Gem.path.unshift(Merb.root / "gems")


I also recommend saving space by deleting the gem cache.

rm -rf gems/cache/*

This creates one problem, if the gems you have installed include binaries (e.g. C extensions), then you’ll have an issue if you develop and deploy to different architectures. I think the most common would be developing on Mac OSX and deploying to Linux. There are many different ways to solve this problem. One might use gem pristine, or as I do below maintain a list of the gems that need compiling and rebuild them for the deployment target.

GEM_BUILDS=['rbtagger','hpricot','mongrel','fastthread']
GEM_ROOT=File.join(File.dirname(__FILE__),'gems')

desc 'Refresh gem builds for the current system'
task :build_refresh do
  gem_dir_list = File.join(GEM_ROOT,'gems')
  gems_built = GEM_BUILDS
  Dir["#{gem_dir_list}/*"].each do|gem_path|
    gems_built.each do|gem|
      if gem_path.match(gem)
        if File.exist?("#{gem_path}/Rakefile")
          puts "building #{gem_path}"
          system("cd #{gem_path} && rake compile")
        else
          base = File.basename(gem_path)
          version = base.split('-').last
          cmd = "gem install -i gems --no-ri --no-rdoc #{gem} --version #{version}"
          puts cmd.inspect
          system(cmd)
        end
        gems_built.reject!{|g| g == gem}
      end
    end
  end
end

Now to run the task:

rake build_refresh

To change the list of compiled gems just modify the GEM_BUILDS constant.

Software , ,

  1. No comments yet.
  1. No trackbacks yet.
CommentLuv Enabled

Comments links could be nofollow free.