summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Pittman <daniel@puppetlabs.com>2011-04-18 13:27:17 -0700
committerDaniel Pittman <daniel@puppetlabs.com>2011-04-19 10:53:31 -0700
commitbe23b8423ba77a5935586e277bf543cd54b9dec7 (patch)
tree96e2d4c93c63605c469e22d16417170216012abf
parente6caa2459a75cdfb015e7f4754dd5b44d166b0b5 (diff)
downloadpuppet-be23b8423ba77a5935586e277bf543cd54b9dec7.tar.gz
puppet-be23b8423ba77a5935586e277bf543cd54b9dec7.tar.xz
puppet-be23b8423ba77a5935586e277bf543cd54b9dec7.zip
(#7013) better default rendering support for faces
We have some specific requirements around rendering, including the ability of authors of actions to add nice, custom rendering. To support that we want solid "basic" rendering for human-focused output. This implements that generic rendering correctly and to spec, to give a sound basis that we can build on for extensible rendering. (#7013) better default rendering support for faces We have some specific requirements around rendering, including the ability of authors of actions to add nice, custom rendering. To support that we want solid "basic" rendering for human-focused output. This implements that generic rendering correctly and to spec, to give a sound basis that we can build on for extensible rendering. Reviewed-By: Max Martin <max@puppetlabs.com>
-rw-r--r--lib/puppet/application/face_base.rb35
-rwxr-xr-xspec/unit/application/face_base_spec.rb49
2 files changed, 80 insertions, 4 deletions
diff --git a/lib/puppet/application/face_base.rb b/lib/puppet/application/face_base.rb
index 7b5bffe54..947204d68 100644
--- a/lib/puppet/application/face_base.rb
+++ b/lib/puppet/application/face_base.rb
@@ -1,6 +1,7 @@
require 'puppet/application'
require 'puppet/face'
require 'optparse'
+require 'pp'
class Puppet::Application::FaceBase < Puppet::Application
should_parse_config
@@ -36,14 +37,40 @@ class Puppet::Application::FaceBase < Puppet::Application
# Override this if you need custom rendering.
def render(result)
- render_method = Puppet::Network::FormatHandler.format(format).render_method
- if render_method == "to_pson"
- jj result
+ if format then
+ render_method = Puppet::Network::FormatHandler.format(format).render_method
+ if render_method == "to_pson"
+ jj result
+ else
+ result.send(render_method)
+ end
else
- result.send(render_method)
+ render_for_humans(result)
end
end
+ def render_for_humans(result)
+ # String to String
+ return result if result.is_a? String
+
+ # Simple hash to table
+ if result.is_a? Hash and result.keys.all? { |x| x.is_a? String or x.is_a? Numeric }
+ output = ''
+ column_a = result.map do |k,v| k.to_s.length end.max + 2
+ column_b = 79 - column_a
+ result.sort_by { |k,v| k.to_s } .each do |key, value|
+ output << key.to_s.ljust(column_a)
+ output << PP.pp(value, '', column_b).
+ chomp.gsub(/\n */) { |x| x + (' ' * column_a) }
+ output << "\n"
+ end
+ return output
+ end
+
+ # ...or pretty-print the inspect outcome.
+ return result.pretty_inspect
+ end
+
def preinit
super
Signal.trap(:INT) do
diff --git a/spec/unit/application/face_base_spec.rb b/spec/unit/application/face_base_spec.rb
index 7e13d4be6..0d39aa1ff 100755
--- a/spec/unit/application/face_base_spec.rb
+++ b/spec/unit/application/face_base_spec.rb
@@ -214,4 +214,53 @@ describe Puppet::Application::FaceBase do
app.main
end
end
+
+ describe "#render" do
+ it "should just return a String" do
+ app.render("hello").should == "hello"
+ end
+
+ [1, 1.000, [1, 2], ["one"], [{ 1 => 1 }]].each do |input|
+ it "should render #{input.class} using the 'pp' library" do
+ app.render(input).should == input.pretty_inspect
+ end
+ end
+
+ it "should render a non-trivially-keyed Hash with the 'pp' library" do
+ hash = { [1,2] => 3, [2,3] => 5, [3,4] => 7 }
+ app.render(hash).should == hash.pretty_inspect
+ end
+
+ it "should render a {String,Numeric}-keyed Hash into a table" do
+ object = Object.new
+ hash = { "one" => 1, "two" => [], "three" => {}, "four" => object,
+ 5 => 5, 6.0 => 6 }
+
+ # Gotta love ASCII-betical sort order. Hope your objects are better
+ # structured for display than my test one is. --daniel 2011-04-18
+ app.render(hash).should == <<EOT
+5 5
+6.0 6
+four #{object.pretty_inspect.chomp}
+one 1
+three {}
+two []
+EOT
+ end
+
+ it "should render a hash nicely with a multi-line value" do
+ hash = {
+ "number" => { "1" => '1' * 40, "2" => '2' * 40, '3' => '3' * 40 },
+ "text" => { "a" => 'a' * 40, 'b' => 'b' * 40, 'c' => 'c' * 40 }
+ }
+ app.render(hash).should == <<EOT
+number {"1"=>"1111111111111111111111111111111111111111",
+ "2"=>"2222222222222222222222222222222222222222",
+ "3"=>"3333333333333333333333333333333333333333"}
+text {"a"=>"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ "b"=>"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
+ "c"=>"cccccccccccccccccccccccccccccccccccccccc"}
+EOT
+ end
+ end
end