/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/export_pot.py

  • Committer: Jelmer Vernooij
  • Date: 2020-03-22 01:35:14 UTC
  • mfrom: (7490.7.6 work)
  • mto: This revision was merged to the branch mainline in revision 7499.
  • Revision ID: jelmer@jelmer.uk-20200322013514-7vw1ntwho04rcuj3
merge lp:brz/3.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
is also left to that stage of the process.
27
27
"""
28
28
 
29
 
from __future__ import absolute_import
30
 
 
31
29
import inspect
32
30
import os
 
31
import sys
33
32
 
34
33
import breezy
35
34
from . import (
38
37
    help_topics,
39
38
    option,
40
39
    plugin as _mod_plugin,
41
 
    help,
42
40
    )
43
41
from .trace import (
44
42
    mutter,
49
47
 
50
48
def _escape(s):
51
49
    s = (s.replace('\\', '\\\\')
52
 
        .replace('\n', '\\n')
53
 
        .replace('\r', '\\r')
54
 
        .replace('\t', '\\t')
55
 
        .replace('"', '\\"')
56
 
        )
 
50
         .replace('\n', '\\n')
 
51
         .replace('\r', '\\r')
 
52
         .replace('\t', '\\t')
 
53
         .replace('"', '\\"')
 
54
         )
57
55
    return s
58
56
 
 
57
 
59
58
def _normalize(s):
60
59
    # This converts the various Python string types into a format that
61
60
    # is appropriate for .po files, namely much closer to C style.
71
70
    return s
72
71
 
73
72
 
74
 
def _parse_source(source_text):
 
73
def _parse_source(source_text, filename='<unknown>'):
75
74
    """Get object to lineno mappings from given source_text"""
76
75
    import ast
77
76
    cls_to_lineno = {}
78
77
    str_to_lineno = {}
79
 
    for node in ast.walk(ast.parse(source_text)):
 
78
    for node in ast.walk(ast.parse(source_text, filename)):
80
79
        # TODO: worry about duplicates?
81
80
        if isinstance(node, ast.ClassDef):
82
81
            # TODO: worry about nesting?
86
85
            # string terminates on. It's more useful to have the line the
87
86
            # string begins on. Unfortunately, counting back newlines is
88
87
            # only an approximation as the AST is ignorant of escaping.
89
 
            str_to_lineno[node.s] = node.lineno - node.s.count('\n')
 
88
            str_to_lineno[node.s] = node.lineno - (0 if sys.version_info >= (3, 8) else node.s.count('\n'))
90
89
    return cls_to_lineno, str_to_lineno
91
90
 
92
91
 
106
105
        # TODO: fix this to do the right thing rather than rely on cwd
107
106
        relpath = os.path.relpath(sourcepath)
108
107
        return cls(relpath,
109
 
            _source_info=_parse_source("".join(inspect.findsource(module)[0])))
 
108
                   _source_info=_parse_source("".join(inspect.findsource(module)[0]), module.__file__))
110
109
 
111
110
    def from_class(self, cls):
112
111
        """Get new context with same details but lineno of class in source"""
116
115
            mutter("Definition of %r not found in %r", cls, self.path)
117
116
            return self
118
117
        return self.__class__(self.path, lineno,
119
 
            (self._cls_to_lineno, self._str_to_lineno))
 
118
                              (self._cls_to_lineno, self._str_to_lineno))
120
119
 
121
120
    def from_string(self, string):
122
121
        """Get new context with same details but lineno of string in source"""
126
125
            mutter("String %r not found in %r", string[:20], self.path)
127
126
            return self
128
127
        return self.__class__(self.path, lineno,
129
 
            (self._cls_to_lineno, self._str_to_lineno))
 
128
                              (self._cls_to_lineno, self._str_to_lineno))
130
129
 
131
130
 
132
131
class _PotExporter(object):
150
149
        else:
151
150
            comment = "# %s\n" % comment
152
151
        mutter("Exporting msg %r at line %d in %r", s[:20], lineno, path)
153
 
        self.outf.write(
 
152
        line = (
154
153
            "#: {path}:{lineno}\n"
155
154
            "{comment}"
156
155
            "msgid {msg}\n"
157
156
            "msgstr \"\"\n"
158
157
            "\n".format(
159
158
                path=path, lineno=lineno, comment=comment, msg=_normalize(s)))
 
159
        self.outf.write(line)
160
160
 
161
161
    def poentry_in_context(self, context, string, comment=None):
162
162
        context = context.from_string(string)
185
185
 
186
186
def _write_option(exporter, context, opt, note):
187
187
    if getattr(opt, 'hidden', False):
188
 
        return   
 
188
        return
189
189
    optname = opt.name
190
190
    if getattr(opt, 'title', None):
191
191
        exporter.poentry_in_context(context, opt.title,
192
 
            "title of {name!r} {what}".format(name=optname, what=note))
 
192
                                    "title of {name!r} {what}".format(name=optname, what=note))
193
193
    for name, _, _, helptxt in opt.iter_switches():
194
194
        if name != optname:
195
195
            if opt.is_hidden(name):
197
197
            name = "=".join([optname, name])
198
198
        if helptxt:
199
199
            exporter.poentry_in_context(context, helptxt,
200
 
                "help of {name!r} {what}".format(name=name, what=note))
 
200
                                        "help of {name!r} {what}".format(name=name, what=note))
201
201
 
202
202
 
203
203
def _standard_options(exporter):
229
229
            return True
230
230
 
231
231
    exporter.poentry_per_paragraph(dcontext.path, dcontext.lineno, doc,
232
 
        exclude_usage)
 
232
                                   exclude_usage)
233
233
    _command_options(exporter, context, cmd)
234
234
 
235
235
 
255
255
    if plugin_name is not None and plugin_name not in plugins:
256
256
        raise errors.BzrError(gettext('Plugin %s is not loaded' % plugin_name))
257
257
    core_plugins = set(
258
 
            name for name in plugins
259
 
            if plugins[name].path().startswith(breezy.__path__[0]))
 
258
        name for name in plugins
 
259
        if plugins[name].path().startswith(breezy.__path__[0]))
260
260
    # plugins
261
261
    for cmd_name in _mod_commands.plugin_command_names():
262
262
        command = _mod_commands.get_cmd_object(cmd_name, False)
271
271
            # TODO: Support extracting from third party plugins.
272
272
            continue
273
273
        note(gettext("Exporting messages from plugin command: {0} in {1}").format(
274
 
             cmd_name, command.plugin_name() ))
 
274
             cmd_name, command.plugin_name()))
275
275
        _write_command_help(exporter, command)
276
276
 
277
277
 
301
301
        doc = topic_registry.get(key)
302
302
        if isinstance(doc, str):
303
303
            exporter.poentry_per_paragraph(
304
 
                    'dummy/help_topics/'+key+'/detail.txt',
305
 
                    1, doc)
306
 
        elif callable(doc): # help topics from files
 
304
                'dummy/help_topics/' + key + '/detail.txt',
 
305
                1, doc)
 
306
        elif callable(doc):  # help topics from files
307
307
            exporter.poentry_per_paragraph(
308
 
                    'en/help_topics/'+key+'.txt',
309
 
                    1, doc(key))
 
308
                'en/help_topics/' + key + '.txt',
 
309
                1, doc(key))
310
310
        summary = topic_registry.get_summary(key)
311
311
        if summary is not None:
312
 
            exporter.poentry('dummy/help_topics/'+key+'/summary.txt',
313
 
                     1, summary)
 
312
            exporter.poentry('dummy/help_topics/' + key + '/summary.txt',
 
313
                             1, summary)
314
314
 
315
315
 
316
316
def export_pot(outf, plugin=None, include_duplicates=False):