/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
1
#!/usr/bin/env python
2
#
3
# bzrgettext - extract docstrings for Bazaar commands
4
#
5
# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
6
# Copyright 2011 Canonical Ltd
7
#
8
# This program is free software; you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation; either version 2 of the License, or
11
# (at your option) any later version.
12
#
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
# GNU General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License
19
# along with this program; if not, write to the Free Software
20
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22
# This script is copied from mercurial/i18n/hggettext and modified
23
# for Bazaar.
24
25
# The normalize function is taken from pygettext which is distributed
26
# with Python under the Python License, which is GPL compatible.
27
28
29
"""Extract docstrings from Bazaar commands.
30
"""
31
32
import os, sys, inspect
33
34
35
def escape(s):
36
    s = (s.replace('\\', '\\\\')
37
        .replace('\n', '\\n')
38
        .replace('\r', '\\r')
39
        .replace('\t', '\\t')
40
        .replace('"', '\\"')
41
        )
42
    return s
43
44
45
def normalize(s):
46
    # This converts the various Python string types into a format that
47
    # is appropriate for .po files, namely much closer to C style.
48
    lines = s.split('\n')
49
    if len(lines) == 1:
50
        s = '"' + escape(s) + '"'
51
    else:
52
        if not lines[-1]:
53
            del lines[-1]
54
            lines[-1] = lines[-1] + '\n'
55
        lines = map(escape, lines)
56
        lineterm = '\\n"\n"'
57
        s = '""\n"' + lineterm.join(lines) + '"'
58
    return s
59
60
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
61
MSGID_FOUND = set()
62
63
def poentry(path, lineno, s, comment=None):
64
    if s in MSGID_FOUND:
65
        return
66
    MSGID_FOUND.add(s)
67
    if comment is None:
68
        comment = ''
69
    else:
70
        comment = "# %s\n" % comment
71
    print ('#: %s:%d\n' % (path, lineno) +
72
           comment+
73
           'msgid %s\n' % normalize(s) +
74
           'msgstr ""\n')
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
75
5830.2.2 by INADA Naoki
Split command's docstring per paragraph.
76
def poentry_per_paragraph(path, lineno, msgid):
77
    paragraphs = msgid.split('\n\n')
78
    for p in paragraphs:
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
79
        poentry(path, lineno, p)
5830.2.2 by INADA Naoki
Split command's docstring per paragraph.
80
        lineno += p.count('\n') + 2
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
81
82
def offset(src, doc, name, default):
83
    """Compute offset or issue a warning on stdout."""
84
    # Backslashes in doc appear doubled in src.
85
    end = src.find(doc.replace('\\', '\\\\'))
86
    if end == -1:
87
        # This can happen if the docstring contains unnecessary escape
88
        # sequences such as \" in a triple-quoted string. The problem
89
        # is that \" is turned into " and so doc wont appear in src.
90
        sys.stderr.write("warning: unknown offset in %s, assuming %d lines\n"
91
                         % (name, default))
92
        return default
93
    else:
94
        return src.count('\n', 0, end)
95
96
97
def importpath(path):
98
    """Import a path like foo/bar/baz.py and return the baz module."""
99
    if path.endswith('.py'):
100
        path = path[:-3]
101
    if path.endswith('/__init__'):
102
        path = path[:-9]
103
    path = path.replace('/', '.')
104
    mod = __import__(path)
105
    for comp in path.split('.')[1:]:
106
        mod = getattr(mod, comp)
107
    return mod
108
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
109
def options(path, lineno, cmdklass):
110
    cmd = cmdklass()
111
    for name, opt in cmd.options().iteritems():
112
        poentry(path, lineno, opt.help,
113
                "help of '%s' option of '%s' command" % (name, cmd.name()))
114
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
115
116
def docstrings(path):
117
    """Extract docstrings from path.
118
119
    This respects the Bazaar cmdtable/table convention and will
120
    only extract docstrings from functions mentioned in these tables.
121
    """
122
    from bzrlib.commands import Command as cmd_klass
5830.2.6 by INADA Naoki
Add target of bzrgettext.py
123
    try:
124
        mod = importpath(path)
125
    except Exception:
126
        # some module raises exception (ex. bzrlib.transport.ftp._gssapi
127
        return
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
128
    for name in dir(mod):
129
        if not name.startswith('cmd_'):
130
            continue
131
        obj = getattr(mod, name)
132
        try:
133
            doc = obj.__doc__
134
            if doc:
135
                doc = inspect.cleandoc(doc)
136
            else:
137
                continue
138
        except AttributeError:
139
            continue
140
        if (inspect.isclass(obj) and issubclass(obj, cmd_klass)
141
                and not obj is cmd_klass):
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
142
            lineno = inspect.findsource(obj)[1]
143
            poentry_per_paragraph(path, lineno, doc)
144
            options(path, lineno, obj)
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
145
146
def bzrerrors():
147
    """Extract fmt string from bzrlib.errors."""
148
    from bzrlib import errors
149
    base_klass = errors.BzrError
150
    for name in dir(errors):
151
        klass = getattr(errors, name)
152
        if not inspect.isclass(klass):
153
            continue
154
        if not issubclass(klass, base_klass):
155
            continue
156
        if klass is base_klass:
157
            continue
158
        if klass.internal_error:
159
            continue
160
        fmt = getattr(klass, "_fmt", None)
161
        if fmt:
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
162
            poentry('bzrlib/erros.py', inspect.findsource(klass)[1], fmt)
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
163
164
165
def rawtext(path):
166
    src = open(path).read()
5830.2.2 by INADA Naoki
Split command's docstring per paragraph.
167
    poentry_per_paragraph(path, 1, src)
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
168
169
170
if __name__ == "__main__":
171
    # It is very important that we import the Bazaar modules from
172
    # the source tree where bzrgettext is executed. Otherwise we might
173
    # accidentally import and extract strings from a Bazaar
174
    # installation mentioned in PYTHONPATH.
175
    sys.path.insert(0, os.getcwd())
176
    import bzrlib.lazy_import
177
    for path in sys.argv[1:]:
178
        if path.endswith('.txt'):
179
            rawtext(path)
180
        else:
181
            docstrings(path)
182
    bzrerrors()