Module: Crimson::Tools::Truncator

Defined in:
lib/crimson/tools/truncator.rb

Overview

Truncates large text output by line count, line length, and byte size. Saves full output to a temp file when truncation occurs.

Defined Under Namespace

Classes: Result

Constant Summary collapse

DEFAULT_MAX_BYTES =

Default maximum output size in bytes.

100_000
DEFAULT_MAX_LINES =

Default maximum number of lines.

2000
DEFAULT_MAX_LINE_LENGTH =

Default maximum length per line.

2000

Class Method Summary collapse

Class Method Details

.save_full_output(text) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Save full text to a temp file and return its path.



83
84
85
86
87
88
89
90
91
# File 'lib/crimson/tools/truncator.rb', line 83

def self.save_full_output(text)
  file = Tempfile.new(["crimson-output-", ".log"])
  file.binmode
  file.write(text)
  file.close
  file.path
rescue => e
  nil
end

.truncate(text, max_bytes: DEFAULT_MAX_BYTES, max_lines: DEFAULT_MAX_LINES, max_line_length: DEFAULT_MAX_LINE_LENGTH) ⇒ Result

Truncate text by line length, line count, and byte size limits.

Parameters:

  • text (String, nil)
  • max_bytes (Integer) (defaults to: DEFAULT_MAX_BYTES)
  • max_lines (Integer) (defaults to: DEFAULT_MAX_LINES)
  • max_line_length (Integer) (defaults to: DEFAULT_MAX_LINE_LENGTH)

Returns:



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/crimson/tools/truncator.rb', line 34

def self.truncate(text, max_bytes: DEFAULT_MAX_BYTES, max_lines: DEFAULT_MAX_LINES, max_line_length: DEFAULT_MAX_LINE_LENGTH)
  return Result.new(text: text, was_truncated: false, full_output_path: nil, original_size: 0) if text.nil? || text.empty?

  original_size = text.bytesize
  truncated = false
  full_output_path = nil

  lines = text.lines
  if lines.any? { |l| l.chomp.length > max_line_length }
    lines = lines.map do |line|
      if line.chomp.length > max_line_length
        line.chomp[0...max_line_length] + "... (line truncated)\n"
      else
        line
      end
    end
    truncated = true
  end

  if lines.length > max_lines
    kept = lines.first(max_lines)
    remaining = lines.length - max_lines
    kept << "\n... (#{remaining} more lines, output truncated)\n"
    lines = kept
    truncated = true
  end

  result = lines.join

  if result.bytesize > max_bytes
    byte_limit = max_bytes - 100
    result = result.byteslice(0, byte_limit) + "\n... (output truncated by size)\n"
    truncated = true
  end

  if truncated && original_size > max_bytes
    full_output_path = save_full_output(text)
  end

  Result.new(
    text: result,
    was_truncated: truncated,
    full_output_path: full_output_path,
    original_size: original_size
  )
end