Class: NOMS::Command::Formatter

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

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Formatter.



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

def initialize(data=nil, opt={})
    @data = data
    @format_raw_object = opt[:format_raw_object] || lambda { |o| o.to_yaml }
end

Instance Method Details

#_fmt(spec) ⇒ Object



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

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

#_fmth(spec) ⇒ Object



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

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

#_string(datum) ⇒ Object



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

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

#filter_object(object) ⇒ Object



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

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

#filter_object_list(objlist) ⇒ Object



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

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



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

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



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

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



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

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



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

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



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

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



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

def render_object_list(objlist)
    objlist['$labels'] ||= true
    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



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

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