summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorlutter <lutter@980ebf18-57e1-0310-9a29-db15c13687c0>2007-01-03 23:22:29 +0000
committerlutter <lutter@980ebf18-57e1-0310-9a29-db15c13687c0>2007-01-03 23:22:29 +0000
commitcbd20f00899433c46ce7cb25f966e54217621d7f (patch)
tree93f25b9ec929cfee62f4cc40732cef8ede157d5e /bin
parent3b6bf05d93b82e433800a0a85ed4f09d13b17e62 (diff)
downloadpuppet-cbd20f00899433c46ce7cb25f966e54217621d7f.tar.gz
Simple script to produce type info
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@2030 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'bin')
-rwxr-xr-xbin/pi235
1 files changed, 235 insertions, 0 deletions
diff --git a/bin/pi b/bin/pi
new file mode 100755
index 000000000..e315ba73d
--- /dev/null
+++ b/bin/pi
@@ -0,0 +1,235 @@
+#!/usr/bin/ruby
+
+#
+# = Synopsis
+#
+# Print help about puppet types on the console. Run with '-h' to get detailed
+# help.
+#
+
+# FIXME: (1) Formatting could be a lot prettier
+# (2) The command line options are kinda screwy; unclear how best to
+# present the various pieces of info to user
+
+require 'puppet'
+require 'puppet/type'
+require 'optparse'
+
+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, [:state, :param])
+ else
+ list_attrs(type, [:state, :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