capistrano_multiconfig_parallel 0.32.0 → 1.0.0

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: 5f2058afba53f3625fe0253f9ea80bcfcd83928f
4
- data.tar.gz: 6d568cea8e8d7e5501166d5e0fe3f2a8c5fd4baa
3
+ metadata.gz: d913f859f09d3474f80d0ebc9df04c6207dbad68
4
+ data.tar.gz: 0fa7d2ff36d4f718ace5e149e7dec0939fd8479b
5
5
  SHA512:
6
- metadata.gz: e18832aa02656f2de014326cc40c3cc7b9107c2c9e32b0c9c8edc9a542054f55d8fe9cf86f2a545006f733adcc4656af66ee76285b70d6f433ddf10748eb7861
7
- data.tar.gz: c3b95a15ab8d3a962d1013918d082b6bd76ddb074d9bdf3d51d9c4dd6c8216223ecfafc937412ca0bfe575d79207d416c1843e2a5640023ce2c902b641b6914f
6
+ metadata.gz: 53e7738c4d3b8ff65dc9a2e2758af6880562c6e9482a54de930368d27ec16bfc5e416232aea4e4392d5f918f728bfb0f7011e9c5ae657580cba2f4991abe28fb
7
+ data.tar.gz: 2f064bbc1b8d6ef2ed23132b8d67ca33bc94964cb2ba2381fbb3dc7e0345d5d5dd32c0d2d05efebe8518eee2c953994cde511a1a9345e66ede2ec74b1ae7feb7
data/README.md CHANGED
@@ -17,6 +17,13 @@ IMPORTANT! The whole reason for this gem was for using [Caphub](https://github.c
17
17
 
18
18
  CAUTION!! PLEASE READ CAREFULLY!! Capistrano is not thread-safe. However in order to work around this problem, each of the task is executing inside a thread that spawns a new process in order to run capistrano tasks The thread monitors the process. This works well, however if the tasks you are executing is working with files, you might get into deadlocks because multiple proceses try to access same resource. Instead of using files , please consider using StringIO instead.
19
19
 
20
+ NEW Improvements in version 1.0.0
21
+ ---------------------------------
22
+
23
+ - added support for Capistrano version 2
24
+ - a lot of refactoring and bug fixes
25
+ - removed Branch variable ( this needs to be passed when asked for additional env options for each job!!!).
26
+
20
27
  Requirements
21
28
  ------------
22
29
 
@@ -29,11 +36,12 @@ Requirements
29
36
  7. [colorize >= 0.7](https://github.com/fazibear/colorize)
30
37
  8. [eventmachine >= 1.0.3](https://github.com/eventmachine/eventmachine)
31
38
  9. [right_popen >= 1.1.3](https://github.com/rightscale/right_popen)
32
- 10. [capistrano >= 3.0](https://github.com/capistrano/capistrano/)
39
+ 10. [capistrano >= 2.0](https://github.com/capistrano/capistrano/)
33
40
  11. [configliere >= 0.4](https://github.com/infochimps-platform/configliere)
34
41
  12. [inquirer >= 0.2](https://github.com/arlimus/inquirer.rb)
35
42
  13. [devnull >= 0.1](https://github.com/arlimus/inquirer.rb)
36
43
  14. [rack >= 1.6](http://rack.github.io/)
44
+ 15. [rake >= 10.4](https://github.com/ruby/rake)
37
45
 
38
46
  Compatibility
39
47
  -------------
@@ -157,13 +165,13 @@ development_stages:
157
165
  #<development_stage> - the name of one of the stages you previously configured
158
166
  #<task_name> - the capistrano task that you want to execute ( example: 'deploy' )
159
167
 
160
- bundle exec multi_cap <development_stage> <task_name> BOX=<box_name>,<box_name>
168
+ bundle exec multi_cap <development_stage> <task_name> BOX=<box_name>,<box_name>
161
169
 
162
170
  ```
163
171
 
164
- If a branch is specified using **BRANCH=name** it will deploy same branch to all sandboxes The branch environment variable is then passed to the capistrano task
172
+ For Capistrano 2 please use **-S box=<box_name>,<box_name>**
165
173
 
166
- Also the script will ask if there are any other environment variables that user might want to pass to each of the sandboxes separately.
174
+ The script will ask if there are any other environment variables that user might want to pass to each of the sandboxes separately.
167
175
 
168
176
  ### 1.2) Deploying the application to multiple stages ( Using the customized command "deploy_multi_stages")
169
177
 
@@ -174,9 +182,7 @@ bundle exec multi_cap deploy_multi_stages STAGES=development, staging, producti
174
182
 
175
183
  NOTE: IF you want to execute a different command on all stages, you can specify environment variable **ACTION=task_name** either when you specify the STAGES, or can be done individually for each task when prompted about additional ENV options
176
184
 
177
- If a branch is specified using **BRANCH=name** it will deploy same branch to all stages.The branch environment variable is then passed to the capistrano task
178
-
179
- Also the script will ask if there are any other environment variables that user might want to pass to each of the stages separately.
185
+ The script will ask if there are any other environment variables that user might want to pass to each of the stages separately.
180
186
 
181
187
  If you use **capistrano-gitflow**, the workers will first deploy to all the other stages and only after staging is tagged , will trigger a new worker to start deploying to production
182
188
 
@@ -228,7 +234,7 @@ Demo:
228
234
 
229
235
  NOTE: IF you want to execute a different command on all stages, you can specify environment variable **ACTION=task_name** either when you specify the STAGES, or can be done individually for each task when prompted about additional ENV options
230
236
 
231
- If a branch is specified using **BRANCH=branch_name** it will deploy same branch to all stages.The branch environment variable is then passed to the capistrano task If you want different branches , capistrano will ask for additional ENV options for each stage, and can be specified then for each stage
237
+ The script will ask for additional ENV options for each stage.
232
238
 
233
239
  If you use **capistrano-gitflow**, the workers will first deploy to all the other stages and only after staging is tagged , will trigger a new worker to start deploying to production
234
240
 
@@ -25,12 +25,13 @@ Gem::Specification.new do |s|
25
25
  s.add_runtime_dependency 'colorize', '~> 0.7', '>= 0.7'
26
26
  s.add_runtime_dependency 'eventmachine', '~> 1.0', '>= 1.0.3'
27
27
  s.add_runtime_dependency 'right_popen', '~> 1.1', '>= 1.1.3'
28
- s.add_runtime_dependency 'capistrano','~> 3.0','>= 3.0'
28
+ s.add_runtime_dependency 'capistrano','>= 2.0','>= 2.0'
29
29
  s.add_runtime_dependency 'activesupport', '~> 4.0','>= 4.0'
30
30
  s.add_runtime_dependency 'configliere', '~> 0.4', '>=0.4'
31
31
  s.add_runtime_dependency 'inquirer', '~> 0.2', '>= 0.2'
32
32
  s.add_runtime_dependency 'devnull','~> 0.1', '>= 0.1'
33
33
  s.add_runtime_dependency 'rack', '~> 1.6', '>= 1.6'
34
+ s.add_runtime_dependency 'rake', '~> 10.4', '>= 10.4'
34
35
 
35
36
  s.add_development_dependency 'rspec-rails', '~> 3.3', '>= 3.3'
36
37
  s.add_development_dependency 'guard', '~> 2.13', '>= 2.13'
Binary file
@@ -28,15 +28,18 @@ require 'io/console'
28
28
 
29
29
  # capistrano requirements
30
30
  require 'rake'
31
- require 'capistrano/all'
32
31
 
33
32
  # fix error with not files that can not be found
34
33
  Gem.find_files('composable_state_machine/**/*.rb').each { |path| require path }
35
34
 
36
- %w(classes helpers celluloid initializers).each do |folder_name|
35
+ %w(helpers classes celluloid core_ext).each do |folder_name|
37
36
  Gem.find_files("capistrano_multiconfig_parallel/#{folder_name}/**/*.rb").each { |path| require path }
38
37
  end
39
38
 
40
39
  require_relative './version'
41
40
  require_relative './base'
42
41
  require_relative './application'
42
+
43
+ %w(initializers).each do |folder_name|
44
+ Gem.find_files("capistrano_multiconfig_parallel/#{folder_name}/**/*.rb").each { |path| require path }
45
+ end
@@ -5,7 +5,7 @@ module CapistranoMulticonfigParallel
5
5
  include Celluloid::Logger
6
6
  include CapistranoMulticonfigParallel::ApplicationHelper
7
7
 
8
- attr_reader :stage_apps, :top_level_tasks, :jobs, :branch_backup, :condition, :manager, :dependency_tracker, :application, :stage, :name, :args, :argv, :default_stage
8
+ attr_reader :stage_apps, :top_level_tasks, :jobs, :condition, :manager, :dependency_tracker, :application, :stage, :name, :args, :argv, :default_stage
9
9
 
10
10
  def initialize
11
11
  Celluloid.boot
@@ -47,12 +47,6 @@ module CapistranoMulticonfigParallel
47
47
  end
48
48
  end
49
49
 
50
- def backup_the_branch
51
- return if custom_command? || @argv['BRANCH'].blank?
52
- @branch_backup = @argv['BRANCH'].to_s
53
- @argv['BRANCH'] = nil
54
- end
55
-
56
50
  def custom_command?
57
51
  if multi_apps?
58
52
  !stages.include?(@top_level_tasks.first) && custom_commands.include?(@top_level_tasks.first)
@@ -91,8 +85,12 @@ module CapistranoMulticonfigParallel
91
85
  @top_level_tasks.push(Rake.application.default_task_name) if @top_level_tasks.blank?
92
86
  end
93
87
 
88
+ def action_key
89
+ capistrano_version_2? ? 'action' : 'ACTION'
90
+ end
91
+
94
92
  def verify_options_custom_command(options)
95
- options[:action] = @argv['ACTION'].present? ? @argv['ACTION'] : 'deploy'
93
+ options[:action] = @argv[action_key].present? ? @argv[action_key] : 'deploy'
96
94
  options
97
95
  end
98
96
 
@@ -107,7 +105,6 @@ module CapistranoMulticonfigParallel
107
105
  options = prepare_options(options)
108
106
  options = options.stringify_keys
109
107
  apps = @dependency_tracker.fetch_apps_needed_for_deployment(options['app'], options['action'])
110
- backup_the_branch if multi_apps?
111
108
  deploy_multiple_apps(apps, options)
112
109
  deploy_app(options) if !custom_command? || !multi_apps?
113
110
  end
@@ -126,8 +123,12 @@ module CapistranoMulticonfigParallel
126
123
  find_loaded_gem('capistrano-gitflow').present?
127
124
  end
128
125
 
126
+ def stages_key
127
+ capistrano_version_2? ? 'stages' : 'STAGES'
128
+ end
129
+
129
130
  def fetch_multi_stages
130
- custom_stages = @argv['STAGES'].blank? ? '' : @argv['STAGES']
131
+ custom_stages = @argv[stages_key].blank? ? '' : @argv[stages_key]
131
132
  custom_stages = strip_characters_from_string(custom_stages).split(',').compact if custom_stages.present?
132
133
  custom_stages = custom_stages.present? ? custom_stages : [@default_stage]
133
134
  custom_stages
@@ -147,9 +148,7 @@ module CapistranoMulticonfigParallel
147
148
 
148
149
  def deploy_app(options = {})
149
150
  options = options.stringify_keys
150
- branch = @branch_backup.present? ? @branch_backup : @argv['BRANCH'].to_s
151
151
  call_task_deploy_app({
152
- branch: branch,
153
152
  app: options['app'],
154
153
  action: options['action']
155
154
  }.reverse_merge(options))
@@ -178,12 +177,17 @@ module CapistranoMulticonfigParallel
178
177
  process_jobs
179
178
  end
180
179
 
180
+ def boxes_key
181
+ capistrano_version_2? ? 'box' : 'BOX'
182
+ end
183
+
181
184
  def call_task_deploy_app(options = {})
182
185
  options = options.stringify_keys
183
- main_box_name = @argv['BOX'].blank? ? '' : @argv['BOX']
186
+ main_box_name = @argv[boxes_key].blank? ? '' : @argv[boxes_key]
187
+ boxes = strip_characters_from_string(main_box_name).split(',').compact
184
188
  stage = options.fetch('stage', @default_stage)
185
- if configuration.development_stages.include?(stage) && main_box_name.present? && /^[a-z0-9,]+/.match(main_box_name)
186
- execute_on_multiple_boxes(main_box_name, options)
189
+ if configuration.development_stages.include?(stage) && boxes.present?
190
+ execute_on_multiple_boxes(boxes, options)
187
191
  else
188
192
  prepare_job(options)
189
193
  end
@@ -212,21 +216,19 @@ module CapistranoMulticonfigParallel
212
216
  terminate
213
217
  end
214
218
 
215
- # rubocop:disable CyclomaticComplexity
216
219
  def prepare_job(options)
217
220
  options = options.stringify_keys
218
- branch_name = options.fetch('branch', {})
219
221
  app = options.fetch('app', '')
220
- box = options['env_options']['BOX']
222
+ box = options['env_options'][boxes_key]
221
223
  message = box.present? ? "BOX #{box}:" : "stage #{options['stage']}:"
222
224
  env_opts = get_app_additional_env_options(app, message)
223
225
 
224
226
  options['env_options'] = options['env_options'].reverse_merge(env_opts)
225
227
 
226
- env_options = branch_name.present? ? { 'BRANCH' => branch_name }.merge(options['env_options']) : options['env_options']
227
- job_env_options = custom_command? && env_options['ACTION'].present? ? env_options.except('ACTION') : env_options
228
+ env_options = options['env_options']
229
+ job_env_options = custom_command? ? env_options.except(action_key) : env_options
228
230
  job = CapistranoMulticonfigParallel::Job.new(Actor.current, options.merge(
229
- action: custom_command? && env_options['ACTION'].present? ? env_options['ACTION'] : options['action'],
231
+ action: custom_command? && env_options[action_key].present? ? env_options[action_key] : options['action'],
230
232
  env_options: job_env_options
231
233
 
232
234
  ))
@@ -253,10 +255,9 @@ module CapistranoMulticonfigParallel
253
255
  options
254
256
  end
255
257
 
256
- def execute_on_multiple_boxes(main_box_name, options)
257
- boxes = strip_characters_from_string(main_box_name).split(',').compact
258
+ def execute_on_multiple_boxes(boxes, options)
258
259
  boxes.each do |box_name|
259
- options['env_options']['BOX'] = box_name
260
+ options['env_options'][boxes_key] = box_name
260
261
  prepare_job(options)
261
262
  end
262
263
  end
@@ -6,15 +6,28 @@ module CapistranoMulticonfigParallel
6
6
  GITFLOW_VERIFY_UPTODATE_TASK = 'gitflow:verify_up_to_date'
7
7
 
8
8
  class << self
9
- attr_accessor :logger, :original_args
9
+ attr_accessor :logger, :original_args, :config, :config_keys
10
10
  include CapistranoMulticonfigParallel::Configuration
11
- include CapistranoMulticonfigParallel::CoreHelper
11
+ include CapistranoMulticonfigParallel::GemHelper
12
+
13
+ def configuration
14
+ @config ||= fetch_configuration
15
+ @config
16
+ end
12
17
 
13
18
  def enable_logging
14
19
  enable_file_logging
15
20
  set_celluloid_exception_handling
16
21
  end
17
22
 
23
+ def capistrano_version
24
+ find_loaded_gem_property('capistrano', 'version')
25
+ end
26
+
27
+ def capistrano_version_2?
28
+ verify_gem_version('capistrano', '3.0', operator: '<')
29
+ end
30
+
18
31
  private
19
32
 
20
33
  def set_celluloid_exception_handling
@@ -22,7 +35,7 @@ module CapistranoMulticonfigParallel
22
35
  Celluloid.task_class = Celluloid::TaskThread
23
36
  Celluloid.exception_handler do |ex|
24
37
  unless ex.is_a?(Interrupt)
25
- rescue_error(ex, 'stderr')
38
+ rescue_error(ex, 'stderr')
26
39
  end
27
40
  end
28
41
  end
@@ -16,10 +16,12 @@ module CapistranoMulticonfigParallel
16
16
  trap_exit :worker_died
17
17
 
18
18
  def initialize(job_manager)
19
- # start SupervisionGroup
20
- @worker_supervisor = Celluloid::SupervisionGroup.run!
21
19
  @job_manager = job_manager
22
20
  @registration_complete = false
21
+ return if configuration.multi_secvential.to_s.downcase == 'true'
22
+ # start SupervisionGroup
23
+ @worker_supervisor = Celluloid::SupervisionGroup.run!
24
+
23
25
  # Get a handle on the SupervisionGroup::Member
24
26
  @mutex = Mutex.new
25
27
  # http://rubydoc.info/gems/celluloid/Celluloid/SupervisionGroup/Member
@@ -80,7 +80,7 @@ module CapistranoMulticonfigParallel
80
80
  elsif msg_for_stdin?(message)
81
81
  stdin_approval(message)
82
82
  else
83
- show_warning "unknown action: #{message.inspect}"
83
+ show_warning "unknown message: #{message.inspect}"
84
84
  end
85
85
  end
86
86
 
@@ -103,16 +103,16 @@ module CapistranoMulticonfigParallel
103
103
  if @job_id == message['job_id']
104
104
  @stdin_result = message.fetch('result', '')
105
105
  else
106
- show_warning "unknown invocation #{message.inspect}"
106
+ show_warning "unknown stdin_approval #{message.inspect}"
107
107
  end
108
108
  end
109
109
 
110
110
  def task_approval(message)
111
111
  return unless msg_for_task?(message)
112
- if @job_id == message['job_id'] && message['task'] == task_name && message['approved'] == 'yes'
112
+ if @job_id == message['job_id'] && message['task'].to_s == task_name.to_s && message['approved'] == 'yes'
113
113
  @task_approved = true
114
114
  else
115
- show_warning "unknown invocation #{message.inspect}"
115
+ show_warning "unknown task_approval #{message.inspect} #{task_data}"
116
116
  end
117
117
  end
118
118
 
@@ -57,7 +57,7 @@ module CapistranoMulticonfigParallel
57
57
 
58
58
  def worker_state
59
59
  default = status.to_s.upcase.red
60
- worker.alive? ? worker.worker_state : default
60
+ worker.present? && worker.alive? ? worker.worker_state : default
61
61
  end
62
62
 
63
63
  def id
@@ -14,7 +14,7 @@ module CapistranoMulticonfigParallel
14
14
  end
15
15
 
16
16
  def filtered_env_keys
17
- %w(STAGES ACTION)
17
+ filtered_env_keys_format(%w(STAGES ACTION))
18
18
  end
19
19
 
20
20
  def job_stage
@@ -27,15 +27,15 @@ module CapistranoMulticonfigParallel
27
27
  end
28
28
 
29
29
  def env_option_filtered?(key, filtered_keys_array = [])
30
- filtered_env_keys.include?(key) || filtered_keys_array.include?(key.to_s)
30
+ filtered_env_keys.include?(env_key_format(key)) || filtered_keys_array.include?(key.to_s)
31
31
  end
32
32
 
33
33
  def setup_env_options(options = {})
34
34
  array_options = []
35
35
  env_options.each do |key, value|
36
- array_options << "#{key}=#{value}" if value.present? && !env_option_filtered?(key, options.fetch(:filtered_keys, []))
36
+ array_options << "#{env_prefix} #{env_key_format(key)}=#{value}" if value.present? && !env_option_filtered?(key, options.fetch(:filtered_keys, []))
37
37
  end
38
- array_options << '--trace' if app_debug_enabled?
38
+ array_options << trace_flag if app_debug_enabled?
39
39
  array_options
40
40
  end
41
41
 
@@ -45,8 +45,9 @@ module CapistranoMulticonfigParallel
45
45
  end
46
46
 
47
47
  def to_s
48
- environment_options = setup_command_line.join(' ')
49
- "cd #{detect_root} && RAILS_ENV=#{@stage} bundle exec multi_cap #{job_stage} #{capistrano_action} #{environment_options}"
48
+ configuration_options = CapistranoMulticonfigParallel.original_args.select { |arg| arg.include?('--') }
49
+ environment_options = setup_command_line(configuration_options).join(' ')
50
+ "cd #{detect_root} && RAILS_ENV=#{stage} bundle exec multi_cap #{job_stage} #{capistrano_action} #{environment_options}"
50
51
  end
51
52
 
52
53
  def to_json
@@ -54,8 +55,7 @@ module CapistranoMulticonfigParallel
54
55
  end
55
56
 
56
57
  def execute_standard_deploy(action = nil)
57
- command = build_capistrano_task(action)
58
- run_shell_command(command)
58
+ run_shell_command(to_s)
59
59
  rescue => ex
60
60
  rescue_error(ex, 'stderr')
61
61
  execute_standard_deploy('deploy:rollback') if action.blank? && @name == 'deploy'
@@ -1,17 +1,20 @@
1
1
  require_relative '../celluloid/rake_worker'
2
2
  require_relative './input_stream'
3
3
  require_relative './output_stream'
4
+ require_relative '../helpers/application_helper'
4
5
  module CapistranoMulticonfigParallel
5
6
  # class used to handle the rake worker and sets all the hooks before and after running the worker
6
7
  class RakeTaskHooks
7
- attr_accessor :task, :env
8
- def initialize(env, task)
8
+ include CapistranoMulticonfigParallel::ApplicationHelper
9
+ attr_accessor :task, :env, :config
10
+ def initialize(env, task, config = nil)
9
11
  @env = env
10
12
  @task = task
13
+ @config = config
11
14
  end
12
15
 
13
16
  def automatic_hooks(&block)
14
- if job_id.present?
17
+ if configuration.multi_secvential.to_s.downcase == 'false' && job_id.present? && @task.present?
15
18
  actor_start_working
16
19
  actor.wait_execution until actor.task_approved
17
20
  actor_execute_block(&block)
@@ -66,7 +69,7 @@ module CapistranoMulticonfigParallel
66
69
  end
67
70
 
68
71
  def job_id
69
- @env[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID]
72
+ capistrano_version_2? ? @config.fetch(CapistranoMulticonfigParallel::ENV_KEY_JOB_ID, nil) : @env[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID]
70
73
  end
71
74
 
72
75
  def rake_actor_id
@@ -9,6 +9,7 @@ module CapistranoMulticonfigParallel
9
9
  def start
10
10
  before_start
11
11
  arguments = multi_fetch_argv(original_args)
12
+ configuration_valid?
12
13
  execute_start(arguments)
13
14
  end
14
15
 
@@ -16,6 +17,17 @@ module CapistranoMulticonfigParallel
16
17
  if arguments[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID].blank?
17
18
  run_the_application
18
19
  else
20
+ ARGV.reject! { |arg| configuration.keys.map(&:to_s).include?(arg.split('=')[0].tr('--', '')) }
21
+ run_capistrano
22
+ end
23
+ end
24
+
25
+ def run_capistrano
26
+ if capistrano_version_2?
27
+ require 'capistrano/cli'
28
+ Capistrano::CLI.execute
29
+ else
30
+ require 'capistrano/all'
19
31
  Capistrano::Application.new.run
20
32
  end
21
33
  end
@@ -27,7 +39,6 @@ module CapistranoMulticonfigParallel
27
39
 
28
40
  def run_the_application
29
41
  execute_with_rescue('stderr') do
30
- configuration_valid?
31
42
  CapistranoMulticonfigParallel::Application.new.start
32
43
  end
33
44
  end
@@ -1,16 +1,24 @@
1
1
  require_relative './core_helper'
2
2
  require_relative './internal_helper'
3
3
  require_relative './stages_helper'
4
+ require_relative './gem_helper'
5
+ require_relative './parse_helper'
6
+ require_relative './capistrano_helper'
4
7
  module CapistranoMulticonfigParallel
5
8
  # class that holds the options that are configurable for this gem
6
9
  module ApplicationHelper
7
10
  include CapistranoMulticonfigParallel::InternalHelper
8
11
  include CapistranoMulticonfigParallel::CoreHelper
12
+ include CapistranoMulticonfigParallel::ParseHelper
9
13
  include CapistranoMulticonfigParallel::StagesHelper
14
+ include CapistranoMulticonfigParallel::GemHelper
15
+ include CapistranoMulticonfigParallel::CapistranoHelper
10
16
 
11
17
  delegate :logger,
12
18
  :configuration,
13
19
  :configuration_valid?,
20
+ :capistrano_version_2?,
21
+ :capistrano_version,
14
22
  :original_args,
15
23
  to: :CapistranoMulticonfigParallel
16
24
 
@@ -40,10 +48,6 @@ module CapistranoMulticonfigParallel
40
48
  string.scan(/.{#{options.fetch('length', 80)}}|.+/).map(&:strip).join(options.fetch('character', $INPUT_RECORD_SEPARATOR))
41
49
  end
42
50
 
43
- def find_loaded_gem(name)
44
- Gem.loaded_specs.values.find { |repo| repo.name == name }
45
- end
46
-
47
51
  def percent_of(index, total)
48
52
  index.to_f / total.to_f * 100.0
49
53
  end
@@ -62,44 +66,6 @@ module CapistranoMulticonfigParallel
62
66
  result.present? && result.downcase == 'y'
63
67
  end
64
68
 
65
- def check_numeric(num)
66
- /^[0-9]+/.match(num.to_s)
67
- end
68
-
69
- def verify_empty_options(options)
70
- if options.is_a?(Hash)
71
- options.reject { |_key, value| value.blank? }
72
- elsif options.is_a?(Array)
73
- options.reject(&:blank?)
74
- else
75
- options
76
- end
77
- end
78
-
79
- def verify_array_of_strings(value)
80
- value.reject(&:blank?)
81
- warn_array_without_strings(value)
82
- end
83
-
84
- def warn_array_without_strings(value)
85
- raise ArgumentError, 'the array must contain only task names' if value.find { |row| !row.is_a?(String) }
86
- end
87
-
88
- def check_hash_set(hash, props)
89
- !Set.new(props).subset?(hash.keys.to_set) || hash.values.find(&:blank?).present?
90
- end
91
-
92
- def value_is_array?(value)
93
- value.present? && value.is_a?(Array)
94
- end
95
-
96
- def strip_characters_from_string(value)
97
- return '' if value.blank?
98
- value = value.delete("\r\n").delete("\n")
99
- value = value.gsub(/\s+/, ' ').strip
100
- value
101
- end
102
-
103
69
  def regex_last_match(number)
104
70
  Regexp.last_match(number)
105
71
  end
@@ -0,0 +1,22 @@
1
+ module CapistranoMulticonfigParallel
2
+ # helper methods used for capistrano actions
3
+ module CapistranoHelper
4
+ module_function
5
+
6
+ def filtered_env_keys_format(keys)
7
+ capistrano_version_2? ? keys.map(&:downcase) : keys
8
+ end
9
+
10
+ def env_prefix
11
+ capistrano_version_2? ? '-S' : ''
12
+ end
13
+
14
+ def env_key_format(key)
15
+ capistrano_version_2? ? key.downcase : key
16
+ end
17
+
18
+ def trace_flag
19
+ capistrano_version_2? ? '--debug' : '--trace'
20
+ end
21
+ end
22
+ end
@@ -1,96 +1,95 @@
1
- require_relative './application_helper'
1
+ require_relative './core_helper'
2
+ require_relative './internal_helper'
3
+ require_relative './parse_helper'
2
4
  module CapistranoMulticonfigParallel
3
5
  # class that holds the options that are configurable for this gem
4
6
  module Configuration
5
- extend ActiveSupport::Concern
7
+ include CapistranoMulticonfigParallel::CoreHelper
8
+ include CapistranoMulticonfigParallel::InternalHelper
9
+ include CapistranoMulticonfigParallel::ParseHelper
6
10
 
7
- included do
8
- include CapistranoMulticonfigParallel::ApplicationHelper
9
- attr_reader :configuration
10
-
11
- def configuration
12
- @config ||= fetch_configuration
13
- @config
14
- end
15
-
16
- def fetch_configuration
17
- @fetched_config = Configliere::Param.new
18
- setup_default_config
19
- setup_configuration
20
- end
11
+ def fetch_configuration
12
+ @fetched_config = Configliere::Param.new
13
+ setup_default_config
14
+ setup_configuration
15
+ end
21
16
 
22
- def setup_default_config
23
- default_internal_config.each do |array_param|
24
- @fetched_config.define array_param[0], array_param[1].symbolize_keys
25
- end
17
+ def setup_default_config
18
+ default_internal_config.each do |array_param|
19
+ @fetched_config.define array_param[0], array_param[1].symbolize_keys
26
20
  end
21
+ end
27
22
 
28
- def setup_configuration
29
- @fetched_config.read config_file if File.file?(config_file)
30
- @fetched_config.use :commandline
23
+ def setup_configuration
24
+ @fetched_config.read config_file if File.file?(config_file)
25
+ @fetched_config.use :commandline
31
26
 
32
- @fetched_config.use :config_block
33
- validate_configuration
34
- end
27
+ @fetched_config.use :config_block
28
+ validate_configuration
29
+ end
35
30
 
36
- def validate_configuration
37
- @fetched_config.finally do |config|
38
- @check_config = config.stringify_keys
39
- check_configuration
40
- end
41
- @fetched_config.process_argv!
42
- @fetched_config.resolve!
31
+ def validate_configuration
32
+ @fetched_config.finally do |config|
33
+ check_configuration(config)
43
34
  end
35
+ @fetched_config.process_argv!
36
+ @fetched_config.resolve!
37
+ @fetched_config
38
+ end
44
39
 
45
- def verify_application_dependencies(value, props)
46
- return unless value.is_a?(Array)
47
- value.reject { |val| val.blank? || !val.is_a?(Hash) }
48
- wrong = check_array_of_hash(value, props.map(&:to_sym))
49
- raise ArgumentError, "invalid configuration for #{wrong.inspect}" if wrong.present?
50
- end
40
+ def verify_application_dependencies(value, props)
41
+ return unless value.is_a?(Array)
42
+ value.reject { |val| val.blank? || !val.is_a?(Hash) }
43
+ wrong = check_array_of_hash(value, props.map(&:to_sym))
44
+ raise ArgumentError, "invalid configuration for #{wrong.inspect}" if wrong.present?
45
+ end
51
46
 
52
- def check_array_of_hash(value, props)
53
- value.find do|hash|
54
- check_hash_set(hash, props)
55
- end
47
+ def check_array_of_hash(value, props)
48
+ value.find do|hash|
49
+ check_hash_set(hash, props)
56
50
  end
51
+ end
57
52
 
58
- def check_boolean(prop)
59
- value = get_prop_config(prop)
60
- raise ArgumentError, "the property `#{prop}` must be boolean" unless %w(true false).include?(value.to_s.downcase)
53
+ def check_boolean(prop)
54
+ value = get_prop_config(prop)
55
+ if %w(true false).include?(value.to_s.downcase)
56
+ true
57
+ else
58
+ raise ArgumentError, "the property `#{prop}` must be boolean"
61
59
  end
60
+ end
62
61
 
63
- def configuration_valid?
64
- configuration
65
- end
62
+ def configuration_valid?
63
+ configuration
64
+ end
66
65
 
67
- def check_boolean_props(props)
68
- props.each do |prop|
69
- @check_config.send("#{prop}=", get_prop_config(prop)) if check_boolean(prop)
70
- end
66
+ def check_boolean_props(props)
67
+ props.each do |prop|
68
+ @check_config[prop] = get_prop_config(prop) if check_boolean(prop)
71
69
  end
70
+ end
72
71
 
73
- def check_array_props(props)
74
- props.each do |prop|
75
- value = get_prop_config(prop)
76
- @check_config.send("#{prop}=", value) if value_is_array?(value) && verify_array_of_strings(value)
77
- end
72
+ def check_array_props(props)
73
+ props.each do |prop|
74
+ value = get_prop_config(prop)
75
+ @check_config[prop] = value if value_is_array?(value) && verify_array_of_strings(value)
78
76
  end
77
+ end
79
78
 
80
- def get_prop_config(prop)
81
- config = @check_config
82
- if prop.include?('.')
83
- multi_level_prop(config, prop)
84
- else
85
- config[prop]
86
- end
79
+ def get_prop_config(prop)
80
+ config = @check_config
81
+ if prop.include?('.')
82
+ multi_level_prop(config, prop)
83
+ else
84
+ config[prop]
87
85
  end
86
+ end
88
87
 
89
- def check_configuration
90
- check_boolean_props(%w(multi_debug multi_secvential websocket_server.enable_debug websocket_server.use_redis terminal.clear_screen))
91
- check_array_props(%w(task_confirmations development_stages apply_stage_confirmation))
92
- verify_application_dependencies(@check_config['application_dependencies'], %w(app priority dependencies))
93
- end
88
+ def check_configuration(config)
89
+ @check_config = config.stringify_keys
90
+ check_boolean_props(%w(multi_debug multi_secvential websocket_server.enable_debug websocket_server.use_redis terminal.clear_screen))
91
+ check_array_props(%w(task_confirmations development_stages apply_stage_confirmation))
92
+ verify_application_dependencies(@check_config['application_dependencies'], %w(app priority dependencies))
94
93
  end
95
94
  end
96
95
  end
@@ -52,10 +52,14 @@ module CapistranoMulticonfigParallel
52
52
  Celluloid::Actor[:terminal_server]
53
53
  end
54
54
 
55
+ def terminal_errors?
56
+ terminal_actor.present? && terminal_actor.alive? && terminal_actor.errors.is_a?(Array)
57
+ end
58
+
55
59
  def log_output_error(error, output, message)
56
60
  return if error_filtered?(error)
57
61
  puts message if output.present?
58
- terminal_actor.errors.push(message) if terminal_actor.alive?
62
+ terminal_actor.errors.push(message) if terminal_errors?
59
63
  end
60
64
 
61
65
  def format_error(exception)
@@ -0,0 +1,33 @@
1
+ module CapistranoMulticonfigParallel
2
+ # helper used to determine gem versions
3
+ module GemHelper
4
+ module_function
5
+
6
+ def find_loaded_gem(name)
7
+ Gem.loaded_specs.values.find { |repo| repo.name == name }
8
+ end
9
+
10
+ def find_loaded_gem_property(gem_name, property = 'version')
11
+ gem_spec = find_loaded_gem(gem_name)
12
+ gem_spec.respond_to?(property) ? gem_spec.send(property) : nil
13
+ end
14
+
15
+ def fetch_gem_version(gem_name)
16
+ version = find_loaded_gem_property(gem_name)
17
+ version.blank? ? nil : get_parsed_version(version)
18
+ end
19
+
20
+ def get_parsed_version(version)
21
+ version = version.to_s.split('.')
22
+ version.pop until version.size == 2
23
+ version.join('.').to_f
24
+ end
25
+
26
+ def verify_gem_version(gem_name, version, options = {})
27
+ options.stringify_keys!
28
+ version = get_parsed_version(version)
29
+ gem_version = fetch_gem_version(gem_name)
30
+ gem_version.blank? ? false : gem_version.send(options.fetch('operator', '<='), version)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,44 @@
1
+ module CapistranoMulticonfigParallel
2
+ # module used for parsing numbers, strings , arrays and hashes
3
+ module ParseHelper
4
+ module_function
5
+
6
+ def check_numeric(num)
7
+ /^[0-9]+/.match(num.to_s)
8
+ end
9
+
10
+ def verify_empty_options(options)
11
+ if options.is_a?(Hash)
12
+ options.reject { |_key, value| value.blank? }
13
+ elsif options.is_a?(Array)
14
+ options.reject(&:blank?)
15
+ else
16
+ options
17
+ end
18
+ end
19
+
20
+ def verify_array_of_strings(value)
21
+ value = verify_empty_options(value)
22
+ value.find { |row| !row.is_a?(String) }.present? ? warn_array_without_strings(value) : true
23
+ end
24
+
25
+ def warn_array_without_strings(value)
26
+ raise ArgumentError, "the array #{value} must contain only task names"
27
+ end
28
+
29
+ def check_hash_set(hash, props)
30
+ !Set.new(props).subset?(hash.keys.to_set) || hash.values.find(&:blank?).present?
31
+ end
32
+
33
+ def value_is_array?(value)
34
+ value.present? && value.is_a?(Array)
35
+ end
36
+
37
+ def strip_characters_from_string(value)
38
+ return '' if value.blank?
39
+ value = value.delete("\r\n").delete("\n")
40
+ value = value.gsub(/\s+/, ' ').strip
41
+ value
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,24 @@
1
+ if CapistranoMulticonfigParallel.capistrano_version_2?
2
+ require 'capistrano/cli'
3
+ Capistrano::Configuration::Execution.class_eval do
4
+ alias_method :original_execute_task, :execute_task
5
+
6
+ def execute_task(task)
7
+ rake = CapistranoMulticonfigParallel::RakeTaskHooks.new(ENV, task, self)
8
+ rake.automatic_hooks do
9
+ original_execute_task(task)
10
+ end
11
+ end
12
+ end
13
+
14
+ Capistrano::Configuration::Callbacks.class_eval do
15
+ alias_method :original_trigger, :trigger
16
+
17
+ def trigger(event, task = nil)
18
+ rake = CapistranoMulticonfigParallel::RakeTaskHooks.new(ENV, task, self)
19
+ rake.automatic_hooks do
20
+ original_trigger(event, task)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -6,8 +6,8 @@ module CapistranoMulticonfigParallel
6
6
 
7
7
  # module used for generating the version
8
8
  module VERSION
9
- MAJOR = 0
10
- MINOR = 32
9
+ MAJOR = 1
10
+ MINOR = 0
11
11
  TINY = 0
12
12
  PRE = nil
13
13
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano_multiconfig_parallel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.32.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - bogdanRada
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-06 00:00:00.000000000 Z
11
+ date: 2016-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid-pmap
@@ -174,22 +174,16 @@ dependencies:
174
174
  name: capistrano
175
175
  requirement: !ruby/object:Gem::Requirement
176
176
  requirements:
177
- - - "~>"
178
- - !ruby/object:Gem::Version
179
- version: '3.0'
180
177
  - - ">="
181
178
  - !ruby/object:Gem::Version
182
- version: '3.0'
179
+ version: '2.0'
183
180
  type: :runtime
184
181
  prerelease: false
185
182
  version_requirements: !ruby/object:Gem::Requirement
186
183
  requirements:
187
- - - "~>"
188
- - !ruby/object:Gem::Version
189
- version: '3.0'
190
184
  - - ">="
191
185
  - !ruby/object:Gem::Version
192
- version: '3.0'
186
+ version: '2.0'
193
187
  - !ruby/object:Gem::Dependency
194
188
  name: activesupport
195
189
  requirement: !ruby/object:Gem::Requirement
@@ -290,6 +284,26 @@ dependencies:
290
284
  - - ">="
291
285
  - !ruby/object:Gem::Version
292
286
  version: '1.6'
287
+ - !ruby/object:Gem::Dependency
288
+ name: rake
289
+ requirement: !ruby/object:Gem::Requirement
290
+ requirements:
291
+ - - "~>"
292
+ - !ruby/object:Gem::Version
293
+ version: '10.4'
294
+ - - ">="
295
+ - !ruby/object:Gem::Version
296
+ version: '10.4'
297
+ type: :runtime
298
+ prerelease: false
299
+ version_requirements: !ruby/object:Gem::Requirement
300
+ requirements:
301
+ - - "~>"
302
+ - !ruby/object:Gem::Version
303
+ version: '10.4'
304
+ - - ">="
305
+ - !ruby/object:Gem::Version
306
+ version: '10.4'
293
307
  - !ruby/object:Gem::Dependency
294
308
  name: rspec-rails
295
309
  requirement: !ruby/object:Gem::Requirement
@@ -659,10 +673,14 @@ files:
659
673
  - lib/capistrano_multiconfig_parallel/cli.rb
660
674
  - lib/capistrano_multiconfig_parallel/configuration/default.yml
661
675
  - lib/capistrano_multiconfig_parallel/helpers/application_helper.rb
676
+ - lib/capistrano_multiconfig_parallel/helpers/capistrano_helper.rb
662
677
  - lib/capistrano_multiconfig_parallel/helpers/configuration.rb
663
678
  - lib/capistrano_multiconfig_parallel/helpers/core_helper.rb
679
+ - lib/capistrano_multiconfig_parallel/helpers/gem_helper.rb
664
680
  - lib/capistrano_multiconfig_parallel/helpers/internal_helper.rb
681
+ - lib/capistrano_multiconfig_parallel/helpers/parse_helper.rb
665
682
  - lib/capistrano_multiconfig_parallel/helpers/stages_helper.rb
683
+ - lib/capistrano_multiconfig_parallel/initializers/capistrano2.rb
666
684
  - lib/capistrano_multiconfig_parallel/initializers/rake.rb
667
685
  - lib/capistrano_multiconfig_parallel/initializers/websocket.rb
668
686
  - lib/capistrano_multiconfig_parallel/version.rb