views:

1082

answers:

4

Hello, this is probably a newbie ruby question. I have several libraries and apps that I need to deploy to several different hosts. All of the apps and libs will share some common settings for those hosts-- e.g. host name, database server/user/pass, etc.

My goal is to do something like:

cap host1 stage deploy
cap host2 stage deploy
cap host1 prod deploy
# ...

My question is how do you include these common settings in all of your deploy.rb files? More specifically, I want to create a an rb file that I can include that has some common settings and several host specific task definitions:

set :use_sudo, false
# set some other options

task :host1 do
    role :app, "host1.example.com"
    role :web, "host1.example.com"
    role :db,  "host1.example.com", :primary => true

    set :rodb_host, "dbhost"
    set :rodb_user, "user"
    set :rodb_pass, "pass"
    set :rodb_name, "db"
 end

 task :host2 do
     #...
 end

deploy.task :carsala do
    transaction do
        setup
        update_code
        symlink
    end
end

And then "include" this file in all of my deploy.rb files where I define stage, prod, etc and overwrite any "common" configuration parameters as necessary. Any suggestions would be appreciated. I've tried a few different things, but I get errors from cap for all of them.

Edit: I've tried

require 'my_module'

But I get errors complaining about an undefined task object.

+1  A: 
require 'my_extension'

Save your extensions in my_extension.rb

Jon Wood
A: 

Jon has it right, that's the simplest way to go, just save it in a separate file and use require 'filename'. You could also use something fancy like Webistrano for deployment which also supports this in the form of Capistrano 'Recipes'. I've been using it for a while on a few projects and have come to love it.

Daniel Beardsley
I tried this, but I get errors complaining about the task object not being defined. Do you require anything at the top of 'my_extension'?
drsnyder
+4  A: 

I just experimented with it a little more and what I discovered is that you have to:

load 'config/my_module'

I can put all of my common definitions here and just load it into my deploy.rb.

It appears from the docs that load loads and executes the file. Alternatively, require attempts to load the library specified. I'm not totally sure about real difference, but it appears that there is some separation between the current app symbol space and the library require'd (hence the errors about the undefined task object) that isn't a problem when you do a load.

drsnyder
Require is used to load Rubygems, but will first load local files of a given if it finds them. Also, require doesn't run the file a 2nd time if it was loaded previously, while load does. Other than that, they are perfectly equivalent. So you can use require to load your own files.
webmat
If I use require, I get an error: "undefined method `namespace'", but if I use load, it works fine.
Gary Richardson
A: 

I'm not sure how complex your needs are, but this works well for me for deployment:

set :application, "app"

set :scm,           :subversion
# ... set all your common variables

task :staging do
  set :repository,    "http://app/repository/trunk/"
  # ... set other uncommon variables in task
end

task :production do
  set :repository,    "http://app/repository/production/"
  # ...
end

Deployment is just

cap staging deploy

or

cap production deploy
Ian Terrell