def self.run(cmd, args=[])
command = parse(cmd)
unless command
error " ! #{cmd} is not a heroku command. See 'heroku help'."
return
end
@current_command = cmd
opts = {}
invalid_options = []
parser = OptionParser.new do |parser|
global_options.each do |global_option|
parser.on(*global_option[:args]) do |value|
opts[global_option[:name]] = value
end
end
command[:options].each do |name, option|
parser.on("-#{option[:short]}", "--#{option[:long]}", option[:desc]) do |value|
opts[name.gsub("-", "_").to_sym] = value
end
end
end
begin
parser.order!(args) do |nonopt|
invalid_options << nonopt
end
rescue OptionParser::InvalidOption => ex
invalid_options << ex.args.first
retry
end
if opts[:help]
run "help", [cmd]
return
end
args.concat(invalid_options)
@current_args = args
@current_options = opts
begin
object = command[:klass].new(args.dup, opts.dup)
object.send(command[:method])
rescue InvalidCommand
error "Unknown command. Run 'heroku help' for usage information."
rescue RestClient::Unauthorized
puts "Authentication failure"
run "login"
retry
rescue RestClient::PaymentRequired => e
retry if run('account:confirm_billing', args.dup)
rescue RestClient::ResourceNotFound => e
error extract_not_found(e.http_body)
rescue RestClient::Locked => e
app = e.response.headers[:x_confirmation_required]
message = extract_error(e.response.body)
if confirmation_required(app, message)
opts[:confirm] = app
retry
end
rescue RestClient::RequestFailed => e
error extract_error(e.http_body)
rescue RestClient::RequestTimeout
error "API request timed out. Please try again, or contact support@heroku.com if this issue persists."
rescue CommandFailed => e
error e.message
end
rescue OptionParser::ParseError => ex
commands[cmd] ? run("help", [cmd]) : run("help")
rescue Interrupt => e
error "\n[canceled]"
end