Class: NOMS::Command::Formatter

Inherits:
Base
  • Object
show all
Defined in:
lib/noms/command/formatter.rb

Instance Attribute Summary

Attributes inherited from Base

#logger

Instance Method Summary collapse

Methods inherited from Base

#default_logger

Constructor Details

#initialize(data = nil, opt = {}) ⇒ Formatter



19
20
21
22
23
24
# File 'lib/noms/command/formatter.rb', line 19

def initialize(data=nil, opt={})
    @log = opt[:logger] || default_logger
    @data = data
    @log.debug("Created formatter for: #{@data.inspect}");
    @format_raw_object = opt[:format_raw_object] || lambda { |o| o.to_yaml }
end

Instance Method Details

#_fmt(spec) ⇒ Object



48
49
50
51
52
53
54
# File 'lib/noms/command/formatter.rb', line 48

def _fmt(spec)
    '%' +
        ((spec['align'] && spec['align'] == 'right') ? '' : '-') +
        (spec['width'] ? spec['width'].to_s : '') +
        (spec['maxwidth'] ? '.' + spec['maxwidth'] : '') +
        's'
end

#_fmth(spec) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/noms/command/formatter.rb', line 56

def _fmth(spec)
    # Headers are always left-aligned
    '%-' +
        (spec['width'] ? spec['width'].to_s : '') +
        (spec['maxwidth'] ? '.' + spec['maxwidth'] : '') +
        's'
end

#_string(datum) ⇒ Object



143
144
145
# File 'lib/noms/command/formatter.rb', line 143

def _string(datum)
    datum.kind_of?(Enumerable) ? datum.to_json : datum.to_s
end

#filter_object(object) ⇒ Object



171
172
173
174
175
176
177
# File 'lib/noms/command/formatter.rb', line 171

def filter_object(object)
    if (object['$fields'] and ! object['$fields'].empty?)
        Hash[object['$fields'].map { |f| [f, object['$data'][f]] }]
    else
        object['$data']
    end
end

#filter_object_list(objlist) ⇒ Object



83
84
85
86
87
88
89
# File 'lib/noms/command/formatter.rb', line 83

def filter_object_list(objlist)
    columns = normalize_columns objlist['$columns']

    objlist['$data'].map do |object|
        Hash[columns.map { |c| [c['heading'], object[c['field']]] }]
    end
end

#normalize_columns(cols) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/noms/command/formatter.rb', line 91

def normalize_columns(cols)
    cols.map do |spec|
        new_spec = { }
        if spec.respond_to? :has_key?
            new_spec.merge! spec
            raise NOMS::Command::Error.new("Column must contain 'field': #{spec.inspect}") unless
                spec['field']
            new_spec['heading'] ||= new_spec['field']
        else
            new_spec = {
                'field' => spec,
                'heading' => spec
            }
        end
        new_spec
    end
end

#render(item = @data) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/noms/command/formatter.rb', line 26

def render(item=@data)
    if item.nil?
        ''
    elsif item.respond_to? :to_ary
        item.map { |it| render it }.join("\n")
    elsif item.respond_to? :has_key?
        if item['$type']
            case item['$type']
            when 'object-list'
                render_object_list item
            when 'object'
                render_object item
            end
        else
            # It's a raw object, do YAML
            @format_raw_object.call item
        end
    else
        item.to_s
    end
end

#render_csv(objlist) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/noms/command/formatter.rb', line 109

def render_csv(objlist)
    labels = objlist.has_key?('$labels') ? objlist['$labels'] : true

    columns = normalize_columns(objlist['$columns'] || [])

    CSV.generate do |csv|
        csv << columns.map { |f| f['heading'] } if labels
        objlist['$data'].each do |object|
            csv << columns.map { |f| _string(object[f['field']]) }
        end
    end.chomp

end

#render_object(object) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/noms/command/formatter.rb', line 147

def render_object(object)
    object['$format'] ||= 'record'

    case object['$format']
    when 'record'
        render_object_record object
    when 'json'
        JSON.pretty_generate(filter_object(object))
    when 'yaml'
        filter_object(object).to_yaml
    else
        raise NOMS::Command::Error.new("object format '#{object['$format']}' not supported")
    end
end

#render_object_lines(objlist) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/noms/command/formatter.rb', line 124

def render_object_lines(objlist)
    columns = normalize_columns(objlist['$columns'] || [])
    labels = objlist.has_key?('$labels') ? objlist['$labels'] : true

    header_fmt = columns.map { |f| _fmth f }.join(' ')
    fmt = columns.map { |f| _fmt f }.join(' ')

    header_cells = columns.map { |f| f['heading'] }
    out = labels ? [ sprintf(header_fmt, *header_cells) ] : []

    out += objlist['$data'].map do |object|
        cells = columns.map { |f| _string(object[f['field']]) }
        sprintf(fmt, *cells)
    end

    out.join("\n")

end

#render_object_list(objlist) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/noms/command/formatter.rb', line 64

def render_object_list(objlist)
    objlist['$format'] ||= 'lines'
    raise NOMS::Command::Error.new("objectlist ('lines' format) must contain '$columns' list") unless
        objlist['$columns'] and objlist['$columns'].respond_to? :map

    case objlist['$format']
    when 'lines'
        render_object_lines objlist
    when 'yaml'
        filter_object_list(objlist).to_yaml
    when 'json'
        JSON.pretty_generate(filter_object_list(objlist))
    when 'csv'
        render_csv objlist
    else
        raise NOMS::Command::Error.new("objectlist format '#{objlist['$format']}' not supported")
    end
end

#render_object_record(object) ⇒ Object



162
163
164
165
166
167
168
169
# File 'lib/noms/command/formatter.rb', line 162

def render_object_record(object)
    labels = object.has_key?('$labels') ? object['$labels'] : true
    fields = (object['$fields'].nil? or object['$fields'].empty?) ? object['$data'].keys.sort : object['$fields']
    data = object['$data']
    fields.map do |field|
        (labels ? (field + ': ') : '' ) + _string(data[field])
    end.join("\n")
end