Making an executable standalone Merb Slice gem

I have a standalone Merb Slice which can be started by running the “slice” command in its top directory. Today I needed to make a gem file for this Slice so that people can install the gem and start it directly by running the Slice’s name, for example, “foo”.

So I created the Rakefile, in which I specified the executable file in the following way:

— Code: Rakefile —

spec = do |s|
  s.rubyforge_project = ‘merb’ = GEM_NAME
  s.version = GEM_VERSION
  s.platform = Gem::Platform::RUBY
  s.has_rdoc = false
  s.summary = SUMMARY
  s.description = s.summary = AUTHOR = EMAIL
  s.homepage = HOMEPAGE
  s.executables = “foo”
  s.require_path = ‘lib’
  s.autorequire = GEM_NAME
  s.files = %w(Rakefile TODO) + Dir.glob(“{config,lib,spec,app,data,public}/**/*”)

Then I created a bin folder within the Slice’s top directory, and created a file named “foo” within the bin folder I put Merb.start in the file “foo”, and I tried to make a gem and installed it. But the Slice did not start correctly this way.

Then I spent a while trying different possibilities, and with somebody’s help, I finally got the right way of doing it.

1. look up the location of merb-slices. This can be done by executing gem list – d | grep merb-slices.

2. locate a file named “slice” under the bin folder of merb-slices.

3. copy the contents of this file to the file you have in your Slice’s bin folder, and amend from that (you may want to remove or change the Merb::Config.use block since your own Slice may have that set somewhere else, for example, in init.rb).


Depending on how you amend the slice binary file, you may encouter a situation that your executable is only able to run within the source folder. For example, if you run “foo” in your Slice’s source folder, it becomes equivalent as running “slice”, but if you run it anywhere else, it fails with the error “No slice found”. If this happens, what you need to do is change the following things in your “foo” binary file:

1. Change __DIR__ (originally assigned to current directory):

Dir.chdir File.join(File.dirname(__FILE__),”..”)
__DIR__ = Dir.getwd

2. Update slice_name:

slice_name = “foo”

3. Add a line before Merb.start to specify the right init file to load:

ARGV.push *[ “-I”, File.join(File.dirname(__FILE__), “..”, “config”, “init.rb”) ]

Note: This assumes init.rb is under config folder of your Slice project.

Leave a Reply

Your email address will not be published. Required fields are marked *