capistrano-multiconfig 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a4a01eddf6db929483491f1ab6e8f1bee0c1de0
4
- data.tar.gz: 37b27ad85cb0cdfb72562e666e3886c90a09256d
3
+ metadata.gz: 2c9b7fb215030f53d9d0eff91305889ad41b26a7
4
+ data.tar.gz: 29adfd8cfd8a8864ea0cb39597aa54b46d143428
5
5
  SHA512:
6
- metadata.gz: 4125540d382803fa4f317d7452eeb83229bae15457aaefab91de85b1f5d2c3331d492b6e3dc9441c48c23d63ecd5e3818875f1141aaacc2f71c5811c7442d7a6
7
- data.tar.gz: a1e9b7b9dbad421babef44a1704180a9a8d90156a87ca8e0b76d8f8048ead068cad6b234f80d08df0b335cc1d216d74142f76fbaff4d4256e2d1cc4e71f4be18
6
+ metadata.gz: 6ddd88b0ee9b23fd0f94f26ce880e3ec304fe38c18aa4afd38c27e4a92b63060f43e129a395a9a68ef0fe449cbc7ec7b4241fb71c6f55a9363f45dfc0b3393aa
7
+ data.tar.gz: 9ec37a468dc70b0524814853c5ca2a7edb223f57458285288cded0cc7679020ccc93382be91a79a733652f1401bba103b7f30f66173cd79c8569de3f5ac6071b
data/README.md CHANGED
@@ -9,6 +9,11 @@ But it's not only about 'stage' configurations. It's about any configuration tha
9
9
  Extension recursively builds configuration list from configuration root directory.
10
10
  Each configuration loads recursively configuration from it namespace files and own configuration file.
11
11
 
12
+ ## Purpose
13
+
14
+ Extension was specially created to implement [Caphub](https://github.com/railsware/caphub) concept.
15
+ [Read more](http://railsware.com/blog/2011/11/18/caphub-multiple-applications-deployment-with-capistrano/).
16
+
12
17
  ## Usage
13
18
 
14
19
  Install gem
@@ -51,7 +56,6 @@ Create configuration files:
51
56
 
52
57
  Add to `Capfile`:
53
58
 
54
- set :config_root, 'config/deploy'
55
59
  require 'capistrano/multiconfig'
56
60
 
57
61
  Put related capistrano configuration to each file according to file meaning.
@@ -89,7 +93,7 @@ So we must provide configuration as first task:
89
93
  Configuration task loads not only configuration associated with it filename.
90
94
  It also recursively load configurations from all namespaces.
91
95
 
92
- For example for *:config_root* `config/deploy` task `cap apps/blog/qa.rb` loads with **order** next configuration files (if they exist):
96
+ For example task `cap apps/blog/qa.rb` loads with **order** next configuration files (if they exist):
93
97
 
94
98
  * config/deploy/apps.rb
95
99
  * config/deploy/apps/blog.rb
@@ -97,6 +101,12 @@ For example for *:config_root* `config/deploy` task `cap apps/blog/qa.rb` loads
97
101
 
98
102
  So it's easy to put shared configuration.
99
103
 
104
+ ## Custom stages configuration location
105
+
106
+ Specify in `Capfile`:
107
+
108
+ set :stages_root, 'deployment'
109
+ require 'capistrano/multiconfig'
100
110
 
101
111
  ## Testing
102
112
 
@@ -107,3 +117,9 @@ So it's easy to put shared configuration.
107
117
 
108
118
  * Copyright (c) 2013 Railsware [www.railsware.com](http://www.railsware.com)
109
119
  * [MIT](www.opensource.org/licenses/MIT)
120
+
121
+ ## References
122
+
123
+ * [capistrano](https://github.com/capistrano/capistrano)
124
+ * [caphub](https://github.com/railsware/caphub)
125
+
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "capistrano-multiconfig"
6
- s.version = "3.0.1"
6
+ s.version = "3.0.2"
7
7
  s.authors = ["Andriy Yanko"]
8
8
  s.email = ["andriy.yanko@gmail.com"]
9
9
  s.homepage = "https://github.com/railsware/multiconfig"
data/fixtures/Capfile CHANGED
@@ -1,7 +1,9 @@
1
- set :config_root, ENV.fetch('CONFIG_ROOT')
1
+ set :stages_root, ENV.fetch('STAGES_ROOT')
2
2
 
3
3
  require 'capistrano/multiconfig'
4
4
 
5
5
  task :hello_world do
6
6
  puts fetch(:message, "hello")
7
7
  end
8
+
9
+ # vim syntax=ruby
@@ -1,33 +1,85 @@
1
- require 'capistrano/multiconfig/configurations'
2
-
3
1
  include Capistrano::DSL
4
2
 
5
- config_root_path = File.expand_path(fetch(:config_root, "config/deploy"))
3
+ def stages_root
4
+ fetch(:stages_root, 'config/deploy')
5
+ end
6
+
7
+ # Build stages with nested configurations
8
+ #
9
+ # @example simple stages
10
+ #
11
+ # config
12
+ # ├── deploy
13
+ # │   ├── production.rb
14
+ # │   └── staging.rb
15
+ # └── deploy.rb
16
+ #
17
+ # * cap production
18
+ # * cap staging
19
+ #
20
+ # @example stages with nested configurations
21
+ #
22
+ # config
23
+ # ├── deploy
24
+ # │   ├── soa
25
+ # │   │   ├── blog
26
+ # │   │   │   ├── production.rb
27
+ # │   │   │   └── staging.rb
28
+ # │   │   └── wiki
29
+ # │   │   └── qa.rb
30
+ # │   └── soa.rb
31
+ # └── deploy.rb
32
+ #
33
+ # * cap soa:blog:production
34
+ # * cap soa:blog:staging
35
+ # * cap soa:wiki:qa
36
+ def stages
37
+ Dir["#{stages_root}/**/*.rb"].map { |file|
38
+ file.slice(stages_root.size + 1 .. -4).tr('/', ':')
39
+ }.tap { |paths|
40
+ paths.reject! { |path|
41
+ paths.any? { |another| another != path && another.start_with?(path) }
42
+ }
43
+ }.sort
44
+ end
6
45
 
7
- config_names = Capistrano::Multiconfig::Configurations.find_names(config_root_path)
46
+ stages.each do |stage|
47
+ Rake::Task.define_task(stage) do
8
48
 
9
- config_names.each do |config_name|
10
- Rake::Task.define_task(config_name) do
11
- set(:config_name, config_name)
49
+ # Set stage variable
50
+ set(:stage, stage)
12
51
 
52
+ # Load defaults variables
13
53
  load "capistrano/defaults.rb"
14
54
 
15
- paths = [ config_root_path + '.rb' ]
16
-
17
- (segments = config_name.split(":")).size.times do |i|
18
- paths << File.join([config_root_path] + segments[0..i]) + '.rb'
55
+ # Load stage configuration(s).
56
+ #
57
+ # For stage 'production' will be loaded next configurations:
58
+ #
59
+ # * config/deploy.rb
60
+ # * config/deploy/production.rb
61
+ #
62
+ # For stage 'soa:blog:production' will be loaded next configurations:
63
+ #
64
+ # * config/deploy.rb
65
+ # * config/deploy/soa.rb
66
+ # * config/deploy/soa/blog.rb
67
+ # * config/deploy/soa/blog/production.rb
68
+ stage.split(':').inject([stages_root]) do |paths, segment|
69
+ paths << File.join(paths.last, segment)
70
+ end.each do |path|
71
+ file = "#{path}.rb"
72
+ load(file) if File.exists?(file)
19
73
  end
20
74
 
21
- paths.each { |path| load(path) if File.exists?(path) }
22
-
75
+ # Load SCM tasks
23
76
  load "capistrano/#{fetch(:scm)}.rb"
77
+
78
+ # Set locale
24
79
  I18n.locale = fetch(:locale, :en)
25
- configure_backend
26
- end.add_description("Load #{config_name} configuration")
27
- end
28
80
 
29
- set(:config_names, config_names)
81
+ # configure core backend
82
+ configure_backend
30
83
 
31
- def stages
32
- fetch(:config_names)
84
+ end.add_description("Load #{stage} configuration")
33
85
  end
@@ -1,7 +1,7 @@
1
1
  describe "integration" do
2
2
  def run_cap(args)
3
3
  Dir.chdir 'fixtures' do
4
- `env CONFIG_ROOT=#{config_root} bundle exec cap #{args}`
4
+ `env STAGES_ROOT=#{stages_root} bundle exec cap #{args}`
5
5
  end
6
6
  end
7
7
 
@@ -10,8 +10,13 @@ describe "integration" do
10
10
  run_cap("-T")
11
11
  end
12
12
 
13
+ context "empty root" do
14
+ let(:stages_root) { 'config/empty' }
15
+ it { should == "" }
16
+ end
17
+
13
18
  context "two files root" do
14
- let(:config_root) { "config/two_files" }
19
+ let(:stages_root) { 'config/two_files' }
15
20
 
16
21
  it "should display configurations" do
17
22
  subject.should == <<-TEXT
@@ -21,24 +26,90 @@ TEXT
21
26
  end
22
27
  end
23
28
 
29
+ context "root with nested directory and two files inside" do
30
+ let(:stages_root) { 'config/nested' }
31
+ it {
32
+ should == <<-TEXT
33
+ cap app:production # Load app:production configuration
34
+ cap app:staging # Load app:staging configuration
35
+ TEXT
36
+ }
37
+ end
38
+
39
+ context "root with two nested directories and two files inside" do
40
+ let(:stages_root) { 'config/two_nested' }
41
+ it {
42
+ should == <<-TEXT
43
+ cap api:production # Load api:production configuration
44
+ cap api:staging # Load api:staging configuration
45
+ cap app:production # Load app:production configuration
46
+ cap app:staging # Load app:staging configuration
47
+ TEXT
48
+ }
49
+ end
50
+
51
+ context "root nested with shared file" do
52
+ let(:stages_root) { 'config/nested_with_shared_file' }
53
+ it {
54
+ should == <<-TEXT
55
+ cap app:production # Load app:production configuration
56
+ cap app:staging # Load app:staging configuration
57
+ TEXT
58
+ }
59
+ end
60
+
61
+ context "root nested with another file" do
62
+ let(:stages_root) { 'config/nested_with_another_file' }
63
+ it {
64
+ should == <<-TEXT
65
+ cap app:production # Load app:production configuration
66
+ cap app:staging # Load app:staging configuration
67
+ cap deploy # Load deploy configuration
68
+ TEXT
69
+ }
70
+ end
71
+
72
+ context "root nested with shared and another file" do
73
+ let(:stages_root) { 'config/nested_with_shared_and_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 with foreign file" do
84
+ let(:stages_root) { 'config/with_foreign_file' }
85
+ it {
86
+ should == <<-TEXT
87
+ cap production # Load production configuration
88
+ cap staging # Load staging configuration
89
+ TEXT
90
+ }
91
+ end
92
+
24
93
  context "third level nested root" do
25
- let(:config_root) { "config/third_level_nested" }
94
+ let(:stages_root) { "config/third_level_nested" }
26
95
 
27
- it "should display configurations" do
28
- subject.should == <<-TEXT
96
+ it {
97
+ should == <<-TEXT
29
98
  cap app:blog:production # Load app:blog:production configuration
30
99
  cap app:blog:staging # Load app:blog:staging configuration
31
100
  cap app:wiki:production # Load app:wiki:production configuration
32
101
  cap app:wiki:qa # Load app:wiki:qa configuration
33
102
  TEXT
34
- end
103
+ }
35
104
  end
36
105
  end
37
106
 
107
+
108
+
38
109
  describe "task invocation" do
39
110
 
40
111
  context "sample configurations" do
41
- let(:config_root) { 'config/sample' }
112
+ let(:stages_root) { 'config/sample' }
42
113
 
43
114
  context "without configuration" do
44
115
  subject { run_cap("hello_world") }
@@ -65,7 +136,7 @@ TEXT
65
136
  end
66
137
 
67
138
  context "configurations with shared file" do
68
- let(:config_root) { 'config/nested_with_shared_file' }
139
+ let(:stages_root) { 'config/nested_with_shared_file' }
69
140
  context "with app:production" do
70
141
  subject { run_cap("app:production hello_world") }
71
142
  it "should display certain message" do
@@ -81,7 +152,7 @@ TEXT
81
152
  end
82
153
 
83
154
  context "configuration with double nested shared file" do
84
- let(:config_root) { 'config/double_nested_shared_file' }
155
+ let(:stages_root) { 'config/double_nested_shared_file' }
85
156
  subject { run_cap("level0:level1:config hello_world") }
86
157
  it "should display nested message from all levels" do
87
158
  subject.should == "hello from level0 level1 world\n"
@@ -89,7 +160,7 @@ TEXT
89
160
  end
90
161
 
91
162
  context "configuration with root and nested" do
92
- let(:config_root) { 'config/root_with_nested' }
163
+ let(:stages_root) { 'config/root_with_nested' }
93
164
  subject { run_cap("app:config hello_world") }
94
165
  it "should display nested message from root" do
95
166
  subject.should == "hello from root world\n"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-multiconfig
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andriy Yanko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-16 00:00:00.000000000 Z
11
+ date: 2013-10-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capistrano
@@ -76,8 +76,6 @@ files:
76
76
  - fixtures/config/with_foreign_file/readme.md
77
77
  - fixtures/config/with_foreign_file/staging.rb
78
78
  - lib/capistrano/multiconfig.rb
79
- - lib/capistrano/multiconfig/configurations.rb
80
- - spec/capistrano/multiconfig/configurations_spec.rb
81
79
  - spec/integration_spec.rb
82
80
  homepage: https://github.com/railsware/multiconfig
83
81
  licenses: []
@@ -103,5 +101,4 @@ signing_key:
103
101
  specification_version: 4
104
102
  summary: Capistrano extension that allows to use multiple configurations
105
103
  test_files:
106
- - spec/capistrano/multiconfig/configurations_spec.rb
107
104
  - spec/integration_spec.rb
@@ -1,49 +0,0 @@
1
- module Capistrano
2
- module Multiconfig
3
- class Configurations
4
- def self.find_names(root_path)
5
- new(root_path).find_names
6
- end
7
-
8
- attr_reader :root_path
9
-
10
- def initialize(root_path)
11
- @root_path = root_path
12
- end
13
-
14
- # find configuration names
15
- def find_names
16
- files = scan_files
17
- files.sort!
18
- remove_shared_files!(files)
19
- build_names(files)
20
- end
21
-
22
- private
23
-
24
- # Scan recursively root path
25
- def scan_files
26
- Dir["#{root_path}/**/*.rb"]
27
- end
28
-
29
- # Remove path when there is the same directory with child.
30
- #
31
- # app/staging.rb (is shared configuration for 'alpha' and 'beta')
32
- # app/staging/alpha.rb
33
- # app/staging/beta.rb
34
- def remove_shared_files!(files)
35
- files.reject! do |file|
36
- dir = file.gsub(/\.rb$/, '/')
37
- files.any? { |f| f[0, dir.size] == dir }
38
- end
39
- end
40
-
41
- # Convert "app/blog/production" to "app:blog:production"
42
- def build_names(files)
43
- files.map do |file|
44
- file.sub("#{root_path}/", '').sub(/\.rb$/, '').gsub('/', ':')
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,100 +0,0 @@
1
- require 'capistrano/multiconfig/configurations'
2
-
3
- describe Capistrano::Multiconfig::Configurations do
4
-
5
- describe ".find_names" do
6
- subject { described_class.find_names(config_root) }
7
-
8
- context "empty root" do
9
- let(:config_root) { 'fixtures/config/empty' }
10
- it { should == [] }
11
- end
12
-
13
- context "root with two files" do
14
- let(:config_root) { 'fixtures/config/two_files' }
15
- it {
16
- should == [
17
- 'production',
18
- 'staging'
19
- ]
20
- }
21
- end
22
-
23
- context "root with nested directory and two files inside" do
24
- let(:config_root) { 'fixtures/config/nested' }
25
- it {
26
- should == [
27
- 'app:production',
28
- 'app:staging'
29
- ]
30
- }
31
- end
32
-
33
- context "root with two nested directories and two files inside" do
34
- let(:config_root) { 'fixtures/config/two_nested' }
35
- it {
36
- should == [
37
- 'api:production',
38
- 'api:staging',
39
- 'app:production',
40
- 'app:staging'
41
- ]
42
- }
43
- end
44
-
45
- context "root with third nested directories" do
46
- let(:config_root) { 'fixtures/config/third_level_nested' }
47
- it {
48
- should == [
49
- 'app:blog:production',
50
- 'app:blog:staging',
51
- 'app:wiki:production',
52
- 'app:wiki:qa'
53
- ]
54
- }
55
- end
56
-
57
- context "root nested with shared file" do
58
- let(:config_root) { 'fixtures/config/nested_with_shared_file' }
59
- it {
60
- should == [
61
- 'app:production',
62
- 'app:staging',
63
- ]
64
- }
65
- end
66
-
67
- context "root nested with another file" do
68
- let(:config_root) { 'fixtures/config/nested_with_another_file' }
69
- it {
70
- should == [
71
- 'app:production',
72
- 'app:staging',
73
- 'deploy'
74
- ]
75
- }
76
- end
77
-
78
- context "root nested with shared and another file" do
79
- let(:config_root) { 'fixtures/config/nested_with_shared_and_another_file' }
80
- it {
81
- should == [
82
- 'app:production',
83
- 'app:staging',
84
- 'deploy'
85
- ]
86
- }
87
- end
88
-
89
- context "root with foreign file" do
90
- let(:config_root) { 'fixtures/config/with_foreign_file' }
91
- it {
92
- should == [
93
- 'production',
94
- 'staging'
95
- ]
96
- }
97
- end
98
-
99
- end
100
- end