Here’s our basic requirements:
- We have a base Rails application, which is being actively maintained.
- We want to offer a customized version of this app, given that:
- servers must reside in our customer’s premise and run on a different domain.
- there’s a specific logging instrumentation for their own monitoring in the datacenter.
To do that, I can see several options to achieve that goal:
- Git branch
Rails::EngineRails::Application
The most obvious answer would be Git branch, for full flexibility.
However I’m not sure if it’s a good idea, because the code base is largely shared and the mainline has a lot more activities – catching up with rebase / merge could be just extra hassle.
We want to decouple the original and the customized versions as far as possible. In other words, we want to have as less often conflicts as possible between the original and the customized.
Rails::Engine or Rails::Application seemed like a close idea (I’m not familiar with Rails Engines), but I don’t understand how to have OurApp::Application and OurCustomizedApp::Application in one place and switch between them globally and dynamically.
Probably it would be nice to have:
- custom initializers, controllers and views in a separate directory to override (or patch) the original
- ability to specify which app (the original or the customized) to boot by an environment variable like
RAILS_APP - separate config files, like so:
config/database.ymlto beconfig/customer1/database.yml - ability to use the same
deploy.rbfor capistrano (probably withconfig/servers.ymlandconfig/customer1/servers.ymlto define roles and IPs?)
Is there practices / conventions for our requirements? Any advice?
Our apps run on Ruby 1.9.2 + Rails 3.0.3.
UPDATE
We started it as a Git branch. We created a rake task to generate a file at config/branch that includes text like “master” or “customized”, and application.rb reads it upon bootstrap. Configs like database.yml or servers.yml now live in config/mainline/ or config/customized/, and application.rb handles them accordingly.
config.paths.config.database = "config/#{branch}/database.yml"
Not perfect, but good enough for now. I’ll update when we find a better way to do this.
I know it’s not the precise answer you’re after, but I believe Git is going to be the least amount of work – and the easiest to manage, long-term – over customising the app and adding logic to handle the additional config files, modifying your deploy files and also managing the (potentially) new css/js/template files.
Using rebase & merge are going to be a lot less error-prone, and as long as you keep your branches synced on a regular basis, you shouldn’t have any serious problems keeping them both up-to-date. After all, that’s what Git is good at! 😉