Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the need for an external dependency for ANSI color #263

Merged
merged 4 commits into from
Jun 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ appear at the top.
* Backend implementations now only need to implement `execute_command`, `upload!` and `download!`
* Removed `Printer` from backend hierarchy for `Local` and `Netssh` backends (they now just extend `Abstract`)
* Removed unused `Net::SSH:LogLevelShim`
* Removed dependency on the `colorize` gem. SSHKit now implements its own ANSI color logic, with no external dependencies. Note that SSHKit now only supports the `:bold` or plain modes. Other modes will be gracefully ignored. [#263](https://github.com/capistrano/sshkit/issues/263)

## 1.7.1

Expand Down
46 changes: 43 additions & 3 deletions lib/sshkit/color.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,56 @@
require 'colorize'

module SSHKit
# Very basic support for ANSI color, so that we don't have to rely on
# any external dependencies. This class handles colorizing strings, and
# automatically disabling color if the underlying output is not a tty.
#
class Color
COLOR_CODES = {
:black => 30,
:red => 31,
:green => 32,
:yellow => 33,
:blue => 34,
:magenta => 35,
:cyan => 36,
:white => 37,
:light_black => 90,
:light_red => 91,
:light_green => 92,
:light_yellow => 93,
:light_blue => 94,
:light_magenta => 95,
:light_cyan => 96,
:light_white => 97
}.freeze

def initialize(output, env=ENV)
@output, @env = output, env
end

# Converts the given obj to string and surrounds in the appropriate ANSI
# color escape sequence, based on the specified color and mode. The color
# must be a symbol (see COLOR_CODES for a complete list).
#
# If the underlying output does not support ANSI color (see `colorize?),
# the string will be not be colorized. Likewise if the specified color
# symbol is unrecognized, the string will not be colorized.
#
# Note that the only mode currently support is :bold. All other values
# will be silently ignored (i.e. treated the same as mode=nil).
#
def colorize(obj, color, mode=nil)
string = obj.to_s
colorize? ? string.colorize(color: color, mode: mode) : string
return string unless colorize?
return string unless COLOR_CODES.key?(color)

result = mode == :bold ? "\e[1;" : "\e[0;"
result << COLOR_CODES.fetch(color).to_s
result << ";49m#{string}\e[0m"
end

# Returns `true` if the underlying output is a tty, or if the SSHKIT_COLOR
# environment variable is set.
#
def colorize?
@env['SSHKIT_COLOR'] || (@output.respond_to?(:tty?) && @output.tty?)
end
Expand Down
1 change: 0 additions & 1 deletion sshkit.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ Gem::Specification.new do |gem|

gem.add_runtime_dependency('net-ssh', '>= 2.8.0')
gem.add_runtime_dependency('net-scp', '>= 1.1.2')
gem.add_runtime_dependency('colorize', '>= 0.7.0')

gem.add_development_dependency('minitest', ['>= 2.11.3', '< 2.12.0'])
gem.add_development_dependency('rake')
Expand Down
50 changes: 50 additions & 0 deletions test/unit/test_color.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,55 @@ def test_does_not_colorize_when_tty_method_not_defined_and_SSHKIT_COLOR_not_pres
color = SSHKit::Color.new(stub(), {})
assert_equal 'hi', color.colorize('hi', :red)
end

def test_colorize_colors
color = SSHKit::Color.new(stub(tty?: true), {})
assert_equal "\e[0;30;49mhi\e[0m", color.colorize('hi', :black)
assert_equal "\e[0;31;49mhi\e[0m", color.colorize('hi', :red)
assert_equal "\e[0;32;49mhi\e[0m", color.colorize('hi', :green)
assert_equal "\e[0;33;49mhi\e[0m", color.colorize('hi', :yellow)
assert_equal "\e[0;34;49mhi\e[0m", color.colorize('hi', :blue)
assert_equal "\e[0;35;49mhi\e[0m", color.colorize('hi', :magenta)
assert_equal "\e[0;36;49mhi\e[0m", color.colorize('hi', :cyan)
assert_equal "\e[0;37;49mhi\e[0m", color.colorize('hi', :white)
assert_equal "\e[0;90;49mhi\e[0m", color.colorize('hi', :light_black)
assert_equal "\e[0;91;49mhi\e[0m", color.colorize('hi', :light_red)
assert_equal "\e[0;92;49mhi\e[0m", color.colorize('hi', :light_green)
assert_equal "\e[0;93;49mhi\e[0m", color.colorize('hi', :light_yellow)
assert_equal "\e[0;94;49mhi\e[0m", color.colorize('hi', :light_blue)
assert_equal "\e[0;95;49mhi\e[0m", color.colorize('hi', :light_magenta)
assert_equal "\e[0;96;49mhi\e[0m", color.colorize('hi', :light_cyan)
assert_equal "\e[0;97;49mhi\e[0m", color.colorize('hi', :light_white)
end

def test_colorize_bold_colors
color = SSHKit::Color.new(stub(tty?: true), {})
assert_equal "\e[1;30;49mhi\e[0m", color.colorize('hi', :black, :bold)
assert_equal "\e[1;31;49mhi\e[0m", color.colorize('hi', :red, :bold)
assert_equal "\e[1;32;49mhi\e[0m", color.colorize('hi', :green, :bold)
assert_equal "\e[1;33;49mhi\e[0m", color.colorize('hi', :yellow, :bold)
assert_equal "\e[1;34;49mhi\e[0m", color.colorize('hi', :blue, :bold)
assert_equal "\e[1;35;49mhi\e[0m", color.colorize('hi', :magenta, :bold)
assert_equal "\e[1;36;49mhi\e[0m", color.colorize('hi', :cyan, :bold)
assert_equal "\e[1;37;49mhi\e[0m", color.colorize('hi', :white, :bold)
assert_equal "\e[1;90;49mhi\e[0m", color.colorize('hi', :light_black, :bold)
assert_equal "\e[1;91;49mhi\e[0m", color.colorize('hi', :light_red, :bold)
assert_equal "\e[1;92;49mhi\e[0m", color.colorize('hi', :light_green, :bold)
assert_equal "\e[1;93;49mhi\e[0m", color.colorize('hi', :light_yellow, :bold)
assert_equal "\e[1;94;49mhi\e[0m", color.colorize('hi', :light_blue, :bold)
assert_equal "\e[1;95;49mhi\e[0m", color.colorize('hi', :light_magenta, :bold)
assert_equal "\e[1;96;49mhi\e[0m", color.colorize('hi', :light_cyan, :bold)
assert_equal "\e[1;97;49mhi\e[0m", color.colorize('hi', :light_white, :bold)
end

def test_ignores_unrecognized_color
color = SSHKit::Color.new(stub(tty?: true), {})
assert_equal 'hi', color.colorize('hi', :tangerine)
end

def test_ignores_unrecognized_mode
color = SSHKit::Color.new(stub(tty?: true), {})
assert_equal "\e[0;31;49mhi\e[0m", color.colorize('hi', :red, :underline)
end
end
end