3
# bzrgettext - extract docstrings for Bazaar commands
5
# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
6
# Copyright 2011 Canonical Ltd
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.
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.
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
22
# This script is copied from mercurial/i18n/hggettext and modified
25
# The normalize function is taken from pygettext which is distributed
26
# with Python under the Python License, which is GPL compatible.
29
"""Extract docstrings from Bazaar commands.
32
import os, sys, inspect
36
s = (s.replace('\\', '\\\\')
46
# This converts the various Python string types into a format that
47
# is appropriate for .po files, namely much closer to C style.
50
s = '"' + escape(s) + '"'
54
lines[-1] = lines[-1] + '\n'
55
lines = map(escape, lines)
57
s = '""\n"' + lineterm.join(lines) + '"'
63
def poentry(path, lineno, s, comment=None):
70
comment = "# %s\n" % comment
71
print ('#: %s:%d\n' % (path, lineno) +
73
'msgid %s\n' % normalize(s) +
76
def poentry_per_paragraph(path, lineno, msgid):
77
paragraphs = msgid.split('\n\n')
79
poentry(path, lineno, p)
80
lineno += p.count('\n') + 2
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('\\', '\\\\'))
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"
94
return src.count('\n', 0, end)
98
"""Import a path like foo/bar/baz.py and return the baz module."""
99
if path.endswith('.py'):
101
if path.endswith('/__init__'):
103
path = path.replace('/', '.')
104
mod = __import__(path)
105
for comp in path.split('.')[1:]:
106
mod = getattr(mod, comp)
109
def options(path, lineno, 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()))
116
def docstrings(path):
117
"""Extract docstrings from path.
119
This respects the Bazaar cmdtable/table convention and will
120
only extract docstrings from functions mentioned in these tables.
122
from bzrlib.commands import Command as cmd_klass
123
mod = importpath(path)
124
for name in dir(mod):
125
if not name.startswith('cmd_'):
127
obj = getattr(mod, name)
131
doc = inspect.cleandoc(doc)
134
except AttributeError:
136
if (inspect.isclass(obj) and issubclass(obj, cmd_klass)
137
and not obj is cmd_klass):
138
lineno = inspect.findsource(obj)[1]
139
poentry_per_paragraph(path, lineno, doc)
140
options(path, lineno, obj)
143
"""Extract fmt string from bzrlib.errors."""
144
from bzrlib import errors
145
base_klass = errors.BzrError
146
for name in dir(errors):
147
klass = getattr(errors, name)
148
if not inspect.isclass(klass):
150
if not issubclass(klass, base_klass):
152
if klass is base_klass:
154
if klass.internal_error:
156
fmt = getattr(klass, "_fmt", None)
158
poentry('bzrlib/erros.py', inspect.findsource(klass)[1], fmt)
162
src = open(path).read()
163
poentry_per_paragraph(path, 1, src)
166
if __name__ == "__main__":
167
# It is very important that we import the Bazaar modules from
168
# the source tree where bzrgettext is executed. Otherwise we might
169
# accidentally import and extract strings from a Bazaar
170
# installation mentioned in PYTHONPATH.
171
sys.path.insert(0, os.getcwd())
172
import bzrlib.lazy_import
173
for path in sys.argv[1:]:
174
if path.endswith('.txt'):