Mercurial > hg
comparison doc/gendoc.py @ 41004:e10641c48fa7
py3: byteify gendoc.py
This is mostly b'' prefixing, with some cargoculting of help.py to get around
`textwrap.dedent()` and __doc__ string requirements.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Tue, 18 Dec 2018 21:17:27 -0500 |
parents | fabbf9310025 |
children | c0865f3da285 |
comparison
equal
deleted
inserted
replaced
41003:87c98ffbc8c7 | 41004:e10641c48fa7 |
---|---|
8 | 8 |
9 import os | 9 import os |
10 import sys | 10 import sys |
11 import textwrap | 11 import textwrap |
12 | 12 |
13 try: | |
14 import msvcrt | |
15 msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) | |
16 msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY) | |
17 except ImportError: | |
18 pass | |
19 | |
13 # This script is executed during installs and may not have C extensions | 20 # This script is executed during installs and may not have C extensions |
14 # available. Relax C module requirements. | 21 # available. Relax C module requirements. |
15 os.environ['HGMODULEPOLICY'] = 'allow' | 22 os.environ[r'HGMODULEPOLICY'] = r'allow' |
16 # import from the live mercurial repo | 23 # import from the live mercurial repo |
17 sys.path.insert(0, "..") | 24 sys.path.insert(0, r"..") |
18 from mercurial import demandimport; demandimport.enable() | 25 from mercurial import demandimport; demandimport.enable() |
19 # Load util so that the locale path is set by i18n.setdatapath() before | 26 # Load util so that the locale path is set by i18n.setdatapath() before |
20 # calling _(). | 27 # calling _(). |
21 from mercurial import util | 28 from mercurial import util |
22 util.datapath | 29 util.datapath |
23 from mercurial import ( | 30 from mercurial import ( |
24 commands, | 31 commands, |
25 extensions, | 32 extensions, |
26 help, | 33 help, |
27 minirst, | 34 minirst, |
35 pycompat, | |
28 ui as uimod, | 36 ui as uimod, |
29 ) | 37 ) |
30 from mercurial.i18n import ( | 38 from mercurial.i18n import ( |
31 gettext, | 39 gettext, |
32 _, | 40 _, |
37 helptable = help.helptable | 45 helptable = help.helptable |
38 loaddoc = help.loaddoc | 46 loaddoc = help.loaddoc |
39 | 47 |
40 def get_desc(docstr): | 48 def get_desc(docstr): |
41 if not docstr: | 49 if not docstr: |
42 return "", "" | 50 return b"", b"" |
43 # sanitize | 51 # sanitize |
44 docstr = docstr.strip("\n") | 52 docstr = docstr.strip(b"\n") |
45 docstr = docstr.rstrip() | 53 docstr = docstr.rstrip() |
46 shortdesc = docstr.splitlines()[0].strip() | 54 shortdesc = docstr.splitlines()[0].strip() |
47 | 55 |
48 i = docstr.find("\n") | 56 i = docstr.find(b"\n") |
49 if i != -1: | 57 if i != -1: |
50 desc = docstr[i + 2:] | 58 desc = docstr[i + 2:] |
51 else: | 59 else: |
52 desc = shortdesc | 60 desc = shortdesc |
53 | 61 |
54 desc = textwrap.dedent(desc) | 62 desc = textwrap.dedent(desc.decode('latin1')).encode('latin1') |
55 | 63 |
56 return (shortdesc, desc) | 64 return (shortdesc, desc) |
57 | 65 |
58 def get_opts(opts): | 66 def get_opts(opts): |
59 for opt in opts: | 67 for opt in opts: |
60 if len(opt) == 5: | 68 if len(opt) == 5: |
61 shortopt, longopt, default, desc, optlabel = opt | 69 shortopt, longopt, default, desc, optlabel = opt |
62 else: | 70 else: |
63 shortopt, longopt, default, desc = opt | 71 shortopt, longopt, default, desc = opt |
64 optlabel = _("VALUE") | 72 optlabel = _(b"VALUE") |
65 allopts = [] | 73 allopts = [] |
66 if shortopt: | 74 if shortopt: |
67 allopts.append("-%s" % shortopt) | 75 allopts.append(b"-%s" % shortopt) |
68 if longopt: | 76 if longopt: |
69 allopts.append("--%s" % longopt) | 77 allopts.append(b"--%s" % longopt) |
70 if isinstance(default, list): | 78 if isinstance(default, list): |
71 allopts[-1] += " <%s[+]>" % optlabel | 79 allopts[-1] += b" <%s[+]>" % optlabel |
72 elif (default is not None) and not isinstance(default, bool): | 80 elif (default is not None) and not isinstance(default, bool): |
73 allopts[-1] += " <%s>" % optlabel | 81 allopts[-1] += b" <%s>" % optlabel |
74 if '\n' in desc: | 82 if b'\n' in desc: |
75 # only remove line breaks and indentation | 83 # only remove line breaks and indentation |
76 desc = ' '.join(l.lstrip() for l in desc.split('\n')) | 84 desc = b' '.join(l.lstrip() for l in desc.split(b'\n')) |
77 desc += default and _(" (default: %s)") % default or "" | 85 desc += default and _(b" (default: %s)") % bytes(default) or b"" |
78 yield (", ".join(allopts), desc) | 86 yield (b", ".join(allopts), desc) |
79 | 87 |
80 def get_cmd(cmd, cmdtable): | 88 def get_cmd(cmd, cmdtable): |
81 d = {} | 89 d = {} |
82 attr = cmdtable[cmd] | 90 attr = cmdtable[cmd] |
83 cmds = cmd.lstrip("^").split("|") | 91 cmds = cmd.lstrip(b"^").split(b"|") |
84 | 92 |
85 d['cmd'] = cmds[0] | 93 d[b'cmd'] = cmds[0] |
86 d['aliases'] = cmd.split("|")[1:] | 94 d[b'aliases'] = cmd.split(b"|")[1:] |
87 d['desc'] = get_desc(gettext(attr[0].__doc__)) | 95 d[b'desc'] = get_desc(gettext(pycompat.getdoc(attr[0]))) |
88 d['opts'] = list(get_opts(attr[1])) | 96 d[b'opts'] = list(get_opts(attr[1])) |
89 | 97 |
90 s = 'hg ' + cmds[0] | 98 s = b'hg ' + cmds[0] |
91 if len(attr) > 2: | 99 if len(attr) > 2: |
92 if not attr[2].startswith('hg'): | 100 if not attr[2].startswith(b'hg'): |
93 s += ' ' + attr[2] | 101 s += b' ' + attr[2] |
94 else: | 102 else: |
95 s = attr[2] | 103 s = attr[2] |
96 d['synopsis'] = s.strip() | 104 d[b'synopsis'] = s.strip() |
97 | 105 |
98 return d | 106 return d |
99 | 107 |
100 def showdoc(ui): | 108 def showdoc(ui): |
101 # print options | 109 # print options |
102 ui.write(minirst.section(_("Options"))) | 110 ui.write(minirst.section(_(b"Options"))) |
103 multioccur = False | 111 multioccur = False |
104 for optstr, desc in get_opts(globalopts): | 112 for optstr, desc in get_opts(globalopts): |
105 ui.write("%s\n %s\n\n" % (optstr, desc)) | 113 ui.write(b"%s\n %s\n\n" % (optstr, desc)) |
106 if optstr.endswith("[+]>"): | 114 if optstr.endswith(b"[+]>"): |
107 multioccur = True | 115 multioccur = True |
108 if multioccur: | 116 if multioccur: |
109 ui.write(_("\n[+] marked option can be specified multiple times\n")) | 117 ui.write(_(b"\n[+] marked option can be specified multiple times\n")) |
110 ui.write("\n") | 118 ui.write(b"\n") |
111 | 119 |
112 # print cmds | 120 # print cmds |
113 ui.write(minirst.section(_("Commands"))) | 121 ui.write(minirst.section(_(b"Commands"))) |
114 commandprinter(ui, table, minirst.subsection) | 122 commandprinter(ui, table, minirst.subsection) |
115 | 123 |
116 # print help topics | 124 # print help topics |
117 # The config help topic is included in the hgrc.5 man page. | 125 # The config help topic is included in the hgrc.5 man page. |
118 helpprinter(ui, helptable, minirst.section, exclude=['config']) | 126 helpprinter(ui, helptable, minirst.section, exclude=[b'config']) |
119 | 127 |
120 ui.write(minirst.section(_("Extensions"))) | 128 ui.write(minirst.section(_(b"Extensions"))) |
121 ui.write(_("This section contains help for extensions that are " | 129 ui.write(_(b"This section contains help for extensions that are " |
122 "distributed together with Mercurial. Help for other " | 130 b"distributed together with Mercurial. Help for other " |
123 "extensions is available in the help system.")) | 131 b"extensions is available in the help system.")) |
124 ui.write(("\n\n" | 132 ui.write((b"\n\n" |
125 ".. contents::\n" | 133 b".. contents::\n" |
126 " :class: htmlonly\n" | 134 b" :class: htmlonly\n" |
127 " :local:\n" | 135 b" :local:\n" |
128 " :depth: 1\n\n")) | 136 b" :depth: 1\n\n")) |
129 | 137 |
130 for extensionname in sorted(allextensionnames()): | 138 for extensionname in sorted(allextensionnames()): |
131 mod = extensions.load(ui, extensionname, None) | 139 mod = extensions.load(ui, extensionname, None) |
132 ui.write(minirst.subsection(extensionname)) | 140 ui.write(minirst.subsection(extensionname)) |
133 ui.write("%s\n\n" % gettext(mod.__doc__)) | 141 ui.write(b"%s\n\n" % gettext(pycompat.getdoc(mod))) |
134 cmdtable = getattr(mod, 'cmdtable', None) | 142 cmdtable = getattr(mod, 'cmdtable', None) |
135 if cmdtable: | 143 if cmdtable: |
136 ui.write(minirst.subsubsection(_('Commands'))) | 144 ui.write(minirst.subsubsection(_(b'Commands'))) |
137 commandprinter(ui, cmdtable, minirst.subsubsubsection) | 145 commandprinter(ui, cmdtable, minirst.subsubsubsection) |
138 | 146 |
139 def showtopic(ui, topic): | 147 def showtopic(ui, topic): |
140 extrahelptable = [ | 148 extrahelptable = [ |
141 (["common"], '', loaddoc('common'), help.TOPIC_CATEGORY_MISC), | 149 ([b"common"], b'', loaddoc(b'common'), help.TOPIC_CATEGORY_MISC), |
142 (["hg.1"], '', loaddoc('hg.1'), help.TOPIC_CATEGORY_CONFIG), | 150 ([b"hg.1"], b'', loaddoc(b'hg.1'), help.TOPIC_CATEGORY_CONFIG), |
143 (["hg-ssh.8"], '', loaddoc('hg-ssh.8'), help.TOPIC_CATEGORY_CONFIG), | 151 ([b"hg-ssh.8"], b'', loaddoc(b'hg-ssh.8'), help.TOPIC_CATEGORY_CONFIG), |
144 (["hgignore.5"], '', loaddoc('hgignore.5'), help.TOPIC_CATEGORY_CONFIG), | 152 ([b"hgignore.5"], b'', loaddoc(b'hgignore.5'), |
145 (["hgrc.5"], '', loaddoc('hgrc.5'), help.TOPIC_CATEGORY_CONFIG), | |
146 (["hgignore.5.gendoc"], '', loaddoc('hgignore'), | |
147 help.TOPIC_CATEGORY_CONFIG), | 153 help.TOPIC_CATEGORY_CONFIG), |
148 (["hgrc.5.gendoc"], '', loaddoc('config'), help.TOPIC_CATEGORY_CONFIG), | 154 ([b"hgrc.5"], b'', loaddoc(b'hgrc.5'), help.TOPIC_CATEGORY_CONFIG), |
155 ([b"hgignore.5.gendoc"], b'', loaddoc(b'hgignore'), | |
156 help.TOPIC_CATEGORY_CONFIG), | |
157 ([b"hgrc.5.gendoc"], b'', loaddoc(b'config'), | |
158 help.TOPIC_CATEGORY_CONFIG), | |
149 ] | 159 ] |
150 helpprinter(ui, helptable + extrahelptable, None, include=[topic]) | 160 helpprinter(ui, helptable + extrahelptable, None, include=[topic]) |
151 | 161 |
152 def helpprinter(ui, helptable, sectionfunc, include=[], exclude=[]): | 162 def helpprinter(ui, helptable, sectionfunc, include=[], exclude=[]): |
153 for h in helptable: | 163 for h in helptable: |
155 if exclude and names[0] in exclude: | 165 if exclude and names[0] in exclude: |
156 continue | 166 continue |
157 if include and names[0] not in include: | 167 if include and names[0] not in include: |
158 continue | 168 continue |
159 for name in names: | 169 for name in names: |
160 ui.write(".. _%s:\n" % name) | 170 ui.write(b".. _%s:\n" % name) |
161 ui.write("\n") | 171 ui.write(b"\n") |
162 if sectionfunc: | 172 if sectionfunc: |
163 ui.write(sectionfunc(sec)) | 173 ui.write(sectionfunc(sec)) |
164 if callable(doc): | 174 if callable(doc): |
165 doc = doc(ui) | 175 doc = doc(ui) |
166 ui.write(doc) | 176 ui.write(doc) |
167 ui.write("\n") | 177 ui.write(b"\n") |
168 | 178 |
169 def commandprinter(ui, cmdtable, sectionfunc): | 179 def commandprinter(ui, cmdtable, sectionfunc): |
170 h = {} | 180 h = {} |
171 for c, attr in cmdtable.items(): | 181 for c, attr in cmdtable.items(): |
172 f = c.split("|")[0] | 182 f = c.split(b"|")[0] |
173 f = f.lstrip("^") | 183 f = f.lstrip(b"^") |
174 h[f] = c | 184 h[f] = c |
175 cmds = h.keys() | 185 cmds = h.keys() |
176 cmds.sort() | 186 |
177 | 187 for f in sorted(cmds): |
178 for f in cmds: | 188 if f.startswith(b"debug"): |
179 if f.startswith("debug"): | |
180 continue | 189 continue |
181 d = get_cmd(h[f], cmdtable) | 190 d = get_cmd(h[f], cmdtable) |
182 ui.write(sectionfunc(d['cmd'])) | 191 ui.write(sectionfunc(d[b'cmd'])) |
183 # short description | 192 # short description |
184 ui.write(d['desc'][0]) | 193 ui.write(d[b'desc'][0]) |
185 # synopsis | 194 # synopsis |
186 ui.write("::\n\n") | 195 ui.write(b"::\n\n") |
187 synopsislines = d['synopsis'].splitlines() | 196 synopsislines = d[b'synopsis'].splitlines() |
188 for line in synopsislines: | 197 for line in synopsislines: |
189 # some commands (such as rebase) have a multi-line | 198 # some commands (such as rebase) have a multi-line |
190 # synopsis | 199 # synopsis |
191 ui.write(" %s\n" % line) | 200 ui.write(b" %s\n" % line) |
192 ui.write('\n') | 201 ui.write(b'\n') |
193 # description | 202 # description |
194 ui.write("%s\n\n" % d['desc'][1]) | 203 ui.write(b"%s\n\n" % d[b'desc'][1]) |
195 # options | 204 # options |
196 opt_output = list(d['opts']) | 205 opt_output = list(d[b'opts']) |
197 if opt_output: | 206 if opt_output: |
198 opts_len = max([len(line[0]) for line in opt_output]) | 207 opts_len = max([len(line[0]) for line in opt_output]) |
199 ui.write(_("Options:\n\n")) | 208 ui.write(_(b"Options:\n\n")) |
200 multioccur = False | 209 multioccur = False |
201 for optstr, desc in opt_output: | 210 for optstr, desc in opt_output: |
202 if desc: | 211 if desc: |
203 s = "%-*s %s" % (opts_len, optstr, desc) | 212 s = b"%-*s %s" % (opts_len, optstr, desc) |
204 else: | 213 else: |
205 s = optstr | 214 s = optstr |
206 ui.write("%s\n" % s) | 215 ui.write(b"%s\n" % s) |
207 if optstr.endswith("[+]>"): | 216 if optstr.endswith(b"[+]>"): |
208 multioccur = True | 217 multioccur = True |
209 if multioccur: | 218 if multioccur: |
210 ui.write(_("\n[+] marked option can be specified" | 219 ui.write(_(b"\n[+] marked option can be specified" |
211 " multiple times\n")) | 220 b" multiple times\n")) |
212 ui.write("\n") | 221 ui.write(b"\n") |
213 # aliases | 222 # aliases |
214 if d['aliases']: | 223 if d[b'aliases']: |
215 ui.write(_(" aliases: %s\n\n") % " ".join(d['aliases'])) | 224 ui.write(_(b" aliases: %s\n\n") % b" ".join(d[b'aliases'])) |
216 | 225 |
217 | 226 |
218 def allextensionnames(): | 227 def allextensionnames(): |
219 return extensions.enabled().keys() + extensions.disabled().keys() | 228 return set(extensions.enabled().keys()) | set(extensions.disabled().keys()) |
220 | 229 |
221 if __name__ == "__main__": | 230 if __name__ == "__main__": |
222 doc = 'hg.1.gendoc' | 231 doc = b'hg.1.gendoc' |
223 if len(sys.argv) > 1: | 232 if len(sys.argv) > 1: |
224 doc = sys.argv[1] | 233 doc = sys.argv[1] |
225 | 234 |
226 ui = uimod.ui.load() | 235 ui = uimod.ui.load() |
227 if doc == 'hg.1.gendoc': | 236 if doc == b'hg.1.gendoc': |
228 showdoc(ui) | 237 showdoc(ui) |
229 else: | 238 else: |
230 showtopic(ui, sys.argv[1]) | 239 showtopic(ui, sys.argv[1]) |