capistrano_multiconfig_parallel 0.7.7 → 0.8.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69b1623c9bafea21ddff2b588f08bee7b214408a
4
- data.tar.gz: 2e9cb754af33f0f6808b9821b97b2e96d65998ad
3
+ metadata.gz: 3ccbcbb8b3f6f253696e7c0f5c4da3a6c86406e9
4
+ data.tar.gz: 42654d0b3a82c272c861d9db8ec1a06ed8cddedd
5
5
  SHA512:
6
- metadata.gz: d492ad626da0730b60f0dd1214ed43e64872d3237fcdf9195290608834e009de3c36989fbfe7d128af13ddb13de6d0ac4a5d13bd20bd50e9bb661b13c67c8975
7
- data.tar.gz: cea9979e1f32025ebf7a9bd2692085a5060670a1ca5bbd530d45d4add7d618ef8a959f0c65b1fd73386039f9aebeee6e2f0e7e421bf4afd84b52f324e15cbb39
6
+ metadata.gz: c16fa1a27b1f804f35b16384a99a98137a70d1624d3d862c426b0f2ee812e9e8c9da9f7dcd0b49cddc7cd614b859df3f13d9c2e5cd2908e6c1627e99c2e7bd3e
7
+ data.tar.gz: 7174e0d08f121447676b29423e990331ac5cd72e169de126d5511552331499c34d60d0e06c97f99769e4cee26c86b97ce7847768d796a07b9799e71a9642710d
@@ -25,10 +25,20 @@ module CapistranoMulticonfigParallel
25
25
  File.expand_path(File.dirname(__dir__))
26
26
  end
27
27
 
28
+ def check_terminal_tty
29
+ $stdin.sync = true if $stdin.isatty
30
+ $stdout.sync = true if $stdout.isatty
31
+ end
32
+
28
33
  def ask_confirm(message, default)
29
- Ask.input message, default: default
30
- rescue
31
- return nil
34
+ `stty -raw echo`
35
+ check_terminal_tty
36
+ result = Ask.input message, default: default
37
+ $stdout.flush
38
+ `stty -raw echo`
39
+ return result
40
+ rescue
41
+ return nil
32
42
  end
33
43
 
34
44
  def log_directory
@@ -111,12 +111,13 @@ module CapistranoMulticonfigParallel
111
111
  def apply_confirmations?
112
112
  CapistranoMulticonfigParallel.configuration.task_confirmation_active.to_s.downcase == 'true'
113
113
  end
114
+
114
115
  def syncronization_required?
115
116
  CapistranoMulticonfigParallel.configuration.syncronize_confirmation.to_s.downcase == 'true'
116
117
  end
117
-
118
+
118
119
  def syncronized_confirmation?
119
- ( syncronization_required? && !@job_manager.executes_deploy_stages?) ||
120
+ (syncronization_required? && !@job_manager.executes_deploy_stages?) ||
120
121
  (syncronization_required? && @job_manager.executes_deploy_stages? && !@job_manager.can_tag_staging? && @job_manager.confirmation_applies_to_all_workers?)
121
122
  end
122
123
 
@@ -223,9 +224,9 @@ module CapistranoMulticonfigParallel
223
224
  end
224
225
 
225
226
  def filtered_env_keys
226
- ["STAGES", "ACTION"]
227
+ %w(STAGES ACTION)
227
228
  end
228
-
229
+
229
230
  def process_job(job)
230
231
  env_options = {}
231
232
  job['env_options'].each do |key, value|
@@ -55,6 +55,10 @@ module CapistranoMulticonfigParallel
55
55
  @client.publish(rake_actor_id(data), data)
56
56
  end
57
57
 
58
+ def publish_io_event(data)
59
+ @client.publish("rake_io_#{@job_id}", 'approved' => 'yes', 'action' => 'stdin', 'job_id' => @job_id, 'result' => data)
60
+ end
61
+
58
62
  def rake_actor_id(data)
59
63
  data['action'].present? && data['action'] == 'count' ? "rake_worker_#{@job_id}_count" : "rake_worker_#{@job_id}"
60
64
  end
@@ -189,6 +193,7 @@ module CapistranoMulticonfigParallel
189
193
  array_options << "#{key}=#{value}" if value.present?
190
194
  end
191
195
  array_options << '--trace' if debug_enabled?
196
+ array_options << '--multi_debug=true' if debug_enabled?
192
197
  setup_command_line(*array_options)
193
198
  end
194
199
 
@@ -94,8 +94,31 @@ module CapistranoMulticonfigParallel
94
94
  @process ||= process
95
95
  end
96
96
 
97
+ def get_question_details(data)
98
+ question = ''
99
+ default = nil
100
+ if data =~ /(.*)\?+\s*\:*\s*(\([^)]*\))*/m
101
+ question = Regexp.last_match(1)
102
+ default = Regexp.last_match(2)
103
+ end
104
+ question.present? ? [question, default] : nil
105
+ end
106
+
107
+ def printing_question?(data)
108
+ get_question_details(data).present?
109
+ end
110
+
111
+ def user_prompt_needed?(data)
112
+ return unless printing_question?(data)
113
+ details = get_question_details(data)
114
+ default = details.second.present? ? details.second : nil
115
+ result = CapistranoMulticonfigParallel.ask_confirm(details.first, default)
116
+ @actor.publish_io_event(result)
117
+ end
118
+
97
119
  def io_callback(io, data)
98
120
  @worker_log.debug("#{io.upcase} ---- #{data}")
121
+ # user_prompt_needed?(data)
99
122
  end
100
123
  end
101
124
  end
@@ -4,45 +4,70 @@ module CapistranoMulticonfigParallel
4
4
  include Celluloid
5
5
  include Celluloid::Logger
6
6
 
7
- attr_accessor :env, :client, :job_id, :action, :task, :task_approved, :successfull_subscription, :subscription_channel, :publisher_channel
7
+ attr_accessor :env, :client, :job_id, :action, :task, :task_approved, :successfull_subscription, :subscription_channel, :publisher_channel, :stdin_result
8
8
 
9
- def work(env, task, options = {})
9
+ def work(env, options = {})
10
10
  @options = options.stringify_keys
11
11
  @env = env
12
- @job_id = find_job_id
13
- @subscription_channel = @options['rake_actor_id']
14
- @publisher_channel = "worker_#{find_job_id}"
15
- @action = @options['rake_actor_id'].include?('_count') ? 'count' : 'invoke'
16
- @task = task
12
+ default_settings
13
+ custom_attributes
14
+ initialize_subscription
15
+ end
16
+
17
+ def custom_attributes
18
+ @publisher_channel = "worker_#{@job_id}"
19
+ @action = @options['actor_id'].include?('_count') ? 'count' : 'invoke'
20
+ @task = @options['task']
21
+ end
22
+
23
+ def wait_execution(name = task_name, time = 0.1)
24
+ info "Before waiting #{name}"
25
+ Actor.current.wait_for(name, time)
26
+ info "After waiting #{name}"
27
+ end
28
+
29
+ def wait_for(name, time)
30
+ info "waiting for #{time} seconds on #{name}"
31
+ sleep time
32
+ info "done waiting on #{name} "
33
+ end
34
+
35
+ def default_settings
36
+ @stdin_result = nil
37
+ @job_id = @options['job_id']
38
+ @subscription_channel = @options['actor_id']
17
39
  @task_approved = false
18
40
  @successfull_subscription = false
19
- @client = CelluloidPubsub::Client.connect(actor: Actor.current, enable_debug: CapistranoMulticonfigParallel::CelluloidManager.debug_websocket?) do |ws|
41
+ end
42
+
43
+ def initialize_subscription
44
+ @client = CelluloidPubsub::Client.connect(actor: Actor.current, enable_debug: debug_enabled?) do |ws|
20
45
  ws.subscribe(@subscription_channel)
21
46
  end if !defined?(@client) || @client.nil?
22
47
  end
23
48
 
24
49
  def debug_enabled?
25
- @client.debug_enabled?
50
+ CapistranoMulticonfigParallel::CelluloidManager.debug_websocket?
26
51
  end
27
52
 
28
53
  def task_name
29
54
  @task.name
30
55
  end
31
56
 
32
- def find_job_id
33
- @env[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID]
34
- end
35
-
36
57
  def task_data
37
58
  {
38
59
  action: @action,
39
60
  task: task_name,
40
- job_id: find_job_id
61
+ job_id: @job_id
41
62
  }
42
63
  end
43
64
 
44
- def publish_new_work(env, task)
45
- work(env, task, rake_actor_id: @options['rake_actor_id'])
65
+ def publish_new_work(env, new_options = {})
66
+ work(env, @options.merge(new_options))
67
+ after_publishing_new_work
68
+ end
69
+
70
+ def after_publishing_new_work
46
71
  publish_to_worker(task_data)
47
72
  end
48
73
 
@@ -51,7 +76,7 @@ module CapistranoMulticonfigParallel
51
76
  end
52
77
 
53
78
  def on_message(message)
54
- debug("Rake worker #{find_job_id} received after parse #{message}") if debug_enabled?
79
+ debug("Rake worker #{@job_id} received after parse #{message}") if debug_enabled?
55
80
  if @client.succesfull_subscription?(message)
56
81
  publish_subscription_successfull
57
82
  elsif message.present? && message['client_action'].blank?
@@ -61,12 +86,24 @@ module CapistranoMulticonfigParallel
61
86
  end
62
87
  end
63
88
 
89
+ def msg_for_stdin?(message)
90
+ message['action'] == 'stdin'
91
+ end
92
+
64
93
  def publish_subscription_successfull
65
- debug("Rake worker #{find_job_id} received parse #{message}") if debug_enabled?
94
+ debug("Rake worker #{@job_id} received parse #{message}") if debug_enabled?
66
95
  publish_to_worker(task_data)
67
96
  @successfull_subscription = true
68
97
  end
69
98
 
99
+ def stdin_approval(message)
100
+ if @job_id.to_i == message['job_id'].to_i && message['approved'] == 'yes'
101
+ @stdin_result = message
102
+ else
103
+ warn "unknown invocation #{message.inspect}" if debug_enabled?
104
+ end
105
+ end
106
+
70
107
  def task_approval(message)
71
108
  if @job_id.to_i == message['job_id'].to_i && message['task'] == task_name && message['approved'] == 'yes'
72
109
  @task_approved = true
@@ -72,6 +72,10 @@ module CapistranoMulticonfigParallel
72
72
  processed_job['task_arguments'].present? ? "#{processed_job['action_name']}[#{processed_job['task_arguments'].join(',')}]" : processed_job['action_name']
73
73
  end
74
74
 
75
+ def worker_stage(processed_job)
76
+ processed_job['app_name'].present? ? "#{processed_job['app_name']}\n#{processed_job['env_name']}" : "#{processed_job['env_name']}"
77
+ end
78
+
75
79
  def get_worker_details(job_id)
76
80
  job = @manager.jobs[job_id]
77
81
  processed_job = @manager.process_job(job)
@@ -81,6 +85,7 @@ module CapistranoMulticonfigParallel
81
85
  'job_id' => job_id,
82
86
  'app_name' => processed_job['app_name'],
83
87
  'env_name' => processed_job['env_name'],
88
+ 'full_stage' => worker_stage(processed_job),
84
89
  'action_name' => worker_action(processed_job),
85
90
  'env_options' => worker_env_options(processed_job),
86
91
  'task_arguments' => job['task_arguments'],
@@ -91,7 +96,7 @@ module CapistranoMulticonfigParallel
91
96
  def add_job_to_table(table, job_id)
92
97
  details = get_worker_details(job_id)
93
98
  row = [{ value: job_id.to_s },
94
- { value: "#{details['app_name']}\n#{details['env_name']}" },
99
+ { value: details['full_stage'] },
95
100
  { value: details['action_name'] },
96
101
  { value: details['env_options'] },
97
102
  { value: "#{details['state']}" }
@@ -4,20 +4,15 @@ 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
6
  def self.start
7
- if $stdin.isatty
8
- $stdin.sync = true
9
- end
10
- if $stdout.isatty
11
- $stdout.sync = true
12
- end
7
+ CapistranoMulticonfigParallel.check_terminal_tty
13
8
  CapistranoMulticonfigParallel.original_args = ARGV.dup
14
9
  CapistranoMulticonfigParallel::Application.new.run
15
- rescue Interrupt
16
- `stty icanon echo`
17
- $stderr.puts 'Command cancelled.'
18
- rescue => error
19
- $stderr.puts error
20
- exit(1)
10
+ rescue Interrupt
11
+ `stty icanon echo`
12
+ $stderr.puts 'Command cancelled.'
13
+ rescue => error
14
+ $stderr.puts error
15
+ exit(1)
21
16
  end
22
17
  end
23
18
  end
@@ -35,11 +35,11 @@ module CapistranoMulticonfigParallel
35
35
  File.join(CapistranoMulticonfigParallel.detect_root.to_s, 'config', 'multi_cap.yml')
36
36
  end
37
37
 
38
- def internal_config_directory
39
- File.join(CapistranoMulticonfigParallel.root.to_s, 'capistrano_multiconfig_parallel', 'initializers')
40
- end
41
-
42
- def command_line_params
38
+ def internal_config_directory
39
+ File.join(CapistranoMulticonfigParallel.root.to_s, 'capistrano_multiconfig_parallel', 'initializers')
40
+ end
41
+
42
+ def command_line_params
43
43
  [
44
44
  {
45
45
  name: 'multi_debug',
@@ -126,7 +126,7 @@ module CapistranoMulticonfigParallel
126
126
  default: default_config[:application_dependencies]
127
127
  }
128
128
  ]
129
- end
129
+ end
130
130
 
131
131
  def capistrano_options
132
132
  command_line_params.map do |param|
@@ -1,28 +1,14 @@
1
+ require_relative '../helpers/extension_helper'
1
2
  Rake::Task.class_eval do
2
3
  alias_method :original_execute, :execute
3
4
 
4
5
  def execute(args = nil)
5
- job_id = ENV[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID]
6
- if job_id.present?
7
- run_the_actor(job_id) do
6
+ if CapistranoMulticonfigParallel::ExtensionHelper.inside_job?
7
+ CapistranoMulticonfigParallel::ExtensionHelper.run_the_actor(self) do
8
8
  original_execute(*args)
9
9
  end
10
10
  else
11
11
  original_execute(*args)
12
12
  end
13
13
  end
14
-
15
- def run_the_actor(job_id)
16
- rake_actor_id = ENV['count_rake'].present? ? "rake_worker_#{job_id}_count" : "rake_worker_#{job_id}"
17
- if Celluloid::Actor[rake_actor_id].blank?
18
- CapistranoMulticonfigParallel::RakeWorker.supervise_as rake_actor_id
19
- Celluloid::Actor[rake_actor_id].work(ENV, self, rake_actor_id: rake_actor_id)
20
- else
21
- Celluloid::Actor[rake_actor_id].publish_new_work(ENV, self)
22
- end
23
- until Celluloid::Actor[rake_actor_id].task_approved
24
- sleep(0.1) # keep current thread alive
25
- end
26
- yield if Celluloid::Actor[rake_actor_id].task_approved
27
- end
28
14
  end
@@ -1,4 +1,5 @@
1
1
  require_relative './standard_deploy'
2
+ require_relative '../celluloid/celluloid_manager'
2
3
  module CapistranoMulticonfigParallel
3
4
  # finds app dependencies, shows menu and delegates jobs to celluloid manager
4
5
  # rubocop:disable ClassLength
@@ -88,8 +89,8 @@ module CapistranoMulticonfigParallel
88
89
 
89
90
  def tag_staging_exists? # check exists task from capistrano-gitflow
90
91
  check_giflow_tasks(
91
- CapistranoMulticonfigParallel::GITFLOW_TAG_STAGING_TASK,
92
- CapistranoMulticonfigParallel::GITFLOW_CALCULATE_TAG_TASK,
92
+ CapistranoMulticonfigParallel::GITFLOW_TAG_STAGING_TASK,
93
+ CapistranoMulticonfigParallel::GITFLOW_CALCULATE_TAG_TASK,
93
94
  CapistranoMulticonfigParallel::GITFLOW_VERIFY_UPTODATE_TASK
94
95
  )
95
96
  rescue
@@ -97,14 +98,14 @@ module CapistranoMulticonfigParallel
97
98
  end
98
99
 
99
100
  def check_giflow_tasks(*tasks)
100
- tasks.all? {|t| Rake::Task[t].present? }
101
+ tasks.all? { |t| Rake::Task[t].present? }
101
102
  end
102
103
 
103
104
  def fetch_multi_stages
104
105
  stages = @argv['STAGES'].blank? ? '' : @argv['STAGES']
105
- stages = parse_inputted_value(value: stages).split(',').compact if stages.present?
106
- stages = stages.present? ? stages : [@default_stage]
107
- return stages
106
+ stages = parse_inputted_value('value' => stages).split(',').compact if stages.present?
107
+ stages = stages.present? ? stages : [@default_stage]
108
+ stages
108
109
  end
109
110
 
110
111
  def wants_deploy_production?
@@ -139,7 +140,7 @@ module CapistranoMulticonfigParallel
139
140
  end
140
141
 
141
142
  def worker_environments
142
- @jobs.map { |job| job['env'] }
143
+ @jobs.map { |job| job['env'] }
143
144
  end
144
145
 
145
146
  def confirmation_applies_to_all_workers?
@@ -189,7 +190,7 @@ module CapistranoMulticonfigParallel
189
190
  message = box.present? ? "BOX #{box}:" : "stage #{options['stage']}:"
190
191
  env_opts = get_app_additional_env_options(app, message)
191
192
 
192
- options['env_options'] = options['env_options'].reverse_merge(env_opts.except('BOX'))
193
+ options['env_options'] = options['env_options'].reverse_merge(env_opts)
193
194
 
194
195
  env_options = branch_name.present? ? { 'BRANCH' => branch_name }.merge(options['env_options']) : options['env_options']
195
196
  job_env_options = custom_command? && env_options['ACTION'].present? ? env_options.except('ACTION') : env_options
@@ -197,7 +198,7 @@ module CapistranoMulticonfigParallel
197
198
  job = {
198
199
  app: app,
199
200
  env: options['stage'],
200
- action: custom_command? && env_options['ACTION'].present? ? env_options['ACTION'] : options['action'],
201
+ action: custom_command? && env_options['ACTION'].present? ? env_options['ACTION'] : options['action'],
201
202
  task_arguments: options['task_arguments'],
202
203
  env_options: job_env_options
203
204
  }
@@ -236,7 +237,7 @@ module CapistranoMulticonfigParallel
236
237
  def fetch_app_additional_env_options
237
238
  options = {}
238
239
  return options if fetch(:app_additional_env_options).blank?
239
- env_options = parse_inputted_value(key: :app_additional_env_options)
240
+ env_options = parse_inputted_value('key' => :app_additional_env_options)
240
241
  env_options = env_options.split(' ')
241
242
  options = multi_fetch_argv(env_options)
242
243
  options.stringify_keys!
@@ -254,7 +255,7 @@ module CapistranoMulticonfigParallel
254
255
  end
255
256
 
256
257
  def execute_on_multiple_boxes(main_box_name, options)
257
- boxes = parse_inputted_value(value: main_box_name).split(',').compact
258
+ boxes = parse_inputted_value('value' => main_box_name).split(',').compact
258
259
  boxes.each do |box_name|
259
260
  options['env_options']['BOX'] = box_name
260
261
  prepare_job(options)
@@ -0,0 +1,41 @@
1
+ module CapistranoMulticonfigParallel
2
+ class ExtensionHelper
3
+ class << self
4
+ def inside_job?
5
+ job_id.present?
6
+ end
7
+
8
+ def job_id
9
+ ENV[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID]
10
+ end
11
+
12
+ def rake_actor_id
13
+ ENV['count_rake'].present? ? "rake_worker_#{job_id}_count" : "rake_worker_#{job_id}"
14
+ end
15
+
16
+ def stdin_result
17
+ Celluloid::Actor[rake_actor_id].stdin_result
18
+ end
19
+
20
+ def run_stdin_actor
21
+ Celluloid::Actor[rake_actor_id].wait_execution('stdin') until stdin_result
22
+ output = stdin_result.dup
23
+ Celluloid::Actor[rake_actor_id].stdin_result = nil
24
+ output
25
+ end
26
+
27
+ def run_the_actor(task)
28
+ if Celluloid::Actor[rake_actor_id].blank?
29
+ CapistranoMulticonfigParallel::RakeWorker.supervise_as rake_actor_id
30
+ Celluloid::Actor[rake_actor_id].work(ENV, actor_id: rake_actor_id, job_id: job_id, task: task)
31
+ else
32
+ Celluloid::Actor[rake_actor_id].publish_new_work(ENV, task: task)
33
+ end
34
+ until Celluloid::Actor[rake_actor_id].task_approved
35
+ Celluloid::Actor[rake_actor_id].wait_execution
36
+ end
37
+ yield if Celluloid::Actor[rake_actor_id].task_approved
38
+ end
39
+ end
40
+ end
41
+ end
@@ -19,7 +19,6 @@ module CapistranoMulticonfigParallel
19
19
  applications << 'all_frameworks'
20
20
  interactive_menu = CapistranoMulticonfigParallel::InteractiveMenu.new
21
21
  applications_selected = interactive_menu.show_all_websites_interactive_menu(applications)
22
-
23
22
  applications_selected = applications_selected.gsub("\r\n", '') if applications_selected.present?
24
23
  applications_selected = applications_selected.gsub("\n", '') if applications_selected.present?
25
24
  applications_selected = applications_selected.split(',') if applications_selected.present?
@@ -69,7 +68,7 @@ module CapistranoMulticonfigParallel
69
68
  end
70
69
 
71
70
  def show_frameworks_used(applications_to_deploy, all_frameworks, action)
72
- return [] if applications_to_deploy.blank? || applications_to_deploy.size <= 1
71
+ return [] if applications_to_deploy.blank? || applications_to_deploy.size < 1
73
72
  puts 'The following frameworks will be used:'
74
73
  app_names = []
75
74
  if all_frameworks.present?
@@ -7,8 +7,8 @@ module CapistranoMulticonfigParallel
7
7
  # module used for generating the version
8
8
  module VERSION
9
9
  MAJOR = 0
10
- MINOR = 7
11
- TINY = 7
10
+ MINOR = 8
11
+ TINY = 0
12
12
  PRE = nil
13
13
 
14
14
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
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.7.7
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - bogdanRada
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-06 00:00:00.000000000 Z
11
+ date: 2015-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid-pmap
@@ -648,6 +648,7 @@ files:
648
648
  - lib/capistrano_multiconfig_parallel/configuration.rb
649
649
  - lib/capistrano_multiconfig_parallel/extensions/rake.rb
650
650
  - lib/capistrano_multiconfig_parallel/helpers/base_manager.rb
651
+ - lib/capistrano_multiconfig_parallel/helpers/extension_helper.rb
651
652
  - lib/capistrano_multiconfig_parallel/helpers/multi_app_manager.rb
652
653
  - lib/capistrano_multiconfig_parallel/helpers/single_app_manager.rb
653
654
  - lib/capistrano_multiconfig_parallel/helpers/standard_deploy.rb