Class: Railbow::Formatters::Base

Inherits:
Object
  • Object
show all
Includes:
TextUtils
Defined in:
lib/railbow/formatters/base.rb

Constant Summary collapse

RESET =
"\e[0m"
BOLD =
"\e[1m"
GREEN =
"\e[32m"
YELLOW =
"\e[33m"
RED =
"\e[31m"
CYAN =
"\e[36m"
DIM =
"\e[2m"
WHITE =
"\e[97m"
TABLE_PALETTE =
[
  196, # red
  208, # orange
  220, # yellow
  76,  # green
  48,  # mint
  39,  # cyan
  33,  # blue
  63,  # indigo
  129, # purple
  170, # pink
  214, # amber
  109  # teal
].freeze
BRIGHT_WHITE =
"\e[1;97m"

Instance Method Summary collapse

Methods included from TextUtils

#display_width, #strip_ansi, #truncate_str

Instance Method Details

#bold(str) ⇒ Object



42
# File 'lib/railbow/formatters/base.rb', line 42

def bold(str) = "#{BOLD}#{str}#{RESET}"

#cyan(str) ⇒ Object



41
# File 'lib/railbow/formatters/base.rb', line 41

def cyan(str) = "#{CYAN}#{str}#{RESET}"

#diff_tag_branch(name) ⇒ Object



50
# File 'lib/railbow/formatters/base.rb', line 50

def diff_tag_branch(name) = "\e[38;5;39m\u2387 #{name}#{RESET}"

#diff_tag_merging(name) ⇒ Object



51
# File 'lib/railbow/formatters/base.rb', line 51

def diff_tag_merging(name) = "\e[38;5;213m\u2B07 #{name}#{RESET}"

#dim(str) ⇒ Object



37
# File 'lib/railbow/formatters/base.rb', line 37

def dim(str) = "#{DIM}#{str}#{RESET}"

#emoji(type) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/railbow/formatters/base.rb', line 130

def emoji(type)
  case type
  when :migrating then "πŸš€"
  when :migrated then "βœ…"
  when :reverting then "βͺ"
  when :reverted then "βœ…"
  when :check then "βœ“"
  when :status then "πŸ“Š"
  else ""
  end
end

#format_date(timestamp, mode = "full") ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/railbow/formatters/base.rb', line 142

def format_date(timestamp, mode = "full")
  ts = timestamp.to_s
  return ts if ts.length != 14

  time = begin
    Time.new(
      ts[0..3].to_i, ts[4..5].to_i, ts[6..7].to_i,
      ts[8..9].to_i, ts[10..11].to_i, ts[12..13].to_i
    )
  rescue ArgumentError
    return ts
  end

  case mode
  when "full"
    time.strftime("%Y-%m-%d %H:%M:%S")
  when "rel"
    format_relative_time_from(time)
  when "short"
    time.strftime("%b %-d")
  when /\Acustom\((.+)\)\z/
    time.strftime($1)
  else
    time.strftime("%Y-%m-%d %H:%M:%S")
  end
end

#format_timing(seconds) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/railbow/formatters/base.rb', line 118

def format_timing(seconds)
  milliseconds = (seconds * 1000).round(1)

  timing_str = if milliseconds < 1
    "#{(milliseconds * 1000).round(0)}ΞΌs"
  else
    "#{milliseconds}ms"
  end

  cyan(timing_str)
end

#green(str) ⇒ Object



38
# File 'lib/railbow/formatters/base.rb', line 38

def green(str) = "#{GREEN}#{str}#{RESET}"

#green_bold(str) ⇒ Object



43
# File 'lib/railbow/formatters/base.rb', line 43

def green_bold(str) = "#{GREEN}#{BOLD}#{str}#{RESET}"

#landed_tag(date, fresh: false) ⇒ Object



53
54
55
56
# File 'lib/railbow/formatters/base.rb', line 53

def landed_tag(date, fresh: false)
  color = fresh ? "\e[38;5;220m" : DIM
  "#{color}β†ͺ #{date.strftime("%b %d")}#{RESET}"
end

#red(str) ⇒ Object



40
# File 'lib/railbow/formatters/base.rb', line 40

def red(str) = "#{RED}#{str}#{RESET}"

#table_color(table_name) ⇒ Object



46
47
48
# File 'lib/railbow/formatters/base.rb', line 46

def table_color(table_name)
  TABLE_PALETTE[Zlib.crc32(table_name.to_s) % TABLE_PALETTE.size]
end

#table_tag(table_name) ⇒ Object



58
59
60
61
# File 'lib/railbow/formatters/base.rb', line 58

def table_tag(table_name)
  color_code = table_color(table_name)
  "\e[38;5;#{color_code}m● #{table_name}#{RESET}"
end

#table_tags(table_names) ⇒ Object



63
64
65
66
67
# File 'lib/railbow/formatters/base.rb', line 63

def table_tags(table_names)
  return "" if table_names.nil? || table_names.empty?

  table_names.map { |t| table_tag(t) }.join(" ")
end

#table_tags_fitted(formatted_str, max_width) ⇒ Object

Re-fits a pre-formatted table_tags string within max_width, showing full table names and "+N" for overflow. Accepts the full formatted string (with ANSI) and splits it into segments.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/railbow/formatters/base.rb', line 72

def table_tags_fitted(formatted_str, max_width)
  return formatted_str if formatted_str.nil? || formatted_str.empty?

  # Split into individual tag segments: each is "\e[38;5;NNNm● name\e[0m"
  segments = formatted_str.scan(/\e\[38;5;\d+m● [^\e]+\e\[0m/)
  return formatted_str if segments.empty?

  total = segments.size
  plain_segments = segments.map { |s| strip_ansi(s) }

  # Try fitting all tags
  return formatted_str if display_width(plain_segments.join(" ")) <= max_width

  # Try fitting progressively fewer tags with +N suffix
  (total - 1).downto(1) do |count|
    remaining = total - count
    suffix = " +#{remaining}"
    candidate = plain_segments[0...count].join(" ") + suffix
    if display_width(candidate) <= max_width
      return segments[0...count].join(" ") + suffix
    end
  end

  # Try fitting a truncated first table name + overflow.
  # Need at least 7 chars: "● t… +N" (dot + color prefix use no visible width beyond the dot)
  if max_width >= 7
    suffix = (total > 1) ? " +#{total - 1}" : ""
    # Available width for "● name…" part
    avail = max_width - display_width(suffix)
    # "● " prefix = 2 chars visible, plus at least 1 char of name + ellipsis (1 char)
    if avail >= 4 # "● " (2) + at least 1 char + "…" (1)
      first_plain = plain_segments[0] # e.g. "● some_table"
      name_part = first_plain.sub(/^● /, "")
      # Truncate name to fit: avail - 2 ("● ") - 1 ("…") = chars for name
      name_max = avail - 2 - 1
      truncated_name = name_part[0, name_max]
      color_match = segments[0].match(/\e\[38;5;\d+m/)
      color = color_match ? color_match[0] : ""
      return "#{color}● #{truncated_name}…#{RESET}#{suffix}"
    end
  end

  # Absolute fallback: just +N
  "+#{total}"
end

#yellow(str) ⇒ Object



39
# File 'lib/railbow/formatters/base.rb', line 39

def yellow(str) = "#{YELLOW}#{str}#{RESET}"

#yellow_bold(str) ⇒ Object



44
# File 'lib/railbow/formatters/base.rb', line 44

def yellow_bold(str) = "#{YELLOW}#{BOLD}#{str}#{RESET}"