Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to include data files in a Ruby Gem?

Tags:

rubygems

I'm working on a Ruby gem that uses configurable "templates" to generate HTML. I want to include a basic set of templates with the gem, and allow the users to override them with better/more customized ones. These templates aren't Ruby code, they are "just files" that need to be read from the disk at some point in the code.

I looked over the RubyGems documentation but they make the (not altogether unreasonable) assumption that a gem contains only code (OK, with some documentation and specific meta-data files thrown in for good measure). There's no reference to how to create the equivalent of "/usr/share/..." files.

What is the best practice for including such files in the gem? Should I simply include them as part of the "sources"? If so, how do I discover their path so I can read them from the disk into the template processor?

like image 706
Oren Ben-Kiki Avatar asked Jun 27 '10 14:06

Oren Ben-Kiki


People also ask

What are Ruby gem files?

A Gemfile is a file that is created to describe the gem dependencies required to run a Ruby program. A Gemfile should always be placed in the root of the project directory.

Where are Ruby files stored?

The main place where libraries are hosted is RubyGems.org, a public repository of gems that can be searched and installed onto your machine. You may browse and search for gems using the RubyGems website, or use the gem command. Using gem search -r , you can search RubyGems' repository.

Is RubyGems included with Ruby?

The gem command allows you to interact with RubyGems. Ruby 1.9 and newer ships with RubyGems built-in but you may need to upgrade for bug fixes or new features. To upgrade RubyGems, visit the download page.


1 Answers

Suppose you have a project structure like this:

bin/
|__ foobar*
lib/
|__ foobar/
|   |__ templates/
|   |   |__ a/
|   |   |__ b/
|___|__ meta.rb
|___|__ utils.rb

In lib/foobar/teplates directory you have your template directories or files.

lib/foobar/meta.rb file contains the name of your project and its version. It's important to keep them (particularly a version number) synced with the name & the version of the project in your gem specification. (The best way to do this is read meta.rb from Rakefile to pass values to the spec.)

For example, meta.rb may look like:

module Foobar
  module Meta
    NAME = 'foobar'
    VERSION = '0.1.2'
  end
end

Then write a function that return a full path to the lib directory regardless whether you are testing your project from the sources directory or the project is installed from the rubygems.

utils.rb:

require_relative 'meta'

module Foobar
  module Utils

    # Return a directory with the project libraries.
    def self.gem_libdir
      t = ["#{File.dirname(File.expand_path($0))}/../lib/#{Meta::NAME}",
           "#{Gem.dir}/gems/#{Meta::NAME}-#{Meta::VERSION}/lib/#{Meta::NAME}"]
      t.each {|i| return i if File.readable?(i) }
      raise "both paths are invalid: #{t}"
    end

    # [...]
  end
end

Having Foobar::Utils.gem_libdir function you can always read your templates in bin/foobar file:

require_relative '../lib/foobar/utils'

puts Dir[Foobar::Utils.gem_libdir + '/*']
puts Foobar::Utils.gem_libdir + '/templates/a/blah-blah'
like image 55
Alexander Gromnitsky Avatar answered Dec 09 '22 23:12

Alexander Gromnitsky