diff --git a/lib/puppet/face/help.rb b/lib/puppet/face/help.rb index 7a382b8c9..9376adf04 100644 --- a/lib/puppet/face/help.rb +++ b/lib/puppet/face/help.rb @@ -1,131 +1,131 @@ require 'puppet/face' require 'puppet/util/command_line' require 'pathname' require 'erb' Puppet::Face.define(:help, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "Display Puppet help." action(:help) do summary "Display help about faces and their actions." arguments "[] []" returns "Short help text for the specified face or action." examples <<-'EOT' Get help for an action: $ puppet help EOT option "--version VERSION" do summary "The version of the face for which to show help." end default when_invoked do |*args| # Check our invocation, because we want varargs and can't do defaults # yet. REVISIT: when we do option defaults, and positional options, we # should rewrite this to use those. --daniel 2011-04-04 options = args.pop if options.nil? or args.length > 2 then if args.select { |x| x == 'help' }.length > 2 then c = "\n %'(),-./=ADEFHILORSTUXY\\_`gnv|".split('') i = <<-'EOT'.gsub(/\s*/, '').to_i(36) 3he6737w1aghshs6nwrivl8mz5mu9nywg9tbtlt081uv6fq5kvxse1td3tj1wvccmte806nb cy6de2ogw0fqjymbfwi6a304vd56vlq71atwmqsvz3gpu0hj42200otlycweufh0hylu79t3 gmrijm6pgn26ic575qkexyuoncbujv0vcscgzh5us2swklsp5cqnuanlrbnget7rt3956kam j8adhdrzqqt9bor0cv2fqgkloref0ygk3dekiwfj1zxrt13moyhn217yy6w4shwyywik7w0l xtuevmh0m7xp6eoswin70khm5nrggkui6z8vdjnrgdqeojq40fya5qexk97g4d8qgw0hvokr pli1biaz503grqf2ycy0ppkhz1hwhl6ifbpet7xd6jjepq4oe0ofl575lxdzjeg25217zyl4 nokn6tj5pq7gcdsjre75rqylydh7iia7s3yrko4f5ud9v8hdtqhu60stcitirvfj6zphppmx 7wfm7i9641d00bhs44n6vh6qvx39pg3urifgr6ihx3e0j1ychzypunyou7iplevitkyg6gbg wm08oy1rvogcjakkqc1f7y1awdfvlb4ego8wrtgu9vzw4vmj59utwifn2ejcs569dh1oaavi sc581n7jjg1dugzdu094fdobtx6rsvk3sfctvqnr36xctold EOT 353.times{i,x=i.divmod(1184);a,b=x.divmod(37);print(c[a]*b)} end raise ArgumentError, "help only takes two (optional) arguments, a face name, and an action" end version = :current if options.has_key? :version then if options[:version].to_s !~ /^current$/i then version = options[:version] else if args.length == 0 then raise ArgumentError, "version only makes sense when a face is given" end end end # Name those parameters... facename, actionname = args if facename then if legacy_applications.include? facename then actionname and raise ArgumentError, "Legacy subcommands don't take actions" return Puppet::Application[facename].help else face = Puppet::Face[facename.to_sym, version] actionname and action = face.get_action(actionname.to_sym) end end case args.length when 0 then template = erb 'global.erb' when 1 then face or fail ArgumentError, "Unable to load face #{facename}" template = erb 'face.erb' when 2 then face or fail ArgumentError, "Unable to load face #{facename}" action or fail ArgumentError, "Unable to load action #{actionname} from #{face}" template = erb 'action.erb' else fail ArgumentError, "Too many arguments to help action" end # Run the ERB template in our current binding, including all the local # variables we established just above. --daniel 2011-04-11 return template.result(binding) end end def erb(name) template = (Pathname(__FILE__).dirname + "help" + name) - erb = ERB.new(template.read, nil, '%') + erb = ERB.new(template.read, nil, '-') erb.filename = template.to_s return erb end def legacy_applications # The list of applications, less those that are duplicated as a face. Puppet::Util::CommandLine.available_subcommands.reject do |appname| Puppet::Face.face? appname.to_sym, :current or # ...this is a nasty way to exclude non-applications. :( %w{face_base indirection_base}.include? appname end.sort end def horribly_extract_summary_from(appname) begin require "puppet/application/#{appname}" help = Puppet::Application[appname].help.split("\n") # Now we find the line with our summary, extract it, and return it. This # depends on the implementation coincidence of how our pages are # formatted. If we can't match the pattern we expect we return the empty # string to ensure we don't blow up in the summary. --daniel 2011-04-11 while line = help.shift do if md = /^puppet-#{appname}\([^\)]+\) -- (.*)$/.match(line) then return md[1] end end rescue Exception # Damn, but I hate this: we just ignore errors here, no matter what # class they are. Meh. end return '' end end diff --git a/lib/puppet/face/help/action.erb b/lib/puppet/face/help/action.erb index aab7f2564..c788f34fd 100644 --- a/lib/puppet/face/help/action.erb +++ b/lib/puppet/face/help/action.erb @@ -1,22 +1,57 @@ -puppet <%= face.name %><%= action.default? ? '' : " #{action.name}" %> - <%= action.summary || face.summary %> +<%= action.summary || face.summary || "unknown face..." %> -% if action.synopsis -usage: <%= action.synopsis %> +<% if action.synopsis -%> +USAGE: <%= action.synopsis %> -% end -% if action.description or action.short_description -<%= action.short_description %> +<% end -%> +<% if action.short_description -%> +<%= action.short_description.strip %> -%end -% unless action.options.empty? +<% end -%> +<% if action.returns -%> +RETURNS: <%= action.returns.strip %> + +<% end -%> OPTIONS: -% action.options.sort.each do |name| -% option = action.get_option name -<%= " " + option.optparse.join(" |" ) %> - <%= option.summary %> +<%# Remove these options once we can introspect them normally. -%> + --mode MODE - The run mode to use (`user`, `agent`, or + `master`). + --render-as FORMAT - The rendering format to use. + --verbose - Whether to log verbosely. + --debug - Whether to log debug information. +<% unless action.options.empty? + optionroom = 30 + summaryroom = 80 - 5 - optionroom + action.options.sort.each do |name| + option = action.get_option name -%> +<%= " " + option.optparse.join(" | ")[0,(optionroom - 1)].ljust(optionroom) + ' - ' -%> +<% if !(option.summary) -%> +unknown option... +<% elsif option.summary.length <= summaryroom -%> +<%= option.summary %> +<% + else + words = option.summary.split + wrapped = [''] + i = 0 + words.each do |word| + if wrapped[i].length + word.length <= summaryroom + wrapped[i] << word + ' ' + else + i += 1 + wrapped[i] = word + ' ' + end + end +-%> +<%= wrapped.shift.strip %> +<% wrapped.each do |line| -%> +<%= (' ' * (optionroom + 5) ) + line.strip %> +<% end + end + end -%> +<% end -%> -% end -% end -% if action.examples +<% if action.examples -%> EXAMPLES: <%= action.examples %> -% end +<% end -%> diff --git a/lib/puppet/face/help/face.erb b/lib/puppet/face/help/face.erb index b249981de..2a0f0181c 100644 --- a/lib/puppet/face/help/face.erb +++ b/lib/puppet/face/help/face.erb @@ -1,48 +1,91 @@ -NAME - <%= face.name %> -- <%= face.summary || "unknown face..." %> +<%= face.summary || "unknown face..." %> -% if face.synopsis -SYNOPSIS -<%= face.synopsis.gsub(/^/, ' ') %> +<% if face.synopsis -%> +USAGE: <%= face.synopsis %> -% end -% if face.description -DESCRIPTION -<%= face.description.chomp.gsub(/^/, ' ') %> +<% end -%> +<% if face.short_description -%> +<%= face.short_description %> -%end -% unless face.options.empty? -OPTIONS -% face.options.sort.each do |name| -% option = face.get_option name -<%= " " + option.optparse.join(" |" ) %> +<% end -%> +OPTIONS: +<%# Remove these options once we can introspect them normally. -%> + --mode MODE - The run mode to use (`user`, `agent`, or + `master`). + --render-as FORMAT - The rendering format to use. + --verbose - Whether to log verbosely. + --debug - Whether to log debug information. +<% unless face.options.empty? + optionroom = 30 + summaryroom = 80 - 5 - optionroom + face.options.sort.each do |name| + option = face.get_option name -%> +<%= " " + option.optparse.join(" | ")[0,(optionroom - 1)].ljust(optionroom) + ' - ' -%> +<% if !(option.summary) -%> +unknown option... +<% elsif option.summary.length <= summaryroom -%> <%= option.summary %> -<%= option.description %> +<% + else + words = option.summary.split + wrapped = [''] + i = 0 + words.each do |word| + if wrapped[i].length + word.length <= summaryroom + wrapped[i] << word + ' ' + else + i += 1 + wrapped[i] = word + ' ' + end + end +-%> +<%= wrapped.shift.strip %> +<% wrapped.each do |line| -%> +<%= (' ' * (optionroom + 5) ) + line.strip %> +<% end + end + end -%> +<% end -%> -% end -% end -ACTIONS -% padding = face.actions.map{|x| x.to_s.length}.max + 2 -% face.actions.each do |actionname| -% action = face.get_action(actionname) - <%= action.name.to_s.ljust(padding) %> <%= action.summary %> -% end +ACTIONS: +<% padding = face.actions.map{|x| x.to_s.length}.max + 2 + summaryroom = 80 - (padding + 4) + face.actions.each do |actionname| + action = face.get_action(actionname) -%> + <%= action.name.to_s.ljust(padding) + ' ' -%> +<% if !(action.summary) -%> +unknown action... +<% elsif action.summary.length <= summaryroom -%> +<%= action.summary %> +<% else + words = action.summary.split + wrapped = [''] + i = 0 + words.each do |word| + if wrapped[i].length + word.length <= summaryroom + wrapped[i] << word + ' ' + else + i += 1 + wrapped[i] = word + ' ' + end + end +-%> +<%= wrapped.shift.strip %> +<% wrapped.each do |line| -%> +<%= (' ' * (padding + 4) ) + line.strip %> +<% end + end +end -%> -% if face.examples -EXAMPLES -<%= face.examples %> -% end -% if face.notes -NOTES -<%= face.notes %> +<% if face.respond_to? :indirection -%> +TERMINI: <%= face.class.terminus_classes(face.indirection.name).join(", ") %> -% end -% unless face.authors.empty? +<% end + unless face.authors.empty? -%> AUTHOR <%= face.authors.join("\n").gsub(/^/, ' * ') %> -%end -COPYRIGHT AND LICENSE +<% end -%> +COPYRIGHT AND LICENSE: <%= face.copyright.gsub(/^/, ' ') %> <%= face.license.gsub(/^/, ' ') %> - diff --git a/lib/puppet/face/help/global.erb b/lib/puppet/face/help/global.erb index 80c77ad26..c5a9ec9e0 100644 --- a/lib/puppet/face/help/global.erb +++ b/lib/puppet/face/help/global.erb @@ -1,19 +1,19 @@ Usage: puppet [options] [options] Available subcommands, from Puppet Faces: -% Puppet::Face.faces.sort.each do |name| -% face = Puppet::Face[name, :current] +<% Puppet::Face.faces.sort.each do |name| + face = Puppet::Face[name, :current] -%> <%= face.name.to_s.ljust(16) %> <%= face.summary %> -% end +<% end -%> -% unless legacy_applications.empty? then # great victory when this is true! +<% unless legacy_applications.empty? then # great victory when this is true! -%> Available applications, soon to be ported to Faces: -% legacy_applications.each do |appname| -% summary = horribly_extract_summary_from appname +<% legacy_applications.each do |appname| + summary = horribly_extract_summary_from appname -%> <%= appname.to_s.ljust(16) %> <%= summary %> -% end -% end +<% end + end -%> See 'puppet help ' for help on a specific subcommand action. See 'puppet help ' for help on a specific subcommand. Puppet v<%= Puppet::PUPPETVERSION %> diff --git a/lib/puppet/face/help/man.erb b/lib/puppet/face/help/man.erb new file mode 100644 index 000000000..6f21fe413 --- /dev/null +++ b/lib/puppet/face/help/man.erb @@ -0,0 +1,132 @@ +puppet-<%= face.name %>(8) -- <%= face.summary || "Unknown face." %> +<%= '=' * (_erbout.length - 1) %> + +<% if face.synopsis -%> +SYNOPSIS +-------- +<%= face.synopsis %> + +<% end + if face.description -%> +DESCRIPTION +----------- +<%= face.description.strip %> + +<% end -%> +OPTIONS +------- +Note that any configuration parameter that's valid in the configuration +file is also a valid long argument, although it may or may not be +relevant to the present action. For example, `server` is a valid +configuration parameter, so you can specify `--server ` as +an argument. + +See the configuration file documentation at + for the +full list of acceptable parameters. A commented list of all +configuration options can also be generated by running puppet with +`--genconfig`. + +* --mode MODE: + The run mode to use for the current action. Valid modes are `user`, `agent`, + and `master`. +* --render-as FORMAT: + The format in which to render output. The most common formats are `json`, + `s` (string), and `yaml`, but other options such as `dot` are + sometimes available. +* --verbose: + Whether to log verbosely. +* --debug: + Whether to log debug information. +<% unless face.options.empty? + face.options.sort.each do |name| + option = face.get_option name -%> +<%= "* " + option.optparse.join(" | " ) %>: +<%= option.description.gsub(/^/, ' ') || ' ' + option.summary %> +<% end + end -%> + +ACTIONS +------- +<% face.actions.each do |actionname| + action = face.get_action(actionname) -%> +* `<%= action.name.to_s %>` - <%= action.summary %>: +<% if action.synopsis -%> + `SYNOPSIS` + + <%= action.synopsis %> + +<% end -%> +<% if action.description -%> + `DESCRIPTION` + +<%= action.description.gsub(/^/, ' ') %> +<% end + unique_options = action.options - face.options + unless unique_options.empty? -%> + `OPTIONS` + +<% unique_options.sort.each do |name| + option = action.get_option name + text = option.description || option.summary -%> + <%= '<' + option.optparse.join("> | <") + '>' %> - +<%= text.gsub(/^/, ' ') %> +<% end -%> + +<% end -%> +<% if action.returns -%> + `RETURNS` + +<%= action.returns.gsub(/^/, ' ') %> + +<% end + if action.notes -%> + `NOTES` + +<%= action.notes.gsub(/^/, ' ') %> + +<% end + end + if face.examples or face.actions.any? {|actionname| face.get_action(actionname).examples} -%> +EXAMPLES +-------- +<% end + if face.examples -%> +<%= face.examples %> + +<% end + face.actions.each do |actionname| + action = face.get_action(actionname) + if action.examples -%> +`<%= action.name.to_s %>` + +<%= action.examples.strip %> +<% end + end -%> + +<% if face.notes or face.respond_to? :indirection -%> +NOTES +----- +<% if face.notes -%> +<%= face.notes.strip %> + +<% end # notes +if face.respond_to? :indirection -%> +This is an indirector face, which exposes `find`, `search`, `save`, and +`destroy` actions for an indirected subsystem of Puppet. Valid termini +for this face include: + +* `<%= face.class.terminus_classes(face.indirection.name).join("`\n* `") %>` + +<% end # indirection + end # notes or indirection + unless face.authors.empty? -%> +AUTHOR +------ +<%= face.authors.join("\n").gsub(/^/, ' * ') %> + +<% end -%> +COPYRIGHT AND LICENSE +--------------------- +<%= face.copyright %> +<%= face.license %>