ardavis
ardavis

Reputation: 9895

How can I place capistrano stages into a sub-directory?

By default, the capistrano stages are placed in /config/deploy/. I have a ton of stages here. I'd also like to have some of my stages grouped like /config/deploy/group1/ and /config/deploy/group2. How could I include multiple paths?

I noticed you could set this:

set :stage_config_path, 'cap/stages'

But I need it to look recursively at config/deploy instead of only in that folder.

It would be nice if I could even do things like:

$ cap group1/stage1 deploy

How would I go about accomplishing this in my Ruby on Rails application?

Upvotes: 1

Views: 282

Answers (1)

ardavis
ardavis

Reputation: 9895

I was able to override some Capistrano methods to get this to work. I wrote the following code at the top of my Capfile:

module Capistrano
  module DSL
    module Stages

      def stages
        names = Dir[stage_definitions].map { |f| "#{File.dirname(f)}/#{File.basename(f, ".rb")}".gsub("#{stage_config_path.to_s}/", '') }
        assert_valid_stage_names(names)
        names
      end

      # Override stage_definitions to include subfolders
      def stage_definitions
        stage_config_path.join("**/*.rb")
      end
    end
  end
end

Explanation

By overriding the #stage_definitions method, I added **/ to that it would look for the .rb files in sub directories.

The next issue was that capistrano/setup.rb had this line of code:

load stage_config_path.join("#{stage}.rb")

That means I need stage to include the folder name. Then I overrode #stages so that the names variable would be an array of stages, including the subdirectory if any. Example:

config/
├── deploy/
│   ├── group_1/
|   ├──   ├── stage1.rb
│   ├── stage2.rb
│   ├── stage3.rb

Becomes:

['group_1/stage1', 'stage2', 'stage3']

That allows the Rake tasks to be created and load the files correctly!

$ cap group_1/stage1 deploy

Upvotes: 3

Related Questions