fluke/devops-client/lib/devops-client/output/base.rb
Tim Lianov 03dc3d8d99 v3
2018-04-04 22:44:39 +03:00

127 lines
3.0 KiB
Ruby

require "terminal-table"
require "csv"
require "json"
module Output
class Base
MAX_CELL_WIDTH = 80
attr_reader :options
def initialize(data_to_output, options={})
@data, @options = data_to_output, options
end
def output(preferred_options)
@options = @options.merge(preferred_options)
case options[:format]
when CommonOptions::TABLE_FORMAT
table
when CommonOptions::JSON_FORMAT
json
when CommonOptions::CSV_FORMAT
csv
end
end
def json
JSON.pretty_generate(@data)
end
private
def output_type
@data.kind_of?(Array) ? :list : :show
end
def outputting_list?
output_type == :list
end
def with_num?
@options[:with_num] || outputting_list?
end
def create_table headers, rows, title=nil, with_num=true, separator=false
return nil if headers.nil? or rows.nil?
shrink_cells_if_width_exceeded(rows)
if with_num
headers.unshift(I18n.t("output.table_header.number"))
rows.each_with_index {|row, i| row.unshift(i + 1)}
end
Terminal::Table.new do |t|
titles = ["#{I18n.t("output.table_header.api_version")}: #{self.options[:api]}",
"#{title}"
]
t.title = titles.join( "\n" )
t.headings = headers
t.add_row rows[0] if rows[0]
(rows[1..-1] || []).each do |r|
t.add_separator if separator
t.add_row r
end
end
end
def create_csv headers, rows, with_num=true, separator=":"
if with_num
headers.unshift(I18n.t("output.table_header.number"))
rows.each_with_index {|row, i| row.unshift(i + 1)}
end
c = CSV.new("", {col_sep: separator, headers: true})
c << headers
rows.each do |r|
row = r.map do |cell|
if cell.is_a?(Array)
cell.join(',')
else
cell.to_s
end
end
c << row
end
c.string
end
def headers_and_rows(records, fields_to_output)
headers = fields_to_output.map { |field| I18n.t("output.table_header.#{field}") }
rows = records.map do |record|
fields_to_output.map { |field| record[field] }
end
[headers, rows]
end
def headers_and_rows_for_array(records, field)
headers = [ I18n.t("output.table_header.#{field}") ]
rows = records.map{|record| [ record ] }
[headers, rows]
end
def time_to_s value
return "null" if value.nil?
Time.at(value).to_s
end
private
def shrink_cells_if_width_exceeded(rows)
rows.each do |row|
row.each_with_index do |cell, i|
if cell.is_a?(String)
row[i] = split_to_parts_of_size(cell, MAX_CELL_WIDTH)
elsif cell.is_a?(Array)
row[i] = cell.join("\n")
end
end
end
end
def split_to_parts_of_size(string, size)
(string || '').chars.each_slice(size).map(&:join).join("\n")
end
end
end