diff --git a/bin/pi b/bin/pi index c1a59631e..68e756a35 100755 --- a/bin/pi +++ b/bin/pi @@ -1,50 +1,50 @@ #!/usr/bin/env ruby # # = Synopsis # # Print help about puppet types on the console. Run with '-h' to get detailed # help. # = Usage # # pi [-h|--help] [-s|--short] [-p|--providers] [-l|--list] [-m|--meta] # # = Description # # Prints details of Puppet types, providers and metaparameters on the console. # # = Options # # help:: # Print this help text # # providers:: # Describe providers in detail for each type # # list:: # List all types # # meta:: # List all metaparameters # # short:: # List only parameters without detail # # = Example # # pi --list # pi file --providers # pi user -s -m # # = Author # # David Lutterkort # # = Copyright # # Copyright (c) 2005 Reductive Labs, LLC # Licensed under the GNU Public License -require 'puppet/application/pi' +require 'puppet/application/describe' -Puppet::Application[:pi].run +Puppet::Application[:describe].run diff --git a/lib/puppet/application/pi.rb b/lib/puppet/application/describe.rb similarity index 98% rename from lib/puppet/application/pi.rb rename to lib/puppet/application/describe.rb index 4a0bb955a..d3d335496 100644 --- a/lib/puppet/application/pi.rb +++ b/lib/puppet/application/describe.rb @@ -1,214 +1,214 @@ 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[:meta] 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.allattrs.each do |name| kind = type.attrtype(name) if attrs.include?(kind) && name != :provider docs[name] = type.attrclass(name).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.allattrs.each do |name| kind = type.attrtype(name) if attrs.include?(kind) && name != :provider params << 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 +Puppet::Application.new(:describe,"#{$0} [options] [type]") do should_not_parse_config option("--short", "-s", "Only list parameters without detail") do |arg| options[:parameters] = false end option("--providers","-p") option("--list", "-l") option("--meta","-m") 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/describe.rb similarity index 54% rename from spec/unit/application/pi.rb rename to spec/unit/application/describe.rb index 84d6a7ff5..f9a601454 100755 --- a/spec/unit/application/pi.rb +++ b/spec/unit/application/describe.rb @@ -1,84 +1,84 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' -require 'puppet/application/pi' +require 'puppet/application/describe' -describe "pi" do +describe Puppet::Application[:describe] do before :each do - @pi = Puppet::Application[:pi] + @describe = Puppet::Application[:describe] end it "should ask Puppet::Application to not parse Puppet configuration file" do - @pi.should_parse_config?.should be_false + @describe.should_parse_config?.should be_false end it "should declare a main command" do - @pi.should respond_to(:main) + @describe.should respond_to(:main) end it "should declare a preinit block" do - @pi.should respond_to(:run_preinit) + @describe.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) + @describe.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') + @describe.options.expects(:[]=).with("#{option}".to_sym, 'arg') + @describe.send("handle_#{option}".to_sym, 'arg') end end describe "in preinit" do it "should set options[:parameteers] to true" do - @pi.run_preinit + @describe.run_preinit - @pi.options[:parameters].should be_true + @describe.options[:parameters].should be_true end end describe "when handling parameters" do it "should set options[:parameters] to false" do - @pi.handle_short(nil) + @describe.handle_short(nil) - @pi.options[:parameters].should be_false + @describe.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 + @describe.run_setup - @pi.options[:types].should == ['1','2'] + @describe.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 + @describe.options[:list] = true @typedoc.expects(:list_types) - @pi.run_command + @describe.run_command end it "should call format_type for each given types" do - @pi.options[:list] = false - @pi.options[:types] = ['type'] + @describe.options[:list] = false + @describe.options[:types] = ['type'] - @typedoc.expects(:format_type).with('type', @pi.options) - @pi.run_command + @typedoc.expects(:format_type).with('type', @describe.options) + @describe.run_command end end end