Forking a Gem for a Rails Project

Forking a gem for a Rails project

Today this is pretty easy to do with Bundler. You make a local copy of the gem and then instead of doing

gem "whatever"

in your Gemfile, you do:

gem "whatever", :path => "/home/pupeno/whatever"

After running bundle install, the gem is picked from that directory. Even if you modify something in there, all you need to do to re-load it is restart Rails.

If you need to deploy an application using your own changes of a Gem, you make a fork, on Github or similar and on the Gemfile you do:

gem "whatever", :git => "git@github.com:/pupeno/whatever.git"

and that's it. It's simple, straightforward and beautiful.

Guide to forking and working on a rails gem

I suggest that you search for how to create a gem first. "Make your own gem" will help you start.

How to deal with forked gems and bundle

Gemfile.lock should know what gem to load, when you do bundle update or installing a new gem, Gemfile.lock will be updated too with new gems, paths, etc.. and also the revision hash.

The hash at the end of the Fetch/Push URL that you see when you run git remote show origin must be the same as the revision from Gemfile.lock.

For example in my case with active-admin gem in Gemfile.lock I have:

GIT
remote: git://github.com/gregbell/active_admin.git
revision: b7e8c7dde2c26a47e5db0dd1efc163405afadd9d
specs:
activeadmin (1.0.0.pre)
...

even if I have 2 active-admin gems, there is only one with revision: b7e8c7dde2c26a47e5db0dd1efc163405afadd9d

However, working with forks, this what I do:

I usually fork it, pull the froked gem on my computer, update the Gemfile of my app to use the gem from local-storage with path parameter, and I can update the gem without pushing it to github everytime I do a small change just to test it.

When I make it work as I needed, I push it to github and change the path in Gemfile of my app, run bundle again to update the path Gemfile.lock and I am all set. At least here you are not confused what gem the app is loading.

How to use a branch in a fork of rails in a project with bundler

balu's answer pointed me to the right course, but here are some more details:

It was necessary to cobble together .gemspec files for most of the gems in the rails repo/2-3-stable branch - my take can be seen or forked at http://github.com/traveliq/rails/commit/46d9042c9125abbbedfc672f8523d81210f4f320

To include that in a Gemfile, use:

git "git://github.com/traveliq/rails.git", :branch => 'tiq-fixes' do
gem 'rails'
gem 'actionmailer'
gem 'actionpack'
gem 'activerecord'
gem 'activeresource'
gem 'activesupport'
end

Note that you can't use 'railties', that only defines the 'rails' gem.

Incidentally, while working on this, it was way easier to point the Gemfile at my local repo, which is done this way (rails being the folder where the repo is cloned, a level down from the Gemfile):

gem 'rails',            :path => 'rails/railties'
gem 'actionmailer', :path => 'rails/actionmailer'
gem 'actionpack', :path => 'rails/actionpack'
gem 'activerecord', :path => 'rails/activerecord'
gem 'activesupport', :path => 'rails/activesupport'

After defining the rails/railties .gemspec, you could also leave out some of those gems, and have bundler use the normally available versions from gemcutter etc.

What is the correct protocol/etiquette for forking a Ruby/Rails gem on Github that may be maintained as an ongoing, parallel fork?

Sounds like you handled the bugfix / fork properly already.

Depending on the license of the gem, release it as yourname-originalname.

You've made substantial changes which the community as a whole may be interested in and this is the accepted standard for forking and releasing.

It also solves your bonus question. Change whatever you want for your release. It's essentially a new project now. Still good to credit the original dev of course :)

Rails: Extract and Edit Source Code of Specific Gem

If you find an error in gem, you'd better make pull request on GitHub. But let's suppose you need your private fork of gem. Best workflow for that:

  1. Download the gem source code from GitHub: git clone https://github.com/author/awesome_gem.git.
  2. In your project's Gemfile add gem awesome_gem, path: "/local/path/to/awesome_gem"
  3. Run bundle install

Now you can make changes to the gem locally, and have your project use local copy of it. When you are done making initial changes, push your Gem to your github repository, and change Gemfile line to something like:

gem awesome_gem, github: 'QQQ/awesome_gem' ('QQQ' being your Github's account name)

Gem needs to be required manually

It does not conform Rails autoloading rules. Create a file instagram_api_client.rb with a content

require 'instagram_api'

in the top level of lib folder. That should do the trick.

For gems, the name of the file to be loaded automatically should be exactly equal to the name of the gem.


Or, as suggested by @TomLord, one might simply specify

gem 'instagram_api_client', require: 'instagram_api'

in the Gemfile itself.

Test local version of gem in Rails project

If you are using a gem and working on it at the same time, the best way is to use Bundler and provide a local path:

gem 'my_bad_gem', path: '../my_bad_gem/'

This will look for the gem under the given (relative in this case) path. Another option is to use local git repositories (see http://bundler.io/v1.3/git.html).



Related Topics



Leave a reply



Submit