Skip to content

Commit

Permalink
More robust console color support logic (athena-framework/athena#488)
Browse files Browse the repository at this point in the history
* Improved spec coverage
  • Loading branch information
Blacksmoke16 authored Dec 15, 2024
1 parent 81d1660 commit a2960fb
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 4 deletions.
2 changes: 1 addition & 1 deletion spec/helper/abstract_question_helper_test_case.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ abstract struct AbstractQuestionHelperTest < ASPEC::TestCase
def initialize
@helper_set = ACON::Helper::HelperSet.new ACON::Helper::Formatter.new

@output = ACON::Output::IO.new IO::Memory.new
@output = ACON::Output::IO.new IO::Memory.new, decorated: false
end

protected def with_input(data : String, interactive : Bool = true, & : ACON::Input::Interface -> Nil) : Nil
Expand Down
79 changes: 79 additions & 0 deletions spec/output/io_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,83 @@ struct IOTest < ASPEC::TestCase
output.puts "foo"
output.to_s.should eq "foo#{EOL}"
end

def test_decorated_dumb_term : Nil
with_isolated_env do
ENV["TERM"] = "dumb"
ACON::Output::IO.new(@io).decorated?.should be_false
end
end

def test_decorated_no_color : Nil
with_isolated_env do
ENV["NO_COLOR"] = "true"
ENV["COLORTERM"] = "truecolor"
ACON::Output::IO.new(@io).decorated?.should be_false
end
end

def test_decorated_no_color_empty : Nil
with_isolated_env do
ENV["NO_COLOR"] = ""
ENV["COLORTERM"] = "truecolor"
ACON::Output::IO.new(@io).decorated?.should be_true
end
end

def test_decorated_force_color : Nil
with_isolated_env do
ENV["FORCE_COLOR"] = "true"
ACON::Output::IO.new(@io).decorated?.should be_true
end
end

def test_decorated_force_color_empty : Nil
with_isolated_env do
ENV["FORCE_COLOR"] = ""
ACON::Output::IO.new(@io).decorated?.should be_false
end
end

def test_decorated_supported_term : Nil
with_isolated_env do
ENV["TERM"] = "xterm-256color"
ACON::Output::IO.new(@io).decorated?.should be_true
end
end

def test_decorated_colorterm : Nil
with_isolated_env do
ENV["COLORTERM"] = "truecolor"
ACON::Output::IO.new(@io).decorated?.should be_true
end
end

def test_decorated_ansicon : Nil
with_isolated_env do
ENV["ANSICON"] = "1"
ACON::Output::IO.new(@io).decorated?.should be_true
end
end

def test_decorated_conemuansi : Nil
with_isolated_env do
ENV["ConEmuANSI"] = "ON"
ACON::Output::IO.new(@io).decorated?.should be_true
end
end

def test_decorated_term_program_hyper : Nil
with_isolated_env do
ENV["TERM_PROGRAM"] = "Hyper"
ACON::Output::IO.new(@io).decorated?.should be_true
end
end

def test_decorated_term_program_non_hyper : Nil
with_isolated_env do
ENV["TERM_PROGRAM"] = "WezTerm"
ACON::Output::IO.new(@io).decorated?.should be_false
end
end
end
14 changes: 14 additions & 0 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,18 @@ struct MockCommandLoader
end
end

def with_isolated_env(&) : Nil
old_values = ENV.dup
begin
ENV.clear

yield
ensure
ENV.clear
old_values.each do |key, old_value|
ENV[key] = old_value
end
end
end

ASPEC.run_all
20 changes: 17 additions & 3 deletions src/output/io.cr
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,23 @@ class Athena::Console::Output::IO < Athena::Console::Output

private def has_color_support? : Bool
# Respect https://no-color.org.
return false if "false" == ENV["NO_COLOR"]?
return true if "Hyper" == ENV["TERM_PROGRAM"]?
return false if ENV["NO_COLOR"]?.presence

@io.tty?
# Respect https://force-color.org.
return true if ENV["FORCE_COLOR"]?.presence

if "Hyper" == ENV["TERM_PROGRAM"]? ||
ENV.has_key?("COLORTERM") ||
ENV.has_key?("ANSICON") ||
"ON" == ENV["ConEmuANSI"]?
return true
end

return @io.tty? unless term = ENV["TERM"]?

return false if "dumb" == term

# See https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js#L157
term.matches? /^((screen|xterm|vt100|vt220|putty|rxvt|ansi|cygwin|linux).*)|(.*-256(color)?(-bce)?)$/
end
end

0 comments on commit a2960fb

Please sign in to comment.