Refactor Tty.

This commit is contained in:
Markus Reiter 2016-08-26 16:04:47 +02:00
parent 19e633f190
commit 6d8ee395fa
19 changed files with 125 additions and 127 deletions

View File

@ -147,8 +147,8 @@ rescue Exception => e
Utils::Analytics.report_exception(e) Utils::Analytics.report_exception(e)
onoe e onoe e
if internal_cmd && defined?(OS::ISSUES_URL) if internal_cmd && defined?(OS::ISSUES_URL)
$stderr.puts "#{Tty.white}Please report this bug:" $stderr.puts "Please report this bug:"
$stderr.puts " #{Tty.em}#{OS::ISSUES_URL}#{Tty.reset}" $stderr.puts " #{Tty.underline}#{OS::ISSUES_URL}#{Tty.reset}"
end end
$stderr.puts e.backtrace $stderr.puts e.backtrace
exit 1 exit 1

View File

@ -81,11 +81,10 @@ module Hbc
if target.exist? if target.exist?
target_abv = " (#{target.abv})" target_abv = " (#{target.abv})"
else else
warning = "Missing #{self.class.artifact_english_name}" error = "#{Tty.red}Missing #{self.class.artifact_english_name}:#{Tty.reset} "
warning = "#{Tty.red}#{warning}#{Tty.reset}: "
end end
"#{warning}#{printable_target}#{target_abv}" "#{error}#{printable_target}#{target_abv}"
end end
end end
end end

View File

@ -27,7 +27,7 @@ module Hbc
end end
def self.formatted_url(url) def self.formatted_url(url)
"#{Tty.em}#{url}#{Tty.reset}" "#{Tty.underline}#{url}#{Tty.reset}"
end end
def self.installation_info(cask) def self.installation_info(cask)

View File

@ -30,7 +30,7 @@ module Hbc
begin begin
Homebrew.install_gem_setup_path! "rubocop-cask", RUBOCOP_CASK_VERSION, "rubocop" Homebrew.install_gem_setup_path! "rubocop-cask", RUBOCOP_CASK_VERSION, "rubocop"
rescue SystemExit rescue SystemExit
raise CaskError, $stderr.string.chomp.sub("#{Tty.red}Error#{Tty.reset}: ", "") raise CaskError, Tty.strip_ansi($stderr.string).chomp.sub(/\AError: /, "")
end end
end end
end end

View File

@ -87,7 +87,7 @@ module Hbc
s = if MacOS.version >= :lion && !ENV["HOMEBREW_NO_EMOJI"] s = if MacOS.version >= :lion && !ENV["HOMEBREW_NO_EMOJI"]
(ENV["HOMEBREW_INSTALL_BADGE"] || "\xf0\x9f\x8d\xba") + " " (ENV["HOMEBREW_INSTALL_BADGE"] || "\xf0\x9f\x8d\xba") + " "
else else
"#{Tty.blue}==>#{Tty.reset} #{Tty.white}Success!#{Tty.reset} " "#{Tty.blue}==>#{Tty.reset} #{Tty.bold}Success!#{Tty.reset} "
end end
s << "#{@cask} was successfully installed!" s << "#{@cask} was successfully installed!"
end end

View File

@ -32,11 +32,6 @@ end
def odebug(title, *sput) def odebug(title, *sput)
return unless Hbc.respond_to?(:debug) return unless Hbc.respond_to?(:debug)
return unless Hbc.debug return unless Hbc.debug
width = Tty.width * 4 - 6
if $stdout.tty? && title.to_s.length > width
title = title.to_s[0, width - 3] + "..."
end
puts "#{Tty.magenta}==>#{Tty.reset} #{Tty.white}#{title}#{Tty.reset}" puts "#{Tty.magenta}==>#{Tty.reset} #{Tty.white}#{title}#{Tty.reset}"
puts sput unless sput.empty? puts sput unless sput.empty?
end end
@ -152,11 +147,11 @@ module Hbc
<<-EOS.undent <<-EOS.undent
Most likely, this means you have an outdated version of Homebrew-Cask. Please run: Most likely, this means you have an outdated version of Homebrew-Cask. Please run:
#{Tty.green}#{UPDATE_CMD} #{Tty.green}#{UPDATE_CMD}#{Tty.reset}
#{Tty.reset}If this doesnt fix the problem, please report this bug: If this doesnt fix the problem, please report this bug:
#{Tty.em}#{ISSUES_URL}#{Tty.reset} #{Tty.underline}#{ISSUES_URL}#{Tty.reset}
EOS EOS
end end

View File

@ -42,7 +42,7 @@ module Homebrew
next if out.nil? || out.empty? next if out.nil? || out.empty?
if first_warning if first_warning
$stderr.puts <<-EOS.undent $stderr.puts <<-EOS.undent
#{Tty.white}Please note that these warnings are just used to help the Homebrew maintainers #{Tty.bold}Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry and just ignore them. Thanks!#{Tty.reset} working fine: please don't worry and just ignore them. Thanks!#{Tty.reset}
EOS EOS

View File

@ -78,11 +78,11 @@ module Homebrew
HOMEBREW_HELP HOMEBREW_HELP
else else
help_lines.map do |line| help_lines.map do |line|
line.slice(2..-1) line.slice(2..-1).
.sub(/^ \* /, "#{Tty.highlight}brew#{Tty.reset} ") sub(/^ \* /, "#{Tty.bold}brew#{Tty.reset} ").
.gsub(/`(.*?)`/, "#{Tty.highlight}\\1#{Tty.reset}") gsub(/`(.*?)`/, "#{Tty.bold}\\1#{Tty.reset}").
.gsub(/<(.*?)>/, "#{Tty.em}\\1#{Tty.reset}") gsub(/<(.*?)>/, "#{Tty.underline}\\1#{Tty.reset}").
.gsub("@hide_from_man_page", "") gsub("@hide_from_man_page", "")
end.join.strip end.join.strip
end end
end end

View File

@ -117,7 +117,7 @@ module Homebrew
puts "#{f.full_name}: #{specs * ", "}#{" [#{attrs * ", "}]" unless attrs.empty?}" puts "#{f.full_name}: #{specs * ", "}#{" [#{attrs * ", "}]" unless attrs.empty?}"
puts f.desc if f.desc puts f.desc if f.desc
puts "#{Tty.em}#{f.homepage}#{Tty.reset}" if f.homepage puts "#{Tty.underline}#{f.homepage}#{Tty.reset}" if f.homepage
conflicts = f.conflicts.map(&:name).sort! conflicts = f.conflicts.map(&:name).sort!
puts "Conflicts with: #{conflicts*", "}" unless conflicts.empty? puts "Conflicts with: #{conflicts*", "}" unless conflicts.empty?
@ -133,7 +133,7 @@ module Homebrew
end end
end end
puts "From: #{Tty.em}#{github_info(f)}#{Tty.reset}" puts "From: #{Tty.underline}#{github_info(f)}#{Tty.reset}"
unless f.deps.empty? unless f.deps.empty?
ohai "Dependencies" ohai "Dependencies"

View File

@ -282,7 +282,7 @@ module Homebrew
EOS EOS
rescue => e rescue => e
ofail <<-EOS.undent ofail <<-EOS.undent
#{Tty.white}Failed to migrate HOMEBREW_REPOSITORY to #{new_homebrew_repository}! #{Tty.bold}Failed to migrate HOMEBREW_REPOSITORY to #{new_homebrew_repository}!#{Tty.reset}
The error was: The error was:
#{e} #{e}
Please try to resolve this error yourself and then run `brew update` again to Please try to resolve this error yourself and then run `brew update` again to

View File

@ -111,7 +111,7 @@ module Debrew
begin begin
puts e.backtrace.first.to_s puts e.backtrace.first.to_s
puts "#{Tty.red}#{e.class.name}#{Tty.reset}: #{e}" puts Formatter.error(e, label: e.class.name)
loop do loop do
Menu.choose do |menu| Menu.choose do |menu|

View File

@ -124,7 +124,7 @@ class Descriptions
short_name = short_names[full_name] short_name = short_names[full_name]
printed_name = short_name_counts[short_name] == 1 ? short_name : full_name printed_name = short_name_counts[short_name] == 1 ? short_name : full_name
description = @descriptions[full_name] || blank description = @descriptions[full_name] || blank
puts "#{Tty.white}#{printed_name}:#{Tty.reset} #{description}" puts "#{Tty.bold}#{printed_name}:#{Tty.reset} #{description}"
end end
end end

View File

@ -93,7 +93,7 @@ module Homebrew
next unless ARGV.verbose? && !text_matches.empty? next unless ARGV.verbose? && !text_matches.empty?
print_filename string, file print_filename string, file
text_matches.first(MAXIMUM_STRING_MATCHES).each do |match, offset| text_matches.first(MAXIMUM_STRING_MATCHES).each do |match, offset|
puts " #{Tty.gray}-->#{Tty.reset} match '#{match}' at offset #{Tty.em}0x#{offset}#{Tty.reset}" puts " #{Tty.gray}-->#{Tty.reset} match '#{match}' at offset #{Tty.bold}0x#{offset}#{Tty.reset}"
end end
if text_matches.size > MAXIMUM_STRING_MATCHES if text_matches.size > MAXIMUM_STRING_MATCHES

View File

@ -318,7 +318,7 @@ class BuildError < RuntimeError
def dump def dump
if !ARGV.verbose? if !ARGV.verbose?
puts puts
puts "#{Tty.red}READ THIS#{Tty.reset}: #{Tty.em}#{OS::ISSUES_URL}#{Tty.reset}" puts "#{Tty.red.underline}READ THIS#{Tty.reset.red}:#{Tty.reset} #{Tty.underline}#{OS::ISSUES_URL}#{Tty.reset}"
if formula.tap if formula.tap
case formula.tap.name case formula.tap.name
when "homebrew/boneyard" when "homebrew/boneyard"

View File

@ -153,7 +153,7 @@ class Migrator
end end
begin begin
oh1 "Migrating #{Tty.green}#{oldname}#{Tty.white} to #{Tty.green}#{newname}#{Tty.reset}" oh1 "Migrating #{Tty.green}#{oldname}#{Tty.reset} to #{Tty.green.bold}#{newname}#{Tty.reset}"
lock lock
unlink_oldname unlink_oldname
move_to_new_directory move_to_new_directory

View File

@ -5,8 +5,11 @@ require "utils/shell"
class TtyTests < Homebrew::TestCase class TtyTests < Homebrew::TestCase
def test_strip_ansi def test_strip_ansi
assert_equal "hello", assert_equal "hello", Tty.strip_ansi("\033\[36;7mhello\033\[0m")
Tty.strip_ansi("\033\[36;7mhello\033\[0m") end
def test_width
assert_kind_of Integer, Tty.width
end end
def test_truncate def test_truncate
@ -21,15 +24,26 @@ class TtyTests < Homebrew::TestCase
def test_no_tty_formatting def test_no_tty_formatting
$stdout.stubs(:tty?).returns false $stdout.stubs(:tty?).returns false
assert_nil Tty.blue assert_equal "", Tty.to_s
assert_nil Tty.white assert_equal "", Tty.red.to_s
assert_nil Tty.red assert_equal "", Tty.green.to_s
assert_nil Tty.green assert_equal "", Tty.yellow.to_s
assert_nil Tty.gray assert_equal "", Tty.blue.to_s
assert_nil Tty.yellow assert_equal "", Tty.magenta.to_s
assert_nil Tty.reset assert_equal "", Tty.cyan.to_s
assert_nil Tty.em assert_equal "", Tty.default.to_s
assert_nil Tty.highlight end
def test_formatting
$stdout.stubs(:tty?).returns(true)
assert_equal "", Tty.to_s
assert_equal "\033[31m", Tty.red.to_s
assert_equal "\033[32m", Tty.green.to_s
assert_equal "\033[33m", Tty.yellow.to_s
assert_equal "\033[34m", Tty.blue.to_s
assert_equal "\033[35m", Tty.magenta.to_s
assert_equal "\033[36m", Tty.cyan.to_s
assert_equal "\033[39m", Tty.default.to_s
end end
end end

View File

@ -10,85 +10,11 @@ require "utils/git"
require "utils/analytics" require "utils/analytics"
require "utils/github" require "utils/github"
require "utils/curl" require "utils/curl"
require "utils/tty"
class Tty
class << self
def strip_ansi(string)
string.gsub(/\033\[\d+(;\d+)*m/, "")
end
def blue
bold 34
end
def white
bold 39
end
def magenta
bold 35
end
def red
underline 31
end
def yellow
underline 33
end
def reset
escape 0
end
def em
underline 39
end
def green
bold 32
end
def gray
bold 30
end
def highlight
bold 39
end
def width
`/usr/bin/tput cols`.strip.to_i
end
def truncate(str)
w = width
w > 10 ? str.to_s[0, w - 4] : str
end
private
def color(n)
escape "0;#{n}"
end
def bold(n)
escape "1;#{n}"
end
def underline(n)
escape "4;#{n}"
end
def escape(n)
"\033[#{n}m" if $stdout.tty?
end
end
end
def ohai(title, *sput) def ohai(title, *sput)
title = Tty.truncate(title) if $stdout.tty? && !ARGV.verbose? title = Tty.truncate(title) if $stdout.tty? && !ARGV.verbose?
puts "#{Tty.blue}==>#{Tty.white} #{title}#{Tty.reset}" puts "#{Tty.blue}==>#{Tty.reset} #{Tty.bold}#{title}#{Tty.reset}"
puts sput puts sput
end end
@ -96,16 +22,16 @@ def oh1(title, options = {})
if $stdout.tty? && !ARGV.verbose? && options.fetch(:truncate, :auto) == :auto if $stdout.tty? && !ARGV.verbose? && options.fetch(:truncate, :auto) == :auto
title = Tty.truncate(title) title = Tty.truncate(title)
end end
puts "#{Tty.green}==>#{Tty.white} #{title}#{Tty.reset}" puts "#{Tty.green}==>#{Tty.reset} #{Tty.bold}#{title}#{Tty.reset}"
end end
# Print a warning (do this rarely) # Print a warning (do this rarely)
def opoo(warning) def opoo(warning)
$stderr.puts "#{Tty.yellow}Warning#{Tty.reset}: #{warning}" $stderr.puts "#{Tty.yellow.underline}Warnin#{Tty.reset.yellow}g:#{Tty.reset} #{warning}"
end end
def onoe(error) def onoe(error)
$stderr.puts "#{Tty.red}Error#{Tty.reset}: #{error}" $stderr.puts "#{Tty.red.underline}Error#{Tty.reset.red}:#{Tty.reset} #{error}"
end end
def ofail(error) def ofail(error)
@ -171,9 +97,9 @@ def pretty_installed(f)
if !$stdout.tty? if !$stdout.tty?
f.to_s f.to_s
elsif Emoji.enabled? elsif Emoji.enabled?
"#{Tty.highlight}#{f} #{Tty.green}#{Emoji.tick}#{Tty.reset}" "#{Tty.bold}#{f} #{Tty.green}#{Emoji.tick}#{Tty.reset}"
else else
"#{Tty.highlight}#{Tty.green}#{f} (installed)#{Tty.reset}" "#{Tty.green.bold}#{f} (installed)#{Tty.reset}"
end end
end end
@ -181,9 +107,9 @@ def pretty_uninstalled(f)
if !$stdout.tty? if !$stdout.tty?
f.to_s f.to_s
elsif Emoji.enabled? elsif Emoji.enabled?
"#{f} #{Tty.red}#{Emoji.cross}#{Tty.reset}" "#{Tty.bold}#{f} #{Tty.red}#{Emoji.cross}#{Tty.reset}"
else else
"#{Tty.red}#{f} (uninstalled)#{Tty.reset}" "#{Tty.red.bold}#{f} (uninstalled)#{Tty.reset}"
end end
end end

View File

@ -14,7 +14,7 @@ module GitHub
super <<-EOS.undent super <<-EOS.undent
GitHub API Error: #{error} GitHub API Error: #{error}
Try again in #{pretty_ratelimit_reset(reset)}, or create a personal access token: Try again in #{pretty_ratelimit_reset(reset)}, or create a personal access token:
#{Tty.em}https://github.com/settings/tokens/new?scopes=&description=Homebrew#{Tty.reset} #{Tty.underline}https://github.com/settings/tokens/new?scopes=&description=Homebrew#{Tty.reset}
and then set the token as: export HOMEBREW_GITHUB_API_TOKEN="your_new_token" and then set the token as: export HOMEBREW_GITHUB_API_TOKEN="your_new_token"
EOS EOS
end end
@ -30,7 +30,7 @@ module GitHub
if ENV["HOMEBREW_GITHUB_API_TOKEN"] if ENV["HOMEBREW_GITHUB_API_TOKEN"]
message << <<-EOS.undent message << <<-EOS.undent
HOMEBREW_GITHUB_API_TOKEN may be invalid or expired; check: HOMEBREW_GITHUB_API_TOKEN may be invalid or expired; check:
#{Tty.em}https://github.com/settings/tokens#{Tty.reset} #{Tty.underline}https://github.com/settings/tokens#{Tty.reset}
EOS EOS
else else
message << <<-EOS.undent message << <<-EOS.undent
@ -38,7 +38,7 @@ module GitHub
Clear them with: Clear them with:
printf "protocol=https\\nhost=github.com\\n" | git credential-osxkeychain erase printf "protocol=https\\nhost=github.com\\n" | git credential-osxkeychain erase
Or create a personal access token: Or create a personal access token:
#{Tty.em}https://github.com/settings/tokens/new?scopes=&description=Homebrew#{Tty.reset} #{Tty.underline}https://github.com/settings/tokens/new?scopes=&description=Homebrew#{Tty.reset}
and then set the token as: export HOMEBREW_GITHUB_API_TOKEN="your_new_token" and then set the token as: export HOMEBREW_GITHUB_API_TOKEN="your_new_token"
EOS EOS
end end

View File

@ -0,0 +1,64 @@
module Tty
module_function
def strip_ansi(string)
string.gsub(/\033\[\d+(;\d+)*m/, "")
end
def width
`/usr/bin/tput cols`.strip.to_i
end
def truncate(string)
(w = width).zero? ? string.to_s : string.to_s[0, w - 4]
end
COLOR_CODES = {
red: 31,
green: 32,
yellow: 33,
blue: 34,
magenta: 35,
cyan: 36,
default: 39,
}.freeze
STYLE_CODES = {
reset: 0,
bold: 1,
italic: 3,
underline: 4,
strikethrough: 9,
no_underline: 24,
}.freeze
CODES = COLOR_CODES.merge(STYLE_CODES).freeze
def append_to_escape_sequence(code)
@escape_sequence ||= []
@escape_sequence << code
self
end
def current_escape_sequence
return "" if @escape_sequence.nil?
"\033[#{@escape_sequence.join(";")}m"
end
def reset_escape_sequence!
@escape_sequence = nil
end
CODES.each do |name, code|
define_singleton_method(name) do
append_to_escape_sequence(code)
end
end
def to_s
return "" unless $stdout.tty?
current_escape_sequence
ensure
reset_escape_sequence!
end
end