0

Still diving into the interesting (but a bit confusing) world of developing my own gem/engine.

I have successfully deployed it to my (private) GitHub account, but as the gem is in continuous development, I don't want to deploy it again and again and then do bundle update, etc., so I found the option to require a gem by specifying a path like this:

gem 'my_gem', path: 'path/to/my/gem'

This works nicely when developing (it even seems to reload changed files from the gem when rails s is running [at least for helpers and views it seems to do it, didn't use controllers and models yet, but hoping this will be the case for them, too], which is niiiice for developing the engine while using it straight away in the host Rails app).

But when deploying to the production server, I'd like to get the gem from github:

gem 'my_gem', git: "git@github.com:my_company/my_gem"

Sadly, bundler doesn't allow to have a gem required more than once (even when they are in separate development/test and production groups), so I'm doing the following:

if File.directory?('../my_gem')
  gem 'my_gem', path: '../my_gem'
else
  gem 'my_gem', git: "git@github.com:my_company/my_gem.git"
end

This seems to work nicely so far (didn't test deployment using Capistrano yet, though). But it leaves some questions:

1) Is this the "right" way to solve my problem? Seems a bit odd that I didn't find a much simpler way yet, something like:

gem 'my_gem', path: '../my_gem', git: "git@github.com:my_company/my_gem.git"

...where I'd expect bundler to simply try the :path option first, and if it's not available, it's try the :git option. But as far as I see, when doing this, it only uses the :git option.

2) Is it good practice to develop gems like this? I'm extracting some functionality from my host app into an engine, and at the same time, I'm enhancing this functionality. So I have the engine gem loaded within my host app, and from within my host app I change the engine's codes which are (thank God!) reflected within my host app without having to restart the rails server. This feels quite "right", but as there is a dummy Rails app within the created engine, I'm a bit unsure whether I rather should develop my engine's strictly isolated from my host app, or not. I think this is a bit of a philosophical question, but maybe someone has an opinion about it and can post pros and contras?

3) How do I tell Capistrano to always update my own gem to the newest version from GitHub automatically?

tshepang
  • 12,111
  • 21
  • 91
  • 136
Joshua Muheim
  • 12,617
  • 9
  • 76
  • 152

1 Answers1

1

You can do

if ENV['RAILS_ENV'] != "development"
  gem 'my_gem', git: "git@github.com:my_company/my_gem.git"
else
  gem 'my_gem', path: '../my_gem'
end

assuming that RAILS_ENV is being passed into the bundle command (which is so when using capistrano).

To update your gem to the latest, try making a capistrano task that essentially does this

/path/to/bundler update my_gem

I can't really comment on your other points. Just my 2 cents.

axsuul
  • 7,370
  • 9
  • 54
  • 71
  • Thank you, this is useful information. I'll wait for some more answers though. :) – Joshua Muheim Oct 01 '12 at 08:43
  • And wouldn't it be better to use `if ENV['RAILS_ENV'] == "production"`? Because in test env I want to use the dev gem, too. – Joshua Muheim Oct 01 '12 at 09:05
  • I think `ENV['RAILS_ENV']` might not be passed in for test environment. But I did `!= "development"` just in case you had a staging environment. – axsuul Oct 01 '12 at 10:35