capistrano_multiconfig_parallel 0.15.6 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +25 -0
  3. data/.gitignore +0 -1
  4. data/Gemfile.lock +327 -0
  5. data/README.md +1 -1
  6. data/lib/capistrano_multiconfig_parallel/all.rb +16 -1
  7. data/lib/capistrano_multiconfig_parallel/application.rb +340 -11
  8. data/lib/capistrano_multiconfig_parallel/base.rb +8 -8
  9. data/lib/capistrano_multiconfig_parallel/celluloid/celluloid_manager.rb +3 -6
  10. data/lib/capistrano_multiconfig_parallel/celluloid/celluloid_worker.rb +6 -0
  11. data/lib/capistrano_multiconfig_parallel/cli.rb +8 -1
  12. data/lib/capistrano_multiconfig_parallel/configuration.rb +8 -30
  13. data/lib/capistrano_multiconfig_parallel/extensions/rake.rb +1 -1
  14. data/lib/capistrano_multiconfig_parallel/{multi_app_helpers → helpers}/dependency_tracker.rb +5 -5
  15. data/lib/capistrano_multiconfig_parallel/helpers/helper.rb +9 -0
  16. data/lib/capistrano_multiconfig_parallel/{extensions → helpers}/rake_hook_actor.rb +0 -1
  17. data/lib/capistrano_multiconfig_parallel/initializers/conf.rb +2 -3
  18. data/lib/capistrano_multiconfig_parallel/initializers/default.yml +3 -3
  19. data/lib/capistrano_multiconfig_parallel/version.rb +2 -2
  20. metadata +11 -9
  21. data/lib/capistrano_multiconfig_parallel/managers/base_manager.rb +0 -348
  22. /data/lib/capistrano_multiconfig_parallel/{extensions → helpers}/input_stream.rb +0 -0
  23. /data/lib/capistrano_multiconfig_parallel/{multi_app_helpers → helpers}/interactive_menu.rb +0 -0
  24. /data/lib/capistrano_multiconfig_parallel/{extensions → helpers}/output_stream.rb +0 -0
  25. /data/lib/capistrano_multiconfig_parallel/{managers → helpers}/standard_deploy.rb +0 -0
@@ -1,20 +1,349 @@
1
1
  module CapistranoMulticonfigParallel
2
- # class used as a wrapper around capistrano
3
- class Application < Capistrano::Application
4
- def name
5
- 'multi_cap'
2
+ # finds app dependencies, shows menu and delegates jobs to celluloid manager
3
+ # rubocop:disable ClassLength
4
+ class Application
5
+ include Celluloid
6
+ include Celluloid::Logger
7
+
8
+ attr_accessor :stages,:stage_apps, :top_level_tasks, :jobs, :branch_backup, :condition, :manager, :dependency_tracker, :application, :stage, :name, :args, :argv, :default_stage
9
+
10
+ def initialize
11
+ @stages = fetch_stages
12
+ @stage_apps = multi_apps? ? @stages.map { |stage| stage.split(':').reverse[1] }.uniq : []
13
+ collect_command_line_tasks(CapistranoMulticonfigParallel.original_args)
14
+ @jobs = []
15
+ CapistranoMulticonfigParallel.configuration_valid?(@stages)
16
+ end
17
+
18
+
19
+ def start
20
+ verify_app_dependencies(@stages) if multi_apps? && configuration.application_dependencies.present?
21
+ check_before_starting
22
+ initialize_data
23
+ run
24
+ end
25
+
26
+ def verify_app_dependencies(stages)
27
+ wrong = configuration.application_dependencies.find do |hash|
28
+ !@stage_apps.include?(hash[:app]) || (hash[:dependencies].present? && hash[:dependencies].find { |val| !@stage_apps.include?(val) })
29
+ end
30
+ raise ArgumentError,"Invalid configuration for #{wrong.inspect}".red if wrong.present?
31
+ end
32
+
33
+
34
+ def fetch_stages
35
+ fetch_stages_paths do |paths|
36
+ paths.reject! { |path| check_stage_path(paths, path) }
37
+ paths.sort if paths.present?
38
+ end
39
+ end
40
+
41
+ def check_stage_path(paths, path)
42
+ paths.any? { |another| another != path && another.start_with?(path + ':') }
43
+ end
44
+
45
+ def stages_paths
46
+ stages_root = 'config/deploy'
47
+ Dir["#{stages_root}/**/*.rb"].map do |file|
48
+ file.slice(stages_root.size + 1..-4).tr('/', ':')
49
+ end
50
+ end
51
+
52
+ def fetch_stages_paths
53
+ stages_paths.tap { |paths| yield paths if block_given? }
54
+ end
55
+
56
+
57
+
58
+ def run_custom_command(options)
59
+ custom_stages = fetch_multi_stages
60
+ return if custom_stages.blank?
61
+ custom_stages = check_multi_stages(custom_stages)
62
+ custom_stages.each do |stage|
63
+ collect_jobs(options.merge('stage' => stage))
64
+ end
65
+ end
66
+
67
+ def deploy_multiple_apps(applications, options)
68
+ options = options.stringify_keys
69
+ return unless applications.present?
70
+ applications.each do |app|
71
+ deploy_app(options.merge('app' => app))
72
+ end
73
+ end
74
+
75
+ def backup_the_branch
76
+ return if custom_command? || @argv['BRANCH'].blank?
77
+ @branch_backup = @argv['BRANCH'].to_s
78
+ @argv['BRANCH'] = nil
79
+ end
80
+
81
+ def can_start?
82
+ @top_level_tasks.size >= 1 && (@stages.include?(@top_level_tasks.first) || custom_command?) && @argv[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID].blank?
83
+ end
84
+
85
+ def custom_command?
86
+ if multi_apps?
87
+ !@stages.include?(@top_level_tasks.first) && custom_commands.values.include?(@top_level_tasks.first)
88
+ else
89
+ !@stages.include?(@top_level_tasks.second) && @stages.include?(@top_level_tasks.first) && custom_commands.values.include?(@top_level_tasks.second)
90
+ end
91
+ end
92
+
93
+ def custom_commands
94
+ key = multi_apps? ? CapistranoMulticonfigParallel::MULTI_KEY : CapistranoMulticonfigParallel::SINGLE_KEY
95
+ CapistranoMulticonfigParallel::CUSTOM_COMMANDS[key]
96
+ end
97
+
98
+ def multi_apps?
99
+ @stages.find { |stage| stage.include?(':') }.present?
100
+ end
101
+
102
+ def configuration
103
+ CapistranoMulticonfigParallel.configuration
104
+ end
105
+
106
+
107
+ def initialize_data
108
+ @application = custom_command? ? nil : @top_level_tasks.first.split(':').reverse[1]
109
+ @stage = custom_command? ? nil : @top_level_tasks.first.split(':').reverse[0]
110
+ @stage = @stage.present? ? @stage : @default_stage
111
+ @name, @args = parse_task_string(@top_level_tasks.second)
112
+ end
113
+
114
+ def collect_command_line_tasks(args) # :nodoc:
115
+ @argv = {}
116
+ @top_level_tasks = []
117
+ args.each do |arg|
118
+ if arg =~ /^(\w+)=(.*)$/m
119
+ @argv[Regexp.last_match(1)] = Regexp.last_match(2)
120
+ else
121
+ @top_level_tasks << arg unless arg =~ /^-/
122
+ end
123
+ end
124
+ @top_level_tasks.push(Rake.application.default_task_name) if @top_level_tasks.blank?
125
+ end
126
+
127
+ def parse_task_string(string) # :nodoc:
128
+ /^([^\[]+)(?:\[(.*)\])$/ =~ string.to_s
129
+
130
+ name = Regexp.last_match(1)
131
+ remaining_args = Regexp.last_match(2)
132
+
133
+ return string, [] unless name
134
+ return name, [] if remaining_args.empty?
135
+
136
+ args = []
137
+
138
+ loop do
139
+ /((?:[^\\,]|\\.)*?)\s*(?:,\s*(.*))?$/ =~ remaining_args
140
+
141
+ remaining_args = Regexp.last_match(2)
142
+ args << Regexp.last_match(1).gsub(/\\(.)/, '\1')
143
+ break if remaining_args.blank?
144
+ end
145
+
146
+ [name, args]
147
+ end
148
+
149
+ def verify_options_custom_command(options)
150
+ options[:action] = @argv['ACTION'].present? ? @argv['ACTION'] : 'deploy'
151
+ options
152
+ end
153
+
154
+ def check_before_starting
155
+ CapistranoMulticonfigParallel.enable_logging
156
+ @dependency_tracker = CapistranoMulticonfigParallel::DependencyTracker.new(Actor.current)
157
+ @default_stage = CapistranoMulticonfigParallel.configuration.development_stages.present? ? CapistranoMulticonfigParallel.configuration.development_stages.first : 'development'
158
+ @condition = Celluloid::Condition.new
159
+ @manager = CapistranoMulticonfigParallel::CelluloidManager.new(Actor.current)
160
+ end
161
+
162
+ def collect_jobs(options = {}, &_block)
163
+ options = prepare_options(options)
164
+ options = options.stringify_keys
165
+ apps = @dependency_tracker.fetch_apps_needed_for_deployment(options['app'], options['action'])
166
+ backup_the_branch if multi_apps?
167
+ deploy_multiple_apps(apps, options)
168
+ deploy_app(options) if !custom_command? || !multi_apps?
169
+ rescue => e
170
+ CapistranoMulticonfigParallel.log_message(e)
171
+ end
172
+
173
+ def process_jobs
174
+ return unless @jobs.present?
175
+ FileUtils.rm Dir["#{CapistranoMulticonfigParallel.log_directory}/worker_*.log"]
176
+ if configuration.multi_secvential.to_s.downcase == 'true'
177
+ @jobs.each { |job| CapistranoMulticonfigParallel::StandardDeploy.new(job) }
178
+ else
179
+ run_async_jobs
180
+ end
181
+ end
182
+
183
+ def tag_staging_exists? # check exists task from capistrano-gitflow
184
+ CapistranoMulticonfigParallel.find_loaded_gem('capistrano-gitflow').present?
185
+ end
186
+
187
+
188
+ def fetch_multi_stages
189
+ custom_stages = @argv['STAGES'].blank? ? '' : @argv['STAGES']
190
+ custom_stages = parse_inputted_value('value' => custom_stages).split(',').compact if custom_stages.present?
191
+ custom_stages = custom_stages.present? ? custom_stages : [@default_stage]
192
+ custom_stages
193
+ end
194
+
195
+ def wants_deploy_production?
196
+ (!custom_command? && @stage == 'production') || (custom_command? && fetch_multi_stages.include?('production'))
197
+ end
198
+
199
+ def can_tag_staging?
200
+ wants_deploy_production? && tag_staging_exists? && fetch_multi_stages.include?('staging')
201
+ end
202
+
203
+ def check_multi_stages(custom_stages)
204
+ can_tag_staging? ? custom_stages.reject { |u| u == 'production' } : custom_stages
205
+ end
206
+
207
+ def deploy_app(options = {})
208
+ options = options.stringify_keys
209
+ app = options['app'].is_a?(Hash) ? options['app'] : { 'app' => options['app'] }
210
+ branch = @branch_backup.present? ? @branch_backup : @argv['BRANCH'].to_s
211
+ call_task_deploy_app({
212
+ branch: branch,
213
+ app: app,
214
+ action: options['action']
215
+ }.reverse_merge(options))
6
216
  end
7
217
 
8
- def sort_options(options)
9
- super.concat(CapistranoMulticonfigParallel.capistrano_options)
218
+ def get_app_additional_env_options(app, app_message)
219
+ app_name = (app.is_a?(Hash) && app[:app].present?) ? app[:app].camelcase : app
220
+ app_name = app_name.present? ? app_name : 'current application'
221
+ message = "Please write additional ENV options for #{app_name} for #{app_message}"
222
+ app_additional_env_options = CapistranoMulticonfigParallel.ask_confirm(message, nil)
223
+ fetch_app_additional_env_options(app_additional_env_options)
10
224
  end
11
225
 
12
- def top_level
13
- job_manager = CapistranoMulticonfigParallel::BaseManager.new
14
- if job_manager.can_start? && !options.show_prereqs && !options.show_tasks
15
- job_manager.start
226
+ def worker_environments
227
+ @jobs.map { |job| job['env'] }
228
+ end
229
+
230
+ def run
231
+ options = {}
232
+ if custom_command?
233
+ options = verify_options_custom_command(options)
234
+ run_custom_command(options)
16
235
  else
17
- super
236
+ collect_jobs(options)
237
+ end
238
+ process_jobs
239
+ end
240
+
241
+ def call_task_deploy_app(options = {})
242
+ options = options.stringify_keys
243
+ main_box_name = @argv['BOX'].blank? ? '' : @argv['BOX']
244
+ stage = options.fetch('stage', @default_stage)
245
+ if CapistranoMulticonfigParallel.configuration.development_stages.include?(stage) && main_box_name.present? && /^[a-z0-9,]+/.match(main_box_name)
246
+ execute_on_multiple_boxes(main_box_name, options)
247
+ else
248
+ prepare_job(options)
249
+ end
250
+ end
251
+
252
+ def run_async_jobs
253
+ return unless @jobs.present?
254
+ @jobs.pmap do |job|
255
+ @manager.async.delegate(job)
256
+ end
257
+ until @manager.registration_complete
258
+ sleep(0.1) # keep current thread alive
259
+ end
260
+ return unless @manager.registration_complete
261
+ @manager.async.process_jobs
262
+ wait_jobs_termination
263
+ end
264
+
265
+ def wait_jobs_termination
266
+ return if configuration.multi_secvential.to_s.downcase == 'true'
267
+ result = @condition.wait
268
+ return unless result.present?
269
+ @manager.terminate
270
+ terminate
271
+ end
272
+
273
+ def prepare_job(options)
274
+ options = options.stringify_keys
275
+ branch_name = options.fetch('branch', {})
276
+ app = options.fetch('app', {})
277
+ app = app.fetch('app', '')
278
+ box = options['env_options']['BOX']
279
+ message = box.present? ? "BOX #{box}:" : "stage #{options['stage']}:"
280
+ env_opts = get_app_additional_env_options(app, message)
281
+
282
+ options['env_options'] = options['env_options'].reverse_merge(env_opts)
283
+
284
+ env_options = branch_name.present? ? { 'BRANCH' => branch_name }.merge(options['env_options']) : options['env_options']
285
+ job_env_options = custom_command? && env_options['ACTION'].present? ? env_options.except('ACTION') : env_options
286
+
287
+ job = {
288
+ id: SecureRandom.random_number(500),
289
+ app: app,
290
+ env: options['stage'],
291
+ action: custom_command? && env_options['ACTION'].present? ? env_options['ACTION'] : options['action'],
292
+ task_arguments: options['task_arguments'],
293
+ env_options: job_env_options
294
+ }
295
+ @jobs << job.stringify_keys
296
+ end
297
+
298
+ def prepare_options(options)
299
+ options = options.stringify_keys
300
+ options['app'] = options.fetch('app', @application.to_s.clone)
301
+ options['action'] = options.fetch('action', @name.to_s.clone)
302
+ options['stage'] = options.fetch('stage', @stage.to_s.clone)
303
+ options['env_options'] = options.fetch('env_options', @argv.clone)
304
+ options['task_arguments'] = options.fetch('task_arguments', @args.clone)
305
+ options
306
+ end
307
+
308
+ def parse_inputted_value(options = {})
309
+ options = options.stringify_keys
310
+ value = options['value'].present? ? options['value'] : nil
311
+ if value.present?
312
+ branch = value.gsub("\r\n", '')
313
+ branch = branch.delete("\n") if branch.present?
314
+ branch = branch.gsub(/\s+/, ' ') if branch.present?
315
+ branch = branch.strip if branch.present?
316
+ return branch
317
+ else
318
+ return ''
319
+ end
320
+ end
321
+
322
+ def fetch_app_additional_env_options(variable)
323
+ options = {}
324
+ return options if variable.blank?
325
+ env_options = parse_inputted_value('value' => variable)
326
+ env_options = env_options.split(' ')
327
+ options = multi_fetch_argv(env_options)
328
+ options.stringify_keys!
329
+ options
330
+ end
331
+
332
+ def multi_fetch_argv(args)
333
+ options = {}
334
+ args.each do |arg|
335
+ if arg =~ /^(\w+)=(.*)$/m
336
+ options[Regexp.last_match(1)] = Regexp.last_match(2)
337
+ end
338
+ end
339
+ options
340
+ end
341
+
342
+ def execute_on_multiple_boxes(main_box_name, options)
343
+ boxes = parse_inputted_value('value' => main_box_name).split(',').compact
344
+ boxes.each do |box_name|
345
+ options['env_options']['BOX'] = box_name
346
+ prepare_job(options)
18
347
  end
19
348
  end
20
349
  end
@@ -1,6 +1,7 @@
1
1
  # base module that has the statis methods that this gem is using
2
2
  module CapistranoMulticonfigParallel
3
3
  include CapistranoMulticonfigParallel::Configuration
4
+ include Helper
4
5
 
5
6
  ENV_KEY_JOB_ID = 'multi_cap_job_id'
6
7
  MULTI_KEY = 'multi'
@@ -57,10 +58,8 @@ module CapistranoMulticonfigParallel
57
58
  FileUtils.mkdir_p(log_directory) unless File.directory?(log_directory)
58
59
  if CapistranoMulticonfigParallel::CelluloidManager.debug_enabled.to_s.downcase == 'true'
59
60
  FileUtils.touch(main_log_file) unless File.file?(main_log_file)
60
- if ENV[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID].blank?
61
- log_file = File.open(main_log_file, 'w')
62
- log_file.sync = true
63
- end
61
+ log_file = File.open(main_log_file, 'w')
62
+ log_file.sync = true
64
63
  self.logger = ::Logger.new(main_log_file)
65
64
  else
66
65
  self.logger = ::Logger.new(DevNull.new)
@@ -75,15 +74,16 @@ module CapistranoMulticonfigParallel
75
74
  err_backtrace = message.respond_to?(:backtrace) ? message.backtrace.join("\n\n") : ''
76
75
  if err_backtrace.present?
77
76
  logger.debug(
78
- class_name: message.class,
79
- message: error_message,
80
- backtrace: err_backtrace
77
+ class_name: message.class,
78
+ message: error_message,
79
+ backtrace: err_backtrace
81
80
  )
82
81
  else
83
82
  logger.debug(message)
84
83
  end
85
84
  end
86
85
 
86
+
87
87
  def detect_root
88
88
  if ENV['MULTI_CAP_ROOT']
89
89
  Pathname.new(ENV['MULTI_CAP_ROOT'])
@@ -98,7 +98,7 @@ module CapistranoMulticonfigParallel
98
98
  root = Pathname.new(FileUtils.pwd)
99
99
  root = root.parent unless root.directory?
100
100
  root = root.parent until root.children.find { |f| f.file? && f.basename.to_s.downcase == 'capfile' }.present? || root.root?
101
- raise "Can't detect Capfile in the application root" if root.root?
101
+ raise "Can't detect Capfile in the application root".red if root.root?
102
102
  root
103
103
  end
104
104
  end
@@ -54,10 +54,7 @@ module CapistranoMulticonfigParallel
54
54
  end
55
55
 
56
56
  def generate_job_id(job)
57
- primary_key = SecureRandom.random_number(500)
58
- job['id'] = primary_key
59
- @jobs[primary_key] = job
60
- @jobs[primary_key]
57
+ @jobs[job['id']] = job
61
58
  job['id']
62
59
  end
63
60
 
@@ -181,8 +178,8 @@ module CapistranoMulticonfigParallel
181
178
  message = "Do you want to continue the deployment and execute #{task.upcase}"
182
179
  message += " for JOB #{worker.job_id}" if worker.present?
183
180
  message += '?'
184
- set :apps_symlink_confirmation, Celluloid::Actor[:terminal_server].show_confirmation(message, 'Y/N')
185
- until fetch(:apps_symlink_confirmation).present?
181
+ apps_symlink_confirmation = Celluloid::Actor[:terminal_server].show_confirmation(message, 'Y/N')
182
+ until apps_symlink_confirmation.present?
186
183
  sleep(0.1) # keep current thread alive
187
184
  end
188
185
  end
@@ -83,6 +83,12 @@ module CapistranoMulticonfigParallel
83
83
  "cd #{CapistranoMulticonfigParallel.detect_root}"
84
84
  end
85
85
 
86
+ # def generate_command_new
87
+ # <<-CMD
88
+ # bundle exec ruby -e "require 'bundler' ; Bundler.with_clean_env { %x[cd #{cd_working_directory} && bundle install && RAILS_ENV=#{@env_name} bundle exec cap #{@task_argv.join(' ')}] } "
89
+ # CMD
90
+ # end
91
+
86
92
  def generate_command
87
93
  <<-CMD
88
94
  #{cd_working_directory} && RAILS_ENV=#{@env_name} bundle exec multi_cap #{@task_argv.join(' ')}
@@ -3,15 +3,22 @@ Gem.find_files('capistrano_multiconfig_parallel/extensions/**/*.rb').each { |pat
3
3
  module CapistranoMulticonfigParallel
4
4
  # this is the class that will be invoked from terminal , and willl use the invoke task as the primary function.
5
5
  class CLI
6
+ # method used to start
6
7
  def self.start
7
8
  CapistranoMulticonfigParallel.check_terminal_tty
8
9
  CapistranoMulticonfigParallel.original_args = ARGV.dup
9
- CapistranoMulticonfigParallel::Application.new.run
10
+ job_manager = CapistranoMulticonfigParallel::Application.new
11
+ if job_manager.can_start?
12
+ job_manager.start
13
+ else
14
+ Capistrano::Application.new.run
15
+ end
10
16
  rescue Interrupt
11
17
  `stty icanon echo`
12
18
  $stderr.puts 'Command cancelled.'
13
19
  rescue => error
14
20
  $stderr.puts error
21
+ $stderr.puts error.backtrace if error.respond_to?(:backtrace)
15
22
  exit(1)
16
23
  end
17
24
  end
@@ -8,15 +8,16 @@ module CapistranoMulticonfigParallel
8
8
 
9
9
  def configuration
10
10
  @config ||= Configliere::Param.new
11
- @config.use :commandline
12
11
  command_line_params.each do |param|
13
- @config.define param[:name], type: param[:type], description: param[:description], default: param[:default]
12
+ param_type = change_config_type(param['type'].to_s)
13
+ @config.define param['name'], type: param_type, description: param['description'], default: param['default']
14
14
  end
15
15
 
16
16
  ARGV.clear
17
+
17
18
  CapistranoMulticonfigParallel.original_args.each { |a| ARGV << a }
18
19
  @config.read config_file if File.file?(config_file)
19
- @config.merge(Settings.use(:commandline).resolve!)
20
+ @config.use :commandline
20
21
 
21
22
  @config.use :config_block
22
23
  @config.finally do |c|
@@ -34,30 +35,14 @@ module CapistranoMulticonfigParallel
34
35
  end
35
36
 
36
37
  def command_line_params
37
- @default_config ||= Configliere::Param.new
38
- @default_config.read File.join(internal_config_directory, 'default.yml')
39
- @default_config.resolve!
40
- @default_config[:default_config].map do |item|
41
- item[:type] = change_config_type(item[:type].to_s)
42
- item
43
- end
38
+ @default_config ||= YAML.load_file(File.join(internal_config_directory, 'default.yml'))['default_config']
39
+ @default_config
44
40
  end
45
41
 
46
42
  def change_config_type(type)
47
- type.include?(':') ? type.delete(':').to_sym : type.constantize
43
+ ['boolean'].include?(type) ? type.delete(':').to_sym : type.constantize
48
44
  end
49
45
 
50
- def capistrano_options
51
- command_line_params.map do |param|
52
- [
53
- "--#{param[:name]}[=CAP_VALUE]",
54
- "--#{param[:name]}",
55
- "[MULTI_CAP] #{param[:description]}. By default #{param[:default]}",
56
- lambda do |_value|
57
- end
58
- ]
59
- end
60
- end
61
46
 
62
47
  def verify_array_of_strings(value)
63
48
  return true if value.blank?
@@ -80,13 +65,7 @@ module CapistranoMulticonfigParallel
80
65
  end
81
66
  end
82
67
 
83
- def verify_app_dependencies(stages)
84
- applications = stages.map { |stage| stage.split(':').reverse[1] }
85
- wrong = configuration.application_dependencies.find do |hash|
86
- !applications.include?(hash[:app]) || (hash[:dependencies].present? && hash[:dependencies].find { |val| !applications.include?(val) })
87
- end
88
- raise ArgumentError, "invalid configuration for #{wrong.inspect}" if wrong.present?
89
- end
68
+
90
69
 
91
70
  def check_boolean(c, prop)
92
71
  raise ArgumentError, "the property `#{prop}` must be boolean" unless %w(true false).include?(c[prop].to_s.downcase)
@@ -94,7 +73,6 @@ module CapistranoMulticonfigParallel
94
73
 
95
74
  def configuration_valid?(stages)
96
75
  configuration
97
- verify_app_dependencies(stages) if configuration.application_dependencies.present?
98
76
  end
99
77
 
100
78
  def check_boolean_props(c, props)
@@ -1,4 +1,4 @@
1
- require_relative './rake_hook_actor'
1
+ require_relative '../helpers/rake_hook_actor'
2
2
  Rake::Task.class_eval do
3
3
  alias_method :original_execute, :execute
4
4
 
@@ -68,8 +68,8 @@ module CapistranoMulticonfigParallel
68
68
 
69
69
  def check_app_dependency_unique(applications_selected, apps_dependencies, applications_to_deploy, action)
70
70
  return applications_to_deploy if applications_selected.blank? || apps_dependencies.blank? || (apps_dependencies.map { |app| app['app'] } - applications_to_deploy.map { |app| app['app'] }).blank?
71
- set :apps_dependency_confirmation, CapistranoMulticonfigParallel.ask_confirm("Do you want to #{action} all dependencies also ?", 'Y/N')
72
- applications_to_deploy = applications_to_deploy.concat(apps_dependencies) if fetch(:apps_dependency_confirmation).present? && fetch(:apps_dependency_confirmation).downcase == 'y'
71
+ apps_dependency_confirmation = CapistranoMulticonfigParallel.ask_confirm("Do you want to #{action} all dependencies also ?", 'Y/N')
72
+ applications_to_deploy = applications_to_deploy.concat(apps_dependencies) if apps_dependency_confirmation.present? && apps_dependency_confirmation.downcase == 'y'
73
73
  applications_to_deploy
74
74
  end
75
75
 
@@ -102,10 +102,10 @@ module CapistranoMulticonfigParallel
102
102
 
103
103
  def print_frameworks_used(app_names, applications_to_deploy, action)
104
104
  app_names.each { |app| puts "#{app}" }
105
- set :apps_deploy_confirmation, CapistranoMulticonfigParallel.ask_confirm("Are you sure you want to #{action} these apps?", 'Y/N')
106
- if fetch(:apps_deploy_confirmation).blank? || (fetch(:apps_deploy_confirmation).present? && fetch(:apps_deploy_confirmation).downcase != 'y')
105
+ apps_deploy_confirmation = CapistranoMulticonfigParallel.ask_confirm("Are you sure you want to #{action} these apps?", 'Y/N')
106
+ if apps_deploy_confirmation.blank? || (apps_deploy_confirmation.present? && apps_deploy_confirmation.downcase != 'y')
107
107
  return []
108
- elsif fetch(:apps_deploy_confirmation).present? && fetch(:apps_deploy_confirmation).downcase == 'y'
108
+ elsif apps_deploy_confirmation.present? && apps_deploy_confirmation.downcase == 'y'
109
109
  return applications_to_deploy
110
110
  end
111
111
  end
@@ -0,0 +1,9 @@
1
+ module Helper
2
+
3
+ module_function
4
+
5
+ def find_loaded_gem(name)
6
+ Gem.loaded_specs.values.detect{|repo| repo.name == name }
7
+ end
8
+
9
+ end
@@ -1,4 +1,3 @@
1
- require 'celluloid/autostart'
2
1
  require_relative '../celluloid/rake_worker'
3
2
  require_relative './input_stream'
4
3
  require_relative './output_stream'
@@ -1,11 +1,10 @@
1
- require 'configliere'
2
1
  require 'configliere/commandline'
3
2
  Configliere::Commandline.class_eval do
4
3
  def resolve!(print_help_and_exit = true)
5
4
  process_argv!
6
- if print_help_and_exit && self[:multi_help]
5
+ if print_help_and_exit && self[:help]
7
6
  dump_help
8
- exit(2)
7
+ # exit(2)
9
8
  end
10
9
  super()
11
10
  self
@@ -1,18 +1,18 @@
1
1
  default_config:
2
2
  - name: 'multi_debug'
3
- type: ':boolean'
3
+ type: 'boolean'
4
4
  description: >-
5
5
  Enable debugging of workers, CAP_VALUE can be true or false
6
6
  default: TRUE
7
7
 
8
8
  - name: 'multi_secvential'
9
- type: ':boolean'
9
+ type: 'boolean'
10
10
  description: >-
11
11
  Forces execution of jobs in sequence, CAP_VALUE can be true or false
12
12
  default: false
13
13
 
14
14
  - name: 'websocket_server.enable_debug'
15
- type: ':boolean'
15
+ type: 'boolean'
16
16
  description: >-
17
17
  Enables debugging of websocket communication between the workers,
18
18
  CAP_VALUE can be true or false
@@ -7,8 +7,8 @@ module CapistranoMulticonfigParallel
7
7
  # module used for generating the version
8
8
  module VERSION
9
9
  MAJOR = 0
10
- MINOR = 15
11
- TINY = 6
10
+ MINOR = 16
11
+ TINY = 0
12
12
  PRE = nil
13
13
 
14
14
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')