class Hatchet::HerokuRun
Used for running Heroku commands
Example:
run_obj = HerokuRun.new("ruby -v", app: app).call puts run_obj.output #=> "ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]" puts run_obj.status.success? #=> true
There’s a bug in specs sometimes where App#run
will return an empty value. When that’s detected then the command will be re-run. This can be optionally disabled by setting ‘retry_on_empty: false` if you’re expecting the command to be empty.
Attributes
command[R]
Public Class Methods
new( command, app: , heroku: {}, retry_on_empty: !ENV["HATCHET_DISABLE_EMPTY_RUN_RETRY"], raw: false, stderr: $stderr)
click to toggle source
# File lib/hatchet/heroku_run.rb, line 53 def initialize( command, app: , heroku: {}, retry_on_empty: !ENV["HATCHET_DISABLE_EMPTY_RUN_RETRY"], raw: false, stderr: $stderr) @raw = raw @app = app @command = build_heroku_command(command, heroku || {}) @retry_on_empty = retry_on_empty @stderr = stderr @result = nil @empty_fail_count = 0 end
Public Instance Methods
call()
click to toggle source
# File lib/hatchet/heroku_run.rb, line 84 def call loop do execute! break unless output.empty? break unless @retry_on_empty @empty_fail_count += 1 break if @empty_fail_count >= 3 message = String.new("Empty output from command #{@command}, retrying the command.") message << "\nTo disable pass in `retry_on_empty: false` or set HATCHET_DISABLE_EMPTY_RUN_RETRY=1 globally" message << "\nfailed_count: #{@empty_fail_count}" message << "\nreleases: #{@app.releases}" message << "\n#{caller.join("\n")}" @stderr.puts message end self end
output()
click to toggle source
# File lib/hatchet/heroku_run.rb, line 75 def output result.stdout end
result()
click to toggle source
# File lib/hatchet/heroku_run.rb, line 70 def result raise "You must run `call` on this object first" unless @result @result end
status()
click to toggle source
# File lib/hatchet/heroku_run.rb, line 79 def status result @status end
Private Instance Methods
build_heroku_command(command, options = {})
click to toggle source
# File lib/hatchet/heroku_run.rb, line 119 def build_heroku_command(command, options = {}) command = command.shellescape unless @raw default_options = { "app" => @app.name, "exit-code" => nil } heroku_options_array = (default_options.merge(options)).map do |k,v| # This was a bad interface decision next if v == Hatchet::App::SkipDefaultOption # for forcefully removing e.g. --exit-code, a user can pass this arg = "--#{k.to_s.shellescape}" arg << "=#{v.to_s.shellescape}" unless v.nil? # nil means we include the option without an argument arg end "heroku run #{heroku_options_array.compact.join(' ')} -- #{command}" end
execute!()
click to toggle source
# File lib/hatchet/heroku_run.rb, line 106 def execute! ShellThrottle.new(platform_api: @app.platform_api).call do |throttle| run_shell! throw(:throttle) if @result.stderr.match?(/reached the API rate limit/) end end
run_shell!()
click to toggle source
# File lib/hatchet/heroku_run.rb, line 113 def run_shell! stdout, stderr, status = Open3.capture3(@command) @result = BashResult.new(stdout: stdout, stderr: stderr, status: status, set_global_status: true) @status = $? end