/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
61
def poentry(path, lineno, s):
62
    return ('#: %s:%d\n' % (path, lineno) +
63
            'msgid %s\n' % normalize(s) +
64
            'msgstr ""\n')
65
5830.2.2 by INADA Naoki
Split command's docstring per paragraph.
66
def poentry_per_paragraph(path, lineno, msgid):
67
    paragraphs = msgid.split('\n\n')
68
    for p in paragraphs:
69
        print poentry(path, lineno, p)
70
        lineno += p.count('\n') + 2
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
71
72
def offset(src, doc, name, default):
73
    """Compute offset or issue a warning on stdout."""
74
    # Backslashes in doc appear doubled in src.
75
    end = src.find(doc.replace('\\', '\\\\'))
76
    if end == -1:
77
        # This can happen if the docstring contains unnecessary escape
78
        # sequences such as \" in a triple-quoted string. The problem
79
        # is that \" is turned into " and so doc wont appear in src.
80
        sys.stderr.write("warning: unknown offset in %s, assuming %d lines\n"
81
                         % (name, default))
82
        return default
83
    else:
84
        return src.count('\n', 0, end)
85
86
87
def importpath(path):
88
    """Import a path like foo/bar/baz.py and return the baz module."""
89
    if path.endswith('.py'):
90
        path = path[:-3]
91
    if path.endswith('/__init__'):
92
        path = path[:-9]
93
    path = path.replace('/', '.')
94
    mod = __import__(path)
95
    for comp in path.split('.')[1:]:
96
        mod = getattr(mod, comp)
97
    return mod
98
99
100
def docstrings(path):
101
    """Extract docstrings from path.
102
103
    This respects the Bazaar cmdtable/table convention and will
104
    only extract docstrings from functions mentioned in these tables.
105
    """
106
    from bzrlib.commands import Command as cmd_klass
107
    mod = importpath(path)
108
    for name in dir(mod):
109
        if not name.startswith('cmd_'):
110
            continue
111
        obj = getattr(mod, name)
112
        try:
113
            doc = obj.__doc__
114
            if doc:
115
                doc = inspect.cleandoc(doc)
116
            else:
117
                continue
118
        except AttributeError:
119
            continue
120
        if (inspect.isclass(obj) and issubclass(obj, cmd_klass)
121
                and not obj is cmd_klass):
5830.2.2 by INADA Naoki
Split command's docstring per paragraph.
122
            poentry_per_paragraph(path, inspect.findsource(obj)[1], doc)
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
123
124
def bzrerrors():
125
    """Extract fmt string from bzrlib.errors."""
126
    from bzrlib import errors
127
    base_klass = errors.BzrError
128
    for name in dir(errors):
129
        klass = getattr(errors, name)
130
        if not inspect.isclass(klass):
131
            continue
132
        if not issubclass(klass, base_klass):
133
            continue
134
        if klass is base_klass:
135
            continue
136
        if klass.internal_error:
137
            continue
138
        fmt = getattr(klass, "_fmt", None)
139
        if fmt:
140
            print poentry('bzrlib/erros.py',
141
                    inspect.findsource(klass)[1], fmt)
142
143
144
def rawtext(path):
145
    src = open(path).read()
5830.2.2 by INADA Naoki
Split command's docstring per paragraph.
146
    poentry_per_paragraph(path, 1, src)
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
147
148
149
if __name__ == "__main__":
150
    # It is very important that we import the Bazaar modules from
151
    # the source tree where bzrgettext is executed. Otherwise we might
152
    # accidentally import and extract strings from a Bazaar
153
    # installation mentioned in PYTHONPATH.
154
    sys.path.insert(0, os.getcwd())
155
    import bzrlib.lazy_import
156
    for path in sys.argv[1:]:
157
        if path.endswith('.txt'):
158
            rawtext(path)
159
        else:
160
            docstrings(path)
161
    bzrerrors()