diff options
| author | elijah <elijah@riseup.net> | 2016-06-29 13:48:49 -0700 | 
|---|---|---|
| committer | elijah <elijah@riseup.net> | 2016-06-29 13:48:49 -0700 | 
| commit | 334e37c6e3686d17d9d7d47c2cefd1bbfe78cf47 (patch) | |
| tree | 8b762e074317d1ce3c25a7f32f02d98babf79862 /lib/leap_cli | |
| parent | 263bb5699350a04484463aabde563679c4fed505 (diff) | |
remove capistrano logger, new log filtering
Diffstat (limited to 'lib/leap_cli')
| -rw-r--r-- | lib/leap_cli/log.rb | 271 | ||||
| -rw-r--r-- | lib/leap_cli/logger.rb | 237 | 
2 files changed, 216 insertions, 292 deletions
| diff --git a/lib/leap_cli/log.rb b/lib/leap_cli/log.rb index 25f7b74..03789c3 100644 --- a/lib/leap_cli/log.rb +++ b/lib/leap_cli/log.rb @@ -21,7 +21,7 @@ module LeapCli      # thread safe logger      def new_logger -      logger.dup #LeapCli::LeapLogger.new +      logger.dup      end      # deprecated @@ -39,6 +39,12 @@ module LeapCli      #      FILE_TITLES = [:updated, :created, :removed, :missing, :nochange, :loading] +    # TODO: use these +    IMPORTANT = 0 +    INFO      = 1 +    DEBUG     = 2 +    TRACE     = 3 +      attr_reader :log_output_stream, :log_file      attr_accessor :indent_level, :log_level, :log_in_color @@ -69,17 +75,20 @@ module LeapCli      # * Integer: the log level (0, 1, 2)      # * Symbol: the prefix title to colorize. may be one of      #   [:error, :warning, :info, :updated, :created, :removed, :no_change, :missing] -    # * Hash: a hash of options. so far, only :indent is supported. +    # * Hash: a hash of options. +    #     :wrap -- if true, appy intend to each line in message. +    #     :color -- apply color to message or prefix +    #     :style -- apply style to message or prefix      #      def log(*args)        level   = args.grep(Integer).first || 1        title   = args.grep(Symbol).first        message = args.grep(String).first        options = args.grep(Hash).first || {} +      host    = options[:host]        unless message && @log_level >= level          return        end -      clear_prefix, colored_prefix = calculate_prefix(title, options)        #        # transform absolute path names @@ -89,26 +98,50 @@ module LeapCli        end        # -      # log to the log file, always +      # apply filters +      # +      if title +        title, filter_flags = LogFilter.apply_title_filters(title.to_s) +      else +        message, filter_flags = LogFilter.apply_message_filters(message) +        return if message.nil? +      end +      options = options.merge(filter_flags) + +      # +      # set line prefix        # -      log_raw(:log, nil, clear_prefix) { message } +      prefix = "" +      prefix += "[" + options[:host] + "] " if options[:host] +      prefix += title + " " if title + +      # +      # write to the log file, always +      # +      log_raw(:log, nil, prefix) { message }        #        # log to stdout, maybe in color        #        if @log_in_color -        prefix = colored_prefix          if options[:wrap]            message = message.split("\n")          end -        if options[:color] && prefix.empty? -          message = colorize(message, options[:color], options[:style]) +        if options[:color] +          if host +            host = "[" + colorize(host, options[:color], options[:style]) + "] " +          elsif title +            title = colorize(title, options[:color], options[:style]) + " " +          else +            message = colorize(message, options[:color], options[:style]) +          end +        elsif title +          title = colorize(title, :cyan, :bold) + " "          end -      else -        prefix = clear_prefix +        # new colorized prefix: +        prefix = [host, title].compact.join(' ')        end -      indent = options[:indent] -      log_raw(:stdout, indent, prefix) { message } +      log_raw(:stdout, options[:indent], prefix) { message }        #        # run block indented, if given @@ -141,7 +174,7 @@ module LeapCli            if messages.any?              timestamp = Time.now.strftime("%b %d %H:%M:%S")              messages.each do |message| -              message = message.strip +              message = message.rstrip                next if message.empty?                @log_output_stream.print("#{timestamp} #{prefix} #{message}\n")              end @@ -161,7 +194,7 @@ module LeapCli            end            indent_str += prefix if prefix            messages.each do |message| -            message = message.strip +            message = message.rstrip              next if message.empty?              STDOUT.print("#{indent_str}#{message}\n")            end @@ -209,49 +242,177 @@ module LeapCli        :default => 49,      } -    def calculate_prefix(title, options) -      clear_prefix = colored_prefix = "" -      if title -        prefix_options = case title -          when :error     then ['error', :red, :bold] -          when :fatal_error then ['fatal error:', :red, :bold] -          when :warning   then ['warning:', :yellow, :bold] -          when :info      then ['info', :cyan, :bold] -          when :note      then ['NOTE:', :cyan, :bold] -          when :updated   then ['updated', :cyan, :bold] -          when :updating  then ['updating', :cyan, :bold] -          when :created   then ['created', :green, :bold] -          when :removed   then ['removed', :red, :bold] -          when :nochange  then ['no change', :magenta] -          when :loading   then ['loading', :magenta] -          when :missing   then ['missing', :yellow, :bold] -          when :skipping  then ['skipping', :yellow, :bold] -          when :run       then ['run', :cyan, :bold] -          when :running   then ['running', :cyan, :bold] -          when :failed    then ['FAILED', :red, :bold] -          when :completed then ['completed', :green, :bold] -          when :ran       then ['ran', :green, :bold] -          when :bail      then ['bailing out', :red, :bold] -          when :invalid   then ['invalid', :red, :bold] -          else [title.to_s, :cyan, :bold] -        end -        if options[:host] -          clear_prefix = "[%s] %s " % [options[:host], prefix_options[0]] -          colored_prefix = "[%s] %s " % [colorize(options[:host], prefix_options[1], prefix_options[2]), prefix_options[0]] -        else -          clear_prefix = "%s " % prefix_options[0] -          colored_prefix = "%s " % colorize(prefix_options[0], prefix_options[1], prefix_options[2]) -        end -      elsif options[:host] -        clear_prefix = "[%s] " % options[:host] -        if options[:color] -          colored_prefix = "[%s] " % colorize(options[:host], options[:color]) -        else -          colored_prefix = clear_prefix +  end +end + +# +# A module to hide, modify, and colorize log entries. +# + +module LeapCli +  module LogFilter +    # +    # options for formatters: +    # +    # :match       => regexp for matching a log line +    # :color       => what color the line should be +    # :style       => what style the line should be +    # :priority    => what order the formatters are applied in. higher numbers first. +    # :match_level => only apply filter at the specified log level +    # :level       => make this line visible at this log level or higher +    # :replace     => replace the matched text +    # :prepend     => insert text at start of message +    # :append      => append text to end of message +    # :exit        => force the exit code to be this (does not interrupt program, just +    #                 ensures a specific exit code when the program eventually exits) +    # +    FORMATTERS = [ +      # TRACE +      { :match => /command finished/,          :color => :white,   :style => :dim, :match_level => 3, :priority => -10 }, +      { :match => /executing locally/,         :color => :yellow,  :match_level => 3, :priority => -20 }, + +      # DEBUG +      #{ :match => /executing .*/,             :color => :green,   :match_level => 2, :priority => -10, :timestamp => true }, +      #{ :match => /.*/,                       :color => :yellow,  :match_level => 2, :priority => -30 }, +      { :match => /^transaction:/,             :level => 3 }, + +      # INFO +      { :match => /.*out\] (fatal:|ERROR:).*/, :color => :red,     :match_level => 1, :priority => -10 }, +      { :match => /Permission denied/,         :color => :red,     :match_level => 1, :priority => -20 }, +      { :match => /sh: .+: command not found/, :color => :magenta, :match_level => 1, :priority => -30 }, + +      # IMPORTANT +      { :match => /^(E|e)rr ::/,               :color => :red,     :match_level => 0, :priority => -10, :exit => 1}, +      { :match => /^ERROR:/,                   :color => :red,                        :priority => -10, :exit => 1}, +      #{ :match => /.*/,                        :color => :blue,    :match_level => 0, :priority => -20 }, + +      # CLEANUP +      #{ :match => /\s+$/,                      :replace => '', :priority => 0}, + +      # DEBIAN PACKAGES +      { :match => /^(Hit|Ign) /,                :color => :green,   :priority => -20}, +      { :match => /^Err /,                      :color => :red,     :priority => -20}, +      { :match => /^W(ARNING)?: /,              :color => :yellow,  :priority => -20}, +      { :match => /^E: /,                       :color => :red,     :priority => -20}, +      { :match => /already the newest version/, :color => :green,   :priority => -20}, +      { :match => /WARNING: The following packages cannot be authenticated!/, :color => :red, :level => 0, :priority => -10}, + +      # PUPPET +      { :match => /^(W|w)arning: Not collecting exported resources without storeconfigs/, :level => 2, :color => :yellow, :priority => -10}, +      { :match => /^(W|w)arning: Found multiple default providers for vcsrepo:/,          :level => 2, :color => :yellow, :priority => -10}, +      { :match => /^(W|w)arning: .*is deprecated.*$/, :level => 2, :color => :yellow, :priority => -10}, +      { :match => /^(W|w)arning: Scope.*$/,           :level => 2, :color => :yellow, :priority => -10}, +      #{ :match => /^(N|n)otice:/,                     :level => 1, :color => :cyan,   :priority => -20}, +      #{ :match => /^(N|n)otice:.*executed successfully$/, :level => 2, :color => :cyan, :priority => -15}, +      { :match => /^(W|w)arning:/,                    :level => 0, :color => :yellow, :priority => -20}, +      { :match => /^Duplicate declaration:/,          :level => 0, :color => :red,    :priority => -20}, +      #{ :match => /Finished catalog run/,             :level => 0, :color => :green,  :priority => -10}, +      { :match => /^APPLY COMPLETE \(changes made\)/, :level => 0, :color => :green, :style => :bold, :priority => -10}, +      { :match => /^APPLY COMPLETE \(no changes\)/,   :level => 0, :color => :green, :style => :bold, :priority => -10}, + +      # PUPPET FATAL ERRORS +      { :match => /^(E|e)rr(or|):/,                :level => 0, :color => :red, :priority => -1, :exit => 1}, +      { :match => /^Wrapped exception:/,           :level => 0, :color => :red, :priority => -1, :exit => 1}, +      { :match => /^Failed to parse template/,     :level => 0, :color => :red, :priority => -1, :exit => 1}, +      { :match => /^Execution of.*returned/,       :level => 0, :color => :red, :priority => -1, :exit => 1}, +      { :match => /^Parameter matches failed:/,    :level => 0, :color => :red, :priority => -1, :exit => 1}, +      { :match => /^Syntax error/,                 :level => 0, :color => :red, :priority => -1, :exit => 1}, +      { :match => /^Cannot reassign variable/,     :level => 0, :color => :red, :priority => -1, :exit => 1}, +      { :match => /^Could not find template/,      :level => 0, :color => :red, :priority => -1, :exit => 1}, +      { :match => /^APPLY COMPLETE.*fail/,         :level => 0, :color => :red, :style => :bold, :priority => -1, :exit => 1}, + +      # TESTS +      { :match => /^PASS: /,                :color => :green,   :priority => -20}, +      { :match => /^(FAIL|ERROR): /,        :color => :red,     :priority => -20}, +      { :match => /^(SKIP|WARN): /,         :color => :yellow,  :priority => -20}, +      { :match => /\d+ tests: \d+ passes, \d+ skips, 0 warnings, 0 failures, 0 errors/, +        :color => :green, :style => :bold, :priority => -20 }, +      { :match => /\d+ tests: \d+ passes, \d+ skips, [1-9][0-9]* warnings, 0 failures, 0 errors/, +        :color => :yellow, :style => :bold,  :priority => -20 }, +      { :match => /\d+ tests: \d+ passes, \d+ skips, \d+ warnings, \d+ failures, [1-9][0-9]* errors/, +        :color => :red, :style => :bold, :priority => -20 }, +      { :match => /\d+ tests: \d+ passes, \d+ skips, \d+ warnings, [1-9][0-9]* failures, \d+ errors/, +        :color => :red, :style => :bold, :priority => -20 }, + +      # LOG SUPPRESSION +      { :match => /^(W|w)arning: You cannot collect without storeconfigs being set/, :level => 2, :priority => 10}, +      { :match => /^(W|w)arning: You cannot collect exported resources without storeconfigs being set/, :level => 2, :priority => 10} +    ] + +    SORTED_FORMATTERS = FORMATTERS.sort_by { |i| -(i[:priority] || i[:prio] || 0) } + +    # +    # same as normal formatters, but only applies to the title, not the message. +    # +    TITLE_FORMATTERS = [ +      # red +      { :match => /error/, :color => :red, :style => :bold }, +      { :match => /fatal_error/, :replace => 'fatal error:', :color => :red, :style => :bold }, +      { :match => /removed/, :color => :red, :style => :bold }, +      { :match => /failed/, :replace => 'FAILED', :color => :red, :style => :bold }, +      { :match => /bail/, :replace => 'bailing out', :color => :red, :style => :bold }, +      { :match => /invalid/, :color => :red, :style => :bold }, + +      # yellow +      { :match => /warning/, :replace => 'warning:', :color => :yellow, :style => :bold }, +      { :match => /missing/, :color => :yellow, :style => :bold }, +      { :match => /skipping/, :color => :yellow, :style => :bold }, + +      # green +      { :match => /created/, :color => :green, :style => :bold }, +      { :match => /completed/, :color => :green, :style => :bold }, +      { :match => /ran/, :color => :green, :style => :bold }, + +      # cyan +      { :match => /note/, :replace => 'NOTE:', :color => :cyan, :style => :bold }, + +      # magenta +      { :match => /nochange/, :replace => 'no change', :color => :magenta }, +      { :match => /loading/, :color => :magenta }, +    ] + +    def self.apply_message_filters(message) +      return self.apply_filters(SORTED_FORMATTERS, message) +    end + +    def self.apply_title_filters(title) +      return self.apply_filters(TITLE_FORMATTERS, title) +    end + +    private + +    def self.apply_filters(formatters, message) +      level = LeapCli.logger.log_level +      result = {} +      formatters.each do |formatter| +        if (formatter[:match_level] == level || formatter[:match_level].nil?) +          if message =~ formatter[:match] +            # puts "applying formatter #{formatter.inspect}" +            result[:level] = formatter[:level] if formatter[:level] +            result[:color] = formatter[:color] if formatter[:color] +            result[:style] = formatter[:style] || formatter[:attribute] # (support original cap colors) + +            message.gsub!(formatter[:match], formatter[:replace]) if formatter[:replace] +            message.replace(formatter[:prepend] + message) unless formatter[:prepend].nil? +            message.replace(message + formatter[:append])  unless formatter[:append].nil? +            message.replace(Time.now.strftime('%Y-%m-%d %T') + ' ' + message) if formatter[:timestamp] + +            if formatter[:exit] +              LeapCli::Util.exit_status(formatter[:exit]) +            end + +            # stop formatting, unless formatter was just for string replacement +            break unless formatter[:replace] +          end          end        end -      return [clear_prefix, colored_prefix] + +      if result[:color] == :hide +        return [nil, {}] +      else +        return [message, result] +      end      end    end -end
\ No newline at end of file +end diff --git a/lib/leap_cli/logger.rb b/lib/leap_cli/logger.rb deleted file mode 100644 index 058322c..0000000 --- a/lib/leap_cli/logger.rb +++ /dev/null @@ -1,237 +0,0 @@ -# -# A drop in replacement for Capistrano::Logger that integrates better with LEAP CLI. -# - -require 'capistrano/logger' - -# -# from Capistrano::Logger -# ========================= -# -# IMPORTANT = 0 -# INFO      = 1 -# DEBUG     = 2 -# TRACE     = 3 -# MAX_LEVEL = 3 -# COLORS = { -#   :none     => "0", -#   :black    => "30", -#   :red      => "31", -#   :green    => "32", -#   :yellow   => "33", -#   :blue     => "34", -#   :magenta  => "35", -#   :cyan     => "36", -#   :white    => "37" -# } -# STYLES = { -#   :bright     => 1, -#   :dim        => 2, -#   :underscore => 4, -#   :blink      => 5, -#   :reverse    => 7, -#   :hidden     => 8 -# } -# - -module LeapCli -  class Logger < Capistrano::Logger - -    def initialize(options={}) -      @options = options -      @level = options[:level] || 0 -      @message_buffer = nil -    end - -    def log(level, message, line_prefix=nil, options={}) -      if message !~ /\n$/ && level <= 2 && line_prefix.is_a?(String) -        # in some cases, when the message doesn't end with a return, we buffer it and -        # wait until we encounter the return before we log the message out. -        @message_buffer ||= "" -        @message_buffer += message -        return -      elsif @message_buffer -        message = @message_buffer + message -        @message_buffer = nil -      end - -      options[:level] ||= level -      [:stdout, :log].each do |mode| -        LeapCli::log_raw(mode) do -          message_lines(mode, message, line_prefix, options) -        end -      end -    end - -    private - -    def message_lines(mode, message, line_prefix, options) -      formatted_message, formatted_prefix, message_options = apply_formatting(mode, message, line_prefix, options) -      if message_options[:level] <= self.level && formatted_message && formatted_message.chars.any? -        if formatted_prefix -          formatted_message.lines.collect { |line| -            "[#{formatted_prefix}] #{line.sub(/\s+$/, '')}" -          } -        else -          formatted_message.lines.collect {|line| line.sub(/\s+$/, '')} -        end -      else -        nil -      end -    end - -    ## -    ## FORMATTING -    ## - -    # -    # options for formatters: -    # -    # :match       =>  regexp for matching a log line -    # :color       => what color the line should be -    # :style       => what style the line should be -    # :priority    => what order the formatters are applied in. higher numbers first. -    # :match_level => only apply filter at the specified log level -    # :level       => make this line visible at this log level or higher -    # :replace     => replace the matched text -    # :exit        => force the exit code to be this (does not interrupt program, just -    #                 ensures a specific exit code when the program eventually exits) -    # -    @formatters = [ -      # TRACE -      { :match => /command finished/,          :color => :white,   :style => :dim, :match_level => 3, :priority => -10 }, -      { :match => /executing locally/,         :color => :yellow,  :match_level => 3, :priority => -20 }, - -      # DEBUG -      #{ :match => /executing .*/,             :color => :green,   :match_level => 2, :priority => -10, :timestamp => true }, -      #{ :match => /.*/,                        :color => :yellow,  :match_level => 2, :priority => -30 }, -      { :match => /^transaction:/,             :level => 3 }, - -      # INFO -      { :match => /.*out\] (fatal:|ERROR:).*/, :color => :red,     :match_level => 1, :priority => -10 }, -      { :match => /Permission denied/,         :color => :red,     :match_level => 1, :priority => -20 }, -      { :match => /sh: .+: command not found/, :color => :magenta, :match_level => 1, :priority => -30 }, - -      # IMPORTANT -      { :match => /^(E|e)rr ::/,                   :color => :red,     :match_level => 0, :priority => -10, :exit => 1}, -      { :match => /^ERROR:/,                   :color => :red,                        :priority => -10, :exit => 1}, -      { :match => /.*/,                        :color => :blue,    :match_level => 0, :priority => -20 }, - -      # CLEANUP -      { :match => /\s+$/,                      :replace => '', :priority => 0}, - -      # DEBIAN PACKAGES -      { :match => /^(Hit|Ign) /,                :color => :green,   :priority => -20}, -      { :match => /^Err /,                      :color => :red,     :priority => -20}, -      { :match => /^W(ARNING)?: /,              :color => :yellow,  :priority => -20}, -      { :match => /^E: /,                       :color => :red,     :priority => -20}, -      { :match => /already the newest version/, :color => :green,   :priority => -20}, -      { :match => /WARNING: The following packages cannot be authenticated!/, :color => :red, :level => 0, :priority => -10}, - -      # PUPPET -      { :match => /^(W|w)arning: Not collecting exported resources without storeconfigs/, :level => 2, :color => :yellow, :priority => -10}, -      { :match => /^(W|w)arning: Found multiple default providers for vcsrepo:/,          :level => 2, :color => :yellow, :priority => -10}, -      { :match => /^(W|w)arning: .*is deprecated.*$/, :level => 2, :color => :yellow, :priority => -10}, -      { :match => /^(W|w)arning: Scope.*$/,           :level => 2, :color => :yellow, :priority => -10}, -      { :match => /^(N|n)otice:/,                     :level => 1, :color => :cyan,   :priority => -20}, -      { :match => /^(N|n)otice:.*executed successfully$/, :level => 2, :color => :cyan, :priority => -15}, -      { :match => /^(W|w)arning:/,                    :level => 0, :color => :yellow, :priority => -20}, -      { :match => /^Duplicate declaration:/,          :level => 0, :color => :red,    :priority => -20}, -      { :match => /Finished catalog run/,             :level => 0, :color => :green,  :priority => -10}, -      { :match => /^APPLY COMPLETE \(changes made\)/, :level => 0, :color => :green,  :priority => -10}, -      { :match => /^APPLY COMPLETE \(no changes\)/,   :level => 0, :color => :green,  :priority => -10}, - -      # PUPPET FATAL ERRORS -      { :match => /^(E|e)rr(or|):/,                :level => 0, :color => :red, :priority => -1, :exit => 1}, -      { :match => /^Wrapped exception:/,           :level => 0, :color => :red, :priority => -1, :exit => 1}, -      { :match => /^Failed to parse template/,     :level => 0, :color => :red, :priority => -1, :exit => 1}, -      { :match => /^Execution of.*returned/,     :level => 0, :color => :red, :priority => -1, :exit => 1}, -      { :match => /^Parameter matches failed:/,    :level => 0, :color => :red, :priority => -1, :exit => 1}, -      { :match => /^Syntax error/,                 :level => 0, :color => :red, :priority => -1, :exit => 1}, -      { :match => /^Cannot reassign variable/,     :level => 0, :color => :red, :priority => -1, :exit => 1}, -      { :match => /^Could not find template/,      :level => 0, :color => :red, :priority => -1, :exit => 1}, -      { :match => /^APPLY COMPLETE.*fail/,         :level => 0, :color => :red, :priority => -1, :exit => 1}, - -      # TESTS -      { :match => /^PASS: /,                :color => :green,   :priority => -20}, -      { :match => /^(FAIL|ERROR): /,        :color => :red,     :priority => -20}, -      { :match => /^(SKIP|WARN): /,         :color => :yellow,  :priority => -20}, -      { :match => /\d+ tests: \d+ passes, \d+ skips, 0 warnings, 0 failures, 0 errors/, :color => :blue, :priority => -20}, - -      # LOG SUPPRESSION -      { :match => /^(W|w)arning: You cannot collect without storeconfigs being set/, :level => 2, :priority => 10}, -      { :match => /^(W|w)arning: You cannot collect exported resources without storeconfigs being set/, :level => 2, :priority => 10} -    ] - -    def self.sorted_formatters -      # Sort matchers in reverse order so we can break if we found a match. -      @sorted_formatters ||= @formatters.sort_by { |i| -(i[:priority] || i[:prio] || 0) } -    end - -    @prefix_formatters = [ -      { :match => /(err|out) :: /,             :replace => '', :priority => 0}, -      { :match => /\s+$/,                      :replace => '', :priority => 0} -    ] -    def self.prefix_formatters; @prefix_formatters; end - -    def apply_formatting(mode, message, line_prefix = nil, options={}) -      message = message.dup -      options = options.dup -      if !line_prefix.nil? -        if !line_prefix.is_a?(String) -          line_prefix = line_prefix.to_s.dup -        else -          line_prefix = line_prefix.dup -        end -      end -      color = options[:color] || :none -      style = options[:style] - -      if line_prefix -        self.class.prefix_formatters.each do |formatter| -          if line_prefix =~ formatter[:match] && formatter[:replace] -            line_prefix.gsub!(formatter[:match], formatter[:replace]) -          end -        end -      end - -      self.class.sorted_formatters.each do |formatter| -        if (formatter[:match_level] == level || formatter[:match_level].nil?) -          if message =~ formatter[:match] -            options[:level] = formatter[:level] if formatter[:level] -            color = formatter[:color] if formatter[:color] -            style = formatter[:style] || formatter[:attribute] # (support original cap colors) - -            message.gsub!(formatter[:match], formatter[:replace]) if formatter[:replace] -            message.replace(formatter[:prepend] + message) unless formatter[:prepend].nil? -            message.replace(message + formatter[:append])  unless formatter[:append].nil? -            message.replace(Time.now.strftime('%Y-%m-%d %T') + ' ' + message) if formatter[:timestamp] - -            if formatter[:exit] -              LeapCli::Util.exit_status(formatter[:exit]) -            end - -            # stop formatting, unless formatter was just for string replacement -            break unless formatter[:replace] -          end -        end -      end - -      if color == :hide -        return nil -      elsif mode == :log || (color == :none && style.nil?) || !LeapCli.logger.log_in_color -        return [message, line_prefix, options] -      else -        term_color = COLORS[color] -        term_style = STYLES[style] -        if line_prefix.nil? -          message.replace format(message, term_color, term_style) -        else -          line_prefix.replace format(line_prefix, term_color, term_style).strip # format() appends a \n -        end -        return [message, line_prefix, options] -      end -    end - -  end -end | 
