# frozen_string_literal: true # rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/PerceivedComplexity # rubocop:disable Metrics/CyclomaticComplexity require 'io/console' module Kernel def sap(*messages) columns = if ::IO.console ::IO.console.winsize[1] else 80 end puts print "\e[1;35m" print " #{::Time.now} ".center(columns, '*') print "\e[0m\n" puts root_path = if defined?(::Rails) ::Rails.root.to_s else `git rev-parse --show-toplevel` end caller[0...5].each do |line| relative_line = line.gsub!(root_path.strip, '.') color = if relative_line == line '34' else '38;5;239' end print "\e[#{color}m" print line print "\e[0m\n" end puts Array(messages).each.with_index do |message, index| if message.respond_to?(:class) print "\e[32m" if defined?(::ActiveRecord::Base) && message.class.ancestors.include?(::ActiveRecord::Base) ap(message.class) else puts "Class: #{message.class}" print "Class Name: #{message.class.name}" end print "\e[0m\n" puts end if defined?(::ActiveRecord::Base) && message.is_a?(::ActiveRecord::Base) ap(message.attributes, :raw => true) else ap(message, :raw => true) end puts if %w{String ActionView::OutputBuffer ActiveSupport::SafeBuffer}.include?(message.class.name) print "\e[1;35m" print ' RAW STRING '.center(columns, '-') print "\e[0m\n" puts print "\e[1;30m" print message.to_str print "\e[0m\n" puts elsif message.respond_to?(:read) && message.method(:read).arity == 1 # Naive Check for Binary Data # https://www.ruby-forum.com/topic/122170 ascii = 0 total = 0 message.read(1024).each_byte do |byte| total += 1 ascii += 1 if byte >= 128 || byte == 0 end message.rewind unless ascii.to_f / total.to_f > 0.33 print "\e[1;35m" print ' RAW STRING '.center(columns, '-') print "\e[0m\n" puts print "\e[1;30m" print message.read print "\e[0m\n" puts end message.rewind end puts unless index + 1 == Array(messages).length end end end # rubocop:enable Metrics/CyclomaticComplexity # rubocop:enable Metrics/PerceivedComplexity # rubocop:enable Metrics/AbcSize