hirb 0.2.10 → 0.3.0
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.
- data/CHANGELOG.rdoc +14 -0
- data/README.rdoc +67 -63
- data/Rakefile +3 -0
- data/lib/hirb.rb +25 -18
- data/lib/hirb/console.rb +3 -3
- data/lib/hirb/dynamic_view.rb +112 -0
- data/lib/hirb/formatter.rb +61 -140
- data/lib/hirb/helpers.rb +11 -1
- data/lib/hirb/helpers/auto_table.rb +20 -12
- data/lib/hirb/helpers/object_table.rb +2 -2
- data/lib/hirb/helpers/table.rb +15 -14
- data/lib/hirb/helpers/tree.rb +19 -15
- data/lib/hirb/import_object.rb +1 -1
- data/lib/hirb/menu.rb +1 -1
- data/lib/hirb/util.rb +1 -1
- data/lib/hirb/version.rb +3 -0
- data/lib/hirb/view.rb +74 -19
- data/lib/hirb/views.rb +8 -0
- data/lib/hirb/views/couch_db.rb +11 -0
- data/lib/hirb/views/misc_db.rb +15 -0
- data/lib/hirb/views/mongo_db.rb +15 -0
- data/lib/hirb/views/orm.rb +11 -0
- data/lib/hirb/views/rails.rb +19 -0
- data/test/dynamic_view_test.rb +96 -0
- data/test/formatter_test.rb +36 -48
- data/test/table_test.rb +41 -4
- data/test/tree_test.rb +17 -0
- data/test/view_test.rb +6 -0
- data/test/views_test.rb +15 -0
- metadata +24 -11
- data/VERSION.yml +0 -5
- data/lib/hirb/hash_struct.rb +0 -17
- data/lib/hirb/helpers/active_record_table.rb +0 -26
- data/lib/hirb/views/activerecord_base.rb +0 -9
- data/test/active_record_table_test.rb +0 -35
data/lib/hirb/helpers.rb
CHANGED
@@ -1,7 +1,17 @@
|
|
1
1
|
module Hirb
|
2
2
|
module Helpers #:nodoc:
|
3
|
+
@helper_classes ||= {}
|
4
|
+
def self.helper_class(klass)
|
5
|
+
@helper_classes[klass.to_s] ||= begin
|
6
|
+
if (helper_class = constants.find {|e| e.to_s == Util.camelize(klass.to_s)})
|
7
|
+
klass = "Hirb::Helpers::#{helper_class}"
|
8
|
+
end
|
9
|
+
Util.any_const_get(klass)
|
10
|
+
end
|
11
|
+
end
|
3
12
|
end
|
4
13
|
end
|
5
|
-
|
14
|
+
|
15
|
+
%w{table object_table auto_table tree parent_child_tree vertical_table}.each do |e|
|
6
16
|
require "hirb/helpers/#{e}"
|
7
17
|
end
|
@@ -1,16 +1,24 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
1
|
+
# This helper wraps around the other table helpers i.e. Hirb::Helpers::Table while
|
2
|
+
# providing default helper options via Hirb::DynamicView. Using these default options, this
|
3
|
+
# helper supports views for the following modules/classes:
|
4
|
+
# ActiveRecord::Base, CouchFoo::Base, CouchPotato::Persistence, CouchRest::ExtendedDocument,
|
5
|
+
# DBI::Row, DataMapper::Resource, Friendly::Document, MongoMapper::Document, MongoMapper::EmbeddedDocument,
|
6
|
+
# Mongoid::Document, Ripple::Document, Sequel::Model.
|
7
|
+
class Hirb::Helpers::AutoTable < Hirb::Helpers::Table
|
8
|
+
extend Hirb::DynamicView
|
9
|
+
|
10
|
+
# Takes same options as Hirb::Helpers::Table.render except as noted below.
|
11
|
+
#
|
12
|
+
# ==== Options:
|
13
|
+
# [:table_class] Explicit table class to use for rendering. Defaults to
|
14
|
+
# Hirb::Helpers::ObjectTable if output is not an Array or Hash. Otherwise
|
15
|
+
# defaults to Hirb::Helpers::Table.
|
4
16
|
def self.render(output, options={})
|
5
|
-
options[:_original_class] = output.class
|
6
17
|
output = Array(output)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
Hirb::Helpers::ObjectTable
|
11
|
-
else
|
12
|
-
Hirb::Helpers::Table
|
13
|
-
end
|
18
|
+
(defaults = dynamic_options(output[0])) && (options = defaults.merge(options))
|
19
|
+
klass = options.delete(:table_class) || (
|
20
|
+
!(output[0].is_a?(Hash) || output[0].is_a?(Array)) ?
|
21
|
+
Hirb::Helpers::ObjectTable : Hirb::Helpers::Table)
|
14
22
|
klass.render(output, options)
|
15
23
|
end
|
16
|
-
end
|
24
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
class Hirb::Helpers::ObjectTable < Hirb::Helpers::Table
|
2
2
|
# Rows are any ruby objects. Takes same options as Hirb::Helpers::Table.render except as noted below.
|
3
3
|
#
|
4
|
-
# Options:
|
5
|
-
#
|
4
|
+
# ==== Options:
|
5
|
+
# [:fields] Methods of the object to represent as columns. Defaults to [:to_s].
|
6
6
|
def self.render(rows, options ={})
|
7
7
|
options[:fields] ||= [:to_s]
|
8
8
|
options[:headers] ||= {:to_s=>'value'} if options[:fields] == [:to_s]
|
data/lib/hirb/helpers/table.rb
CHANGED
@@ -68,7 +68,7 @@ module Hirb
|
|
68
68
|
# ==== Options:
|
69
69
|
# [*:fields*] An array which overrides the default fields and can be used to indicate field order.
|
70
70
|
# [*:headers*] A hash of fields and their header names. Fields that aren't specified here default to their name.
|
71
|
-
#
|
71
|
+
# When set to false, headers are hidden. Can also be an array but only for array rows.
|
72
72
|
# [*:max_fields*] A hash of fields and their maximum allowed lengths. Maximum length can also be a percentage of the total width
|
73
73
|
# (decimal less than one). When a field exceeds it's maximum then it's
|
74
74
|
# truncated and has a ... appended to it. Fields that aren't specified have no maximum.
|
@@ -90,7 +90,6 @@ module Hirb
|
|
90
90
|
# [*:description*] When set to true, renders row count description at bottom. Default is true.
|
91
91
|
# [*:escape_special_chars*] When set to true, escapes special characters \n,\t,\r so they don't disrupt tables. Default is false for
|
92
92
|
# vertical tables and true for anything else.
|
93
|
-
# [*:return_rows*] When set to true, returns rows that have been initialized but not rendered. Default is false.
|
94
93
|
# Examples:
|
95
94
|
# Hirb::Helpers::Table.render [[1,2], [2,3]]
|
96
95
|
# Hirb::Helpers::Table.render [[1,2], [2,3]], :max_fields=>{0=>10}, :header_filter=>:capitalize
|
@@ -100,7 +99,7 @@ module Hirb
|
|
100
99
|
# Hirb::Helpers::Table.render [{:age=>10, :weight=>100}, {:age=>80, :weight=>500}], :filters=>{:age=>[:to_f]}
|
101
100
|
def render(rows, options={})
|
102
101
|
options[:vertical] ? Helpers::VerticalTable.render(rows, options) :
|
103
|
-
|
102
|
+
new(rows, options).render
|
104
103
|
rescue TooManyFieldsForWidthError
|
105
104
|
$stderr.puts "", "** Error: Too many fields for the current width. Configure your width " +
|
106
105
|
"and/or fields to avoid this error. Defaulting to a vertical table. **"
|
@@ -121,6 +120,8 @@ module Hirb
|
|
121
120
|
#:stopdoc:
|
122
121
|
attr_accessor :width, :max_fields, :field_lengths, :fields
|
123
122
|
def initialize(rows, options={})
|
123
|
+
raise ArgumentError, "Table must be an array of hashes or array of arrays" unless rows.is_a?(Array) &&
|
124
|
+
(rows[0].is_a?(Hash) or rows[0].is_a?(Array) or rows.empty?)
|
124
125
|
@options = {:description=>true, :filters=>{}, :change_fields=>{}, :escape_special_chars=>true,
|
125
126
|
:filter_any=>Helpers::Table.filter_any, :resize=>true}.merge(options)
|
126
127
|
@fields = set_fields(rows)
|
@@ -134,19 +135,18 @@ module Hirb
|
|
134
135
|
end
|
135
136
|
|
136
137
|
def set_fields(rows)
|
137
|
-
|
138
|
-
|
138
|
+
@options[:change_fields] = array_to_indices_hash(@options[:change_fields]) if @options[:change_fields].is_a?(Array)
|
139
|
+
return @options[:fields].dup if @options[:fields]
|
140
|
+
|
141
|
+
fields = if rows[0].is_a?(Hash)
|
142
|
+
keys = @options[:all_fields] ? rows.map {|e| e.keys}.flatten.uniq : rows[0].keys
|
143
|
+
keys.sort {|a,b| a.to_s <=> b.to_s}
|
139
144
|
else
|
140
|
-
|
141
|
-
keys = @options[:all_fields] ? rows.map {|e| e.keys}.flatten.uniq : rows[0].keys
|
142
|
-
keys.sort {|a,b| a.to_s <=> b.to_s}
|
143
|
-
else
|
144
|
-
rows[0].is_a?(Array) ? (0..rows[0].length - 1).to_a : []
|
145
|
-
end
|
145
|
+
rows[0].is_a?(Array) ? (0..rows[0].length - 1).to_a : []
|
146
146
|
end
|
147
|
-
|
147
|
+
|
148
148
|
@options[:change_fields].each do |oldf, newf|
|
149
|
-
(index = fields.index(oldf))
|
149
|
+
(index = fields.index(oldf)) && fields[index] = newf
|
150
150
|
end
|
151
151
|
fields
|
152
152
|
end
|
@@ -267,7 +267,8 @@ module Hirb
|
|
267
267
|
|
268
268
|
# find max length for each field; start with the headers
|
269
269
|
def default_field_lengths
|
270
|
-
field_lengths = @headers ? @headers.inject({}) {|h,(k,v)| h[k] = String.size(v); h} :
|
270
|
+
field_lengths = @headers ? @headers.inject({}) {|h,(k,v)| h[k] = String.size(v); h} :
|
271
|
+
@fields.inject({}) {|h,e| h[e] = 1; h }
|
271
272
|
@rows.each do |row|
|
272
273
|
@fields.each do |field|
|
273
274
|
len = String.size(row[field])
|
data/lib/hirb/helpers/tree.rb
CHANGED
@@ -43,6 +43,7 @@ class Hirb::Helpers::Tree
|
|
43
43
|
# [:indent] Number of spaces to indent between levels for basic + number trees. Default is 4.
|
44
44
|
# [:limit] Limits the level or depth of a tree that is displayed. Root node is level 0.
|
45
45
|
# [:description] Displays brief description about tree ie how many nodes it has.
|
46
|
+
# [:multi_line_nodes] Handles multi-lined nodes by indenting their newlines. Default is false.
|
46
47
|
# Examples:
|
47
48
|
# Hirb::Helpers::Tree.render([[0, 'root'], [1, 'child']], :type=>:directory)
|
48
49
|
def render(nodes, options={})
|
@@ -81,28 +82,27 @@ class Hirb::Helpers::Tree
|
|
81
82
|
@indent = ' ' * (@options[:indent] || 4 )
|
82
83
|
@nodes = @nodes.select {|e| e[:level] <= @options[:limit] } if @options[:limit]
|
83
84
|
case @type.to_s
|
84
|
-
when 'directory'
|
85
|
-
|
86
|
-
|
87
|
-
render_number
|
88
|
-
else
|
89
|
-
render_basic
|
85
|
+
when 'directory' then render_directory
|
86
|
+
when 'number' then render_number
|
87
|
+
else render_basic
|
90
88
|
end
|
91
89
|
end
|
92
90
|
|
91
|
+
def render_nodes
|
92
|
+
value_indent = @options[:multi_line_nodes] ? @indent : nil
|
93
|
+
@nodes.map {|e| yield(e) + e.value(value_indent) }.join("\n")
|
94
|
+
end
|
95
|
+
|
93
96
|
def render_directory
|
94
97
|
mark_last_nodes_per_level
|
95
|
-
|
96
|
-
@nodes.each_with_index {|e, i|
|
98
|
+
render_nodes {|e|
|
97
99
|
value = ''
|
98
100
|
unless e.root?
|
99
101
|
value << e.render_parent_characters
|
100
102
|
value << (e[:last_node] ? "`-- " : "|-- ")
|
101
103
|
end
|
102
|
-
value
|
103
|
-
new_nodes << value
|
104
|
+
value
|
104
105
|
}
|
105
|
-
new_nodes.join("\n")
|
106
106
|
end
|
107
107
|
|
108
108
|
def render_number
|
@@ -113,13 +113,13 @@ class Hirb::Helpers::Tree
|
|
113
113
|
counter[parent_level_key] += 1
|
114
114
|
e[:pre_value] = "#{counter[parent_level_key]}. "
|
115
115
|
}
|
116
|
-
|
116
|
+
render_nodes {|e| @indent * e[:level] + e[:pre_value] }
|
117
117
|
end
|
118
|
-
|
118
|
+
|
119
119
|
def render_basic
|
120
|
-
|
120
|
+
render_nodes {|e| @indent * e[:level] }
|
121
121
|
end
|
122
|
-
|
122
|
+
|
123
123
|
def validate_nodes
|
124
124
|
@nodes.each do |e|
|
125
125
|
raise ParentlessNodeError if (e[:level] > e.previous[:level]) && (e[:level] - e.previous[:level]) > 1
|
@@ -146,6 +146,10 @@ class Hirb::Helpers::Tree
|
|
146
146
|
replace(hash)
|
147
147
|
end
|
148
148
|
|
149
|
+
def value(indent=nil)
|
150
|
+
indent ? self[:value].gsub("\n", "\n#{indent * self[:level]}") : self[:value]
|
151
|
+
end
|
152
|
+
|
149
153
|
def parent
|
150
154
|
self[:tree].nodes.slice(0 .. self[:index]).reverse.detect {|e| e[:level] < self[:level]}
|
151
155
|
end
|
data/lib/hirb/import_object.rb
CHANGED
data/lib/hirb/menu.rb
CHANGED
@@ -197,7 +197,7 @@ module Hirb
|
|
197
197
|
end
|
198
198
|
|
199
199
|
def table_helper_class?
|
200
|
-
@options[:helper_class].is_a?(Class) &&
|
200
|
+
@options[:helper_class].is_a?(Class) && @options[:helper_class] < Helpers::Table
|
201
201
|
end
|
202
202
|
|
203
203
|
def unalias_field(field)
|
data/lib/hirb/util.rb
CHANGED
data/lib/hirb/version.rb
ADDED
data/lib/hirb/view.rb
CHANGED
@@ -1,6 +1,64 @@
|
|
1
1
|
module Hirb
|
2
|
-
# This class is responsible for managing all view-related functionality.
|
3
|
-
#
|
2
|
+
# This class is responsible for managing all view-related functionality.
|
3
|
+
#
|
4
|
+
# == Create a View
|
5
|
+
# Let's create a simple view for Hash objects:
|
6
|
+
# $ irb -rubygems
|
7
|
+
# >> require 'hirb'
|
8
|
+
# =>true
|
9
|
+
# >> Hirb.enable
|
10
|
+
# =>nil
|
11
|
+
# >> require 'yaml'
|
12
|
+
# =>true
|
13
|
+
#
|
14
|
+
# # A view method is the smallest view
|
15
|
+
# >> def yaml(output); output.to_yaml; end
|
16
|
+
# => nil
|
17
|
+
# # Add the view
|
18
|
+
# >> Hirb.add_view Hash, :method=>:yaml
|
19
|
+
# => true
|
20
|
+
#
|
21
|
+
# # Hashes now appear as yaml
|
22
|
+
# >> {:a=>1, :b=>{:c=>3}}
|
23
|
+
# ---
|
24
|
+
# :a : 1
|
25
|
+
# :b :
|
26
|
+
# :c : 3
|
27
|
+
# => true
|
28
|
+
#
|
29
|
+
# Another way of creating a view is a Helper class:
|
30
|
+
#
|
31
|
+
# # Create yaml view class
|
32
|
+
# >> class Hirb::Helpers::Yaml; def self.render(output, options={}); output.to_yaml; end ;end
|
33
|
+
# =>nil
|
34
|
+
# # Add the view
|
35
|
+
# >> Hirb.add_view Hash, :class=>Hirb::Helpers::Yaml
|
36
|
+
# =>true
|
37
|
+
#
|
38
|
+
# # Hashes appear as yaml like above ...
|
39
|
+
#
|
40
|
+
# == Configure a View
|
41
|
+
# To configure the above Helper class as a view, either pass Hirb.enable a hash:
|
42
|
+
# # In .irbrc
|
43
|
+
# require 'hirb'
|
44
|
+
# # View class needs to come before enable()
|
45
|
+
# class Hirb::Helpers::Yaml; def self.render(output, options={}); output.to_yaml; end ;end
|
46
|
+
# Hirb.enable :output=>{"Hash"=>{:class=>"Hirb::Helpers::Yaml"}}
|
47
|
+
#
|
48
|
+
# Or create a config file at config/hirb.yml or ~/.hirb.yml:
|
49
|
+
# # The config file for the yaml example would look like:
|
50
|
+
# # ---
|
51
|
+
# # :output :
|
52
|
+
# # Hash :
|
53
|
+
# # :class : Hirb::Helpers::Yaml
|
54
|
+
#
|
55
|
+
# # In .irbrc
|
56
|
+
# require 'hirb'
|
57
|
+
# # View class needs to come before enable()
|
58
|
+
# class Hirb::Helpers::Yaml; def self.render(output, options={}); output.to_yaml; end ;end
|
59
|
+
# Hirb.enable
|
60
|
+
#
|
61
|
+
# For more about configuring Hirb, see the Config Files section in Hirb.
|
4
62
|
module View
|
5
63
|
DEFAULT_WIDTH = 120
|
6
64
|
DEFAULT_HEIGHT = 40
|
@@ -10,26 +68,23 @@ module Hirb
|
|
10
68
|
|
11
69
|
# This activates view functionality i.e. the formatter, pager and size detection. If irb exists, it overrides irb's output
|
12
70
|
# method with Hirb::View.view_output. When called multiple times, new configs are merged into the existing config.
|
13
|
-
# If using Wirble, you should call this after it. The view configuration
|
14
|
-
#
|
15
|
-
# In addition to the config keys mentioned in Hirb, the options also take the following keys:
|
71
|
+
# If using Wirble, you should call this after it. The view configuration can be specified in a hash via a config file,
|
72
|
+
# or as options to this method. In addition to the config keys mentioned in Hirb, options also take the following keys:
|
16
73
|
# ==== Options:
|
17
74
|
# * config_file: Name of config file(s) that are merged into existing config
|
18
75
|
# * output_method: Specify an object's class and instance method (separated by a period) to be realiased with
|
19
76
|
# hirb's view system. The instance method should take a string to be output. Default is IRB::Irb.output_value
|
20
77
|
# if using irb.
|
21
78
|
# Examples:
|
22
|
-
# Hirb
|
23
|
-
# Hirb
|
24
|
-
# Hirb::View.enable {|c| c.output = {'String'=>{:class=>'Hirb::Helpers::Table'}} }
|
79
|
+
# Hirb.enable
|
80
|
+
# Hirb.enable :formatter=>false, :output_method=>"Mini.output"
|
25
81
|
def enable(options={}, &block)
|
26
82
|
Array(options.delete(:config_file)).each {|e|
|
27
83
|
@new_config_file = true
|
28
84
|
Hirb.config_files << e
|
29
85
|
}
|
30
86
|
enable_output_method(options.delete(:output_method))
|
31
|
-
|
32
|
-
merge_or_load_config(Util.recursive_hash_merge(options, HashStruct.block_to_hash(block)))
|
87
|
+
merge_or_load_config options
|
33
88
|
resize(config[:width], config[:height])
|
34
89
|
@enabled = true
|
35
90
|
end
|
@@ -102,14 +157,18 @@ module Hirb
|
|
102
157
|
config ? config[:height] : DEFAULT_HEIGHT
|
103
158
|
end
|
104
159
|
|
105
|
-
# Current formatter config
|
160
|
+
# Current formatter config, storing a hash of all static views
|
106
161
|
def formatter_config
|
107
162
|
formatter.config
|
108
163
|
end
|
109
164
|
|
110
|
-
#
|
111
|
-
def
|
112
|
-
|
165
|
+
# Adds a view when View is enabled. See Formatter.add_view for more details.
|
166
|
+
def add(klass, view_config)
|
167
|
+
if enabled?
|
168
|
+
formatter.add_view(klass, view_config)
|
169
|
+
else
|
170
|
+
puts "View must be enabled to add a view"
|
171
|
+
end
|
113
172
|
end
|
114
173
|
|
115
174
|
#:stopdoc:
|
@@ -217,8 +276,4 @@ module Hirb
|
|
217
276
|
#:startdoc:
|
218
277
|
end
|
219
278
|
end
|
220
|
-
|
221
|
-
# Namespace for autoloaded views
|
222
|
-
module Views
|
223
|
-
end
|
224
|
-
end
|
279
|
+
end
|
data/lib/hirb/views.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
module Hirb::Views::CouchDb #:nodoc:
|
2
|
+
def default_couch(obj)
|
3
|
+
{:fields=>([:_id] + obj.class.properties.map {|e| e.name }) }
|
4
|
+
end
|
5
|
+
|
6
|
+
alias_method :couch_rest__extended_document_view, :default_couch
|
7
|
+
alias_method :couch_foo__base_view, :default_couch
|
8
|
+
alias_method :couch_potato__persistence_view, :default_couch
|
9
|
+
end
|
10
|
+
|
11
|
+
Hirb::DynamicView.add Hirb::Views::CouchDb, :helper=>:auto_table
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Hirb::Views::MiscDb #:nodoc:
|
2
|
+
def friendly__document_view(obj)
|
3
|
+
{:fields=>obj.class.attributes.keys - [:id]}
|
4
|
+
end
|
5
|
+
|
6
|
+
def ripple__document_view(obj)
|
7
|
+
{:fields=>obj.class.properties.keys}
|
8
|
+
end
|
9
|
+
|
10
|
+
def d_b_i__row_view(obj)
|
11
|
+
{:fields=>obj.column_names, :table_class=>Hirb::Helpers::Table}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Hirb::DynamicView.add Hirb::Views::MiscDb, :helper=>:auto_table
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Hirb::Views::MongoDb #:nodoc:
|
2
|
+
def mongoid__document_view(obj)
|
3
|
+
{:fields=>['_id'] + obj.class.fields.keys}
|
4
|
+
end
|
5
|
+
|
6
|
+
def mongo_mapper__document_view(obj)
|
7
|
+
{:fields=>obj.class.column_names}
|
8
|
+
end
|
9
|
+
|
10
|
+
def mongo_mapper__embedded_document_view(obj)
|
11
|
+
{:fields=>obj.class.column_names}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Hirb::DynamicView.add Hirb::Views::MongoDb, :helper=>:auto_table
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Hirb::Views::ORM #:nodoc:
|
2
|
+
def data_mapper__resource_view(obj)
|
3
|
+
{:fields=>obj.class.properties.map {|e| e.name }}
|
4
|
+
end
|
5
|
+
|
6
|
+
def sequel__model_view(obj)
|
7
|
+
{:fields=>obj.class.columns}
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Hirb::DynamicView.add Hirb::Views::ORM, :helper=>:auto_table
|