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:
- Download the gem source code from GitHub:
git clone https://github.com/author/awesome_gem.git
. - In your project's Gemfile add
gem awesome_gem, path: "/local/path/to/awesome_gem"
- 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
How to Fix Rubygems Recent Deprecation Warning
How to Simulate Java-Like Annotations in Ruby
Ruby 1.9 Hash with a Dash in a Key
Split String into a List, But Keeping the Split Pattern
Why Many People Use "-%>" Instead of "%>" in Rails
Ruby on Rails Rmagick on Windows 7
Asynchronous Http Request in Ruby
(Ruby) Getting Net::Smtp Working with Gmail...
How to Run Ruby and Git Commands in One Place on Windows
Actionview::Template::Error (Incompatible Character Encodings: Utf-8 and Ascii-8Bit)
Rails - Whenever Gem - Dynamic Values
How to Set Http_Referer When Testing in Rails
Differencebetween 'After_Create' and 'After_Save' and When to Use Which