Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

use io/console if possible #965

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 29 additions & 24 deletions lib/heroku/auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@

require "netrc"

begin
require "io/console"
rescue LoadError
end

class Heroku::Auth
class << self
include Heroku::Helpers
Expand Down Expand Up @@ -169,13 +174,13 @@ def echo_off
with_tty do
system "stty -echo"
end
end
end unless defined?($stdin.noecho)

def echo_on
with_tty do
system "stty echo"
end
end
end unless defined?($stdin.noecho)

def ask_for_credentials
puts "Enter your Heroku credentials."
Expand All @@ -184,35 +189,35 @@ def ask_for_credentials
user = ask

print "Password (typing will be hidden): "
password = running_on_windows? ? ask_for_password_on_windows : ask_for_password
password = ask_for_password

[user, api_key(user, password)]
end

def ask_for_password_on_windows
require "Win32API"
char = nil
password = ''
if !defined?($stdin.noecho) and running_on_windows?
def ask_for_password
require "Win32API"
char = nil
password = ''

while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do
break if char == 10 || char == 13 # received carriage return or newline
if char == 127 || char == 8 # backspace and delete
password.slice!(-1, 1)
else
# windows might throw a -1 at us so make sure to handle RangeError
(password << char.chr) rescue RangeError
while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do
break if char == 10 || char == 13 # received carriage return or newline
if char == 127 || char == 8 # backspace and delete
password.slice!(-1, 1)
else
# windows might throw a -1 at us so make sure to handle RangeError
(password << char.chr) rescue RangeError
end
end
puts
return password
end
else
def ask_for_password
noecho_tty do |tty|
ask.tap {puts if tty}
end
end
puts
return password
end

def ask_for_password
echo_off
password = ask
puts
echo_on
return password
end

def ask_for_and_save_credentials
Expand Down
3 changes: 1 addition & 2 deletions lib/heroku/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,10 @@ def self.start(*args)
Heroku::Command.load
Heroku::Command.run(command, args)
rescue Interrupt
`stty icanon echo`
error("Command cancelled.")
rescue => error
styled_error(error)
exit(1)
exit(false)
end
end

Expand Down
19 changes: 8 additions & 11 deletions lib/heroku/command/run.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,7 @@ def run_attached(command)
end

def rendezvous_session(rendezvous_url, &on_connect)
begin
set_buffer(false)
raw_tty do
rendezvous = Heroku::Client::Rendezvous.new(
:rendezvous_url => rendezvous_url,
:connect_timeout => (ENV["HEROKU_CONNECT_TIMEOUT"] || 120).to_i,
Expand All @@ -130,16 +129,14 @@ def rendezvous_session(rendezvous_url, &on_connect)
:output => $stdout)
rendezvous.on_connect(&on_connect)
rendezvous.start
rescue Timeout::Error
error "\nTimeout awaiting process"
rescue OpenSSL::SSL::SSLError
error "Authentication error"
rescue Errno::ECONNREFUSED, Errno::ECONNRESET
error "\nError connecting to process"
rescue Interrupt
ensure
set_buffer(true)
end
rescue Timeout::Error
error "\nTimeout awaiting process"
rescue OpenSSL::SSL::SSLError
error "Authentication error"
rescue Errno::ECONNREFUSED, Errno::ECONNRESET
error "\nError connecting to process"
rescue Interrupt
end

def console_history_dir
Expand Down
40 changes: 35 additions & 5 deletions lib/heroku/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,42 @@ def json_decode(json)
nil
end

def set_buffer(enable)
with_tty do
if enable
`stty icanon echo`
if defined?($stdin.noecho)
def noecho_tty(&block)
$stdin.noecho {yield true}
rescue Errno::ENOTTY
yield false
end

def raw_tty(&block)
$stdin.noecho {yield true}
rescue Errno::ENOTTY
yield false
end
else
def noecho_tty(&block)
if $stdin.tty?
begin
`stty echo`
yield
ensure
`stty -echo`
end
else
yield
end
end

def raw_tty(&block)
if $stdin.tty?
begin
`stty icanon echo`
yield
ensure
`stty -icanon -echo`
end
else
`stty -icanon -echo`
yield
end
end
end
Expand Down