Gentoo Archives: gentoo-commits

From: "Mike Frysinger (vapier)" <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-projects commit in portage-utils/man: mkman.py mkman.sh
Date: Sun, 29 Sep 2013 22:12:55
Message-Id: 20130929221251.74BA62004E@flycatcher.gentoo.org
1 vapier 13/09/29 22:12:51
2
3 Added: mkman.py
4 Removed: mkman.sh
5 Log:
6 man: rewrite helper script in python to avoid `help2man` as that tends to mangle things
7
8 Revision Changes Path
9 1.1 portage-utils/man/mkman.py
10
11 file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/man/mkman.py?rev=1.1&view=markup
12 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/man/mkman.py?rev=1.1&content-type=text/plain
13
14 Index: mkman.py
15 ===================================================================
16 #!/usr/bin/python
17
18 """Generate man pages for the q applets"""
19
20 from __future__ import print_function
21
22 import datetime
23 import functools
24 import glob
25 import locale
26 import multiprocessing
27 import os
28 import re
29 import subprocess
30 import sys
31
32
33 MKMAN_DIR = os.path.realpath(os.path.join(__file__, '..'))
34 FRAGS_DIR = os.path.join(MKMAN_DIR, 'include')
35
36 TOPDIR = os.path.join(MKMAN_DIR, '..')
37 Q = os.path.join(TOPDIR, 'q')
38
39
40 def FindApplets():
41 """Return a list of all supported applets"""
42 applets = os.path.join(TOPDIR, 'applets.sh')
43 return subprocess.check_output([applets]).splitlines()
44
45
46 COMMON_AUTHORS = [
47 'Ned Ludd <solar@g.o>',
48 'Mike Frysinger <vapier@g.o>',
49 ]
50 TEMPLATE = r""".TH %(applet)s "1" "%(date)s" "Gentoo Foundation" "%(applet)s"
51 .SH NAME
52 %(applet)s \- %(short_desc)s
53 .SH SYNOPSIS
54 .B %(applet)s
55 \fI%(usage)s\fR
56 .SH DESCRIPTION
57 %(description)s
58 .SH OPTIONS
59 %(options)s
60 %(extra_sections)s
61 .SH "REPORTING BUGS"
62 Please report bugs via http://bugs.gentoo.org/
63 .br
64 Product: Portage Development; Component: Tools
65 .SH AUTHORS
66 .nf
67 %(authors)s
68 .fi
69 .SH "SEE ALSO"
70 %(see_also)s
71 """
72
73 def MkMan(applets, applet, output):
74 """Generate a man page for |applet| and write it to |output|"""
75 print('%-10s: generating %s' % (applet, output))
76
77 # Extract the main use string and description:
78 # Usage: q <applet> <args> : invoke a portage utility applet
79 ahelp = subprocess.check_output([Q, applet, '--help'])
80 lines = ahelp.splitlines()
81 m = re.search(r'^Usage: %s (.*) : (.*)' % applet, ahelp)
82 usage = m.group(1)
83 short_desc = m.group(2)
84
85 authors = COMMON_AUTHORS
86 see_also = sorted(['.BR %s (1)' % x for x in applets if x != applet])
87
88 description = ''
89 desc_file = os.path.join(FRAGS_DIR, '%s.desc' % applet)
90 if os.path.exists(desc_file):
91 description = open(desc_file).read().rstrip()
92
93 # Extract all the options
94 options = []
95 for line, i in zip(lines, xrange(len(lines))):
96 if not line.startswith('Options: '):
97 continue
98
99 for option in [x.strip().split() for x in lines[i + 1:]]:
100 flags = [option[0].rstrip(',')]
101 option.pop(0)
102 if option[0][0] == '-':
103 flags += [option[0].rstrip(',')]
104 option.pop(0)
105
106 if option[0] == '<arg>':
107 flags = [r'\fB%s\fR \fI<arg>\fR' % x for x in flags]
108 option.pop(0)
109 else:
110 flags = [r'\fB%s\fR' % x for x in flags]
111
112 assert option[0] == '*', 'help line for %s is broken: %r' % (applet, option)
113 option.pop(0)
114
115 options += [
116 '.TP',
117 ', '.join(flags).replace('-', r'\-'),
118 ' '.join(option),
119 ]
120 break
121
122 # Handle applets that have applets
123 extra_sections = []
124 if 'Currently defined applets:' in ahelp:
125 alines = lines[lines.index('Currently defined applets:') + 1:]
126 alines = alines[:alines.index('')]
127 extra_sections += (
128 ['.SH APPLETS', '.nf',
129 '.B This applet also has sub applets:'] +
130 alines +
131 ['.fi']
132 )
133
134 # Handle any fragments this applet has available
135 for frag in sorted(glob.glob(os.path.join(FRAGS_DIR, '%s-*.include' % applet))):
136 with open(frag) as f:
137 extra_sections += [x.rstrip() for x in f.readlines()]
138
139 data = {
140 'applet': applet,
141 'date': datetime.datetime.now().strftime('%b %Y'),
142 'short_desc': short_desc,
143 'usage': usage,
144 'description': description,
145 'options': '\n'.join(options),
146 'extra_sections': '\n'.join(extra_sections),
147 'authors': '\n'.join(authors),
148 'see_also': ',\n'.join(see_also),
149 'rcsid': '',
150 }
151 with open(output, 'w') as f:
152 f.write(TEMPLATE % data)
153
154
155 def _MkMan(applets, applet):
156 """Trampoline to MkMan for multiprocessing pickle"""
157 output = os.path.join(MKMAN_DIR, '%s.1' % applet)
158 MkMan(applets, applet, output)
159
160
161 def main(argv):
162 os.environ['NOCOLOR'] = '1'
163
164 if not argv:
165 argv = FindApplets()
166 # Support file completion like "qfile.1" or "./qdepends.1"
167 applets = [os.path.basename(x).split('.', 1)[0] for x in argv]
168
169 p = multiprocessing.Pool()
170 functor = functools.partial(_MkMan, applets)
171 p.map(functor, applets)
172
173
174 if __name__ == '__main__':
175 sys.exit(main(sys.argv[1:]))