├── .gitignore ├── .travis.yml ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── capistrano-multiconfig.gemspec ├── fixtures ├── Capfile └── config │ ├── double_nested_shared_file │ ├── level0.rb │ └── level0 │ │ ├── level1.rb │ │ └── level1 │ │ └── config.rb │ ├── empty │ └── .gitkeep │ ├── nested │ └── app │ │ ├── production.rb │ │ └── staging.rb │ ├── nested_with_another_file │ ├── app │ │ ├── production.rb │ │ └── staging.rb │ └── deploy.rb │ ├── nested_with_shared_and_another_file │ ├── app.rb │ ├── app │ │ ├── production.rb │ │ └── staging.rb │ └── deploy.rb │ ├── nested_with_shared_file │ ├── app.rb │ └── app │ │ ├── production.rb │ │ └── staging.rb │ ├── root_with_nested.rb │ ├── root_with_nested │ └── app │ │ └── config.rb │ ├── sample │ └── apps │ │ ├── world1.rb │ │ └── world2.rb │ ├── third_level_nested │ └── app │ │ ├── blog │ │ ├── production.rb │ │ └── staging.rb │ │ └── wiki │ │ ├── production.rb │ │ └── qa.rb │ ├── two_files │ ├── production.rb │ └── staging.rb │ ├── two_files_with_same_prefix │ ├── qa.rb │ └── qa1.rb │ ├── two_nested │ ├── api │ │ ├── production.rb │ │ └── staging.rb │ └── app │ │ ├── production.rb │ │ └── staging.rb │ └── with_foreign_file │ ├── production.rb │ ├── readme.md │ └── staging.rb ├── lib ├── capistrano-multiconfig.rb └── capistrano │ ├── multiconfig.rb │ └── multiconfig │ └── dsl.rb └── spec └── integration_spec.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | Gemfile.lock 4 | pkg/* 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.1.10 4 | - 2.2.5 5 | - 2.3.1 6 | cache: bundler 7 | script: 8 | - bundle exec rspec 9 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gemspec 4 | 5 | gem "capistrano", "3.7.1" 6 | 7 | group :test do 8 | gem "rspec", "2.14.1" 9 | end 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Railsware (www.railsware.com) 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # capistrano-multiconfig 2 | 3 | [![Build Status](https://travis-ci.org/railsware/capistrano-multiconfig.png)](https://travis-ci.org/railsware/capistrano-multiconfig) 4 | 5 | ## Description 6 | 7 | Capistrano extension that allows to use multiple configurations. 8 | 9 | Multiconfig extension is similar to [multistage](https://github.com/capistrano/capistrano-ext) extenstion. 10 | But it's not only about 'stage' configurations. It's about any configuration that you may need. 11 | Extension recursively builds configuration list from configuration root directory. 12 | Each configuration loads recursively configuration from it namespace files and own configuration file. 13 | 14 | ## Purpose 15 | 16 | Extension was specially created to implement [Caphub](https://github.com/railsware/caphub) concept. 17 | [Read more](http://railsware.com/blog/2011/11/18/caphub-multiple-applications-deployment-with-capistrano/). 18 | 19 | ## Usage 20 | 21 | Install gem 22 | 23 | $ gem install capistrano-multiconfig 24 | 25 | 26 | ## Capistrano3 27 | 28 | Use multiconfig v3.x.x 29 | 30 | Replace `capistrano/setup` with `capistrano/multiconfig` in your `Capfile`: 31 | 32 | # set :stages_root, 'config/deploy' 33 | require 'capistrano/multiconfig' 34 | 35 | Optionally you may set another path to your multistages configurations with *:stages_root*. 36 | 37 | ## Capistrano2 38 | 39 | For legacy capistrano v2.x.x use multiconfig gem v0.0.x 40 | 41 | Add to `Capfile` 42 | 43 | set :config_root, 'path/to/your/configurations' 44 | require 'capistrano/multiconfig' 45 | 46 | 47 | ## Example 48 | 49 | Assume we need next configurations: 50 | 51 | * services:billing:production 52 | * services:billing:qa 53 | * blog:production 54 | * blog:staging 55 | * dev:wiki 56 | 57 | Choose configuration root directory for example `config/deploy` 58 | 59 | Create configuration files: 60 | 61 | config/deploy/services/billing/production.rb 62 | config/deploy/services/billing/qa.rb 63 | config/deploy/blog/production.rb 64 | config/deploy/blog/staging.rb 65 | config/deploy/dev/wiki.rb 66 | 67 | Add to `Capfile`: 68 | 69 | require 'capistrano/multiconfig' 70 | 71 | Put related capistrano configuration to each file according to file meaning. 72 | 73 | Check tasks: 74 | 75 | $ cap -T 76 | cap services:billing:production # Load services:billing:production configuration 77 | cap services:billing:qa # Load services:billing:qa configuration 78 | cap blog:production # Load blog:production configuration 79 | cap blog:staging # Load blog:staging configuration 80 | cap wiki # Load wiki configuration 81 | cap invoke # Invoke a single command on the remote servers. 82 | cap shell # Begin an interactive Capistrano session. 83 | 84 | Let's try to run task without specified configuration: 85 | 86 | $ cap shell 87 | triggering start callbacks for `shell' 88 | * executing `multiconfig:ensure' 89 | No configuration specified. Please specify one of: 90 | * wiki:production 91 | * wiki:staging 92 | * blog:production 93 | * blog:staging 94 | (e.g. `cap wiki:production shell') 95 | 96 | 97 | So we must provide configuration as first task: 98 | 99 | $ cap services:billing:qa shell 100 | 101 | ## Configuration Loading 102 | 103 | Configuration task loads not only configuration associated with it filename. 104 | It also recursively load configurations from all namespaces. 105 | 106 | For example task `cap apps/blog/qa.rb` loads with **order** next configuration files (if they exist): 107 | 108 | * config/deploy/apps.rb 109 | * config/deploy/apps/blog.rb 110 | * config/deploy/apps/blog/qa.rb 111 | 112 | So it's easy to put shared configuration. 113 | 114 | ## Custom stages configuration location 115 | 116 | Specify in `Capfile`: 117 | 118 | set :stages_root, 'deployment' 119 | require 'capistrano/multiconfig' 120 | 121 | ## Testing 122 | 123 | $ bundle install 124 | $ rspec -fs spec 125 | 126 | ## Authors 127 | 128 | * [Andriy Yanko](http://ayanko.github.io) 129 | 130 | ## License 131 | 132 | * Copyright (c) 2013 Railsware [www.railsware.com](http://www.railsware.com) 133 | * [MIT](www.opensource.org/licenses/MIT) 134 | 135 | ## References 136 | 137 | * [capistrano](https://github.com/capistrano/capistrano) 138 | * [caphub](https://github.com/railsware/caphub) 139 | 140 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | -------------------------------------------------------------------------------- /capistrano-multiconfig.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | 4 | Gem::Specification.new do |s| 5 | s.name = "capistrano-multiconfig" 6 | s.version = "3.1.0" 7 | s.authors = ["Andriy Yanko"] 8 | s.email = ["andriy.yanko@gmail.com"] 9 | s.homepage = "https://github.com/railsware/capistrano-multiconfig" 10 | s.summary = %q{Capistrano extension that allows to use multiple configurations} 11 | s.description = %q{ 12 | Multiconfig extension is similar to [multistage](https://github.com/capistrano/capistrano-ext) extension. 13 | But it's not only about 'stage' configurations. It's about any configuration that you may need. 14 | Extension recursively builds configuration list from configuration root directory. 15 | Each configuration loads recursively configuration from namespace files and own configuration file. 16 | } 17 | s.license = "MIT" 18 | 19 | s.files = `git ls-files`.split("\n") 20 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 21 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 22 | s.require_paths = ["lib"] 23 | 24 | s.add_runtime_dependency "capistrano", ">=3.7.0" 25 | end 26 | -------------------------------------------------------------------------------- /fixtures/Capfile: -------------------------------------------------------------------------------- 1 | set :stages_root, ENV.fetch('STAGES_ROOT') 2 | 3 | require 'capistrano/multiconfig' 4 | 5 | task :hello_world do 6 | puts fetch(:message, "hello") 7 | end 8 | 9 | # vim syntax=ruby 10 | -------------------------------------------------------------------------------- /fixtures/config/double_nested_shared_file/level0.rb: -------------------------------------------------------------------------------- 1 | set :message, "hello from level0" 2 | -------------------------------------------------------------------------------- /fixtures/config/double_nested_shared_file/level0/level1.rb: -------------------------------------------------------------------------------- 1 | set :message, "#{fetch(:message)} level1" 2 | -------------------------------------------------------------------------------- /fixtures/config/double_nested_shared_file/level0/level1/config.rb: -------------------------------------------------------------------------------- 1 | set :message, "#{fetch(:message)} world" 2 | -------------------------------------------------------------------------------- /fixtures/config/empty/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/empty/.gitkeep -------------------------------------------------------------------------------- /fixtures/config/nested/app/production.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/nested/app/production.rb -------------------------------------------------------------------------------- /fixtures/config/nested/app/staging.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/nested/app/staging.rb -------------------------------------------------------------------------------- /fixtures/config/nested_with_another_file/app/production.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/nested_with_another_file/app/production.rb -------------------------------------------------------------------------------- /fixtures/config/nested_with_another_file/app/staging.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/nested_with_another_file/app/staging.rb -------------------------------------------------------------------------------- /fixtures/config/nested_with_another_file/deploy.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/nested_with_another_file/deploy.rb -------------------------------------------------------------------------------- /fixtures/config/nested_with_shared_and_another_file/app.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/nested_with_shared_and_another_file/app.rb -------------------------------------------------------------------------------- /fixtures/config/nested_with_shared_and_another_file/app/production.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/nested_with_shared_and_another_file/app/production.rb -------------------------------------------------------------------------------- /fixtures/config/nested_with_shared_and_another_file/app/staging.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/nested_with_shared_and_another_file/app/staging.rb -------------------------------------------------------------------------------- /fixtures/config/nested_with_shared_and_another_file/deploy.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/nested_with_shared_and_another_file/deploy.rb -------------------------------------------------------------------------------- /fixtures/config/nested_with_shared_file/app.rb: -------------------------------------------------------------------------------- 1 | set :message, "hello from shared world" 2 | -------------------------------------------------------------------------------- /fixtures/config/nested_with_shared_file/app/production.rb: -------------------------------------------------------------------------------- 1 | set :message, "hello from production world" 2 | -------------------------------------------------------------------------------- /fixtures/config/nested_with_shared_file/app/staging.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/nested_with_shared_file/app/staging.rb -------------------------------------------------------------------------------- /fixtures/config/root_with_nested.rb: -------------------------------------------------------------------------------- 1 | set :message, "hello from root" 2 | -------------------------------------------------------------------------------- /fixtures/config/root_with_nested/app/config.rb: -------------------------------------------------------------------------------- 1 | set :message, "#{fetch(:message)} world" 2 | -------------------------------------------------------------------------------- /fixtures/config/sample/apps/world1.rb: -------------------------------------------------------------------------------- 1 | set :message, "hello from world1" 2 | -------------------------------------------------------------------------------- /fixtures/config/sample/apps/world2.rb: -------------------------------------------------------------------------------- 1 | set :message, "hello from world2" 2 | -------------------------------------------------------------------------------- /fixtures/config/third_level_nested/app/blog/production.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/third_level_nested/app/blog/production.rb -------------------------------------------------------------------------------- /fixtures/config/third_level_nested/app/blog/staging.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/third_level_nested/app/blog/staging.rb -------------------------------------------------------------------------------- /fixtures/config/third_level_nested/app/wiki/production.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/third_level_nested/app/wiki/production.rb -------------------------------------------------------------------------------- /fixtures/config/third_level_nested/app/wiki/qa.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/third_level_nested/app/wiki/qa.rb -------------------------------------------------------------------------------- /fixtures/config/two_files/production.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/two_files/production.rb -------------------------------------------------------------------------------- /fixtures/config/two_files/staging.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/two_files/staging.rb -------------------------------------------------------------------------------- /fixtures/config/two_files_with_same_prefix/qa.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/two_files_with_same_prefix/qa.rb -------------------------------------------------------------------------------- /fixtures/config/two_files_with_same_prefix/qa1.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/two_files_with_same_prefix/qa1.rb -------------------------------------------------------------------------------- /fixtures/config/two_nested/api/production.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/two_nested/api/production.rb -------------------------------------------------------------------------------- /fixtures/config/two_nested/api/staging.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/two_nested/api/staging.rb -------------------------------------------------------------------------------- /fixtures/config/two_nested/app/production.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/two_nested/app/production.rb -------------------------------------------------------------------------------- /fixtures/config/two_nested/app/staging.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/two_nested/app/staging.rb -------------------------------------------------------------------------------- /fixtures/config/with_foreign_file/production.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/with_foreign_file/production.rb -------------------------------------------------------------------------------- /fixtures/config/with_foreign_file/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/with_foreign_file/readme.md -------------------------------------------------------------------------------- /fixtures/config/with_foreign_file/staging.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/fixtures/config/with_foreign_file/staging.rb -------------------------------------------------------------------------------- /lib/capistrano-multiconfig.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/railsware/capistrano-multiconfig/ab0191c733a8aa55f7a597e7ad8c7e1c7084b2fd/lib/capistrano-multiconfig.rb -------------------------------------------------------------------------------- /lib/capistrano/multiconfig.rb: -------------------------------------------------------------------------------- 1 | require 'capistrano/multiconfig/dsl' 2 | 3 | include Capistrano::DSL 4 | include Capistrano::Multiconfig::DSL 5 | 6 | namespace :load do 7 | task :defaults do 8 | load 'capistrano/defaults.rb' 9 | end 10 | end 11 | 12 | if Gem::Version.new(Capistrano::VERSION) >= Gem::Version.new('3.5.0') 13 | require "airbrussh/capistrano" 14 | 15 | Airbrussh.configure do |airbrussh| 16 | airbrussh.banner = false 17 | airbrussh.command_output = true 18 | end 19 | end 20 | 21 | stages.each do |stage| 22 | Rake::Task.define_task(stage) do 23 | 24 | # Set stage variable 25 | set(:stage, stage) 26 | 27 | # Load defaults variables 28 | invoke 'load:defaults' 29 | 30 | # Load stage configuration(s). 31 | # 32 | # For stage 'production' will be loaded next configurations: 33 | # 34 | # * config/deploy.rb 35 | # * config/deploy/production.rb 36 | # 37 | # For stage 'soa:blog:production' will be loaded next configurations: 38 | # 39 | # * config/deploy.rb 40 | # * config/deploy/soa.rb 41 | # * config/deploy/soa/blog.rb 42 | # * config/deploy/soa/blog/production.rb 43 | stage.split(':').inject([stages_root]) do |paths, segment| 44 | paths << File.join(paths.last, segment) 45 | end.each do |path| 46 | file = "#{path}.rb" 47 | load(file) if File.exists?(file) 48 | end 49 | 50 | # Set locale 51 | I18n.locale = fetch(:locale, :en) 52 | 53 | # configure core backend 54 | configure_backend 55 | 56 | end.add_description("Load #{stage} configuration") 57 | end 58 | -------------------------------------------------------------------------------- /lib/capistrano/multiconfig/dsl.rb: -------------------------------------------------------------------------------- 1 | module Capistrano 2 | module Multiconfig 3 | module DSL 4 | def stages_root 5 | fetch(:stages_root, 'config/deploy') 6 | end 7 | 8 | # Build stages with nested configurations 9 | # 10 | # @example simple stages 11 | # 12 | # config 13 | # ├── deploy 14 | # │   ├── production.rb 15 | # │   └── staging.rb 16 | # └── deploy.rb 17 | # 18 | # * cap production 19 | # * cap staging 20 | # 21 | # @example stages with nested configurations 22 | # 23 | # config 24 | # ├── deploy 25 | # │   ├── soa 26 | # │   │   ├── blog 27 | # │   │   │   ├── production.rb 28 | # │   │   │   └── staging.rb 29 | # │   │   └── wiki 30 | # │   │   └── qa.rb 31 | # │   └── soa.rb 32 | # └── deploy.rb 33 | # 34 | # * cap soa:blog:production 35 | # * cap soa:blog:staging 36 | # * cap soa:wiki:qa 37 | def stages 38 | Dir["#{stages_root}/**/*.rb"].map { |file| 39 | file.slice(stages_root.size + 1 .. -4).tr('/', ':') 40 | }.tap { |paths| 41 | paths.reject! { |path| 42 | paths.any? { |another| another != path && another.start_with?(path + ':') } 43 | } 44 | }.sort 45 | end 46 | end 47 | end 48 | end 49 | 50 | self.extend Capistrano::Multiconfig::DSL 51 | -------------------------------------------------------------------------------- /spec/integration_spec.rb: -------------------------------------------------------------------------------- 1 | describe "integration" do 2 | def run_cap(args) 3 | Dir.chdir 'fixtures' do 4 | `env STAGES_ROOT=#{stages_root} bundle exec cap #{args}` 5 | end 6 | end 7 | 8 | describe "displaying tasks" do 9 | subject do 10 | run_cap("-T") 11 | end 12 | 13 | context "empty root" do 14 | let(:stages_root) { 'config/empty' } 15 | it { should == "" } 16 | end 17 | 18 | context "two files root" do 19 | let(:stages_root) { 'config/two_files' } 20 | 21 | it "should display configurations" do 22 | subject.should == <<-TEXT 23 | cap production # Load production configuration 24 | cap staging # Load staging configuration 25 | TEXT 26 | end 27 | end 28 | 29 | context "two files with same prefix root" do 30 | let(:stages_root) { 'config/two_files_with_same_prefix' } 31 | 32 | it "should display configurations" do 33 | subject.should == <<-TEXT 34 | cap qa # Load qa configuration 35 | cap qa1 # Load qa1 configuration 36 | TEXT 37 | end 38 | end 39 | 40 | context "root with nested directory and two files inside" do 41 | let(:stages_root) { 'config/nested' } 42 | it { 43 | should == <<-TEXT 44 | cap app:production # Load app:production configuration 45 | cap app:staging # Load app:staging configuration 46 | TEXT 47 | } 48 | end 49 | 50 | context "root with two nested directories and two files inside" do 51 | let(:stages_root) { 'config/two_nested' } 52 | it { 53 | should == <<-TEXT 54 | cap api:production # Load api:production configuration 55 | cap api:staging # Load api:staging configuration 56 | cap app:production # Load app:production configuration 57 | cap app:staging # Load app:staging configuration 58 | TEXT 59 | } 60 | end 61 | 62 | context "root nested with shared file" do 63 | let(:stages_root) { 'config/nested_with_shared_file' } 64 | it { 65 | should == <<-TEXT 66 | cap app:production # Load app:production configuration 67 | cap app:staging # Load app:staging configuration 68 | TEXT 69 | } 70 | end 71 | 72 | context "root nested with another file" do 73 | let(:stages_root) { 'config/nested_with_another_file' } 74 | it { 75 | should == <<-TEXT 76 | cap app:production # Load app:production configuration 77 | cap app:staging # Load app:staging configuration 78 | cap deploy # Load deploy configuration 79 | TEXT 80 | } 81 | end 82 | 83 | context "root nested with shared and another file" do 84 | let(:stages_root) { 'config/nested_with_shared_and_another_file' } 85 | it { 86 | should == <<-TEXT 87 | cap app:production # Load app:production configuration 88 | cap app:staging # Load app:staging configuration 89 | cap deploy # Load deploy configuration 90 | TEXT 91 | } 92 | end 93 | 94 | context "root with foreign file" do 95 | let(:stages_root) { 'config/with_foreign_file' } 96 | it { 97 | should == <<-TEXT 98 | cap production # Load production configuration 99 | cap staging # Load staging configuration 100 | TEXT 101 | } 102 | end 103 | 104 | context "third level nested root" do 105 | let(:stages_root) { "config/third_level_nested" } 106 | 107 | it { 108 | should == <<-TEXT 109 | cap app:blog:production # Load app:blog:production configuration 110 | cap app:blog:staging # Load app:blog:staging configuration 111 | cap app:wiki:production # Load app:wiki:production configuration 112 | cap app:wiki:qa # Load app:wiki:qa configuration 113 | TEXT 114 | } 115 | end 116 | end 117 | 118 | 119 | 120 | describe "task invocation" do 121 | 122 | context "sample configurations" do 123 | let(:stages_root) { 'config/sample' } 124 | 125 | context "without configuration" do 126 | subject { run_cap("hello_world") } 127 | it "should require configuration" do 128 | subject.should include("Stage not set") 129 | end 130 | end 131 | 132 | context "with apps:world1 configuration" do 133 | subject { run_cap("apps:world1 hello_world") } 134 | 135 | it "should use value set in configuration" do 136 | subject.should == "hello from world1\n" 137 | end 138 | end 139 | 140 | context "with apps:world2 configuration" do 141 | subject { run_cap("apps:world2 hello_world") } 142 | 143 | it "should use value set in configuration" do 144 | subject.should == "hello from world2\n" 145 | end 146 | end 147 | end 148 | 149 | context "configurations with shared file" do 150 | let(:stages_root) { 'config/nested_with_shared_file' } 151 | context "with app:production" do 152 | subject { run_cap("app:production hello_world") } 153 | it "should display certain message" do 154 | subject.should == "hello from production world\n" 155 | end 156 | end 157 | context "with app:staging" do 158 | subject { run_cap("app:staging hello_world") } 159 | it "should display shared message" do 160 | subject.should == "hello from shared world\n" 161 | end 162 | end 163 | end 164 | 165 | context "configuration with double nested shared file" do 166 | let(:stages_root) { 'config/double_nested_shared_file' } 167 | subject { run_cap("level0:level1:config hello_world") } 168 | it "should display nested message from all levels" do 169 | subject.should == "hello from level0 level1 world\n" 170 | end 171 | end 172 | 173 | context "configuration with root and nested" do 174 | let(:stages_root) { 'config/root_with_nested' } 175 | subject { run_cap("app:config hello_world") } 176 | it "should display nested message from root" do 177 | subject.should == "hello from root world\n" 178 | end 179 | end 180 | end 181 | 182 | end 183 | --------------------------------------------------------------------------------