~bzr-pqm/bzr/bzr.dev

5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
1
# Copyright (C) 2011 Canonical Ltd
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17
# The normalize function is taken from pygettext which is distributed
18
# with Python under the Python License, which is GPL compatible.
19
20
"""Extract docstrings from Bazaar commands.
21
"""
22
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
23
import inspect
24
import os
25
import sys
26
27
from bzrlib import (
28
    commands as _mod_commands,
29
    errors,
30
    help_topics,
31
    osutils,
32
    plugin,
33
    )
34
35
36
def _escape(s):
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
37
    s = (s.replace('\\', '\\\\')
38
        .replace('\n', '\\n')
39
        .replace('\r', '\\r')
40
        .replace('\t', '\\t')
41
        .replace('"', '\\"')
42
        )
43
    return s
44
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
45
def _normalize(s):
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
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:
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
50
        s = '"' + _escape(s) + '"'
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
51
    else:
52
        if not lines[-1]:
53
            del lines[-1]
54
            lines[-1] = lines[-1] + '\n'
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
55
        lines = map(_escape, lines)
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
56
        lineterm = '\\n"\n"'
57
        s = '""\n"' + lineterm.join(lines) + '"'
58
    return s
59
60
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
61
_FOUND_MSGID = None # set by entry function.
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
62
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
63
def _poentry(outf, path, lineno, s, comment=None):
64
    if s in _FOUND_MSGID:
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
65
        return
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
66
    _FOUND_MSGID.add(s)
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
67
    if comment is None:
68
        comment = ''
69
    else:
70
        comment = "# %s\n" % comment
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
71
    print >>outf, ('#: %s:%d\n' % (path, lineno) +
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
72
           comment+
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
73
           'msgid %s\n' % _normalize(s) +
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
74
           'msgstr ""\n')
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
75
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
76
def _poentry_per_paragraph(outf, path, lineno, msgid):
5830.2.2 by INADA Naoki
Split command's docstring per paragraph.
77
    paragraphs = msgid.split('\n\n')
78
    for p in paragraphs:
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
79
        _poentry(outf, 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
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
82
def _offset(src, doc, default):
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
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
        return default
88
    else:
89
        return src.count('\n', 0, end)
90
91
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
92
def _command_options(outf, path, cmd):
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
93
    for name, opt in cmd.options().iteritems():
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
94
        src, lineno = inspect.findsource(cmd.__class__)
95
        lineno = _offset(''.join(src), opt.help, lineno)
96
        _poentry(outf, path, lineno, opt.help,
5830.2.3 by INADA Naoki
bzrgettext extracts help message of command option too.
97
                "help of '%s' option of '%s' command" % (name, cmd.name()))
98
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
99
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
100
def _write_command_help(outf, cmd_name, cmd):
101
    path = inspect.getfile(cmd.__class__)
102
    if path.endswith('.pyc'):
103
        path = path[:-1]
104
    path = os.path.relpath(path)
105
    lineno = inspect.findsource(cmd.__class__)[1]
106
    doc = inspect.getdoc(cmd)
107
108
    _poentry_per_paragraph(outf, path, lineno, doc)
109
    _command_options(outf, path, cmd)
110
111
def _command_helps(outf):
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
112
    """Extract docstrings from path.
113
114
    This respects the Bazaar cmdtable/table convention and will
115
    only extract docstrings from functions mentioned in these tables.
116
    """
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
117
    import bzrlib.plugin
118
    from glob import glob
119
120
    # builtin commands
121
    for cmd_name in _mod_commands.builtin_command_names():
122
        command = _mod_commands.get_cmd_object(cmd_name, False)
123
        _write_command_help(outf, cmd_name, command)
124
125
    plugin_path = bzrlib.plugin.get_core_plugin_path()
126
    core_plugins = glob(plugin_path + '/*/__init__.py')
127
    core_plugins = [os.path.basename(os.path.dirname(p))
128
                        for p in core_plugins]
129
    # core plugins
130
    for cmd_name in _mod_commands.plugin_command_names():
131
        command = _mod_commands.get_cmd_object(cmd_name, False)
132
        if command.plugin_name() not in core_plugins:
133
            # skip non-core plugins
134
            # TODO: Support extracting from third party plugins.
135
            continue
136
        _write_command_help(outf, cmd_name, command)
137
138
139
def _error_messages(outf):
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
140
    """Extract fmt string from bzrlib.errors."""
141
    from bzrlib import errors
142
    base_klass = errors.BzrError
143
    for name in dir(errors):
144
        klass = getattr(errors, name)
145
        if not inspect.isclass(klass):
146
            continue
147
        if not issubclass(klass, base_klass):
148
            continue
149
        if klass is base_klass:
150
            continue
151
        if klass.internal_error:
152
            continue
153
        fmt = getattr(klass, "_fmt", None)
154
        if fmt:
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
155
            _poentry(outf, 'bzrlib/errors.py', inspect.findsource(klass)[1], fmt)
5830.2.1 by INADA Naoki
Add update-pot command to Makefile and tools/bzrgettext script that
156
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
157
def _help_topics(outf):
5830.2.9 by INADA Naoki
Export from help_topics that is directly registered into
158
    from bzrlib.help_topics import topic_registry
159
    for key in topic_registry.keys():
160
        doc = topic_registry.get(key)
161
        if isinstance(doc, str):
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
162
            _poentry_per_paragraph(
163
                    outf,
5830.2.11 by INADA Naoki
Change dummy file path for help topics.
164
                    'dummy/help_topics/'+key+'/detail.txt',
165
                    1, doc)
5830.2.9 by INADA Naoki
Export from help_topics that is directly registered into
166
167
        summary = topic_registry.get_summary(key)
168
        if summary is not None:
5830.2.12 by INADA Naoki
Make "export-pot" hidden command.
169
            _poentry(outf, 'dummy/help_topics/'+key+'/summary.txt',
170
                     1, summary)
171
172
def export_pot(outf):
173
    global _FOUND_MSGID
174
    _FOUND_MSGID = set()
175
    _command_helps(outf)
176
    _error_messages(outf)
177
    _help_topics(outf)