summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am18
-rwxr-xr-xsrc/fedpkg.py15
-rw-r--r--src/pyfedpkg/man_page.py162
3 files changed, 192 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am
index 4df6dbb..506ad96 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -79,7 +79,23 @@ ppc-koji: $(srcdir)/src/secondary-koji
rm -f ppc-koji
install -p -m 755 -T $(srcdir)/src/secondary-koji ppc-koji
-pyfedpkg_PYTHON = $(wildcard $(srcdir)/src/pyfedpkg/*.py)
+if HAVE_PYTHON
+CLEANFILES += fedpkg.1
+man1_MANS = fedpkg.1
+fedpkg.1: fedpkg
+ tmpfile="fedpkg.1.$$$$"; \
+ if env PYTHONPATH=$(srcdir)/src python -c 'import fedpkg; fedpkg.parse_cmdline(True)' > "$$tmpfile"; then \
+ mv -f "$$tmpfile" "$@"; \
+ else \
+ rm -f "$$tmpfile"; \
+ s="$$?"; \
+ echo "Error generating man page: $$s"; \
+ exit "$$s"; \
+ fi
+endif
+
+noinst_PYTHON = $(srcdir)/src/pyfedpkg/man_page.py
+pyfedpkg_PYTHON = $(filter-out $(noinst_PYTHON),$(wildcard $(srcdir)/src/pyfedpkg/*.py))
fedora_cert_PYTHON = $(wildcard $(srcdir)/src/fedora_cert/*.py)
fedora_certdir = $(pythondir)/fedora_cert
diff --git a/src/fedpkg.py b/src/fedpkg.py
index 4e7344b..e3e98a5 100755
--- a/src/fedpkg.py
+++ b/src/fedpkg.py
@@ -1230,8 +1230,19 @@ packages will be built sequentially.
' name-version-release')
parser_verrel.set_defaults(command = verrel)
- # Parse the args
- return parser.parse_args()
+ if not generate_manpage:
+ # Parse the args
+ return parser.parse_args()
+ else:
+ # Generate the man page
+
+ # Use the "as man_page" part to avoid overwriting the pyfedpkg
+ # namespace, which would break all usage of pyfedpkg.* outside
+ # of this else branch.
+ import pyfedpkg.man_page as man_page
+ man_page.generate(parser, subparsers)
+ sys.exit(0)
+ # no return possible
# The main code goes here
diff --git a/src/pyfedpkg/man_page.py b/src/pyfedpkg/man_page.py
new file mode 100644
index 0000000..47285f2
--- /dev/null
+++ b/src/pyfedpkg/man_page.py
@@ -0,0 +1,162 @@
+# Print a man page from the help texts.
+
+
+import argparse
+import sys
+import datetime
+
+
+# We could substitute the "" in .TH with the fedpkg version if we knew it
+man_header = """\
+.\" man page for fedpkg
+.TH fedpkg 1 "%(today)s" "" "fedora\-packager"
+.SH "NAME"
+fedpkg \- Fedora Packaging utility
+.SH "SYNOPSIS"
+.B "fedpkg"
+[
+.I global_options
+]
+.I "command"
+[
+.I command_options
+]
+[
+.I command_arguments
+]
+.br
+.B "fedpkg"
+.B "help"
+.br
+.B "fedpkg"
+.I "command"
+.B "\-\-help"
+.SH "DESCRIPTION"
+.B "fedpkg"
+is a script to interact with the Fedora Packaging system.
+"""
+
+man_footer = """\
+.SH "SEE ALSO"
+.UR "https://fedorahosted.org/fedora\-packager/"
+.BR "https://fedorahosted.org/fedora\-packager/"
+"""
+
+class ManFormatter(object):
+
+ def __init__(self, man):
+ self.man = man
+
+ def write(self, data):
+ #print "MF:", repr(data)
+ for line in data.split('\n'):
+ #print 'MFL:', line
+ self.man.write(' %s\n' % line)
+
+
+def strip_usage(s):
+ """Strip "usage: " string from beginning of string if present"""
+ if s.startswith('usage: '):
+ return s.replace('usage: ', '', 1)
+ else:
+ return s
+
+
+def man_constants():
+ """Global constants for man file templates"""
+ today = datetime.date.today()
+ today_manstr = today.strftime('%Y\-%m\-%d')
+ return {'today': today_manstr}
+
+
+def generate(parser, subparsers):
+ """\
+ Generate the man page on stdout
+
+ Given the argparse based parser and subparsers arguments, generate
+ the corresponding man page and write it to stdout.
+ """
+
+ # Not nice, but works: Redirect any print statement output to
+ # stderr to avoid clobbering the man page output on stdout.
+ man_file = sys.stdout
+ sys.stdout = sys.stderr
+
+ mf = ManFormatter(man_file)
+
+ choices = subparsers.choices
+ k = choices.keys()
+ k.sort()
+
+ man_file.write(man_header % man_constants())
+
+ helptext = parser.format_help()
+ helptext = strip_usage(helptext)
+ helptextsplit = helptext.split('\n')
+ helptextsplit = [ line for line in helptextsplit
+ if not line.startswith(' -h, --help') ]
+
+ man_file.write('.SS "%s"\n' % ("Global Options",))
+
+ outflag = False
+ for line in helptextsplit:
+ if line == "optional arguments:":
+ outflag = True
+ elif line == "":
+ outflag = False
+ elif outflag:
+ man_file.write("%s\n" % line)
+
+ help_texts = {}
+ for pa in subparsers._choices_actions:
+ help_texts[pa.dest] = getattr(pa, 'help', None)
+
+ if True: # Either kill THIS
+ # determine length of longest command and generate format string
+ commands = help_texts.keys()
+ commands.sort(lambda a,b: cmp(len(b), len(a)))
+ max_cmdlen = len(commands[0])
+ fmtstring = ' %%-%ds %%s\n' % (max_cmdlen,)
+
+ man_file.write('.SS "Commands"\n')
+
+ for command in k:
+ cmdparser = choices[command]
+ if not cmdparser.add_help:
+ continue
+ man_file.write(fmtstring % (command, help_texts[command]))
+
+ if True: # Or kill THIS
+ man_file.write('.SH "COMMAND OVERVIEW"\n')
+
+ for command in k:
+ cmdparser = choices[command]
+ if not cmdparser.add_help:
+ continue
+ usage = cmdparser.format_usage()
+ usage = strip_usage(usage)
+ usage = ''.join(usage.split('\n'))
+ usage = ' '.join(usage.split())
+ if help_texts[command]:
+ man_file.write('.TP\n.B "%s"\n%s\n' % (usage, help_texts[command]))
+ else:
+ man_file.write('.TP\n.B "%s"\n' % (usage))
+
+ man_file.write('.SH "COMMAND REFERENCE"\n')
+ for command in k:
+ cmdparser = choices[command]
+ if not cmdparser.add_help:
+ continue
+
+ man_file.write('.SS "%s"\n' % cmdparser.prog)
+
+ help = help_texts[command]
+ if help and not cmdparser.description:
+ if not help.endswith('.'): help = "%s." % help
+ cmdparser.description = help
+
+ formatter = cmdparser.formatter_class(cmdparser.prog)
+ h = cmdparser.format_help()
+ mf.write(h)
+
+ man_file.write(man_footer)