diff options
author | Brice Figureau <brice-puppet@daysofwonder.com> | 2009-02-14 17:15:39 +0100 |
---|---|---|
committer | Brice Figureau <brice-puppet@daysofwonder.com> | 2009-02-16 20:12:10 +0100 |
commit | 3390d8db8b1d31b52a71b9502deb0e0784cf8ade (patch) | |
tree | b7e7ba9e33abe598089b88bdf9cf21c153b385aa | |
parent | 8265d6eaf7dd7d4fb2af30363bfbcc698dea1436 (diff) | |
download | puppet-3390d8db8b1d31b52a71b9502deb0e0784cf8ade.tar.gz puppet-3390d8db8b1d31b52a71b9502deb0e0784cf8ade.tar.xz puppet-3390d8db8b1d31b52a71b9502deb0e0784cf8ade.zip |
Move pi to the Application Controller paradigm
Signed-off-by: Brice Figureau <brice-puppet@daysofwonder.com>
-rwxr-xr-x | bin/pi | 223 | ||||
-rw-r--r-- | lib/puppet/application/pi.rb | 216 | ||||
-rwxr-xr-x | spec/unit/application/pi.rb | 84 |
3 files changed, 303 insertions, 220 deletions
@@ -11,224 +11,7 @@ # (2) The command line options are kinda screwy; unclear how best to # present the various pieces of info to user -require 'puppet' -require 'optparse' +require 'puppet/application' +require 'puppet/application/pi' -class Formatter - - def initialize(width) - @width = width - end - - def wrap(txt, opts) - return "" unless txt && !txt.empty? - work = (opts[:scrub] ? scrub(txt) : txt) - indent = (opts[:indent] ? opts[:indent] : 0) - textLen = @width - indent - patt = Regexp.new("^(.{0,#{textLen}})[ \n]") - prefix = " " * indent - - res = [] - - while work.length > textLen - if work =~ patt - res << $1 - work.slice!(0, $&.length) - else - res << work.slice!(0, textLen) - end - end - res << work if work.length.nonzero? - return prefix + res.join("\n" + prefix) - end - - def header(txt, sep = "-") - "\n#{txt}\n" + sep * txt.size - end - - private - - def scrub(text) - # For text with no carriage returns, there's nothing to do. - if text !~ /\n/ - return text - end - indent = nil - - # If we can match an indentation, then just remove that same level of - # indent from every line. - if text =~ /^(\s+)/ - indent = $1 - return text.gsub(/^#{indent}/,'') - else - return text - end - end - -end - -class TypeDoc - - def initialize - @format = Formatter.new(76) - @types = {} - Puppet::Type.loadall - Puppet::Type.eachtype { |type| - next if type.name == :component - @types[type.name] = type - } - end - - def list_types - puts "These are the types known to puppet:\n" - @types.keys.sort { |a, b| - a.to_s <=> b.to_s - }.each do |name| - type = @types[name] - s = type.doc.gsub(/\s+/, " ") - n = s.index(".") - if n.nil? - s = ".. no documentation .." - elsif n > 45 - s = s[0, 45] + " ..." - else - s = s[0, n] - end - printf "%-15s - %s\n", name, s - end - end - - def format_type(name, opts) - name = name.to_sym - unless @types.has_key?(name) - puts "Unknown type #{name}" - return - end - type = @types[name] - puts @format.header(name.to_s, "=") - puts @format.wrap(type.doc, :indent => 0, :scrub => true) + "\n\n" - - puts @format.header("Parameters") - if opts[:parameters] - format_attrs(type, [:property, :param]) - else - list_attrs(type, [:property, :param]) - end - - if opts[:metaparams] - puts @format.header("Meta Parameters") - if opts[:parameters] - format_attrs(type, [:meta]) - else - list_attrs(type, [:meta]) - end - end - - if type.providers.size > 0 - puts @format.header("Providers") - if opts[:providers] - format_providers(type) - else - list_providers(type) - end - end - end - - # List details about attributes - def format_attrs(type, attrs) - docs = {} - type.eachattr do |obj, kind| - if attrs.include?(kind) && obj.name != :provider - docs[obj.name] = obj.doc - end - end - - docs.sort { |a,b| - a[0].to_s <=> b[0].to_s - }.each { |name, doc| - print "\n- **%s**" % name - if type.namevar == name and name != :name - puts " (*namevar*)" - else - puts "" - end - puts @format.wrap(doc, :indent => 4, :scrub => true) - } - end - - # List the names of attributes - def list_attrs(type, attrs) - params = [] - type.eachattr do |obj, kind| - if attrs.include?(kind) && obj.name != :provider - params << obj.name.to_s - end - end - puts @format.wrap(params.sort.join(", "), :indent => 4) - end - - def format_providers(type) - type.providers.sort { |a,b| - a.to_s <=> b.to_s - }.each { |prov| - puts "\n- **%s**" % prov - puts @format.wrap(type.provider(prov).doc, - :indent => 4, :scrub => true) - } - end - - def list_providers(type) - list = type.providers.sort { |a,b| - a.to_s <=> b.to_s - }.join(", ") - puts @format.wrap(list, :indent => 4) - end - -end - -def process_args - result = { - :list => false, - :providers => false, - :parameters => true, - :metaparams => false - } - opts = OptionParser.new("#{$0} [options] [type]") - opts.separator(" Print documentation for puppet types and their parameters") - opts.on("-l", "--list", "List all types") do |val| - result[:list] = true - end - opts.on("-p", "--providers", - "Describe providers in detail") do |val| - result[:providers] = true - end - opts.on("-s", "--short", - "Only list parameters without detail") do |val| - result[:parameters] = false - end - opts.on("-m", "--meta", - "Include metaparams") do |val| - result[:metaparams] = true - end - result[:types] = opts.order(ARGV) - # Check for obviously bogus options - unless result[:list] || result[:types].size > 0 - $stderr.puts opts - exit(1) - end - if result[:list] && result[:types].size > 0 - $stderr.puts "Warning: ignoring types when listing all types" - end - - return result -end - -opts = process_args - -doc = TypeDoc.new - -if opts[:list] - doc.list_types -else - opts[:types].each { |name| doc.format_type(name, opts) } -end +Puppet::Application[:pi].run
\ No newline at end of file diff --git a/lib/puppet/application/pi.rb b/lib/puppet/application/pi.rb new file mode 100644 index 000000000..4c73418a8 --- /dev/null +++ b/lib/puppet/application/pi.rb @@ -0,0 +1,216 @@ +require 'puppet' +require 'puppet/application' + +class Formatter + + def initialize(width) + @width = width + end + + def wrap(txt, opts) + return "" unless txt && !txt.empty? + work = (opts[:scrub] ? scrub(txt) : txt) + indent = (opts[:indent] ? opts[:indent] : 0) + textLen = @width - indent + patt = Regexp.new("^(.{0,#{textLen}})[ \n]") + prefix = " " * indent + + res = [] + + while work.length > textLen + if work =~ patt + res << $1 + work.slice!(0, $&.length) + else + res << work.slice!(0, textLen) + end + end + res << work if work.length.nonzero? + return prefix + res.join("\n" + prefix) + end + + def header(txt, sep = "-") + "\n#{txt}\n" + sep * txt.size + end + + private + + def scrub(text) + # For text with no carriage returns, there's nothing to do. + if text !~ /\n/ + return text + end + indent = nil + + # If we can match an indentation, then just remove that same level of + # indent from every line. + if text =~ /^(\s+)/ + indent = $1 + return text.gsub(/^#{indent}/,'') + else + return text + end + end + +end + +class TypeDoc + + def initialize + @format = Formatter.new(76) + @types = {} + Puppet::Type.loadall + Puppet::Type.eachtype { |type| + next if type.name == :component + @types[type.name] = type + } + end + + def list_types + puts "These are the types known to puppet:\n" + @types.keys.sort { |a, b| + a.to_s <=> b.to_s + }.each do |name| + type = @types[name] + s = type.doc.gsub(/\s+/, " ") + n = s.index(".") + if n.nil? + s = ".. no documentation .." + elsif n > 45 + s = s[0, 45] + " ..." + else + s = s[0, n] + end + printf "%-15s - %s\n", name, s + end + end + + def format_type(name, opts) + name = name.to_sym + unless @types.has_key?(name) + puts "Unknown type #{name}" + return + end + type = @types[name] + puts @format.header(name.to_s, "=") + puts @format.wrap(type.doc, :indent => 0, :scrub => true) + "\n\n" + + puts @format.header("Parameters") + if opts[:parameters] + format_attrs(type, [:property, :param]) + else + list_attrs(type, [:property, :param]) + end + + if opts[:metaparams] + puts @format.header("Meta Parameters") + if opts[:parameters] + format_attrs(type, [:meta]) + else + list_attrs(type, [:meta]) + end + end + + if type.providers.size > 0 + puts @format.header("Providers") + if opts[:providers] + format_providers(type) + else + list_providers(type) + end + end + end + + # List details about attributes + def format_attrs(type, attrs) + docs = {} + type.eachattr do |obj, kind| + if attrs.include?(kind) && obj.name != :provider + docs[obj.name] = obj.doc + end + end + + docs.sort { |a,b| + a[0].to_s <=> b[0].to_s + }.each { |name, doc| + print "\n- **%s**" % name + if type.namevar == name and name != :name + puts " (*namevar*)" + else + puts "" + end + puts @format.wrap(doc, :indent => 4, :scrub => true) + } + end + + # List the names of attributes + def list_attrs(type, attrs) + params = [] + type.eachattr do |obj, kind| + if attrs.include?(kind) && obj.name != :provider + params << obj.name.to_s + end + end + puts @format.wrap(params.sort.join(", "), :indent => 4) + end + + def format_providers(type) + type.providers.sort { |a,b| + a.to_s <=> b.to_s + }.each { |prov| + puts "\n- **%s**" % prov + puts @format.wrap(type.provider(prov).doc, + :indent => 4, :scrub => true) + } + end + + def list_providers(type) + list = type.providers.sort { |a,b| + a.to_s <=> b.to_s + }.join(", ") + puts @format.wrap(list, :indent => 4) + end + +end + +Puppet::Application.new(:pi,"#{$0} [options] [type]") do + @opt_parser.separator(" Print documentation for puppet types and their parameters") + + should_not_parse_config + + option("--short", "-s", "Only list parameters without detail") do |arg| + options[:parameters] = false + end + + option("--providers","-p", "Describe providers in detail") + option("--list", "-l", "List all types") + option("--meta","-m", "Include metaparams") + option("--help","-h") do |v| + puts @opt_parser + end + + preinit do + options[:parameters] = true + end + + command(:main) do + doc = TypeDoc.new + + if options[:list] + doc.list_types + else + options[:types].each { |name| doc.format_type(name, options) } + end + end + + setup do + options[:types] = ARGV.dup + unless options[:list] || options[:types].size > 0 + handle_help(nil) + end + if options[:list] && options[:types].size > 0 + $stderr.puts "Warning: ignoring types when listing all types" + end + end + +end diff --git a/spec/unit/application/pi.rb b/spec/unit/application/pi.rb new file mode 100755 index 000000000..84d6a7ff5 --- /dev/null +++ b/spec/unit/application/pi.rb @@ -0,0 +1,84 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet/application/pi' + +describe "pi" do + before :each do + @pi = Puppet::Application[:pi] + end + + it "should ask Puppet::Application to not parse Puppet configuration file" do + @pi.should_parse_config?.should be_false + end + + it "should declare a main command" do + @pi.should respond_to(:main) + end + + it "should declare a preinit block" do + @pi.should respond_to(:run_preinit) + end + + [:providers,:list,:meta].each do |option| + it "should declare handle_#{option} method" do + @pi.should respond_to("handle_#{option}".to_sym) + end + + it "should store argument value when calling handle_#{option}" do + @pi.options.expects(:[]=).with("#{option}".to_sym, 'arg') + @pi.send("handle_#{option}".to_sym, 'arg') + end + end + + + describe "in preinit" do + it "should set options[:parameteers] to true" do + @pi.run_preinit + + @pi.options[:parameters].should be_true + end + end + + describe "when handling parameters" do + it "should set options[:parameters] to false" do + @pi.handle_short(nil) + + @pi.options[:parameters].should be_false + end + end + + describe "during setup" do + it "should collect ARGV in options[:types]" do + ARGV.stubs(:dup).returns(['1','2']) + @pi.run_setup + + @pi.options[:types].should == ['1','2'] + end + end + + describe "when running" do + + before :each do + @typedoc = stub 'type_doc' + TypeDoc.stubs(:new).returns(@typedoc) + end + + it "should call list_types if options list is set" do + @pi.options[:list] = true + + @typedoc.expects(:list_types) + + @pi.run_command + end + + it "should call format_type for each given types" do + @pi.options[:list] = false + @pi.options[:types] = ['type'] + + @typedoc.expects(:format_type).with('type', @pi.options) + @pi.run_command + end + end +end |