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.

Recent Comments