diff --git a/lib/formatters/ansi_common.rb b/lib/formatters/ansi_common.rb index dcf03c5..2bf3e84 100644 --- a/lib/formatters/ansi_common.rb +++ b/lib/formatters/ansi_common.rb @@ -2,6 +2,8 @@ require_relative 'ansi_colors' # gather common definitions and functions class AnsiCommon + ANSI_REGEX = /\e\[[0-9;]*m/ # TODO: support for \x1b and \033 + def self.ansi_trace(trace, symbol) match = trace.match(/(↳ )?(.*:\d+)(:in `)?(.*'?)/) # only m2(=file) and m4(=optional function) are useful return trace unless match diff --git a/lib/formatters/ansi_formatter.rb b/lib/formatters/ansi_formatter.rb index 10f40ff..535add2 100644 --- a/lib/formatters/ansi_formatter.rb +++ b/lib/formatters/ansi_formatter.rb @@ -118,8 +118,24 @@ class AnsiFormatter < SemanticLogger::Formatters::Color elsif log.name =~ /^(ActionView|ActiveRecord)::Base/ log.level = :debug log.message.lstrip! - if log.name == 'ActiveRecord::Base' && log.message.starts_with?('↳ ') - log.message = AnsiCommon.ansi_trace(log.message, '⇄') + if log.name == 'ActiveRecord::Base' + unbold(log.message) + + if log.message.starts_with?('↳ ') + log.message = AnsiCommon.ansi_trace(log.message, '⇄') + else + sql_match = log.message.match(/\s+\[\[.*\]\]$/) + if sql_match + sql_command = sql_match.pre_match + sql_type, sql_entry = sql_command.split("\e[0m") + sql_color_entry = sql_entry.match(AnsiCommon::ANSI_REGEX).to_s + sql_args = JSON.parse(sql_match.to_s).map(&:last) + sql_args.each_with_index do |value, index| + sql_entry.gsub!("$#{index + 1}", colorize(value.inspect, BOLD) + sql_color_entry) + end + log.message = [sql_type, sql_entry].join(CLEAR) + end + end elsif log.name == 'ActionView::Base' match = log.message.match(/^Rendered( layout| collection of|) (.*?\.erb)(.*)(\(Duration:.*\))/) if match @@ -162,6 +178,8 @@ class AnsiFormatter < SemanticLogger::Formatters::Color FAILOVER_WRAP end + def unbold(text) = text.gsub!(BOLD, '') + def message colorize(log.message) if log.message end diff --git a/lib/formatters/ansi_wrapper.rb b/lib/formatters/ansi_wrapper.rb index 3c7ce64..8eacc74 100644 --- a/lib/formatters/ansi_wrapper.rb +++ b/lib/formatters/ansi_wrapper.rb @@ -1,8 +1,6 @@ # AnsiWrapper cares about Ansi Colour Code \e[... class AnsiWrapper TAB_TO_SPACES = 2 - ANSI_REGEX = /\e\[[0-9;]*m/ # TODO: support for \x1b and \033 - ANSI_RESET = "\e[0m".freeze def self.wrap(text, length, prefix = '', continuation = prefix) if visible_length(prefix) != visible_length(continuation) @@ -21,21 +19,21 @@ class AnsiWrapper last_ansi = '' lines.each_with_index.map do |line, index| current = index.zero? ? prefix : continuation - current += last_ansi unless last_ansi.empty? || last_ansi == ANSI_RESET + current += last_ansi unless last_ansi.empty? || last_ansi == AnsiColors::CLEAR current += line last_ansi = scan_for_actual_ansi(line, last_ansi) - current += ANSI_RESET if last_ansi.empty? || last_ansi != ANSI_RESET + current += AnsiColors::CLEAR if last_ansi.empty? || last_ansi != AnsiColors::CLEAR current end end private_class_method def self.scan_for_actual_ansi(line, last_ansi) - line.scan(ANSI_REGEX).each do |match| + line.scan(AnsiCommon::ANSI_REGEX).each do |match| ansi_code = match.to_s - if ansi_code == ANSI_RESET - last_ansi = ANSI_RESET + if ansi_code == AnsiColors::CLEAR + last_ansi = AnsiColors::CLEAR else last_ansi += ansi_code end @@ -54,13 +52,13 @@ class AnsiWrapper private_class_method def self.visible_length(line) raise 'line should not contain carriage return character!' if line.match "\n" - ansi_code_length = line.scan(ANSI_REGEX).map(&:length).sum + ansi_code_length = line.scan(AnsiCommon::ANSI_REGEX).map(&:length).sum line.length - ansi_code_length end # TODO: might be refactored with less complexity private_class_method def self.visible_split(line, length, stack = '') # rubocop:disable Metrics/AbcSize,Metrics/MethodLength - before, ansi_code, after = line.partition(ANSI_REGEX) + before, ansi_code, after = line.partition(AnsiCommon::ANSI_REGEX) stack_length = visible_length(stack) visible_length = before.length + stack_length if visible_length == length