Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/utils/stringutil.py @ 39380:0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
This commit splits the core of pprint() to a new function that is
a generator of chunks instead of a function returning a single
value. This will make it possible to stream output without waiting for
all data to be formatted first. And it will make it easier to
implement support for indenting.
Differential Revision: https://phab.mercurial-scm.org/D4397
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Mon, 27 Aug 2018 09:02:39 -0700 |
parents | ce145f8eface |
children | 5ed7c6caf24d |
rev | line source |
---|---|
37086
f99d64e8a4e4
stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37085
diff
changeset
|
1 # stringutil.py - utility for generic string formatting, parsing, etc. |
8226
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
2 # |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
3 # Copyright 2005 K. Thananchayan <thananck@yahoo.com> |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com> |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
6 # |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
7 # This software may be used and distributed according to the terms of the |
10263 | 8 # GNU General Public License version 2 or any later version. |
1082 | 9 |
37086
f99d64e8a4e4
stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37085
diff
changeset
|
10 from __future__ import absolute_import |
1082 | 11 |
37476
e9dea82ea1f3
wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents:
37322
diff
changeset
|
12 import ast |
31462
3b7a6941a6ef
py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents:
31460
diff
changeset
|
13 import codecs |
21907
7e5dfa00e3c2
util: rename 're' to 'remod'
Siddharth Agarwal <sid0@fb.com>
parents:
21857
diff
changeset
|
14 import re as remod |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
15 import textwrap |
39323
ce145f8eface
stringutil: teach pprint() to recognize generators
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39100
diff
changeset
|
16 import types |
3769 | 17 |
37086
f99d64e8a4e4
stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37085
diff
changeset
|
18 from ..i18n import _ |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
19 from ..thirdparty import attr |
37086
f99d64e8a4e4
stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37085
diff
changeset
|
20 |
f99d64e8a4e4
stringutil: move generic string helpers to new module
Yuya Nishihara <yuya@tcha.org>
parents:
37085
diff
changeset
|
21 from .. import ( |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
22 encoding, |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
23 error, |
28818
6041fb8f2da8
pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
28497
diff
changeset
|
24 pycompat, |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
25 ) |
37013
8453699a1f21
util: observable proxy objects for sockets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36994
diff
changeset
|
26 |
38478
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
27 # regex special chars pulled from https://bugs.python.org/issue29995 |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
28 # which was part of Python 3.7. |
38481
de275ab362cb
stringutil: update list of re-special characters to include &~
Augie Fackler <augie@google.com>
parents:
38478
diff
changeset
|
29 _respecial = pycompat.bytestr(b'()[]{}?*+-|^$\\.&~# \t\n\r\v\f') |
38478
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
30 _regexescapemap = {ord(i): (b'\\' + i).decode('latin1') for i in _respecial} |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
31 |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
32 def reescape(pat): |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
33 """Drop-in replacement for re.escape.""" |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
34 # NOTE: it is intentional that this works on unicodes and not |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
35 # bytes, as it's only possible to do the escaping with |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
36 # unicode.translate, not bytes.translate. Sigh. |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
37 wantuni = True |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
38 if isinstance(pat, bytes): |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
39 wantuni = False |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
40 pat = pat.decode('latin1') |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
41 pat = pat.translate(_regexescapemap) |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
42 if wantuni: |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
43 return pat |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
44 return pat.encode('latin1') |
96f65bdf0bf4
stringutil: add a new function to do minimal regex escaping
Augie Fackler <augie@google.com>
parents:
38276
diff
changeset
|
45 |
37986
32bc3815efae
stringutil: flip the default of pprint() to bprefix=False
Yuya Nishihara <yuya@tcha.org>
parents:
37985
diff
changeset
|
46 def pprint(o, bprefix=False): |
37300
2f859ad7ed8c
stringutil: add function to pretty print an object
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37290
diff
changeset
|
47 """Pretty print an object.""" |
39380
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
48 return b''.join(pprintgen(o, bprefix=bprefix)) |
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
49 |
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
50 def pprintgen(o, bprefix=False): |
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
51 """Pretty print an object to a generator of atoms.""" |
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
52 |
37619
68132a95df31
stringutil: support more types with pprint()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
53 if isinstance(o, bytes): |
37750
f7194c925003
stringutil: make b prefixes on string output optional
Augie Fackler <augie@google.com>
parents:
37749
diff
changeset
|
54 if bprefix: |
39380
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
55 yield "b'%s'" % escapestr(o) |
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
56 else: |
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
57 yield "'%s'" % escapestr(o) |
37619
68132a95df31
stringutil: support more types with pprint()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
58 elif isinstance(o, bytearray): |
68132a95df31
stringutil: support more types with pprint()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
59 # codecs.escape_encode() can't handle bytearray, so escapestr fails |
68132a95df31
stringutil: support more types with pprint()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37476
diff
changeset
|
60 # without coercion. |
39380
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
61 yield "bytearray['%s']" % escapestr(bytes(o)) |
37300
2f859ad7ed8c
stringutil: add function to pretty print an object
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37290
diff
changeset
|
62 elif isinstance(o, list): |
39380
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
63 yield '[%s]' % (b', '.join(pprint(a, bprefix=bprefix) for a in o)) |
37300
2f859ad7ed8c
stringutil: add function to pretty print an object
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37290
diff
changeset
|
64 elif isinstance(o, dict): |
39380
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
65 yield '{%s}' % (b', '.join( |
37750
f7194c925003
stringutil: make b prefixes on string output optional
Augie Fackler <augie@google.com>
parents:
37749
diff
changeset
|
66 '%s: %s' % (pprint(k, bprefix=bprefix), |
f7194c925003
stringutil: make b prefixes on string output optional
Augie Fackler <augie@google.com>
parents:
37749
diff
changeset
|
67 pprint(v, bprefix=bprefix)) |
f7194c925003
stringutil: make b prefixes on string output optional
Augie Fackler <augie@google.com>
parents:
37749
diff
changeset
|
68 for k, v in sorted(o.items()))) |
39088
2aebe138ef6e
stringutil: teach pprint about sets
Augie Fackler <augie@google.com>
parents:
38823
diff
changeset
|
69 elif isinstance(o, set): |
39380
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
70 yield 'set([%s])' % (b', '.join( |
39088
2aebe138ef6e
stringutil: teach pprint about sets
Augie Fackler <augie@google.com>
parents:
38823
diff
changeset
|
71 pprint(k, bprefix=bprefix) for k in sorted(o))) |
37976
bf6bb710b40f
stringutil: teach pprint about tuples
Augie Fackler <augie@google.com>
parents:
37750
diff
changeset
|
72 elif isinstance(o, tuple): |
39380
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
73 yield '(%s)' % (b', '.join(pprint(a, bprefix=bprefix) for a in o)) |
39323
ce145f8eface
stringutil: teach pprint() to recognize generators
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39100
diff
changeset
|
74 elif isinstance(o, types.GeneratorType): |
39380
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
75 yield 'gen[%s]' % (b', '.join(pprint(a, bprefix=bprefix) for a in o)) |
37300
2f859ad7ed8c
stringutil: add function to pretty print an object
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37290
diff
changeset
|
76 else: |
39380
0d21b1f1722c
stringutil: refactor core of pprint so it emits chunks
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39323
diff
changeset
|
77 yield pycompat.byterepr(o) |
37300
2f859ad7ed8c
stringutil: add function to pretty print an object
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37290
diff
changeset
|
78 |
38273
f3033692ccef
stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents:
37986
diff
changeset
|
79 def prettyrepr(o): |
f3033692ccef
stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents:
37986
diff
changeset
|
80 """Pretty print a representation of a possibly-nested object""" |
f3033692ccef
stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents:
37986
diff
changeset
|
81 lines = [] |
f3033692ccef
stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents:
37986
diff
changeset
|
82 rs = pycompat.byterepr(o) |
38276
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
83 p0 = p1 = 0 |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
84 while p0 < len(rs): |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
85 # '... field=<type ... field=<type ...' |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
86 # ~~~~~~~~~~~~~~~~ |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
87 # p0 p1 q0 q1 |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
88 q0 = -1 |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
89 q1 = rs.find('<', p1 + 1) |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
90 if q1 < 0: |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
91 q1 = len(rs) |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
92 elif q1 > p1 + 1 and rs.startswith('=', q1 - 1): |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
93 # backtrack for ' field=<' |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
94 q0 = rs.rfind(' ', p1 + 1, q1 - 1) |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
95 if q0 < 0: |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
96 q0 = q1 |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
97 else: |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
98 q0 += 1 # skip ' ' |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
99 l = rs.count('<', 0, p0) - rs.count('>', 0, p0) |
38273
f3033692ccef
stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents:
37986
diff
changeset
|
100 assert l >= 0 |
38276
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
101 lines.append((l, rs[p0:q0].rstrip())) |
fbb2eddea4d2
stringutil: fix prettyrepr() to not orphan foo=<...> line
Yuya Nishihara <yuya@tcha.org>
parents:
38273
diff
changeset
|
102 p0, p1 = q0, q1 |
38273
f3033692ccef
stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents:
37986
diff
changeset
|
103 return '\n'.join(' ' * l + s for l, s in lines) |
f3033692ccef
stringutil: promote smartset.prettyformat() to utility function
Yuya Nishihara <yuya@tcha.org>
parents:
37986
diff
changeset
|
104 |
38577
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
105 def buildrepr(r): |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
106 """Format an optional printable representation from unexpanded bits |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
107 |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
108 ======== ================================= |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
109 type(r) example |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
110 ======== ================================= |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
111 tuple ('<not %r>', other) |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
112 bytes '<branch closed>' |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
113 callable lambda: '<branch %r>' % sorted(b) |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
114 object other |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
115 ======== ================================= |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
116 """ |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
117 if r is None: |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
118 return '' |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
119 elif isinstance(r, tuple): |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
120 return r[0] % pycompat.rapply(pycompat.maybebytestr, r[1:]) |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
121 elif isinstance(r, bytes): |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
122 return r |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
123 elif callable(r): |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
124 return r() |
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
125 else: |
39089
38409be2f521
stringutil: have buildrepr delegate to pprint for unknown types
Augie Fackler <augie@google.com>
parents:
39088
diff
changeset
|
126 return pprint(r) |
38577
a3130208db1c
stringutil: move _formatsetrepr() from smartset
Yuya Nishihara <yuya@tcha.org>
parents:
38481
diff
changeset
|
127 |
1015
22571b8d35d3
Add automatic binary file detection to diff and export
mpm@selenic.com
parents:
917
diff
changeset
|
128 def binary(s): |
6507
9699864de219
Let util.binary check entire data for \0 (issue1066, issue1079)
Christian Ebert <blacktrash@gmx.net>
parents:
6501
diff
changeset
|
129 """return true if a string is binary data""" |
8118
35f7fda52c92
util: return boolean result directly in util.binary
Martin Geisler <mg@lazybytes.net>
parents:
8011
diff
changeset
|
130 return bool(s and '\0' in s) |
6762 | 131 |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
132 def stringmatcher(pattern, casesensitive=True): |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
133 """ |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
134 accepts a string, possibly starting with 're:' or 'literal:' prefix. |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
135 returns the matcher name, pattern, and matcher function. |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
136 missing or unknown prefixes are treated as literal matches. |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
137 |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
138 helper for tests: |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
139 >>> def test(pattern, *tests): |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
140 ... kind, pattern, matcher = stringmatcher(pattern) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
141 ... return (kind, pattern, [bool(matcher(t)) for t in tests]) |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
142 >>> def itest(pattern, *tests): |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
143 ... kind, pattern, matcher = stringmatcher(pattern, casesensitive=False) |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
144 ... return (kind, pattern, [bool(matcher(t)) for t in tests]) |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
145 |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
146 exact matching (no prefix): |
34146
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34101
diff
changeset
|
147 >>> test(b'abcdefg', b'abc', b'def', b'abcdefg') |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
148 ('literal', 'abcdefg', [False, False, True]) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
149 |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
150 regex matching ('re:' prefix) |
34146
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34101
diff
changeset
|
151 >>> test(b're:a.+b', b'nomatch', b'fooadef', b'fooadefbar') |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
152 ('re', 'a.+b', [False, False, True]) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
153 |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
154 force exact matches ('literal:' prefix) |
34146
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34101
diff
changeset
|
155 >>> test(b'literal:re:foobar', b'foobar', b're:foobar') |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
156 ('literal', 're:foobar', [False, True]) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
157 |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
158 unknown prefixes are ignored and treated as literals |
34146
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34101
diff
changeset
|
159 >>> test(b'foo:bar', b'foo', b'bar', b'foo:bar') |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
160 ('literal', 'foo:bar', [False, False, True]) |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
161 |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
162 case insensitive regex matches |
34146
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34101
diff
changeset
|
163 >>> itest(b're:A.+b', b'nomatch', b'fooadef', b'fooadefBar') |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
164 ('re', 'A.+b', [False, False, True]) |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
165 |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
166 case insensitive literal matches |
34146
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34101
diff
changeset
|
167 >>> itest(b'ABCDEFG', b'abc', b'def', b'abcdefg') |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
168 ('literal', 'ABCDEFG', [False, False, True]) |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
169 """ |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
170 if pattern.startswith('re:'): |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
171 pattern = pattern[3:] |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
172 try: |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
173 flags = 0 |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
174 if not casesensitive: |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
175 flags = remod.I |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
176 regex = remod.compile(pattern, flags) |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
177 except remod.error as e: |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
178 raise error.ParseError(_('invalid regular expression: %s') |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
179 % e) |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
180 return 're', pattern, regex.search |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
181 elif pattern.startswith('literal:'): |
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
182 pattern = pattern[8:] |
30773
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
183 |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
184 match = pattern.__eq__ |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
185 |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
186 if not casesensitive: |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
187 ipat = encoding.lower(pattern) |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
188 match = lambda s: ipat == encoding.lower(s) |
c390b40fe1d7
util: teach stringmatcher to handle forced case insensitive matches
Matt Harbison <matt_harbison@yahoo.com>
parents:
30761
diff
changeset
|
189 return 'literal', pattern, match |
26481
7d132557e44a
util: extract stringmatcher() from revset
Matt Harbison <matt_harbison@yahoo.com>
parents:
26480
diff
changeset
|
190 |
1903
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
191 def shortuser(user): |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
192 """Return a short representation of a user name or email address.""" |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
193 f = user.find('@') |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
194 if f >= 0: |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
195 user = user[:f] |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
196 f = user.find('<') |
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
197 if f >= 0: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
198 user = user[f + 1:] |
3176
7492b33bdd9f
shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3147
diff
changeset
|
199 f = user.find(' ') |
7492b33bdd9f
shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3147
diff
changeset
|
200 if f >= 0: |
7492b33bdd9f
shortuser should stop before the first space character.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3147
diff
changeset
|
201 user = user[:f] |
3533
bb44489b901f
shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents:
3466
diff
changeset
|
202 f = user.find('.') |
bb44489b901f
shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents:
3466
diff
changeset
|
203 if f >= 0: |
bb44489b901f
shortname: truncate at '.' too
Matt Mackall <mpm@selenic.com>
parents:
3466
diff
changeset
|
204 user = user[:f] |
1903
e4abeafd6eb1
move shortuser into util module.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
205 return user |
1920 | 206 |
16360
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
207 def emailuser(user): |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
208 """Return the user portion of an email address.""" |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
209 f = user.find('@') |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
210 if f >= 0: |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
211 user = user[:f] |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
212 f = user.find('<') |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
213 if f >= 0: |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
214 user = user[f + 1:] |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
215 return user |
e5788269741a
templates/filters: extracting the user portion of an email address
Matteo Capobianco <m.capobianco@gmail.com>
parents:
15720
diff
changeset
|
216 |
5975
75d9fe70c654
templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents:
5949
diff
changeset
|
217 def email(author): |
75d9fe70c654
templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents:
5949
diff
changeset
|
218 '''get email of author.''' |
75d9fe70c654
templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents:
5949
diff
changeset
|
219 r = author.find('>') |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
220 if r == -1: |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
221 r = None |
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10264
diff
changeset
|
222 return author[author.find('<') + 1:r] |
5975
75d9fe70c654
templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents:
5949
diff
changeset
|
223 |
37158
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
224 def person(author): |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
225 """Returns the name before an email address, |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
226 interpreting it as per RFC 5322 |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
227 |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
228 >>> person(b'foo@bar') |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
229 'foo' |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
230 >>> person(b'Foo Bar <foo@bar>') |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
231 'Foo Bar' |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
232 >>> person(b'"Foo Bar" <foo@bar>') |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
233 'Foo Bar' |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
234 >>> person(b'"Foo \"buz\" Bar" <foo@bar>') |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
235 'Foo "buz" Bar' |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
236 >>> # The following are invalid, but do exist in real-life |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
237 ... |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
238 >>> person(b'Foo "buz" Bar <foo@bar>') |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
239 'Foo "buz" Bar' |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
240 >>> person(b'"Foo Bar <foo@bar>') |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
241 'Foo Bar' |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
242 """ |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
243 if '@' not in author: |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
244 return author |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
245 f = author.find('<') |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
246 if f != -1: |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
247 return author[:f].strip(' "').replace('\\"', '"') |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
248 f = author.find('@') |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
249 return author[:f].replace('.', ' ') |
fb7140f1d09d
stringutil: move person function from templatefilters
Connor Sheehan <sheehan@mozilla.com>
parents:
37157
diff
changeset
|
250 |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
251 @attr.s(hash=True) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
252 class mailmapping(object): |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
253 '''Represents a username/email key or value in |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
254 a mailmap file''' |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
255 email = attr.ib() |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
256 name = attr.ib(default=None) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
257 |
37248
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
258 def _ismailmaplineinvalid(names, emails): |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
259 '''Returns True if the parsed names and emails |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
260 in a mailmap entry are invalid. |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
261 |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
262 >>> # No names or emails fails |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
263 >>> names, emails = [], [] |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
264 >>> _ismailmaplineinvalid(names, emails) |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
265 True |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
266 >>> # Only one email fails |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
267 >>> emails = [b'email@email.com'] |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
268 >>> _ismailmaplineinvalid(names, emails) |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
269 True |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
270 >>> # One email and one name passes |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
271 >>> names = [b'Test Name'] |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
272 >>> _ismailmaplineinvalid(names, emails) |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
273 False |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
274 >>> # No names but two emails passes |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
275 >>> names = [] |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
276 >>> emails = [b'proper@email.com', b'commit@email.com'] |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
277 >>> _ismailmaplineinvalid(names, emails) |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
278 False |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
279 ''' |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
280 return not emails or not names and len(emails) < 2 |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
281 |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
282 def parsemailmap(mailmapcontent): |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
283 """Parses data in the .mailmap format |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
284 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
285 >>> mmdata = b"\\n".join([ |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
286 ... b'# Comment', |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
287 ... b'Name <commit1@email.xx>', |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
288 ... b'<name@email.xx> <commit2@email.xx>', |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
289 ... b'Name <proper@email.xx> <commit3@email.xx>', |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
290 ... b'Name <proper@email.xx> Commit <commit4@email.xx>', |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
291 ... ]) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
292 >>> mm = parsemailmap(mmdata) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
293 >>> for key in sorted(mm.keys()): |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
294 ... print(key) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
295 mailmapping(email='commit1@email.xx', name=None) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
296 mailmapping(email='commit2@email.xx', name=None) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
297 mailmapping(email='commit3@email.xx', name=None) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
298 mailmapping(email='commit4@email.xx', name='Commit') |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
299 >>> for val in sorted(mm.values()): |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
300 ... print(val) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
301 mailmapping(email='commit1@email.xx', name='Name') |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
302 mailmapping(email='name@email.xx', name=None) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
303 mailmapping(email='proper@email.xx', name='Name') |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
304 mailmapping(email='proper@email.xx', name='Name') |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
305 """ |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
306 mailmap = {} |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
307 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
308 if mailmapcontent is None: |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
309 return mailmap |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
310 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
311 for line in mailmapcontent.splitlines(): |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
312 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
313 # Don't bother checking the line if it is a comment or |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
314 # is an improperly formed author field |
37248
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
315 if line.lstrip().startswith('#'): |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
316 continue |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
317 |
37247
54b896f195d1
stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents:
37212
diff
changeset
|
318 # names, emails hold the parsed emails and names for each line |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
319 # name_builder holds the words in a persons name |
37247
54b896f195d1
stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents:
37212
diff
changeset
|
320 names, emails = [], [] |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
321 namebuilder = [] |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
322 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
323 for element in line.split(): |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
324 if element.startswith('#'): |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
325 # If we reach a comment in the mailmap file, move on |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
326 break |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
327 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
328 elif element.startswith('<') and element.endswith('>'): |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
329 # We have found an email. |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
330 # Parse it, and finalize any names from earlier |
37247
54b896f195d1
stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents:
37212
diff
changeset
|
331 emails.append(element[1:-1]) # Slice off the "<>" |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
332 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
333 if namebuilder: |
37247
54b896f195d1
stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents:
37212
diff
changeset
|
334 names.append(' '.join(namebuilder)) |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
335 namebuilder = [] |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
336 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
337 # Break if we have found a second email, any other |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
338 # data does not fit the spec for .mailmap |
37247
54b896f195d1
stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents:
37212
diff
changeset
|
339 if len(emails) > 1: |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
340 break |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
341 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
342 else: |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
343 # We have found another word in the committers name |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
344 namebuilder.append(element) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
345 |
37248
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
346 # Check to see if we have parsed the line into a valid form |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
347 # We require at least one email, and either at least one |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
348 # name or a second email |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
349 if _ismailmaplineinvalid(names, emails): |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
350 continue |
0e7550b0964c
stringutil: improve check for failed mailmap line parsing
Connor Sheehan <sheehan@mozilla.com>
parents:
37247
diff
changeset
|
351 |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
352 mailmapkey = mailmapping( |
37247
54b896f195d1
stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents:
37212
diff
changeset
|
353 email=emails[-1], |
54b896f195d1
stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents:
37212
diff
changeset
|
354 name=names[-1] if len(names) == 2 else None, |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
355 ) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
356 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
357 mailmap[mailmapkey] = mailmapping( |
37247
54b896f195d1
stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents:
37212
diff
changeset
|
358 email=emails[0], |
54b896f195d1
stringutil: rename local email/names variables to their plural forms
Connor Sheehan <sheehan@mozilla.com>
parents:
37212
diff
changeset
|
359 name=names[0] if names else None, |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
360 ) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
361 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
362 return mailmap |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
363 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
364 def mapname(mailmap, author): |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
365 """Returns the author field according to the mailmap cache, or |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
366 the original author field. |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
367 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
368 >>> mmdata = b"\\n".join([ |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
369 ... b'# Comment', |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
370 ... b'Name <commit1@email.xx>', |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
371 ... b'<name@email.xx> <commit2@email.xx>', |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
372 ... b'Name <proper@email.xx> <commit3@email.xx>', |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
373 ... b'Name <proper@email.xx> Commit <commit4@email.xx>', |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
374 ... ]) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
375 >>> m = parsemailmap(mmdata) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
376 >>> mapname(m, b'Commit <commit1@email.xx>') |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
377 'Name <commit1@email.xx>' |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
378 >>> mapname(m, b'Name <commit2@email.xx>') |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
379 'Name <name@email.xx>' |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
380 >>> mapname(m, b'Commit <commit3@email.xx>') |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
381 'Name <proper@email.xx>' |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
382 >>> mapname(m, b'Commit <commit4@email.xx>') |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
383 'Name <proper@email.xx>' |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
384 >>> mapname(m, b'Unknown Name <unknown@email.com>') |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
385 'Unknown Name <unknown@email.com>' |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
386 """ |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
387 # If the author field coming in isn't in the correct format, |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
388 # or the mailmap is empty just return the original author field |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
389 if not isauthorwellformed(author) or not mailmap: |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
390 return author |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
391 |
37249
2ed180117f76
stringutil: edit comment to reflect actual data type name
Connor Sheehan <sheehan@mozilla.com>
parents:
37248
diff
changeset
|
392 # Turn the user name into a mailmapping |
37212
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
393 commit = mailmapping(name=person(author), email=email(author)) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
394 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
395 try: |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
396 # Try and use both the commit email and name as the key |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
397 proper = mailmap[commit] |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
398 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
399 except KeyError: |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
400 # If the lookup fails, use just the email as the key instead |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
401 # We call this commit2 as not to erase original commit fields |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
402 commit2 = mailmapping(email=commit.email) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
403 proper = mailmap.get(commit2, mailmapping(None, None)) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
404 |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
405 # Return the author field with proper values filled in |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
406 return '%s <%s>' % ( |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
407 proper.name if proper.name else commit.name, |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
408 proper.email if proper.email else commit.email, |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
409 ) |
2a2ce93e12f4
templatefuncs: add mailmap template function
Connor Sheehan <sheehan@mozilla.com>
parents:
37158
diff
changeset
|
410 |
37157
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
411 _correctauthorformat = remod.compile(br'^[^<]+\s\<[^<>]+@[^<>]+\>$') |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
412 |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
413 def isauthorwellformed(author): |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
414 '''Return True if the author field is well formed |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
415 (ie "Contributor Name <contrib@email.dom>") |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
416 |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
417 >>> isauthorwellformed(b'Good Author <good@author.com>') |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
418 True |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
419 >>> isauthorwellformed(b'Author <good@author.com>') |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
420 True |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
421 >>> isauthorwellformed(b'Bad Author') |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
422 False |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
423 >>> isauthorwellformed(b'Bad Author <author@author.com') |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
424 False |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
425 >>> isauthorwellformed(b'Bad Author author@author.com') |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
426 False |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
427 >>> isauthorwellformed(b'<author@author.com>') |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
428 False |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
429 >>> isauthorwellformed(b'Bad Author <author>') |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
430 False |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
431 ''' |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
432 return _correctauthorformat.match(author) is not None |
f8e1f48de118
stringutil: add isauthorwellformed function
Connor Sheehan <sheehan@mozilla.com>
parents:
37086
diff
changeset
|
433 |
3767
1861fa38a6a7
Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3721
diff
changeset
|
434 def ellipsis(text, maxlength=400): |
21857
86c2d792a4b7
util: replace 'ellipsis' implementation by 'encoding.trim'
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21813
diff
changeset
|
435 """Trim string to at most maxlength (default: 400) columns in display.""" |
86c2d792a4b7
util: replace 'ellipsis' implementation by 'encoding.trim'
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
21813
diff
changeset
|
436 return encoding.trim(text, maxlength, ellipsis='...') |
3767
1861fa38a6a7
Move ellipsis code to util.ellipsis() and improve maxlength handling.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
3721
diff
changeset
|
437 |
31460
53865692a354
util: wrap s.encode('string_escape') call for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31458
diff
changeset
|
438 def escapestr(s): |
39100
1419ba5e3b56
stringutil: if we get a memoryview in escapestr, coerce it to bytes
Augie Fackler <augie@google.com>
parents:
39089
diff
changeset
|
439 if isinstance(s, memoryview): |
1419ba5e3b56
stringutil: if we get a memoryview in escapestr, coerce it to bytes
Augie Fackler <augie@google.com>
parents:
39089
diff
changeset
|
440 s = bytes(s) |
31462
3b7a6941a6ef
py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents:
31460
diff
changeset
|
441 # call underlying function of s.encode('string_escape') directly for |
3b7a6941a6ef
py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents:
31460
diff
changeset
|
442 # Python 3 compatibility |
3b7a6941a6ef
py3: call codecs.escape_encode() directly
Yuya Nishihara <yuya@tcha.org>
parents:
31460
diff
changeset
|
443 return codecs.escape_encode(s)[0] |
31460
53865692a354
util: wrap s.encode('string_escape') call for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31458
diff
changeset
|
444 |
31491
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31474
diff
changeset
|
445 def unescapestr(s): |
31492
cad95575dc46
py3: call codecs.escape_decode() directly
Yuya Nishihara <yuya@tcha.org>
parents:
31491
diff
changeset
|
446 return codecs.escape_decode(s)[0] |
31491
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31474
diff
changeset
|
447 |
33708
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33691
diff
changeset
|
448 def forcebytestr(obj): |
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33691
diff
changeset
|
449 """Portably format an arbitrary object (e.g. exception) into a byte |
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33691
diff
changeset
|
450 string.""" |
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33691
diff
changeset
|
451 try: |
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33691
diff
changeset
|
452 return pycompat.bytestr(obj) |
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33691
diff
changeset
|
453 except UnicodeEncodeError: |
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33691
diff
changeset
|
454 # non-ascii string, may be lossy |
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33691
diff
changeset
|
455 return pycompat.bytestr(encoding.strtolocal(str(obj))) |
1d5e497c08b3
py3: convert arbitrary exception object to byte string more reliably
Yuya Nishihara <yuya@tcha.org>
parents:
33691
diff
changeset
|
456 |
5291
23651848d638
extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents:
5213
diff
changeset
|
457 def uirepr(s): |
23651848d638
extdiff: avoid repr() doubling paths backslashes under Windows
Patrick Mezard <pmezard@gmail.com>
parents:
5213
diff
changeset
|
458 # Avoid double backslash in Windows path repr() |
36299
1fa33bd848ee
py3: fix bytes-unicode dance while building docstring of extdiff
Yuya Nishihara <yuya@tcha.org>
parents:
36272
diff
changeset
|
459 return pycompat.byterepr(pycompat.bytestr(s)).replace(b'\\\\', b'\\') |
7547
4949729ee9ee
python implementation of diffstat
Alexander Solovyov <piranha@piranha.org.ua>
parents:
7537
diff
changeset
|
460 |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
461 # delay import of textwrap |
37082
736024df4498
util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents:
37081
diff
changeset
|
462 def _MBTextWrapper(**kwargs): |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
463 class tw(textwrap.TextWrapper): |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
464 """ |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
465 Extend TextWrapper for width-awareness. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
466 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
467 Neither number of 'bytes' in any encoding nor 'characters' is |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
468 appropriate to calculate terminal columns for specified string. |
12957
9f2ac318b92e
util: clarify purpose of MBTextWrapper class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
12938
diff
changeset
|
469 |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
470 Original TextWrapper implementation uses built-in 'len()' directly, |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
471 so overriding is needed to use width information of each characters. |
12957
9f2ac318b92e
util: clarify purpose of MBTextWrapper class
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
12938
diff
changeset
|
472 |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
473 In addition, characters classified into 'ambiguous' width are |
17424
e7cfe3587ea4
fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents:
17391
diff
changeset
|
474 treated as wide in East Asian area, but as narrow in other. |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
475 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
476 This requires use decision to determine width of such characters. |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
477 """ |
15065
24a6c3f903bb
util: wrap lines with multi-byte characters correctly (issue2943)
Mads Kiilerich <mads@kiilerich.com>
parents:
15024
diff
changeset
|
478 def _cutdown(self, ucstr, space_left): |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
479 l = 0 |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
480 colwidth = encoding.ucolwidth |
38823
e7aa113b14f7
global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
38577
diff
changeset
|
481 for i in pycompat.xrange(len(ucstr)): |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
482 l += colwidth(ucstr[i]) |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
483 if space_left < l: |
15065
24a6c3f903bb
util: wrap lines with multi-byte characters correctly (issue2943)
Mads Kiilerich <mads@kiilerich.com>
parents:
15024
diff
changeset
|
484 return (ucstr[:i], ucstr[i:]) |
24a6c3f903bb
util: wrap lines with multi-byte characters correctly (issue2943)
Mads Kiilerich <mads@kiilerich.com>
parents:
15024
diff
changeset
|
485 return ucstr, '' |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
486 |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
487 # overriding of base class |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
488 def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width): |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
489 space_left = max(width - cur_len, 1) |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
490 |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
491 if self.break_long_words: |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
492 cut, res = self._cutdown(reversed_chunks[-1], space_left) |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
493 cur_line.append(cut) |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
494 reversed_chunks[-1] = res |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
495 elif not cur_line: |
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
496 cur_line.append(reversed_chunks.pop()) |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
497 |
26201
c5b2074ae8c0
util: capitalize Python in MBTextWrapper._wrap_chunks comment
timeless@mozdev.org
parents:
26126
diff
changeset
|
498 # this overriding code is imported from TextWrapper of Python 2.6 |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
499 # to calculate columns of string by 'encoding.ucolwidth()' |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
500 def _wrap_chunks(self, chunks): |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
501 colwidth = encoding.ucolwidth |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
502 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
503 lines = [] |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
504 if self.width <= 0: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
505 raise ValueError("invalid width %r (must be > 0)" % self.width) |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
506 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
507 # Arrange in reverse order so items can be efficiently popped |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
508 # from a stack of chucks. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
509 chunks.reverse() |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
510 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
511 while chunks: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
512 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
513 # Start the list of chunks that will make up the current line. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
514 # cur_len is just the length of all the chunks in cur_line. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
515 cur_line = [] |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
516 cur_len = 0 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
517 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
518 # Figure out which static string will prefix this line. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
519 if lines: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
520 indent = self.subsequent_indent |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
521 else: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
522 indent = self.initial_indent |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
523 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
524 # Maximum width for this line. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
525 width = self.width - len(indent) |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
526 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
527 # First chunk on line is whitespace -- drop it, unless this |
17424
e7cfe3587ea4
fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents:
17391
diff
changeset
|
528 # is the very beginning of the text (i.e. no lines started yet). |
32560
47ce079b1afa
util: look for empty-sysstr instead of empty-bytesstr in textwrap code
Augie Fackler <raf@durin42.com>
parents:
32496
diff
changeset
|
529 if self.drop_whitespace and chunks[-1].strip() == r'' and lines: |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
530 del chunks[-1] |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
531 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
532 while chunks: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
533 l = colwidth(chunks[-1]) |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
534 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
535 # Can at least squeeze this chunk onto the current line. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
536 if cur_len + l <= width: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
537 cur_line.append(chunks.pop()) |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
538 cur_len += l |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
539 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
540 # Nope, this line is full. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
541 else: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
542 break |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
543 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
544 # The current line is full, and the next chunk is too big to |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
545 # fit on *any* line (not just this one). |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
546 if chunks and colwidth(chunks[-1]) > width: |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
547 self._handle_long_word(chunks, cur_line, cur_len, width) |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
548 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
549 # If the last chunk on this line is all whitespace, drop it. |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
550 if (self.drop_whitespace and |
32560
47ce079b1afa
util: look for empty-sysstr instead of empty-bytesstr in textwrap code
Augie Fackler <raf@durin42.com>
parents:
32496
diff
changeset
|
551 cur_line and cur_line[-1].strip() == r''): |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
552 del cur_line[-1] |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
553 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
554 # Convert current line back to a string and store it in list |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
555 # of all lines (return value). |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
556 if cur_line: |
32579
3b8155305fbe
util: use sysstr.join instead of bytes.join in textwrap wrapper
Augie Fackler <raf@durin42.com>
parents:
32560
diff
changeset
|
557 lines.append(indent + r''.join(cur_line)) |
15066
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
558 |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
559 return lines |
24efa83d81cb
i18n: calculate terminal columns by width information of each characters
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15065
diff
changeset
|
560 |
37082
736024df4498
util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents:
37081
diff
changeset
|
561 global _MBTextWrapper |
736024df4498
util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents:
37081
diff
changeset
|
562 _MBTextWrapper = tw |
13316
d119403fd266
util: delay loading of textwrap
Matt Mackall <mpm@selenic.com>
parents:
13313
diff
changeset
|
563 return tw(**kwargs) |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
564 |
12698
7aef77e74cf3
util: make wrap() require a width argument
Matt Mackall <mpm@selenic.com>
parents:
12689
diff
changeset
|
565 def wrap(line, width, initindent='', hangindent=''): |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
566 maxindent = max(len(hangindent), len(initindent)) |
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
567 if width <= maxindent: |
9417
4c3fb45123e5
util, minirst: do not crash with COLUMNS=0
Martin Geisler <mg@lazybytes.net>
parents:
9397
diff
changeset
|
568 # adjust for weird terminal size |
11297
d320e70442a5
replace Python standard textwrap by MBCS sensitive one for i18n text
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
11256
diff
changeset
|
569 width = max(78, maxindent + 1) |
31347
a9a28ca17615
util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31324
diff
changeset
|
570 line = line.decode(pycompat.sysstr(encoding.encoding), |
37083
bad90b80b315
util: adjust indent level in wrap()
Yuya Nishihara <yuya@tcha.org>
parents:
37082
diff
changeset
|
571 pycompat.sysstr(encoding.encodingmode)) |
31347
a9a28ca17615
util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31324
diff
changeset
|
572 initindent = initindent.decode(pycompat.sysstr(encoding.encoding), |
37083
bad90b80b315
util: adjust indent level in wrap()
Yuya Nishihara <yuya@tcha.org>
parents:
37082
diff
changeset
|
573 pycompat.sysstr(encoding.encodingmode)) |
31347
a9a28ca17615
util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31324
diff
changeset
|
574 hangindent = hangindent.decode(pycompat.sysstr(encoding.encoding), |
37083
bad90b80b315
util: adjust indent level in wrap()
Yuya Nishihara <yuya@tcha.org>
parents:
37082
diff
changeset
|
575 pycompat.sysstr(encoding.encodingmode)) |
37082
736024df4498
util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents:
37081
diff
changeset
|
576 wrapper = _MBTextWrapper(width=width, |
736024df4498
util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents:
37081
diff
changeset
|
577 initial_indent=initindent, |
736024df4498
util: mark MBTextWrapper as private
Yuya Nishihara <yuya@tcha.org>
parents:
37081
diff
changeset
|
578 subsequent_indent=hangindent) |
31347
a9a28ca17615
util: pass encoding.[encoding|encodingmode] as unicodes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
31324
diff
changeset
|
579 return wrapper.fill(line).encode(pycompat.sysstr(encoding.encoding)) |
8938
9b8c9266c59d
commands: wrap short descriptions in 'hg help'
Martin Geisler <mg@lazybytes.net>
parents:
8785
diff
changeset
|
580 |
12088
1f71dffabc53
parsebool: accept always as true and never as false
Augie Fackler <durin42@gmail.com>
parents:
12087
diff
changeset
|
581 _booleans = {'1': True, 'yes': True, 'true': True, 'on': True, 'always': True, |
1f71dffabc53
parsebool: accept always as true and never as false
Augie Fackler <durin42@gmail.com>
parents:
12087
diff
changeset
|
582 '0': False, 'no': False, 'false': False, 'off': False, |
1f71dffabc53
parsebool: accept always as true and never as false
Augie Fackler <durin42@gmail.com>
parents:
12087
diff
changeset
|
583 'never': False} |
12087
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
584 |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
585 def parsebool(s): |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
586 """Parse s into a boolean. |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
587 |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
588 If s is not a valid boolean, returns None. |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
589 """ |
a88a4720c2f0
parsebool: create new function and use it for config parsing
Augie Fackler <durin42@gmail.com>
parents:
12086
diff
changeset
|
590 return _booleans.get(s.lower(), None) |
37290
cc5a040fe150
wireproto: syntax for encoding CBOR into frames
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37249
diff
changeset
|
591 |
37476
e9dea82ea1f3
wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents:
37322
diff
changeset
|
592 def evalpythonliteral(s): |
e9dea82ea1f3
wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents:
37322
diff
changeset
|
593 """Evaluate a string containing a Python literal expression""" |
e9dea82ea1f3
wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents:
37322
diff
changeset
|
594 # We could backport our tokenizer hack to rewrite '' to u'' if we want |
37681
3942bd8db8b2
stringutil: ast.literal_eval needs a unicode on py3
Augie Fackler <augie@google.com>
parents:
37619
diff
changeset
|
595 if pycompat.ispy3: |
3942bd8db8b2
stringutil: ast.literal_eval needs a unicode on py3
Augie Fackler <augie@google.com>
parents:
37619
diff
changeset
|
596 return ast.literal_eval(s.decode('latin1')) |
37476
e9dea82ea1f3
wireproto: convert python literal to object without using unsafe eval()
Yuya Nishihara <yuya@tcha.org>
parents:
37322
diff
changeset
|
597 return ast.literal_eval(s) |