Class: CapistranoMulticonfigParallel::JobCommand

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
ApplicationHelper
Defined in:
lib/capistrano_multiconfig_parallel/classes/job_command.rb

Overview

class used to find application dependencies

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ApplicationHelper

action_confirmed?, fetch_parsed_string, fetch_remaining_arguments, find_remaining_args, get_question_details, message_from_bundler?, message_is_about_a_task?, message_is_for_stdout?, msg_for_stdin?, parse_json, parse_task_string, percent_of, regex_last_match, setup_command_line_standard, truncate, wrap_string

Methods included from CapistranoHelper

env_key_format, env_prefix, filtered_env_keys_format, setup_flags_for_job, trace_flag

Methods included from GemHelper

fetch_gem_version, find_loaded_gem, find_loaded_gem_property, format_gem_version, get_parsed_version, verify_gem_version

Methods included from StagesHelper

app_names_from_stages, application_supports_multi_apps?, check_stage_path, checks_paths, configuration_has_valid_path?, fetch_apps_from_file, fetch_paths_from_file, fetch_stages_app, fetch_stages_paths, independent_deploy?, multi_apps?, sorted_paths, stages, stages_paths, stages_root

Methods included from ParseHelper

check_hash_set, check_numeric, strip_characters_from_string, value_is_array?, verify_array_of_strings, verify_empty_options, warn_array_without_strings

Methods included from CoreHelper

app_debug_enabled?, ask_confirm, ask_stdout_confirmation, check_terminal_tty, debug_websocket?, development_debug?, error_filtered?, execute_with_rescue, find_worker_log, force_confirmation, format_error, log_error, log_output_error, log_to_file, multi_fetch_argv, print_to_log_file, rescue_error, rescue_interrupt, setup_filename_logger, setup_logger_formatter, show_warning, terminal_actor, terminal_errors?, websocket_config, websocket_server_config

Methods included from InternalHelper

arg_is_in_default_config?, check_file, create_log_file, custom_commands, default_config_keys, default_internal_config, default_internal_configuration_params, detect_root, enable_main_log_file, fail_capfile_not_found, fetch_default_internal_config, find_config_type, find_env_multi_cap_root, find_file_by_names, find_file_in_directory, get_current_gem_name, internal_config_directory, internal_config_file, log_directory, main_log_file, multi_level_prop, pathname_is_root?, pwd_directory, pwd_parent_dir, root, setup_default_configuration_types, sliced_default_config, try_detect_file, try_detect_file_in_dir

Constructor Details

#initialize(job) ⇒ JobCommand

Returns a new instance of JobCommand.



13
14
15
16
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 13

def initialize(job)
  @job = job
  @job_final_gemfile = job_gemfile_multi
end

Instance Attribute Details

#jobObject (readonly)

Returns the value of attribute job.



9
10
11
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 9

def job
  @job
end

#job_capistrano_versionObject (readonly)

Returns the value of attribute job_capistrano_version.



9
10
11
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 9

def job_capistrano_version
  @job_capistrano_version
end

#job_final_capfileObject (readonly)

Returns the value of attribute job_final_capfile.



9
10
11
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 9

def job_final_capfile
  @job_final_capfile
end

#job_final_gemfileObject (readonly)

Returns the value of attribute job_final_gemfile.



9
10
11
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 9

def job_final_gemfile
  @job_final_gemfile
end

#legacy_capistranoObject (readonly)

Returns the value of attribute legacy_capistrano.



9
10
11
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 9

def legacy_capistrano
  @legacy_capistrano
end

#tempfileObject (readonly)

Returns the value of attribute tempfile.



9
10
11
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 9

def tempfile
  @tempfile
end

Instance Method Details

#bash_bin_pathObject



171
172
173
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 171

def bash_bin_path
  @bash_bin_path ||= `which bash`
end

#bundle_gemfile_env(gemfile = job_gemfile) ⇒ Object



70
71
72
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 70

def bundle_gemfile_env(gemfile = job_gemfile)
  "BUNDLE_GEMFILE=#{gemfile}"
end

#capfile_nameObject



41
42
43
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 41

def capfile_name
  find_capfile.present? ? find_capfile.basename : nil
end

#capistrano_actionObject



105
106
107
108
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 105

def capistrano_action
  argv = task_arguments.present? ? "[#{task_arguments}]" : ''
  "#{action}#{argv}"
end

#capistrano_sentinel_available?Boolean

Returns:

  • (Boolean)


84
85
86
87
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 84

def capistrano_sentinel_available?
  gitflow_version = job_gem_version(capistrano_sentinel_name)
  gitflow_version.present? ? true : false
end

#capistrano_sentinel_nameObject



80
81
82
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 80

def capistrano_sentinel_name
  "capistrano_sentinel"
end

#capistrano_sentinel_needs_updating?Boolean

Returns:

  • (Boolean)


145
146
147
148
149
150
151
152
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 145

def capistrano_sentinel_needs_updating?
  if capistrano_sentinel_available?
    loaded_capistrano_sentinel_version == job_capistrano_sentinel_version
  else
    # the capistrano_sentinel is not part of the Gemfile so no need checking if needs updating
    true
  end
end

#check_capistrano_sentinel_availabilityObject



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 285

def check_capistrano_sentinel_availability
  #  '#{find_loaded_gem_property(capistrano_sentinel_name)}'
  #  path: '/home/raul/workspace/github/capistrano_sentinel'
  if capistrano_sentinel_available?
    @job_final_gemfile = job_gemfile
  else
    FileUtils.rm_rf(job_gemfile_multi) if File.exists?(job_gemfile_multi)
    FileUtils.touch(job_gemfile_multi)
    File.open(job_gemfile_multi, 'w') do |f|
      cmd=<<-CMD
      source "https://rubygems.org" do
        gem "#{capistrano_sentinel_name}", '#{find_loaded_gem_property(capistrano_sentinel_name)}'
      end
      instance_eval(File.read(File.dirname(__FILE__) + "/Gemfile"))
      CMD
      f.write(cmd)
    end
    FileUtils.copy(job_gemfile_lock, "#{job_gemfile_multi}.lock")
  end
end

#check_rvm_loadedObject



202
203
204
205
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 202

def check_rvm_loaded
  return  "cd #{job_path}" unless rvm_enabled_for_job?
  "source #{rvm_scripts_path} && rvm rvmrc trust #{job_path} && cd #{job_path} && source #{job_rvmrc_file}"
end

#create_job_tempfile_command(output) ⇒ Object



179
180
181
182
183
184
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 179

def create_job_tempfile_command(output)
  @tempfile = Tempfile.new(["multi_cap_#{job.id}_command_", ".rb"], encoding: 'utf-8')
  @tempfile.write(output)
  ObjectSpace.undefine_finalizer(@tempfile) # force garbage collector not to remove automatically the file
  @tempfile.close
end

#env_option_filtered?(key, filtered_keys_array = []) ⇒ Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 110

def env_option_filtered?(key, filtered_keys_array = [])
  filtered_env_keys.include?(env_key_format(key)) || filtered_keys_array.include?(key.to_s)
end

#execute_standard_deploy(action = nil) ⇒ Object



338
339
340
341
342
343
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 338

def execute_standard_deploy(action = nil)
  run_shell_command(fetch_deploy_command)
rescue => ex
  rescue_error(ex, 'stderr')
  execute_standard_deploy('deploy:rollback') if action.blank? && @name == 'deploy'
end

#fetch_bundler_check_command(gemfile = job_gemfile) ⇒ Object



26
27
28
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 26

def fetch_bundler_check_command(gemfile = job_gemfile)
  "#{check_rvm_loaded} && if [ `which bundler |wc -l` = 0 ]; then gem install bundler;fi && (#{bundle_gemfile_env(gemfile)} bundle check || #{bundle_gemfile_env(gemfile)} bundle install )"
end

#fetch_bundler_worker_commandObject



30
31
32
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 30

def fetch_bundler_worker_command
  get_command_script(fetch_bundler_check_command, "bundler")
end

#fetch_deploy_commandObject



244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 244

def fetch_deploy_command
  prepare_application_for_deployment
  #  config_flags = CapistranoMulticonfigParallel.configuration_flags.merge("capistrano_version": job_capistrano_version)
  environment_options = setup_command_line.join(' ')
  command = "#{fetch_bundler_check_command(@job_final_gemfile)} && WS_PORT=#{CelluloidPubsub::WebServer.find_unused_port} WEBSOCKET_LOGGING=#{debug_websocket?} LOG_FILE=#{websocket_config.fetch('log_file_path', nil)} #{bundle_gemfile_env(@job_final_gemfile)} bundle exec cap #{job_stage} #{capistrano_action} #{environment_options}"

  if @job_final_capfile != job_capfile
    command += " -f #{@job_final_capfile}"
  end

  get_command_script(command)
end

#filtered_env_keysObject



66
67
68
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 66

def filtered_env_keys
  %w(STAGES ACTION)
end

#find_capfile(custom_path = job_path) ⇒ Object



35
36
37
38
39
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 35

def find_capfile(custom_path = job_path)
  @capfile_path ||= find_file_by_names(custom_path, 'capfile').first
  raise "Please make sure you have a Capfile in the project root directory #{custom_path}".red if @capfile_path.blank?
  @capfile_path
end

#gem_specsObject



45
46
47
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 45

def gem_specs
  @specs = lockfile_parser.specs
end

#get_command_script(command, action = nil) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 219

def get_command_script(command, action = nil)
  command = rvm_bash_prefix(command)
  command = command.inspect
  command_text =<<-CMD
  require 'rubygems'
  require 'bundler'
  Bundler.with_clean_env {
    Kernel.exec(#{command})
  }
  CMD

  if rvm_enabled_for_job?
    create_job_tempfile_command(command_text)
    log_to_worker("JOB #{@job_id}  created Tempfile #{@tempfile.path} with contents #{File.read(@tempfile.path)}", action)
    "ruby #{@tempfile.path}"
  else
    final_command=<<-CMD
    cd #{job_path} && bundle exec ruby -e "#{command_text}"
    CMD
    log_to_worker("JOB #{@job_id}  prepared command #{final_command}", action)
    final_command
  end
end

#gitflow_enabled?Boolean

Returns:

  • (Boolean)


75
76
77
78
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 75

def gitflow_enabled?
  gitflow_version = job_gem_version("capistrano-gitflow")
  gitflow_version.present? ? true : false
end

#job_capfileObject



258
259
260
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 258

def job_capfile
  File.join(job_path, capfile_name.to_s)
end

#job_capfile_multiObject



262
263
264
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 262

def job_capfile_multi
  "#{job_capfile}.multi_cap"
end

#job_capistrano_sentinel_versionObject



93
94
95
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 93

def job_capistrano_sentinel_version
  job_gem_version(capistrano_sentinel_name)
end

#job_gem_version(gem_name) ⇒ Object



61
62
63
64
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 61

def job_gem_version(gem_name)
  gem_spec = gem_specs.find {|spec| spec.name == gem_name}
  gem_spec.present? ? gem_spec.version.to_s : nil
end

#job_gemfileObject



49
50
51
52
53
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 49

def job_gemfile
  @job_gemfile ||=File.join(job_path, 'Gemfile')
  raise "Please make sure you have a Gemfile in the project root directory #{job_path}".red unless File.exists?(@job_gemfile)
  @job_gemfile
end

#job_gemfile_lockObject



55
56
57
58
59
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 55

def job_gemfile_lock
  @job_gemfile_lock ||= "#{job_gemfile}.lock"
  raise "Please make sure you have a Gemfile.lock in the project root directory #{job_path}".red unless File.exists?(@job_gemfile_lock)
  @job_gemfile_lock
end

#job_gemfile_multiObject



266
267
268
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 266

def job_gemfile_multi
  File.join(job_path, "Gemfile.multi_cap")
end

#job_pathObject



154
155
156
157
158
159
160
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 154

def job_path
  if path.present? && File.directory?(path) && find_capfile(path).present?
    path
  else
    detect_root
  end
end

#job_rvmrc_enabled?Boolean

Returns:

  • (Boolean)


194
195
196
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 194

def job_rvmrc_enabled?
  File.exists?(job_rvmrc_file)
end

#job_rvmrc_fileObject



190
191
192
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 190

def job_rvmrc_file
  File.join(job_path, '.rvmrc')
end

#job_stageObject



101
102
103
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 101

def job_stage
  app.present? && application_supports_multi_apps?(job_path) ? "#{app}:#{stage}" : "#{stage}"
end

#job_stage_for_terminalObject



97
98
99
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 97

def job_stage_for_terminal
  app.present? ? "#{app}:#{stage}" : "#{stage}"
end

#legacy_capistrano_version?Boolean

Returns:

  • (Boolean)


137
138
139
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 137

def legacy_capistrano_version?
  verify_gem_version(job_capistrano_version, '3.0', operator: '<')
end

#loaded_capistrano_sentinel_versionObject



89
90
91
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 89

def loaded_capistrano_sentinel_version
  find_loaded_gem_property(capistrano_sentinel_name)
end

#lockfile_parserObject



18
19
20
21
22
23
24
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 18

def lockfile_parser
  if File.exists?(job_gemfile) && File.exists?(job_gemfile_lock)
    @lockfile_parser ||= Bundler::LockfileParser.new(Bundler.read_file("#{job_gemfile_lock}"))
  else
    raise "please install the gems separately for this application #{job_path} and re-try again!"
  end
end

#log_to_worker(message, action = nil) ⇒ Object



211
212
213
214
215
216
217
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 211

def log_to_worker(message, action = nil)
  if action.present? || action.to_s == id.to_s
    log_to_file(message, job_id: id, prefix: action)
  else
    log_to_file(message)
  end
end

#prepare_application_for_deploymentObject



270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 270

def prepare_application_for_deployment
  unless capistrano_sentinel_needs_updating?
    raise "Please consider upgrading the gem #{capistrano_sentinel_name} to version #{loaded_capistrano_sentinel_version} from #{job_capistrano_sentinel_version} in #{job_path} "
  end
  config = @job.application.patched_job_paths.find{|hash| hash[:path] == job_path}
  if config.present?
    @job_final_gemfile = config[:gemfile]
    @job_final_capfile = config[:capfile]
  else
    check_capistrano_sentinel_availability
    prepare_capfile
    @job.application.patched_job_paths << {path: job_path, gemfile: @job_final_gemfile, capfile: @job_final_capfile}
  end
end

#prepare_capfileObject



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 306

def prepare_capfile
  capfile_valid = File.foreach(job_capfile).grep(/#{capistrano_sentinel_name}/).any?
  if capistrano_sentinel_available? && capfile_valid.present?
    @job_final_capfile = job_capfile
  elsif capfile_valid.blank? && capistrano_sentinel_available?
    @job_final_capfile = job_capfile
    File.open(job_capfile, 'a+') do |f|
      cmd=<<-CMD
      require "#{capistrano_sentinel_name}"
      CMD
      f.write(cmd)
    end
  elsif capistrano_sentinel_available? == false
    @job_final_capfile = job_capfile_multi
    FileUtils.copy(job_capfile, job_capfile_multi)
    File.open(job_capfile_multi, 'a+') do |f|
      cmd=<<-CMD
      require "#{capistrano_sentinel_name}"
      CMD
      f.write(cmd)
    end
  end
end

#rollback_changes_to_applicationObject



331
332
333
334
335
336
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 331

def rollback_changes_to_application
  FileUtils.rm_rf(job_gemfile_multi) if File.exists?(job_gemfile_multi)
  FileUtils.rm_rf("#{job_gemfile_multi}.lock") if File.exists?("#{job_gemfile_multi}.lock")
  FileUtils.rm_rf(job_capfile_multi) if  File.exists?(job_capfile_multi)
  FileUtils.rm_rf(@tempfile.path) if defined?(@tempfile) && @tempfile
end

#rvm_bash_prefix(command) ⇒ Object



207
208
209
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 207

def rvm_bash_prefix(command)
  rvm_enabled_for_job? ? "bash --login -c '#{command}'" : command
end

#rvm_bin_pathObject



167
168
169
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 167

def rvm_bin_path
  @rvm_path ||= `which rvm`
end

#rvm_enabled_for_job?Boolean

Returns:

  • (Boolean)


198
199
200
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 198

def rvm_enabled_for_job?
  job_rvmrc_enabled? && rvm_installed? && bash_bin_path.present?
end

#rvm_installed?Boolean

Returns:

  • (Boolean)


175
176
177
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 175

def rvm_installed?
  rvm_bin_path.present?
end

#rvm_scripts_pathObject



186
187
188
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 186

def rvm_scripts_path
  File.join(File.dirname(File.dirname(rvm_bin_path)), 'scripts', 'rvm')
end

#setup_command_line(*args) ⇒ Object



128
129
130
131
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 128

def setup_command_line(*args)
  new_arguments, options = setup_command_line_standard(*args)
  setup_env_options(options).concat(new_arguments)
end

#setup_env_options(options = {}) ⇒ Object



114
115
116
117
118
119
120
121
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 114

def setup_env_options(options = {})
  array_options = []
  filtered_keys = options.delete(:filtered_keys) || []
  env_options.each do |key, value|
    array_options << "#{env_prefix(key, legacy_capistrano)} #{env_key_format(key, legacy_capistrano)}=#{value}" if value.present? && !env_option_filtered?(key, filtered_keys)
  end
  setup_remaining_flags(array_options, options)
end

#setup_remaining_flags(array_options, options) ⇒ Object



123
124
125
126
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 123

def setup_remaining_flags(array_options, options)
  array_options << trace_flag(legacy_capistrano) if app_debug_enabled?
  array_options.concat(setup_flags_for_job(options))
end

#user_home_directoryObject



162
163
164
165
# File 'lib/capistrano_multiconfig_parallel/classes/job_command.rb', line 162

def user_home_directory
  user = Etc.getlogin
  Dir.home(user)
end