##// END OF EJS Templates
posix: always seek to EOF when opening a file in append mode...
posix: always seek to EOF when opening a file in append mode Python 3 already does this, so skip it there. Consider the program: #include <stdio.h> int main() { FILE *f = fopen("narf", "w"); fprintf(f, "narf\n"); fclose(f); f = fopen("narf", "a"); printf("%ld\n", ftell(f)); fprintf(f, "troz\n"); printf("%ld\n", ftell(f)); return 0; } on macOS, FreeBSD, and Linux with glibc, this program prints 5 10 but on musl libc (Alpine Linux and probably others) this prints 0 10 By my reading of https://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html this is technically correct, specifically: > Opening a file with append mode (a as the first character in the > mode argument) shall cause all subsequent writes to the file to be > forced to the then current end-of-file, regardless of intervening > calls to fseek(). in other words, the file position doesn't really matter in append-mode files, and we can't depend on it being at all meaningful unless we perform a seek() before tell() after open(..., 'a'). Experimentally after a .write() we can do a .tell() and it'll always be reasonable, but I'm unclear from reading the specification if that's a smart thing to rely on. This matches what we do on Windows and what Python 3 does for free, so let's just be consistent. Thanks to Yuya for the idea.

File last commit:

r42438:a42cc325 default
r42778:97ada9b8 5.0.2 stable
Show More
gendoc.py
240 lines | 7.2 KiB | text/x-python | PythonLexer
timeless
doc: add execute bit and fix shbang line for gendoc.py
r27496 #!/usr/bin/env python
Takumi IINO
gendoc: dispatch print document content by commandline arguments...
r19425 """usage: %s DOC ...
where DOC is the name of a document
"""
Pulkit Goyal
py3: make gendoc use absolute_import...
r28966 from __future__ import absolute_import
import os
import sys
import textwrap
Gregory Szorc
doc: make gendoc.py module import policy aware...
r27330
Matt Harbison
py3: byteify gendoc.py...
r41040 try:
import msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
except ImportError:
pass
Gregory Szorc
doc: make gendoc.py module import policy aware...
r27330 # This script is executed during installs and may not have C extensions
# available. Relax C module requirements.
Matt Harbison
py3: byteify gendoc.py...
r41040 os.environ[r'HGMODULEPOLICY'] = r'allow'
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 # import from the live mercurial repo
Matt Harbison
py3: byteify gendoc.py...
r41040 sys.path.insert(0, r"..")
Matt Mackall
gendoc: use demandimport
r5209 from mercurial import demandimport; demandimport.enable()
Yuya Nishihara
gendoc: make sure locale path is set before loading any modules...
r32336 # Load util so that the locale path is set by i18n.setdatapath() before
# calling _().
from mercurial import util
util.datapath
Pulkit Goyal
py3: make gendoc use absolute_import...
r28966 from mercurial import (
commands,
Matt Harbison
py3: byteify sys.argv in gendoc.py
r41059 encoding,
Pulkit Goyal
py3: make gendoc use absolute_import...
r28966 extensions,
help,
minirst,
Matt Harbison
py3: byteify gendoc.py...
r41040 pycompat,
Pulkit Goyal
py3: make gendoc use absolute_import...
r28966 ui as uimod,
)
from mercurial.i18n import (
gettext,
_,
)
table = commands.table
globalopts = commands.globalopts
helptable = help.helptable
loaddoc = help.loaddoc
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814
def get_desc(docstr):
if not docstr:
Matt Harbison
py3: byteify gendoc.py...
r41040 return b"", b""
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 # sanitize
Matt Harbison
py3: byteify gendoc.py...
r41040 docstr = docstr.strip(b"\n")
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 docstr = docstr.rstrip()
shortdesc = docstr.splitlines()[0].strip()
Matt Harbison
py3: byteify gendoc.py...
r41040 i = docstr.find(b"\n")
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 if i != -1:
Matt Mackall
many, many trivial check-code fixups
r10282 desc = docstr[i + 2:]
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 else:
Erik Zielke
gendoc: dedent documentation from docstrings...
r12780 desc = shortdesc
Matt Harbison
py3: byteify gendoc.py...
r41040 desc = textwrap.dedent(desc.decode('latin1')).encode('latin1')
Erik Zielke
gendoc: dedent documentation from docstrings...
r12780
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 return (shortdesc, desc)
def get_opts(opts):
FUJIWARA Katsunori
help: show value requirement and multiple occurrence of options...
r11321 for opt in opts:
if len(opt) == 5:
shortopt, longopt, default, desc, optlabel = opt
else:
shortopt, longopt, default, desc = opt
Matt Harbison
py3: byteify gendoc.py...
r41040 optlabel = _(b"VALUE")
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 allopts = []
if shortopt:
Matt Harbison
py3: byteify gendoc.py...
r41040 allopts.append(b"-%s" % shortopt)
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 if longopt:
Matt Harbison
py3: byteify gendoc.py...
r41040 allopts.append(b"--%s" % longopt)
FUJIWARA Katsunori
doc: show details of command options in pages generated by docutils...
r20081 if isinstance(default, list):
Matt Harbison
py3: byteify gendoc.py...
r41040 allopts[-1] += b" <%s[+]>" % optlabel
FUJIWARA Katsunori
doc: show details of command options in pages generated by docutils...
r20081 elif (default is not None) and not isinstance(default, bool):
Matt Harbison
py3: byteify gendoc.py...
r41040 allopts[-1] += b" <%s>" % optlabel
if b'\n' in desc:
Simon Heimberg
doc: gendoc.py creates valid output for option descriptions with newlines...
r20655 # only remove line breaks and indentation
Matt Harbison
py3: byteify gendoc.py...
r41040 desc = b' '.join(l.lstrip() for l in desc.split(b'\n'))
desc += default and _(b" (default: %s)") % bytes(default) or b""
yield (b", ".join(allopts), desc)
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814
Erik Zielke
gendoc: refactor get_cmd...
r12756 def get_cmd(cmd, cmdtable):
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 d = {}
Erik Zielke
gendoc: refactor get_cmd...
r12756 attr = cmdtable[cmd]
Matt Harbison
py3: byteify gendoc.py...
r41040 cmds = cmd.lstrip(b"^").split(b"|")
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814
Matt Harbison
py3: byteify gendoc.py...
r41040 d[b'cmd'] = cmds[0]
d[b'aliases'] = cmd.split(b"|")[1:]
d[b'desc'] = get_desc(gettext(pycompat.getdoc(attr[0])))
d[b'opts'] = list(get_opts(attr[1]))
Matt Mackall
doc: handle shortened command synopses
r7376
Matt Harbison
py3: byteify gendoc.py...
r41040 s = b'hg ' + cmds[0]
Matt Mackall
doc: handle shortened command synopses
r7376 if len(attr) > 2:
Matt Harbison
py3: byteify gendoc.py...
r41040 if not attr[2].startswith(b'hg'):
s += b' ' + attr[2]
Matt Mackall
doc: handle shortened command synopses
r7376 else:
s = attr[2]
Matt Harbison
py3: byteify gendoc.py...
r41040 d[b'synopsis'] = s.strip()
Matt Mackall
doc: handle shortened command synopses
r7376
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 return d
Takumi IINO
gendoc: rename to showdoc from show_doc...
r19423 def showdoc(ui):
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 # print options
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(minirst.section(_(b"Options")))
FUJIWARA Katsunori
doc: show details of command options in pages generated by docutils...
r20081 multioccur = False
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 for optstr, desc in get_opts(globalopts):
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(b"%s\n %s\n\n" % (optstr, desc))
if optstr.endswith(b"[+]>"):
FUJIWARA Katsunori
doc: show details of command options in pages generated by docutils...
r20081 multioccur = True
if multioccur:
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(_(b"\n[+] marked option can be specified multiple times\n"))
ui.write(b"\n")
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814
# print cmds
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(minirst.section(_(b"Commands")))
Dan Villiom Podlaski Christiansen
help: use a full header for topic titles...
r18748 commandprinter(ui, table, minirst.subsection)
Erik Zielke
gendoc: refactor get_cmd...
r12756
Takumi IINO
gendoc: extract print help topics into a dedicated function...
r19233 # print help topics
# The config help topic is included in the hgrc.5 man page.
Matt Harbison
py3: byteify gendoc.py...
r41040 helpprinter(ui, helptable, minirst.section, exclude=[b'config'])
Erik Zielke
gendoc: refactor get_cmd...
r12756
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(minirst.section(_(b"Extensions")))
ui.write(_(b"This section contains help for extensions that are "
b"distributed together with Mercurial. Help for other "
b"extensions is available in the help system."))
ui.write((b"\n\n"
b".. contents::\n"
b" :class: htmlonly\n"
b" :local:\n"
b" :depth: 1\n\n"))
Erik Zielke
gendoc: automatically create help for default extensions....
r12781
for extensionname in sorted(allextensionnames()):
Jun Wu
mercurial: pass ui to extensions.load (issue5007)...
r27660 mod = extensions.load(ui, extensionname, None)
Dan Villiom Podlaski Christiansen
help: use a full header for topic titles...
r18748 ui.write(minirst.subsection(extensionname))
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(b"%s\n\n" % gettext(pycompat.getdoc(mod)))
Erik Zielke
gendoc: automatically create help for default extensions....
r12781 cmdtable = getattr(mod, 'cmdtable', None)
if cmdtable:
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(minirst.subsubsection(_(b'Commands')))
Dan Villiom Podlaski Christiansen
help: use a full header for topic titles...
r18748 commandprinter(ui, cmdtable, minirst.subsubsubsection)
Erik Zielke
gendoc: automatically create help for default extensions....
r12781
Takumi IINO
gendoc: add showtopic...
r19424 def showtopic(ui, topic):
extrahelptable = [
Matt Harbison
py3: byteify gendoc.py...
r41040 ([b"common"], b'', loaddoc(b'common'), help.TOPIC_CATEGORY_MISC),
([b"hg.1"], b'', loaddoc(b'hg.1'), help.TOPIC_CATEGORY_CONFIG),
([b"hg-ssh.8"], b'', loaddoc(b'hg-ssh.8'), help.TOPIC_CATEGORY_CONFIG),
([b"hgignore.5"], b'', loaddoc(b'hgignore.5'),
Rodrigo Damazio
help: assigning topic categories...
r40330 help.TOPIC_CATEGORY_CONFIG),
Matt Harbison
py3: byteify gendoc.py...
r41040 ([b"hgrc.5"], b'', loaddoc(b'hgrc.5'), help.TOPIC_CATEGORY_CONFIG),
([b"hgignore.5.gendoc"], b'', loaddoc(b'hgignore'),
help.TOPIC_CATEGORY_CONFIG),
([b"hgrc.5.gendoc"], b'', loaddoc(b'config'),
help.TOPIC_CATEGORY_CONFIG),
Takumi IINO
gendoc: add showtopic...
r19424 ]
helpprinter(ui, helptable + extrahelptable, None, include=[topic])
Takumi IINO
gendoc: extract print help topics into a dedicated function...
r19233 def helpprinter(ui, helptable, sectionfunc, include=[], exclude=[]):
rdamazio@google.com
help: adding support for command categories...
r40327 for h in helptable:
names, sec, doc = h[0:3]
Takumi IINO
gendoc: extract print help topics into a dedicated function...
r19233 if exclude and names[0] in exclude:
continue
if include and names[0] not in include:
continue
for name in names:
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(b".. _%s:\n" % name)
ui.write(b"\n")
Takumi IINO
gendoc: extract print help topics into a dedicated function...
r19233 if sectionfunc:
ui.write(sectionfunc(sec))
Augie Fackler
gendoc: restore use of callable() since it was readded in Python 3.2
r21793 if callable(doc):
Yuya Nishihara
help: pass around ui to doc loader (API)...
r26413 doc = doc(ui)
Takumi IINO
gendoc: extract print help topics into a dedicated function...
r19233 ui.write(doc)
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(b"\n")
Takumi IINO
gendoc: extract print help topics into a dedicated function...
r19233
Erik Zielke
gendoc: automatically create help for default extensions....
r12781 def commandprinter(ui, cmdtable, sectionfunc):
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 h = {}
Erik Zielke
gendoc: refactor get_cmd...
r12756 for c, attr in cmdtable.items():
Matt Harbison
py3: byteify gendoc.py...
r41040 f = c.split(b"|")[0]
f = f.lstrip(b"^")
Christian Ebert
gendoc: fix indentation
r6488 h[f] = c
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 cmds = h.keys()
Matt Harbison
py3: byteify gendoc.py...
r41040 for f in sorted(cmds):
if f.startswith(b"debug"):
Matt Mackall
many, many trivial check-code fixups
r10282 continue
Erik Zielke
gendoc: refactor get_cmd...
r12756 d = get_cmd(h[f], cmdtable)
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(sectionfunc(d[b'cmd']))
FUJIWARA Katsunori
doc: show short description of each commands in generated documents...
r20689 # short description
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(d[b'desc'][0])
Christian Ebert
gendoc: fix indentation
r6488 # synopsis
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(b"::\n\n")
synopsislines = d[b'synopsis'].splitlines()
Martin Geisler
gendoc: support multi-line synopses
r12813 for line in synopsislines:
# some commands (such as rebase) have a multi-line
# synopsis
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(b" %s\n" % line)
ui.write(b'\n')
Christian Ebert
gendoc: fix indentation
r6488 # description
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(b"%s\n\n" % d[b'desc'][1])
Christian Ebert
gendoc: fix indentation
r6488 # options
Matt Harbison
py3: byteify gendoc.py...
r41040 opt_output = list(d[b'opts'])
Christian Ebert
gendoc: fix indentation
r6488 if opt_output:
opts_len = max([len(line[0]) for line in opt_output])
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(_(b"Options:\n\n"))
FUJIWARA Katsunori
doc: show details of command options in pages generated by docutils...
r20081 multioccur = False
Christian Ebert
gendoc: fix indentation
r6488 for optstr, desc in opt_output:
if desc:
Matt Harbison
py3: byteify gendoc.py...
r41040 s = b"%-*s %s" % (opts_len, optstr, desc)
Christian Ebert
gendoc: fix indentation
r6488 else:
s = optstr
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(b"%s\n" % s)
if optstr.endswith(b"[+]>"):
FUJIWARA Katsunori
doc: show details of command options in pages generated by docutils...
r20081 multioccur = True
if multioccur:
Matt Harbison
py3: byteify gendoc.py...
r41040 ui.write(_(b"\n[+] marked option can be specified"
b" multiple times\n"))
ui.write(b"\n")
Christian Ebert
gendoc: fix indentation
r6488 # aliases
Matt Harbison
py3: byteify gendoc.py...
r41040 if d[b'aliases']:
ui.write(_(b" aliases: %s\n\n") % b" ".join(d[b'aliases']))
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814
Matt Mackall
Generate docs for help topics
r3797
Erik Zielke
gendoc: automatically create help for default extensions....
r12781 def allextensionnames():
Matt Harbison
py3: byteify gendoc.py...
r41040 return set(extensions.enabled().keys()) | set(extensions.disabled().keys())
Erik Zielke
gendoc: automatically create help for default extensions....
r12781
Benoit Boissinot
generate hg manpage from commands.py docstring...
r1814 if __name__ == "__main__":
Matt Harbison
py3: byteify gendoc.py...
r41040 doc = b'hg.1.gendoc'
Takumi IINO
gendoc: dispatch print document content by commandline arguments...
r19425 if len(sys.argv) > 1:
Matt Harbison
py3: byteify sys.argv in gendoc.py
r41059 doc = encoding.strtolocal(sys.argv[1])
Takumi IINO
gendoc: dispatch print document content by commandline arguments...
r19425
Yuya Nishihara
ui: factor out ui.load() to create a ui without loading configs (API)...
r30559 ui = uimod.ui.load()
Matt Harbison
py3: byteify gendoc.py...
r41040 if doc == b'hg.1.gendoc':
Yuya Nishihara
gendoc: use real ui in place of stdout...
r26412 showdoc(ui)
Takumi IINO
gendoc: dispatch print document content by commandline arguments...
r19425 else:
Matt Harbison
py3: byteify one more sys.argv in gendoc.py
r41066 showtopic(ui, encoding.strtolocal(sys.argv[1]))