Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(PUP-12075) Render puppet man page correctly #9466

Merged
merged 2 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 43 additions & 23 deletions lib/puppet/face/help.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,33 @@ def legacy_applications
end.sort
end

def generate_summary(appname)
if is_face_app?(appname)
begin
face = Puppet::Face[appname, :current]
# Add deprecation message to summary if the face is deprecated
summary = face.deprecated? ? face.summary + ' ' + _("(Deprecated)") : face.summary
[appname, summary, ' ']
rescue StandardError, LoadError
error_message = _("!%{sub_command}! Subcommand unavailable due to error.") % { sub_command: appname }
error_message += ' ' + _("Check error logs.")
[error_message, '', ' ']
end
else
begin
summary = Puppet::Application[appname].summary
if summary.empty?
summary = horribly_extract_summary_from(appname)
end
[appname, summary, ' ']
rescue StandardError, LoadError
error_message = _("!%{sub_command}! Subcommand unavailable due to error.") % { sub_command: appname }
error_message += ' ' + _("Check error logs.")
[error_message, '', ' ']
end
end
end

# Return a list of all applications (both legacy and Face applications), along with a summary
# of their functionality.
# @return [Array] An Array of Arrays. The outer array contains one entry per application; each
Expand All @@ -162,45 +189,38 @@ def all_application_summaries

if appname == COMMON || appname == SPECIALIZED || appname == BLANK
result << appname
elsif is_face_app?(appname)
begin
face = Puppet::Face[appname, :current]
# Add deprecation message to summary if the face is deprecated
summary = face.deprecated? ? face.summary + ' ' + _("(Deprecated)") : face.summary
result << [appname, summary, ' ']
rescue StandardError, LoadError
error_message = _("!%{sub_command}! Subcommand unavailable due to error.") % { sub_command: appname }
error_message += ' ' + _("Check error logs.")
result << [error_message, '', ' ']
end
else
begin
summary = Puppet::Application[appname].summary
if summary.empty?
summary = horribly_extract_summary_from(appname)
end
result << [appname, summary, ' ']
rescue StandardError, LoadError
error_message = _("!%{sub_command}! Subcommand unavailable due to error.") % { sub_command: appname }
error_message += ' ' + _("Check error logs.")
result << [error_message, '', ' ']
end
result << generate_summary(appname)
end
end
end

COMMON = 'Common:'
SPECIALIZED = 'Specialized:'
BLANK = "\n"
COMMON_APPS = %w[apply agent config help lookup module resource]
def available_application_names_special_sort
full_list = Puppet::Application.available_application_names
a_list = full_list & %w[apply agent config help lookup module resource]
a_list = full_list & COMMON_APPS
a_list = a_list.sort
also_ran = full_list - a_list
also_ran = also_ran.sort
[[COMMON], a_list, [BLANK], [SPECIALIZED], also_ran].flatten(1)
end

def common_app_summaries
COMMON_APPS.map do |appname|
generate_summary(appname)
end
end

def specialized_app_summaries
specialized_apps = Puppet::Application.available_application_names - COMMON_APPS
specialized_apps.filter_map do |appname|
generate_summary(appname) unless exclude_from_docs?(appname)
end
end

def horribly_extract_summary_from(appname)
help = Puppet::Application[appname].help.split("\n")
# Now we find the line with our summary, extract it, and return it. This
Expand Down
2 changes: 2 additions & 0 deletions lib/puppet/reference/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
val = "the Host's fully qualified domain name, as determined by Facter"
when 'srv_domain'
val = 'example.com'
when 'http_user_agent'
val = 'Puppet/<version> Ruby/<version> (<architecture>)'
end

# Leave out the section information; it was apparently confusing people.
Expand Down
2 changes: 1 addition & 1 deletion man/man5/puppet.conf.5
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,7 @@ The time to wait for data to be read from an HTTP connection\. If nothing is rea
The HTTP User\-Agent string to send when making network requests\.
.
.IP "\(bu" 4
\fIDefault\fR: \fBPuppet/8\.9\.0 Ruby/3\.1\.1\-p18 (x86_64\-linux)\fR
\fIDefault\fR: \fBPuppet/<version> Ruby/<version> (<architecture>)\fR
.
.IP "" 0
.
Expand Down
129 changes: 121 additions & 8 deletions man/man8/puppet.8
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,138 @@
.TH "PUPPET" "8" "August 2024" "Puppet, Inc." "Puppet manual"
.
.SH "NAME"
\fBpuppet\fR
\fBpuppet\fR \- an automated configuration management tool
.
.SH "SYNOPSIS"
\fBpuppet\fR \fIsubcommand\fR [options] \fIaction\fR [options]
.
.SH "DESCRIPTION"
Puppet, an automated administrative engine for your Linux, Unix, and Windows systems, performs administrative tasks (such as adding users, installing packages, and updating server configurations) based on a centralized specification\.
.
.SH "COMMANDS"
.
.SS "Common"
\fBapply\fR
.
.br
\~\~\~\~Apply Puppet manifests locally
.
.P
\fBagent\fR
.
.br
\~\~\~\~The puppet agent daemon
.
.P
\fBconfig\fR
.
.br
\~\~\~\~Interact with Puppet\'s settings\.
.
.P
\fBhelp\fR
.
.br
\~\~\~\~Display Puppet help\.
.
.P
\fBlookup\fR
.
.br
\~\~\~\~Interactive Hiera lookup
.
.P
\fBmodule\fR
.
.br
\~\~\~\~Creates, installs and searches for modules on the Puppet Forge\.
.
.P
\fBresource\fR
.
.br
\~\~\~\~The resource abstraction layer shell
.
.SS "Specialized"
\fBcatalog\fR
.
.br
\~\~\~\~Compile, save, view, and convert catalogs\.
.
.P
\fBdescribe\fR
.
.br
\~\~\~\~Display help about resource types
.
.P
\fBdevice\fR
.
.br
\~\~\~\~Manage remote network devices
.
.P
\fBdoc\fR
.
.br
\~\~\~\~Generate Puppet references
.
.P
Usage: puppet \fIsubcommand\fR [options] \fIaction\fR [options]
\fBepp\fR
.
.br
\~\~\~\~Interact directly with the EPP template parser/renderer\.
.
.P
Available subcommands:
\fBfacts\fR
.
.br
\~\~\~\~Retrieve and store facts\.
.
.P
\fBfilebucket\fR
.
.br
\~\~\~\~Store and retrieve files in a filebucket
.
.P
Common:
\fBgenerate\fR
.
.br
agent The puppet agent daemon apply Apply Puppet manifests locally config Interact with Puppet\'s settings\. help Display Puppet help\. lookup Interactive Hiera lookup module Creates, installs and searches for modules on the Puppet Forge\. resource The resource abstraction layer shell
\~\~\~\~Generates Puppet code from Ruby definitions\.
.
.P
Specialized:
\fBnode\fR
.
.br
catalog Compile, save, view, and convert catalogs\. describe Display help about resource types device Manage remote network devices doc Generate Puppet references epp Interact directly with the EPP template parser/renderer\. facts Retrieve and store facts\. filebucket Store and retrieve files in a filebucket generate Generates Puppet code from Ruby definitions\. node View and manage node definitions\. parser Interact directly with the parser\. plugin Interact with the Puppet plugin system\. script Run a puppet manifests as a script without compiling a catalog ssl Manage SSL keys and certificates for puppet SSL clients
\~\~\~\~View and manage node definitions\.
.
.P
\fBparser\fR
.
.br
\~\~\~\~Interact directly with the parser\.
.
.P
\fBplugin\fR
.
.br
\~\~\~\~Interact with the Puppet plugin system\.
.
.P
\fBscript\fR
.
.br
\~\~\~\~Run a puppet manifests as a script without compiling a catalog
.
.P
\fBssl\fR
.
.br
\~\~\~\~Manage SSL keys and certificates for puppet SSL clients
.
.SH "SEE ALSO"
See \fBpuppet help <subcommand>\fR for help on a specific subcommand\.
.
.P
See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v8\.9\.0
See \fBpuppet help <subcommand> <action>\fR for help on a specific subcommand action\.
34 changes: 34 additions & 0 deletions rakelib/man/puppet.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
puppet(8) - an automated configuration management tool
=========

## SYNOPSIS

`puppet` <subcommand> [options] <action> [options]

## DESCRIPTION

Puppet, an automated administrative engine for your Linux, Unix, and Windows systems, performs administrative tasks
(such as adding users, installing packages, and updating server configurations) based on a centralized specification.

## COMMANDS

### Common

<% common.each do |appname, summary, _| -%>
`<%= appname.to_s %>`<br>
&nbsp;&nbsp;&nbsp;&nbsp;<%= summary %>

<% end -%>

### Specialized

<% specialized.each do |appname, summary, _| -%>
`<%= appname.to_s %>`<br>
&nbsp;&nbsp;&nbsp;&nbsp;<%= summary %>

<% end -%>

## SEE ALSO
See `puppet help <subcommand>` for help on a specific subcommand.

See `puppet help <subcommand> <action>` for help on a specific subcommand action.
24 changes: 16 additions & 8 deletions rakelib/manpages.rake
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ task :gen_manpages do
Puppet.initialize_settings
helpface = Puppet::Face[:help, '0.0.1']

bins = Dir.glob(%w{bin/*})
non_face_applications = helpface.legacy_applications
faces = Puppet::Face.faces.map(&:to_s)
apps = non_face_applications + faces
Expand All @@ -30,19 +29,28 @@ task :gen_manpages do
abort("Ronn does not appear to be installed")
end

# ronn shells out to groff
groff = %x{which groff}.chomp
unless File.executable?(groff)
abort("Groff does not appear to be installed")
end

%x{mkdir -p ./man/man5 ./man/man8}
%x{RUBYLIB=./lib:$RUBYLIB bin/puppet doc --reference configuration > ./man/man5/puppetconf.5.ronn}
%x{#{ronn} #{ronn_args} ./man/man5/puppetconf.5.ronn}
FileUtils.mv("./man/man5/puppetconf.5", "./man/man5/puppet.conf.5")
FileUtils.rm("./man/man5/puppetconf.5.ronn")

# Create LEGACY binary man pages (i.e. delete me for 2.8.0)
bins.each do |bin|
b = bin.gsub( /^s?bin\//, "")
%x{RUBYLIB=./lib:$RUBYLIB #{bin} --help > ./man/man8/#{b}.8.ronn}
%x{#{ronn} #{ronn_args} ./man/man8/#{b}.8.ronn}
FileUtils.rm("./man/man8/#{b}.8.ronn")
end
# Create puppet binary man page
# puppet --help outputs raw text, not ronn, so trying to convert that to roff
# fails miserably. Render valid ronn so we can convert to roff
common = helpface.common_app_summaries
specialized = helpface.specialized_app_summaries
template_binding = OpenStruct.new(common: common, specialized: specialized).instance_eval {binding}
content = ERB.new(File.read(File.join(__dir__, 'man/puppet.erb')), trim_mode: '-').result(template_binding)
File.write("./man/man8/puppet.8.ronn", content)
%x{#{ronn} #{ronn_args} ./man/man8/puppet.8.ronn}
FileUtils.rm("./man/man8/puppet.8.ronn")

apps.each do |app|
%x{RUBYLIB=./lib:$RUBYLIB bin/puppet help #{app} --ronn > ./man/man8/puppet-#{app}.8.ronn}
Expand Down