File: l10n_diff_index.py

package info (click to toggle)
trac 1.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 17,452 kB
  • ctags: 8,602
  • sloc: python: 71,206; makefile: 358; sh: 79; xml: 10
file content (107 lines) | stat: -rwxr-xr-x 3,106 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2013 Edgewall Software
# Copyright (C) 2013 Christian Boos <cboos@edgewall.org>
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://trac.edgewall.com/license.html.
#
# This software consists of voluntary contributions made by many
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://trac.edgewall.org/.

"""

L10N tool which prepares an index of "interesting" changes found in a
.diff.

Skipped changes are:
 - the changes for which the msgid has changed
 - removal only of msgstr content


Example workflow 1), review changes to the 'fr' translation before
committing:

  make diff-fr | less


Example workflow 2), force a pull of all changes from Transifex::

  make update updateopts=-N
  tx pull -f
  make update updateopts=-N
  svn diff > tx.diff
  python l10n_diff_index.py tx.diff
  svn revert -R .

And then use either::

  emacs tx.diff.index --eval '(grep-mode)'

or::

  vim -c :cbuffer -c :copen tx.diff.index

This makes it easier to go through the potentially interesting changes
only, and apply the corresponding chunks if needed.

"""

from __future__ import print_function

from bisect import bisect_left
import re

interesting_changes_re = re.compile(r'''
                                               \n
       \s (?: msgid(?:_plural)?\s)? ".*"       \n  # ' ' msgid or "...",
   (?:
       [-\s]  ".*"                             \n  # ' ' or - "...",
   |
       -      msgstr(?:\[\d+\])? \s ".*"       \n  # or the -msgstr
   )*

 (?:
     ( \+     msgstr(?:\[\d+\])? \s "[^"].*" ) \n  # \1 is a non-empty +msgstr
 |
       [+\s]  msgstr(?:\[\d+\])? \s ".*"       \n  # or after the msgstr,
   (?: [-\s]  ".*"                             \n  # optional ' ' or -"...",
   )*
     ( \+     "[^"].*" )                           # \2 is a non-empty +"..."
 )
''', re.MULTILINE | re.VERBOSE)

def index_diffs(path, diffs):
    linenums = []
    re.sub(r'\n', lambda m: linenums.append(m.start()), diffs)
    index = []
    for m in interesting_changes_re.finditer(diffs):
        line = m.group(m.lastindex)
        if line.startswith(('+"Project-Id-Version:', '+"PO-Revision-Date:')):
            continue
        pos = m.start(m.lastindex)
        index.append((bisect_left(linenums, pos) + 1, line))
    return index

def write_index_for(path):
    with open(path, 'rb') as f:
        diffs = unicode(f.read(), 'utf-8')
    changes = index_diffs(path, diffs)
    if changes:
        index = path + '.index'
        with open(index, 'wb') as idx:
            for n, line in changes:
                print((u"%s:%s: %s" % (path, n, line)).encode('utf-8'),
                      file=idx)
        print("%s: %d changes indexed in %s" % (path, len(changes), index))
    else:
        print("%s: no interesting changes" % path)

if __name__ == '__main__':
    import sys
    for path in sys.argv[1:]:
        write_index_for(path)