Class: Pike13::CLI::Formatter
- Inherits:
-
Object
- Object
- Pike13::CLI::Formatter
- Defined in:
- lib/pike13/cli/formatter.rb
Overview
Handles output formatting for CLI commands Supports JSON, table, and CSV formats
Class Method Summary collapse
- .calculate_column_widths(headers, items, max_width: 50, min_width: 10) ⇒ Object
- .csv_escape(value) ⇒ Object
- .extract_array_from_response(data) ⇒ Object
-
.output(data, format: :json, compact: false, color: false) ⇒ void
Output data in the specified format The SDK returns raw API responses (Hash or Array).
- .output_csv(data) ⇒ Object
- .output_table(data, color: false) ⇒ Object
- .truncate(str, max_length) ⇒ Object
Class Method Details
.calculate_column_widths(headers, items, max_width: 50, min_width: 10) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/pike13/cli/formatter.rb', line 111 def self.calculate_column_widths(headers, items, max_width: 50, min_width: 10) # Calculate the width needed for each column headers.map.with_index do |header, _i| # Start with header width max_len = header.to_s.length # Check data widths (sample first 100 rows for performance) items.first(100).each do |item| next unless item.is_a?(Hash) value_len = item[header].to_s.length max_len = value_len if value_len > max_len end # Constrain to min/max max_len.clamp(min_width, max_width) end end |
.csv_escape(value) ⇒ Object
134 135 136 137 138 139 |
# File 'lib/pike13/cli/formatter.rb', line 134 def self.csv_escape(value) return "" if value.nil? str = value.to_s str.include?(",") || str.include?('"') || str.include?("\n") ? "\"#{str.gsub('"', '""')}\"" : str end |
.extract_array_from_response(data) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/pike13/cli/formatter.rb', line 87 def self.extract_array_from_response(data) case data when Array data when Hash # Handle reporting API response (v3) if data.dig("data", "attributes", "rows") rows = data.dig("data", "attributes", "rows") fields = data.dig("data", "attributes", "fields") || [] # Convert rows (arrays) to hashes using field names return rows.map do |row| fields.each_with_index.to_h { |field, i| [field["name"], row[i]] } end end # Try to find an array value in the hash (common API response pattern) # Look for keys like "locations", "people", "events", etc. array_value = data.values.find { |v| v.is_a?(Array) } array_value || [data] else [data] end end |
.output(data, format: :json, compact: false, color: false) ⇒ void
This method returns an undefined value.
Output data in the specified format The SDK returns raw API responses (Hash or Array)
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/pike13/cli/formatter.rb', line 19 def self.output(data, format: :json, compact: false, color: false) case format.to_sym when :json puts compact ? JSON.generate(data) : JSON.pretty_generate(data) when :table output_table(data, color: color) when :csv output_csv(data) else puts JSON.pretty_generate(data) end end |
.output_csv(data) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/pike13/cli/formatter.rb', line 66 def self.output_csv(data) return puts "" if data.nil? || (data.respond_to?(:empty?) && data.empty?) # Extract array from wrapper if needed items = extract_array_from_response(data) return puts "" if items.empty? first = items.first return puts "" if first.nil? || !first.is_a?(Hash) headers = first.keys # Print CSV header puts headers.join(",") # Print CSV rows items.each do |item| puts headers.map { |h| csv_escape(item[h]) }.join(",") end end |
.output_table(data, color: false) ⇒ Object
32 33 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 |
# File 'lib/pike13/cli/formatter.rb', line 32 def self.output_table(data, color: false) return puts "No data" if data.nil? || (data.respond_to?(:empty?) && data.empty?) # Extract array from wrapper if needed items = extract_array_from_response(data) return puts "No data" if items.empty? # Get headers from first item first = items.first return puts "No data" if first.nil? headers = first.is_a?(Hash) ? first.keys : ["value"] # Calculate optimal column widths col_widths = calculate_column_widths(headers, items) # Print header header_line = headers.map.with_index { |h, i| h.to_s.ljust(col_widths[i]) }.join(" | ") puts color ? header_line.bold.cyan : header_line puts "-" * header_line.length # Print rows items.each do |item| if item.is_a?(Hash) row = headers.map.with_index do |h, i| truncate(item[h].to_s, col_widths[i]).ljust(col_widths[i]) end puts row.join(" | ") else puts truncate(item.to_s, col_widths[0]) end end end |
.truncate(str, max_length) ⇒ Object
130 131 132 |
# File 'lib/pike13/cli/formatter.rb', line 130 def self.truncate(str, max_length) str.length > max_length ? "#{str[0...(max_length - 3)]}..." : str end |