91 lines
2 KiB
Ruby
91 lines
2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module Ci
|
|
module Ansi2json
|
|
class Style
|
|
attr_reader :fg, :bg, :mask
|
|
|
|
def initialize(fg: nil, bg: nil, mask: 0)
|
|
@fg = fg
|
|
@bg = bg
|
|
@mask = mask
|
|
|
|
update_formats
|
|
end
|
|
|
|
def update(ansi_commands)
|
|
# treat e\[m as \e[0m
|
|
ansi_commands = ['0'] if ansi_commands.empty?
|
|
|
|
evaluate_stack_command(ansi_commands)
|
|
end
|
|
|
|
def set?
|
|
@fg || @bg || @formats.any?
|
|
end
|
|
|
|
def reset!
|
|
@fg = nil
|
|
@bg = nil
|
|
@mask = 0
|
|
@formats = []
|
|
end
|
|
|
|
def ==(other)
|
|
self.to_h == other.to_h
|
|
end
|
|
|
|
def to_s
|
|
[@fg, @bg, @formats].flatten.compact.join(' ')
|
|
end
|
|
|
|
def to_h
|
|
{ fg: @fg, bg: @bg, mask: @mask }
|
|
end
|
|
|
|
private
|
|
|
|
def evaluate_stack_command(ansi_commands)
|
|
command = ansi_commands.shift
|
|
return unless command
|
|
|
|
if changes = Gitlab::Ci::Ansi2json::Parser.new(command, ansi_commands).changes
|
|
apply_changes(changes)
|
|
end
|
|
|
|
evaluate_stack_command(ansi_commands)
|
|
end
|
|
|
|
def apply_changes(changes)
|
|
case
|
|
when changes[:reset]
|
|
reset!
|
|
when changes.key?(:fg)
|
|
@fg = changes[:fg]
|
|
when changes.key?(:bg)
|
|
@bg = changes[:bg]
|
|
when changes[:enable]
|
|
@mask |= changes[:enable]
|
|
when changes[:disable]
|
|
@mask &= ~changes[:disable]
|
|
else
|
|
return
|
|
end
|
|
|
|
update_formats
|
|
end
|
|
|
|
def update_formats
|
|
# Most terminals show bold colored text in the light color variant
|
|
# Let's mimic that here
|
|
if @fg.present? && Gitlab::Ci::Ansi2json::Parser.bold?(@mask)
|
|
@fg = @fg.sub(/fg-([a-z]{2,}+)/, 'fg-l-\1')
|
|
end
|
|
|
|
@formats = Gitlab::Ci::Ansi2json::Parser.matching_formats(@mask)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|