olek-capistrano-multiconfig 0.0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1 @@
1
+ source "http://rubygems.org"
data/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # capistrano-multiconfig
2
+
3
+ ## Description
4
+
5
+ Capistrano extension that allows to use multiple configurations.
6
+
7
+ Multiconfig extension is similar to [multistage](https://github.com/capistrano/capistrano-ext) extenstion.
8
+ But it's not only about 'stage' configurations. It's about any configuration that you may need.
9
+ Extension recursively builds configuration list from configuration root directory.
10
+ Each configuration loads recursively configuration from it namespace files and own configuration file.
11
+
12
+ ## Usage
13
+
14
+ Install gem
15
+
16
+ $ gem install capistrano-multistage
17
+
18
+
19
+ Add to `Capfile`
20
+
21
+ set :config, 'path/to/your/configurations'
22
+ require 'capistrano/multiconfig'
23
+
24
+ ## Example
25
+
26
+ Assume we need next configurations:
27
+
28
+ * services:billing:production
29
+ * services:billing:qa
30
+ * blog:production
31
+ * blog:staging
32
+ * dev:wiki
33
+
34
+ Choose configuration root directory for example `config/deploy`
35
+
36
+ Create configuration files:
37
+
38
+ config/deploy/services/billing/production.rb
39
+ config/deploy/services/billing/qa.rb
40
+ config/deploy/blog/production.rb
41
+ config/deploy/blog/staging.rb
42
+ config/deploy/dev/wiki.rb
43
+
44
+ Add to `Capfile`:
45
+
46
+ set :config_root, 'config/deploy'
47
+ require 'capistrano/multiconfig'
48
+
49
+ Put related capistrano configuration to each file according to file meaning.
50
+
51
+ Check tasks:
52
+
53
+ $ cap -T
54
+ cap services:billing:production # Load services:billing:production configuration
55
+ cap services:billing:qa # Load services:billing:qa configuration
56
+ cap blog:production # Load blog:production configuration
57
+ cap blog:staging # Load blog:staging configuration
58
+ cap wiki # Load wiki configuration
59
+ cap invoke # Invoke a single command on the remote servers.
60
+ cap shell # Begin an interactive Capistrano session.
61
+
62
+ Let's try to run task without specified configuration:
63
+
64
+ $ cap shell
65
+ triggering start callbacks for `shell'
66
+ * executing `multiconfig:ensure'
67
+ No configuration specified. Please specify one of:
68
+ * wiki:production
69
+ * wiki:staging
70
+ * blog:production
71
+ * blog:staging
72
+ (e.g. `cap wiki:production shell')
73
+
74
+
75
+ So we must provide configuration as first task:
76
+
77
+ $ cap services:billing:qa shell
78
+
79
+ ## Configuration Loading
80
+
81
+ Configuration task loads not only configuration associated with it filename.
82
+ It also recursively load configurations from all namespaces.
83
+
84
+ For example for *:config_root* `config/deploy` task `cap apps/blog/qa.rb` loads with **order** next configuration files (if they exist):
85
+
86
+ * config/deploy/apps.rb
87
+ * config/deploy/apps/blog.rb
88
+ * config/deploy/apps/blog/qa.rb
89
+
90
+ So it's easy to put shared configuration.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "olek-capistrano-multiconfig"
6
+ s.version = "0.0.3.1"
7
+ s.authors = ["Andriy Yanko"]
8
+ s.email = ["andriy.yanko@gmail.com"]
9
+ s.homepage = "https://github.com/railsware/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) extenstion.
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
+
18
+ s.rubyforge_project = "capistrano-multiconfig"
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+
25
+ s.add_runtime_dependency "capistrano", ">=2.5.5"
26
+ end
@@ -0,0 +1,2 @@
1
+ require 'capistrano/multiconfig/configurations'
2
+ require 'capistrano/multiconfig/ensure'
@@ -0,0 +1,92 @@
1
+ Capistrano::Configuration.instance.load do
2
+ # configurations root directory
3
+ config_root = File.expand_path(fetch(:config_root, "config/deploy"))
4
+
5
+ # list of configurations files
6
+ config_files = Dir["#{config_root}/**/*.rb"]
7
+
8
+ # remove configuration file if it's part of another configuration
9
+ config_files.reject! do |config_file|
10
+ config_dir = config_file.gsub(/\.rb$/, '/')
11
+ config_files.any? { |file| file[0, config_dir.size] == config_dir }
12
+ end
13
+
14
+ # build configuration names list
15
+ config_names = config_files.map do |config_file|
16
+ config_file.sub("#{config_root}/", '').sub(/\.rb$/, '').gsub('/', ':')
17
+ end
18
+
19
+ # ensure that configuration segments don't override any method, task or namespace
20
+ config_names.each do |config_name|
21
+ config_name.split(':').each do |segment|
22
+ if all_methods.any? { |m| m == segment }
23
+ raise ArgumentError,
24
+ "Config task #{config_name} name overrides #{segment.inspect} (method|task|namespace)"
25
+ end
26
+ end
27
+ end
28
+
29
+ # create configuration task for each configuration name
30
+ config_names.each do |config_name|
31
+ segments = config_name.split(':')
32
+ namespace_names = segments[0, segments.size - 1]
33
+ task_name = segments.last
34
+
35
+ # create configuration task block.
36
+ # NOTE: Capistrano 'namespace' DSL invokes instance_eval that
37
+ # that pass evaluable object as argument to block.
38
+ block = lambda do |parent|
39
+ desc "Load #{config_name} configuration"
40
+ task(task_name) do
41
+ # set configuration name as :config_name variable
42
+ top.set(:config_name, config_name)
43
+
44
+ # recursively load configurations
45
+ segments.size.times do |i|
46
+ path = ([config_root] + segments[0..i]).join('/') + '.rb'
47
+ top.load(:file => path) if File.exists?(path)
48
+ end
49
+ top_stage_path = File.join(config_root, segments.last) + '.rb'
50
+ top.load(:file => top_stage_path) if File.exists?(top_stage_path)
51
+ end
52
+ end
53
+
54
+ # wrap task block into namespace blocks
55
+ #
56
+ # namespace_names = [nsN, ..., ns2, ns1]
57
+ #
58
+ # block = block0 = lambda do |parent|
59
+ # desc "DESC"
60
+ # task(:task_name) { TASK }
61
+ # end
62
+ # block = block1 = lambda { |parent| parent.namespace(:ns1, &block0) }
63
+ # block = block2 = lambda { |parent| parent.namespace(:ns2, &block1) }
64
+ # ...
65
+ # block = blockN = lambda { |parent| parent.namespace(:nsN, &blockN-1) }
66
+ #
67
+ block = namespace_names.reverse.inject(block) do |child, name|
68
+ lambda do |parent|
69
+ parent.namespace(name, &child)
70
+ end
71
+ end
72
+
73
+ # create namespaced configuration task
74
+ #
75
+ # block = lambda do
76
+ # namespace :nsN do
77
+ # ...
78
+ # namespace :ns2 do
79
+ # namespace :ns1 do
80
+ # desc "DESC"
81
+ # task(:task_name) { TASK }
82
+ # end
83
+ # end
84
+ # ...
85
+ # end
86
+ # end
87
+ block.call(top)
88
+ end
89
+
90
+ # set configuration names list
91
+ set(:config_names, config_names)
92
+ end
@@ -0,0 +1,15 @@
1
+ Capistrano::Configuration.instance.load do
2
+ namespace :multiconfig do
3
+ desc "[internal] Ensure that a configuration has been selected"
4
+ task :ensure do
5
+ unless exists?(:config_name)
6
+ puts "No configuration specified. Please specify one of:"
7
+ config_names.each { |name| puts " * #{name}" }
8
+ puts "(e.g. `cap #{config_names.first} #{ARGV.last}')"
9
+ abort
10
+ end
11
+ end
12
+ end
13
+
14
+ on :start, 'multiconfig:ensure', :except => config_names
15
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: olek-capistrano-multiconfig
3
+ version: !ruby/object:Gem::Version
4
+ hash: 65
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 3
10
+ - 1
11
+ version: 0.0.3.1
12
+ platform: ruby
13
+ authors:
14
+ - Andriy Yanko
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2012-01-24 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: capistrano
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 17
30
+ segments:
31
+ - 2
32
+ - 5
33
+ - 5
34
+ version: 2.5.5
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ description: "\n\
38
+ Multiconfig extension is similar to [multistage](https://github.com/capistrano/capistrano-ext) extenstion.\n\
39
+ But it's not only about 'stage' configurations. It's about any configuration that you may need.\n\
40
+ Extension recursively builds configuration list from configuration root directory.\n\
41
+ Each configuration loads recursively configuration from namespace files and own configuration file.\n "
42
+ email:
43
+ - andriy.yanko@gmail.com
44
+ executables: []
45
+
46
+ extensions: []
47
+
48
+ extra_rdoc_files: []
49
+
50
+ files:
51
+ - .gitignore
52
+ - Gemfile
53
+ - README.md
54
+ - Rakefile
55
+ - capistrano-multiconfig.gemspec
56
+ - lib/capistrano/multiconfig.rb
57
+ - lib/capistrano/multiconfig/configurations.rb
58
+ - lib/capistrano/multiconfig/ensure.rb
59
+ homepage: https://github.com/railsware/multiconfig
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options: []
64
+
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ hash: 3
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ requirements: []
86
+
87
+ rubyforge_project: capistrano-multiconfig
88
+ rubygems_version: 1.8.13
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Capistrano extension that allows to use multiple configurations
92
+ test_files: []
93
+