Class: CapistranoMulticonfigParallel::Application
- Inherits:
-
Object
- Object
- CapistranoMulticonfigParallel::Application
- Includes:
- BaseActorHelper
- Defined in:
- lib/capistrano_multiconfig_parallel/application.rb
Overview
finds app dependencies, shows menu and delegates jobs to celluloid manager
Instance Attribute Summary collapse
-
#application ⇒ Object
readonly
Returns the value of attribute application.
-
#args ⇒ Object
readonly
Returns the value of attribute args.
-
#argv ⇒ Object
readonly
Returns the value of attribute argv.
-
#condition ⇒ Object
readonly
Returns the value of attribute condition.
-
#default_stage ⇒ Object
readonly
Returns the value of attribute default_stage.
-
#dependency_tracker ⇒ Object
readonly
Returns the value of attribute dependency_tracker.
-
#jobs ⇒ Object
readonly
Returns the value of attribute jobs.
-
#manager ⇒ Object
readonly
Returns the value of attribute manager.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#stage ⇒ Object
readonly
Returns the value of attribute stage.
-
#stage_apps ⇒ Object
readonly
Returns the value of attribute stage_apps.
-
#top_level_tasks ⇒ Object
readonly
Returns the value of attribute top_level_tasks.
Instance Method Summary collapse
- #action_key ⇒ Object
- #boxes_key ⇒ Object
- #call_task_deploy_app(options = {}) ⇒ Object
- #can_tag_staging? ⇒ Boolean
- #check_before_starting ⇒ Object
-
#collect_command_line_tasks(args) ⇒ Object
:nodoc:.
- #collect_jobs(options = {}, &_block) ⇒ Object
- #custom_command? ⇒ Boolean
- #deploy_app(options = {}) ⇒ Object
- #deploy_multiple_apps(applications, options) ⇒ Object
- #execute_on_multiple_boxes(boxes, options) ⇒ Object
- #fetch_app_additional_env_options(variable) ⇒ Object
- #fetch_multi_stages ⇒ Object
- #get_app_additional_env_options(app, app_message) ⇒ Object
-
#initialize ⇒ Application
constructor
A new instance of Application.
- #initialize_data ⇒ Object
- #job_can_tag_staging?(job) ⇒ Boolean
- #job_path(options) ⇒ Object
- #job_stage(options) ⇒ Object
- #job_stage_valid?(options) ⇒ Boolean
- #prepare_job(options) ⇒ Object
- #prepare_options(options) ⇒ Object
- #process_jobs ⇒ Object
- #raise_invalid_job_config ⇒ Object
- #run ⇒ Object
- #run_async_jobs ⇒ Object
- #run_custom_command(options) ⇒ Object
- #stages_key ⇒ Object
- #start ⇒ Object
-
#tag_staging_exists? ⇒ Boolean
check exists task from capistrano-gitflow.
- #verify_app_dependencies ⇒ Object
- #verify_options_custom_command(options) ⇒ Object
- #verify_valid_data ⇒ Object
- #wait_jobs_termination ⇒ Object
- #wants_deploy_production? ⇒ Boolean
Methods included from BaseActorHelper
Constructor Details
#initialize ⇒ Application
Returns a new instance of Application.
9 10 11 12 13 14 15 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 9 def initialize Celluloid.boot unless Celluloid.running? CapistranoMulticonfigParallel.enable_logging @stage_apps = multi_apps? ? app_names_from_stages : [] collect_command_line_tasks(CapistranoMulticonfigParallel.original_args) @jobs = [] end |
Instance Attribute Details
#application ⇒ Object (readonly)
Returns the value of attribute application.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def application @application end |
#args ⇒ Object (readonly)
Returns the value of attribute args.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def args @args end |
#argv ⇒ Object (readonly)
Returns the value of attribute argv.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def argv @argv end |
#condition ⇒ Object (readonly)
Returns the value of attribute condition.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def condition @condition end |
#default_stage ⇒ Object (readonly)
Returns the value of attribute default_stage.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def default_stage @default_stage end |
#dependency_tracker ⇒ Object (readonly)
Returns the value of attribute dependency_tracker.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def dependency_tracker @dependency_tracker end |
#jobs ⇒ Object (readonly)
Returns the value of attribute jobs.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def jobs @jobs end |
#manager ⇒ Object (readonly)
Returns the value of attribute manager.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def manager @manager end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def name @name end |
#stage ⇒ Object (readonly)
Returns the value of attribute stage.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def stage @stage end |
#stage_apps ⇒ Object (readonly)
Returns the value of attribute stage_apps.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def stage_apps @stage_apps end |
#top_level_tasks ⇒ Object (readonly)
Returns the value of attribute top_level_tasks.
7 8 9 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 7 def top_level_tasks @top_level_tasks end |
Instance Method Details
#action_key ⇒ Object
82 83 84 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 82 def action_key 'ACTION' end |
#boxes_key ⇒ Object
166 167 168 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 166 def boxes_key 'BOX' end |
#call_task_deploy_app(options = {}) ⇒ Object
170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 170 def call_task_deploy_app( = {}) = .stringify_keys main_box_name = @argv[boxes_key].blank? ? '' : @argv[boxes_key] boxes = strip_characters_from_string(main_box_name).split(',').compact stage = .fetch('stage', @default_stage) if configuration.development_stages.include?(stage) && boxes.present? execute_on_multiple_boxes(boxes, ) else prepare_job() end end |
#can_tag_staging? ⇒ Boolean
135 136 137 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 135 def can_tag_staging? wants_deploy_production? && fetch_multi_stages.include?('staging') end |
#check_before_starting ⇒ Object
91 92 93 94 95 96 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 91 def check_before_starting @dependency_tracker = CapistranoMulticonfigParallel::DependencyTracker.new(Actor.current) @default_stage = configuration.development_stages.present? ? configuration.development_stages.first : 'development' @condition = Celluloid::Condition.new @manager = CapistranoMulticonfigParallel::CelluloidManager.new(Actor.current) end |
#collect_command_line_tasks(args) ⇒ Object
:nodoc:
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 69 def collect_command_line_tasks(args) # :nodoc: @argv = {} @top_level_tasks = [] args.each do |arg| if arg =~ /^(\w+)=(.*)$/m @argv[Regexp.last_match(1)] = Regexp.last_match(2) else @top_level_tasks << arg unless arg =~ /^-/ end end @top_level_tasks.push(Rake.application.default_task_name) if @top_level_tasks.blank? end |
#collect_jobs(options = {}, &_block) ⇒ Object
98 99 100 101 102 103 104 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 98 def collect_jobs( = {}, &_block) = () = .stringify_keys apps, = @dependency_tracker.fetch_apps_needed_for_deployment(['app'], ['action']) deploy_multiple_apps(apps, ) deploy_app(.merge()) if !custom_command? || !multi_apps? end |
#custom_command? ⇒ Boolean
48 49 50 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 48 def custom_command? custom_commands.include?(@top_level_tasks.first) end |
#deploy_app(options = {}) ⇒ Object
139 140 141 142 143 144 145 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 139 def deploy_app( = {}) = .stringify_keys call_task_deploy_app({ app: ['app'], action: ['action'] }.reverse_merge()) end |
#deploy_multiple_apps(applications, options) ⇒ Object
40 41 42 43 44 45 46 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 40 def deploy_multiple_apps(applications, ) = .stringify_keys return unless applications.present? applications.each do |app| deploy_app(.merge('app' => app['app'], 'path' => app.fetch('path', nil))) end end |
#execute_on_multiple_boxes(boxes, options) ⇒ Object
263 264 265 266 267 268 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 263 def execute_on_multiple_boxes(boxes, ) boxes.each do |box_name| ['env_options'][boxes_key] = box_name prepare_job() end end |
#fetch_app_additional_env_options(variable) ⇒ Object
253 254 255 256 257 258 259 260 261 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 253 def (variable) = {} return if variable.blank? = strip_characters_from_string(variable) = .split(' ') = multi_fetch_argv() .stringify_keys! end |
#fetch_multi_stages ⇒ Object
124 125 126 127 128 129 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 124 def fetch_multi_stages custom_stages = @argv[stages_key].blank? ? '' : @argv[stages_key] custom_stages = strip_characters_from_string(custom_stages).split(',').compact if custom_stages.present? custom_stages = custom_stages.present? ? custom_stages : [@default_stage] custom_stages end |
#get_app_additional_env_options(app, app_message) ⇒ Object
147 148 149 150 151 152 153 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 147 def (app, ) app_name = (app.is_a?(Hash) && app[:app].present?) ? app[:app].camelcase : app app_name = app_name.present? ? app_name : 'current application' = "Please write additional ENV options for #{app_name} for #{}" = ask_confirm(, nil) () end |
#initialize_data ⇒ Object
62 63 64 65 66 67 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 62 def initialize_data @application = custom_command? ? nil : @top_level_tasks.first.split(':').reverse[1] @stage = custom_command? ? nil : @top_level_tasks.first.split(':').reverse[0] @stage = @stage.present? ? @stage : @default_stage @name, @args = parse_task_string(@top_level_tasks.second) end |
#job_can_tag_staging?(job) ⇒ Boolean
226 227 228 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 226 def job_can_tag_staging?(job) can_tag_staging? && job.stage == 'production' && job.gitflow.present? end |
#job_path(options) ⇒ Object
230 231 232 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 230 def job_path() .fetch("path", detect_root) end |
#job_stage(options) ⇒ Object
238 239 240 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 238 def job_stage() multi_apps?(job_path()) && .fetch('app', nil).present? ? "#{['app']}:#{['stage']}" : "#{['stage']}" end |
#job_stage_valid?(options) ⇒ Boolean
234 235 236 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 234 def job_stage_valid?() stages(job_path()).include?(job_stage()) end |
#prepare_job(options) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 205 def prepare_job() = .stringify_keys return raise_invalid_job_config if !job_stage_valid?() app = .fetch('app', '') box = ['env_options'][boxes_key] = box.present? ? "BOX #{box}:" : "stage #{['stage']}:" env_opts = (app, ) ['env_options'] = ['env_options'].reverse_merge(env_opts) = ['env_options'] = custom_command? ? .except(action_key) : job = CapistranoMulticonfigParallel::Job.new(Actor.current, .merge( action: custom_command? && [action_key].present? ? [action_key] : ['action'], env_options: , path: .fetch('path', nil) )) @jobs << job unless job_can_tag_staging?(job) end |
#prepare_options(options) ⇒ Object
243 244 245 246 247 248 249 250 251 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 243 def () = .stringify_keys ['app'] = .fetch('app', @application.to_s.clone) ['action'] = .fetch('action', @name.to_s.clone) ['stage'] = .fetch('stage', @stage.to_s.clone) ['env_options'] = .fetch('env_options', @argv.clone) ['task_arguments'] = .fetch('task_arguments', @args.clone) end |
#process_jobs ⇒ Object
106 107 108 109 110 111 112 113 114 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 106 def process_jobs return unless @jobs.present? FileUtils.rm Dir["#{log_directory}/worker_*.log"] if configuration.multi_secvential.to_s.downcase == 'true' @jobs.each(&:execute_standard_deploy) else run_async_jobs end end |
#raise_invalid_job_config ⇒ Object
57 58 59 60 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 57 def raise_invalid_job_config puts 'Invalid execution, please call something such as `multi_cap production deploy`, where production is a stage you have defined'.red exit(false) end |
#run ⇒ Object
155 156 157 158 159 160 161 162 163 164 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 155 def run = {} if custom_command? = () run_custom_command() else collect_jobs() end process_jobs end |
#run_async_jobs ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 182 def run_async_jobs return unless @jobs.present? @jobs.pmap do |job| @manager.async.delegate_job(job) end unless can_tag_staging? && tag_staging_exists? until @manager.registration_complete sleep(0.1) # keep current thread alive end return unless @manager.registration_complete @manager.async.process_jobs end wait_jobs_termination end |
#run_custom_command(options) ⇒ Object
32 33 34 35 36 37 38 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 32 def run_custom_command() custom_stages = fetch_multi_stages return if custom_stages.blank? custom_stages.each do |stage| collect_jobs(.merge('stage' => stage)) end end |
#stages_key ⇒ Object
120 121 122 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 120 def stages_key 'STAGES' end |
#start ⇒ Object
17 18 19 20 21 22 23 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 17 def start verify_app_dependencies if multi_apps? && configuration.application_dependencies.present? initialize_data verify_valid_data check_before_starting run end |
#tag_staging_exists? ⇒ Boolean
check exists task from capistrano-gitflow
116 117 118 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 116 def tag_staging_exists? # check exists task from capistrano-gitflow @jobs.find(&:gitflow).present? end |
#verify_app_dependencies ⇒ Object
25 26 27 28 29 30 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 25 def verify_app_dependencies wrong = configuration.application_dependencies.find do |hash| !@stage_apps.include?(hash[:app]) || (hash[:dependencies].present? && hash[:dependencies].find { |val| !@stage_apps.include?(val) }) end raise ArgumentError, "Invalid configuration for #{wrong.inspect}".red if wrong.present? end |
#verify_options_custom_command(options) ⇒ Object
86 87 88 89 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 86 def () [:action] = @argv[action_key].present? ? @argv[action_key] : 'deploy' end |
#verify_valid_data ⇒ Object
52 53 54 55 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 52 def verify_valid_data return if @top_level_tasks != ['default'] raise_invalid_job_config end |
#wait_jobs_termination ⇒ Object
197 198 199 200 201 202 203 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 197 def wait_jobs_termination return if configuration.multi_secvential.to_s.downcase == 'true' result = @condition.wait return unless result.present? @manager.terminate terminate end |
#wants_deploy_production? ⇒ Boolean
131 132 133 |
# File 'lib/capistrano_multiconfig_parallel/application.rb', line 131 def wants_deploy_production? (!custom_command? && @stage == 'production') || (custom_command? && fetch_multi_stages.include?('production')) end |