hammer_cli 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +75 -44
- data/bin/hammer +2 -0
- data/lib/hammer_cli/abstract.rb +55 -7
- data/lib/hammer_cli/apipie/command.rb +8 -2
- data/lib/hammer_cli/apipie/options.rb +12 -12
- data/lib/hammer_cli/apipie/read_command.rb +4 -9
- data/lib/hammer_cli/apipie/resource.rb +66 -16
- data/lib/hammer_cli/apipie/write_command.rb +1 -1
- data/lib/hammer_cli/exception_handler.rb +9 -9
- data/lib/hammer_cli/main.rb +6 -0
- data/lib/hammer_cli/messages.rb +7 -7
- data/lib/hammer_cli/output/adapter/abstract.rb +8 -3
- data/lib/hammer_cli/output/adapter/base.rb +13 -36
- data/lib/hammer_cli/output/adapter/silent.rb +3 -3
- data/lib/hammer_cli/output/adapter/table.rb +10 -23
- data/lib/hammer_cli/output/dsl.rb +10 -10
- data/lib/hammer_cli/output/fields.rb +35 -44
- data/lib/hammer_cli/output/formatters.rb +81 -0
- data/lib/hammer_cli/output/output.rb +8 -6
- data/lib/hammer_cli/output.rb +1 -0
- data/lib/hammer_cli/settings.rb +4 -4
- data/lib/hammer_cli/version.rb +1 -1
- metadata +22 -37
@@ -3,11 +3,16 @@ module HammerCLI::Output::Adapter
|
|
3
3
|
|
4
4
|
class Abstract
|
5
5
|
|
6
|
-
def
|
6
|
+
def initialize(context={}, formatters=HammerCLI::Output::Formatters::FormatterLibrary.new)
|
7
|
+
@context = context
|
8
|
+
@formatters = formatters
|
9
|
+
end
|
10
|
+
|
11
|
+
def print_message(msg)
|
7
12
|
puts msg
|
8
13
|
end
|
9
14
|
|
10
|
-
def print_error
|
15
|
+
def print_error(msg, details=nil)
|
11
16
|
details = details.split("\n") if details.kind_of? String
|
12
17
|
|
13
18
|
if details
|
@@ -19,7 +24,7 @@ module HammerCLI::Output::Adapter
|
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
22
|
-
def print_records
|
27
|
+
def print_records(fields, data)
|
23
28
|
raise NotImplementedError
|
24
29
|
end
|
25
30
|
|
@@ -1,17 +1,12 @@
|
|
1
1
|
module HammerCLI::Output::Adapter
|
2
2
|
class Base < Abstract
|
3
3
|
|
4
|
-
HEADING_LINE_WIDTH = 80
|
5
4
|
GROUP_INDENT = " "*2
|
6
5
|
LABEL_DIVIDER = ": "
|
7
6
|
|
8
|
-
def print_records
|
7
|
+
def print_records(fields, data)
|
9
8
|
self.fields = fields
|
10
9
|
|
11
|
-
puts "-"*HEADING_LINE_WIDTH
|
12
|
-
puts " " + heading.to_s
|
13
|
-
puts "-"*HEADING_LINE_WIDTH
|
14
|
-
|
15
10
|
data.each do |d|
|
16
11
|
fields.collect do |f|
|
17
12
|
render_field(f, d)
|
@@ -52,7 +47,8 @@ module HammerCLI::Output::Adapter
|
|
52
47
|
puts
|
53
48
|
indent = indent.to_s + " "*(label_width_for_list(self.fields)+LABEL_DIVIDER.size)
|
54
49
|
|
55
|
-
field.get_value(data)
|
50
|
+
data = field.get_value(data) || []
|
51
|
+
data.each do |d|
|
56
52
|
field.output_definition.fields.collect do |f|
|
57
53
|
render_field(f, d, indent)
|
58
54
|
end
|
@@ -66,26 +62,14 @@ module HammerCLI::Output::Adapter
|
|
66
62
|
puts field.attributes.collect{|attr| data[attr] }.join(" ")
|
67
63
|
end
|
68
64
|
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
def format_List(list)
|
77
|
-
list.join(", ") if list
|
78
|
-
end
|
79
|
-
|
80
|
-
def format_OSName(os)
|
81
|
-
"%{name} %{major}.%{minor}" % os
|
82
|
-
end
|
83
|
-
|
84
|
-
def format_Server(server)
|
85
|
-
"%{name} (%{url})" % server
|
65
|
+
def find_renderer(field)
|
66
|
+
field.class.ancestors.each do |cls|
|
67
|
+
render_method = "render_"+field_type(cls)
|
68
|
+
return method(render_method) if respond_to?(render_method, true)
|
69
|
+
end
|
70
|
+
raise "No renderer found for field %s" % field.class
|
86
71
|
end
|
87
72
|
|
88
|
-
|
89
73
|
def render_field(field, data, indent="")
|
90
74
|
renderer = find_renderer(field)
|
91
75
|
renderer.call(field, data, indent)
|
@@ -94,9 +78,9 @@ module HammerCLI::Output::Adapter
|
|
94
78
|
def render_label(field, indent="")
|
95
79
|
if field.label
|
96
80
|
w = label_width_for_list(self.fields) - indent.size + 1
|
97
|
-
print indent.to_s+"
|
81
|
+
print indent.to_s+"%#{-w}s" % (field.label.to_s+LABEL_DIVIDER)
|
98
82
|
else
|
99
|
-
print indent.to_s
|
83
|
+
print indent.to_s
|
100
84
|
end
|
101
85
|
end
|
102
86
|
|
@@ -104,18 +88,11 @@ module HammerCLI::Output::Adapter
|
|
104
88
|
format_method = "format_"+field_type(field.class)
|
105
89
|
|
106
90
|
value = field.get_value(data)
|
107
|
-
|
91
|
+
formatter = @formatters.formatter_for_type(field.class)
|
92
|
+
value = formatter.format(value) if formatter
|
108
93
|
value
|
109
94
|
end
|
110
95
|
|
111
|
-
def find_renderer(field)
|
112
|
-
field.class.ancestors.each do |cls|
|
113
|
-
render_method = "render_"+field_type(cls)
|
114
|
-
return method(render_method) if respond_to?(render_method, true)
|
115
|
-
end
|
116
|
-
raise "No renderer found for field %s" % field.class
|
117
|
-
end
|
118
|
-
|
119
96
|
def field_type(field_class)
|
120
97
|
field_class.name.split("::")[-1]
|
121
98
|
end
|
@@ -3,13 +3,13 @@ module HammerCLI::Output::Adapter
|
|
3
3
|
|
4
4
|
class Silent
|
5
5
|
|
6
|
-
def print_message
|
6
|
+
def print_message(msg)
|
7
7
|
end
|
8
8
|
|
9
|
-
def print_error
|
9
|
+
def print_error(msg, details=[])
|
10
10
|
end
|
11
11
|
|
12
|
-
def print_records
|
12
|
+
def print_records(fields, data)
|
13
13
|
end
|
14
14
|
|
15
15
|
end
|
@@ -2,32 +2,33 @@ require 'table_print'
|
|
2
2
|
|
3
3
|
module HammerCLI::Output::Adapter
|
4
4
|
|
5
|
-
class Table <
|
5
|
+
class Table < Abstract
|
6
6
|
|
7
|
-
def print_records
|
7
|
+
def print_records(fields, data)
|
8
8
|
|
9
9
|
rows = data.collect do |d|
|
10
10
|
row = {}
|
11
11
|
fields.each do |f|
|
12
|
-
row[f.label.to_sym] = f.get_value(d)
|
12
|
+
row[f.label.to_sym] = f.get_value(d) || ""
|
13
13
|
end
|
14
14
|
row
|
15
15
|
end
|
16
16
|
|
17
17
|
options = fields.collect do |f|
|
18
|
-
|
19
|
-
|
18
|
+
next if f.class <= Fields::Id && !@context[:show_ids]
|
19
|
+
{ f.label.to_sym => { :formatters => Array(@formatters.formatter_for_type(f.class)) } }
|
20
20
|
end
|
21
21
|
|
22
22
|
printer = TablePrint::Printer.new(rows, options)
|
23
23
|
output = printer.table_print
|
24
|
-
dashes = /\n(
|
25
|
-
|
24
|
+
dashes = /\n([-|]+)\n/.match(output)
|
25
|
+
|
26
|
+
puts dashes[1] if dashes
|
26
27
|
puts output
|
27
|
-
puts dashes[1]
|
28
|
+
puts dashes[1] if dashes
|
28
29
|
end
|
29
30
|
|
30
|
-
def print_heading
|
31
|
+
def print_heading(heading, size)
|
31
32
|
size = heading.size if heading.size > size
|
32
33
|
puts '-' * size
|
33
34
|
puts ' ' * ((size-heading.size)/2) + heading
|
@@ -36,18 +37,4 @@ module HammerCLI::Output::Adapter
|
|
36
37
|
|
37
38
|
end
|
38
39
|
|
39
|
-
class Formatter
|
40
|
-
def initialize adapter, method
|
41
|
-
@adapter = adapter
|
42
|
-
@method = method
|
43
|
-
end
|
44
|
-
|
45
|
-
def format value
|
46
|
-
if @adapter.respond_to?(@method, true)
|
47
|
-
value = @adapter.send(@method, value)
|
48
|
-
end
|
49
|
-
value
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
40
|
end
|
@@ -2,7 +2,7 @@ module HammerCLI::Output
|
|
2
2
|
|
3
3
|
class Dsl
|
4
4
|
|
5
|
-
def initialize
|
5
|
+
def initialize(options={})
|
6
6
|
@current_path = options[:path] || []
|
7
7
|
end
|
8
8
|
|
@@ -11,38 +11,38 @@ module HammerCLI::Output
|
|
11
11
|
@fields
|
12
12
|
end
|
13
13
|
|
14
|
-
def build
|
14
|
+
def build(&block)
|
15
15
|
self.instance_eval &block
|
16
16
|
end
|
17
17
|
|
18
18
|
protected
|
19
19
|
|
20
|
-
def field
|
20
|
+
def field(key, label, type=nil, options={}, &block)
|
21
21
|
options[:path] = current_path.clone << key
|
22
22
|
options[:label] = label
|
23
|
-
type ||=
|
23
|
+
type ||= Fields::DataField
|
24
24
|
custom_field type, options, &block
|
25
25
|
end
|
26
26
|
|
27
|
-
def custom_field
|
27
|
+
def custom_field(type, options={}, &block)
|
28
28
|
self.fields << type.new(options, &block)
|
29
29
|
end
|
30
30
|
|
31
|
-
def label
|
31
|
+
def label(label, &block)
|
32
32
|
options = {}
|
33
33
|
options[:path] = current_path.clone
|
34
34
|
options[:label] = label
|
35
|
-
custom_field
|
35
|
+
custom_field Fields::Label, options, &block
|
36
36
|
end
|
37
37
|
|
38
|
-
def from
|
38
|
+
def from(key)
|
39
39
|
self.current_path.push key
|
40
40
|
yield if block_given?
|
41
41
|
self.current_path.pop
|
42
42
|
end
|
43
43
|
|
44
|
-
def collection
|
45
|
-
field key, label,
|
44
|
+
def collection(key, label, options={}, &block)
|
45
|
+
field key, label, Fields::Collection, options, &block
|
46
46
|
end
|
47
47
|
|
48
48
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'hammer_cli/output/dsl'
|
2
2
|
|
3
|
-
module
|
4
|
-
|
3
|
+
module Fields
|
5
4
|
|
6
5
|
class Field
|
7
6
|
|
@@ -61,66 +60,58 @@ module HammerCLI::Output
|
|
61
60
|
|
62
61
|
end
|
63
62
|
|
63
|
+
class Date < DataField
|
64
|
+
end
|
64
65
|
|
65
|
-
|
66
|
+
class Id < DataField
|
67
|
+
end
|
66
68
|
|
69
|
+
class List < DataField
|
70
|
+
end
|
67
71
|
|
68
|
-
|
69
|
-
|
72
|
+
class KeyValue < DataField
|
73
|
+
end
|
70
74
|
|
71
|
-
class OSName < HammerCLI::Output::DataField
|
72
|
-
end
|
73
75
|
|
74
|
-
|
76
|
+
class Joint < DataField
|
77
|
+
def initialize(options={}, &block)
|
78
|
+
super(options)
|
79
|
+
@attributes = options[:attributes] || []
|
75
80
|
end
|
76
81
|
|
77
|
-
|
78
|
-
|
82
|
+
attr_reader :attributes
|
83
|
+
end
|
79
84
|
|
80
|
-
|
81
|
-
end
|
85
|
+
class Label < LabeledField
|
82
86
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
87
|
+
def initialize(options={}, &block)
|
88
|
+
super(options)
|
89
|
+
dsl = HammerCLI::Output::Dsl.new :path => options[:path]
|
90
|
+
dsl.build &block if block_given?
|
88
91
|
|
89
|
-
|
92
|
+
self.output_definition.append dsl.fields
|
90
93
|
end
|
91
94
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
super(options)
|
96
|
-
dsl = HammerCLI::Output::Dsl.new :path => options[:path]
|
97
|
-
dsl.build &block if block_given?
|
98
|
-
|
99
|
-
self.output_definition.append dsl.fields
|
100
|
-
end
|
101
|
-
|
102
|
-
def output_definition
|
103
|
-
@output_definition ||= HammerCLI::Output::Definition.new
|
104
|
-
@output_definition
|
105
|
-
end
|
106
|
-
|
95
|
+
def output_definition
|
96
|
+
@output_definition ||= HammerCLI::Output::Definition.new
|
97
|
+
@output_definition
|
107
98
|
end
|
108
99
|
|
109
|
-
|
100
|
+
end
|
110
101
|
|
111
|
-
|
112
|
-
super(options)
|
113
|
-
dsl = HammerCLI::Output::Dsl.new
|
114
|
-
dsl.build &block if block_given?
|
102
|
+
class Collection < DataField
|
115
103
|
|
116
|
-
|
117
|
-
|
104
|
+
def initialize(options={}, &block)
|
105
|
+
super(options)
|
106
|
+
dsl = HammerCLI::Output::Dsl.new
|
107
|
+
dsl.build &block if block_given?
|
118
108
|
|
119
|
-
|
120
|
-
|
121
|
-
@output_definition
|
122
|
-
end
|
109
|
+
self.output_definition.append dsl.fields
|
110
|
+
end
|
123
111
|
|
112
|
+
def output_definition
|
113
|
+
@output_definition ||= HammerCLI::Output::Definition.new
|
114
|
+
@output_definition
|
124
115
|
end
|
125
116
|
|
126
117
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module HammerCLI::Output
|
2
|
+
module Formatters
|
3
|
+
|
4
|
+
# Registry for formatters
|
5
|
+
class FormatterLibrary
|
6
|
+
def initialize(formatter_map={})
|
7
|
+
@_formatters = {}
|
8
|
+
formatter_map.each do |type, formatters|
|
9
|
+
register_formatter(type, formatters)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def register_formatter(type, *formatters)
|
14
|
+
if @_formatters[type].nil?
|
15
|
+
@_formatters[type] = FormatterContainer.new *formatters
|
16
|
+
else
|
17
|
+
formatters.each { |f| @_formatters[type].add_formatter(f) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def formatter_for_type(type)
|
22
|
+
@_formatters[type.name.split('::').last.to_sym]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# abstract formatter
|
27
|
+
class FieldFormatter
|
28
|
+
def format(data)
|
29
|
+
data
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class FormatterContainer < FieldFormatter
|
34
|
+
|
35
|
+
def initialize(*formatters)
|
36
|
+
@formatters = formatters
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_formatter(*formatters)
|
40
|
+
@formatters += formatters
|
41
|
+
end
|
42
|
+
|
43
|
+
def format(data)
|
44
|
+
@formatters.inject(data) { |d,f| f.format(d) }
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class ColorFormatter
|
50
|
+
def initialize(color)
|
51
|
+
@color = color
|
52
|
+
end
|
53
|
+
|
54
|
+
def format(data)
|
55
|
+
c = HighLine.color(data.to_s, @color)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class DateFormatter < FieldFormatter
|
60
|
+
def format(string_date)
|
61
|
+
t = DateTime.parse(string_date.to_s)
|
62
|
+
t.strftime("%Y/%m/%d %H:%M:%S")
|
63
|
+
rescue ArgumentError
|
64
|
+
""
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class ListFormatter < FieldFormatter
|
69
|
+
def format(list)
|
70
|
+
list.join(", ") if list
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
DEFAULT_FORMATTERS = FormatterLibrary.new(
|
75
|
+
:Date => DateFormatter.new,
|
76
|
+
:List => ListFormatter.new)
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
@@ -4,23 +4,25 @@ module HammerCLI::Output
|
|
4
4
|
attr_accessor :adapter
|
5
5
|
attr_reader :definition
|
6
6
|
|
7
|
-
def initialize
|
8
|
-
@
|
7
|
+
def initialize(options={})
|
8
|
+
@context = options[:context] || {}
|
9
|
+
@adapter = options[:adapter] || HammerCLI::Output::Adapter::Base.new(
|
10
|
+
@context, HammerCLI::Output::Formatters::DEFAULT_FORMATTERS)
|
9
11
|
@definition = options[:definition] || HammerCLI::Output::Definition.new
|
10
12
|
end
|
11
13
|
|
12
|
-
def print_message
|
14
|
+
def print_message(msg)
|
13
15
|
adapter.print_message(msg.to_s)
|
14
16
|
end
|
15
17
|
|
16
|
-
def print_error
|
18
|
+
def print_error(msg, details=nil)
|
17
19
|
adapter.print_error(msg.to_s, details)
|
18
20
|
end
|
19
21
|
|
20
|
-
def print_records
|
22
|
+
def print_records(records)
|
21
23
|
records = [records] unless records.kind_of?(Array)
|
22
24
|
|
23
|
-
adapter.print_records(definition.fields, records
|
25
|
+
adapter.print_records(definition.fields, records)
|
24
26
|
end
|
25
27
|
|
26
28
|
end
|
data/lib/hammer_cli/output.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'output/output')
|
2
2
|
require File.join(File.dirname(__FILE__), 'output/fields')
|
3
|
+
require File.join(File.dirname(__FILE__), 'output/formatters')
|
3
4
|
require File.join(File.dirname(__FILE__), 'output/adapter')
|
4
5
|
require File.join(File.dirname(__FILE__), 'output/definition')
|
5
6
|
require File.join(File.dirname(__FILE__), 'output/dsl')
|
data/lib/hammer_cli/settings.rb
CHANGED
@@ -5,11 +5,11 @@ module HammerCLI
|
|
5
5
|
|
6
6
|
class Settings
|
7
7
|
|
8
|
-
def self.[]
|
8
|
+
def self.[](key)
|
9
9
|
settings[key.to_sym]
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.load_from_file
|
12
|
+
def self.load_from_file(files)
|
13
13
|
files.reverse.each do |path|
|
14
14
|
full_path = File.expand_path path
|
15
15
|
if File.exists? full_path
|
@@ -22,7 +22,7 @@ module HammerCLI
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def self.load
|
25
|
+
def self.load(settings_hash)
|
26
26
|
settings.merge! settings_hash.inject({}){ |sym_hash,(k,v)| sym_hash[k.to_sym] = v; sym_hash }
|
27
27
|
end
|
28
28
|
|
@@ -33,7 +33,7 @@ module HammerCLI
|
|
33
33
|
|
34
34
|
def self.path_history
|
35
35
|
@path_history ||= []
|
36
|
-
@path_history
|
36
|
+
@path_history
|
37
37
|
end
|
38
38
|
|
39
39
|
private
|
data/lib/hammer_cli/version.rb
CHANGED