widgets: use qtutils.BlockSignals to manage blockSignals(bool)
[git-cola.git] / extras / build_pot.py
blob57a0cdda5889f6db8c95422c903c7758cecd7080
1 """build_pot command for setup.py"""
2 # pylint: disable=attribute-defined-outside-init
3 # pylint: disable=no-name-in-module,import-error
4 from __future__ import absolute_import, division, unicode_literals
5 import os
6 import glob
7 from distutils import log
8 from distutils.core import Command
9 from distutils.errors import DistutilsOptionError
11 from . import build_util
14 class build_pot(Command):
15 """Distutils command build_pot"""
17 description = 'extract strings from python sources for translation'
19 # List of options:
20 # - long name,
21 # - short name (None if no short name),
22 # - help string.
23 user_options = [
24 ('build-dir=', 'd', 'Directory to put POT file'),
25 ('output=', 'o', 'POT filename'),
26 ('lang=', None, 'Comma-separated list of languages to update po-files'),
27 ('no-lang', 'N', "Don't update po-files"),
28 ('english', 'E', 'Regenerate English PO file'),
30 user_options = build_util.stringify_options(user_options)
31 boolean_options = build_util.stringify_list(['no-lang', 'english'])
33 def initialize_options(self):
34 self.build_dir = None
35 self.output = None
36 self.lang = None
37 self.no_lang = False
38 self.english = False
40 def finalize_options(self):
41 if self.build_dir is None:
42 self.build_dir = 'po'
43 if not self.output:
44 self.output = (self.distribution.get_name() or 'messages') + '.pot'
45 if self.lang is not None:
46 self.lang = [i.strip() for i in self.lang.split(',') if i.strip()]
47 if self.lang and self.no_lang:
48 raise DistutilsOptionError(
49 "You can't use options " "--lang=XXX and --no-lang in the same time."
52 def run(self):
53 """Run xgettext for project sources"""
54 # project name based on `name` argument in setup() call
55 prj_name = self.distribution.get_name()
56 # output file
57 if self.build_dir != '.':
58 fullname = os.path.join(self.build_dir, self.output)
59 else:
60 fullname = self.output
61 log.info('Generate POT file: ' + fullname)
62 if not os.path.isdir(self.build_dir):
63 log.info('Make directory: ' + self.build_dir)
64 os.makedirs(self.build_dir)
66 cmd = [
67 'xgettext',
68 '--language=Python',
69 '--keyword=N_',
70 '--no-wrap',
71 '--no-location',
72 '--omit-header',
73 '--sort-output',
74 '--output-dir',
75 self.build_dir,
76 '--output',
77 self.output,
79 cmd.extend(glob.glob('bin/git-*'))
80 cmd.extend(glob.glob('share/git-cola/bin/git-*'))
81 cmd.extend(glob.glob('cola/*.py'))
82 cmd.extend(glob.glob('cola/*/*.py'))
83 self.spawn(cmd)
85 _force_LF(fullname)
86 # regenerate english PO
87 if self.english:
88 log.info('Regenerating English PO file...')
89 if prj_name:
90 en_po = prj_name + '-' + 'en.po'
91 else:
92 en_po = 'en.po'
93 self.spawn(
95 'msginit',
96 '--no-translator',
97 '--locale',
98 'en',
99 '--input',
100 os.path.join(self.build_dir, self.output),
101 '--output-file',
102 os.path.join(self.build_dir, en_po),
105 # search and update all po-files
106 if self.no_lang:
107 return
108 for po in glob.glob(os.path.join(self.build_dir, '*.po')):
109 if self.lang is not None:
110 po_lang = os.path.splitext(os.path.basename(po))[0]
111 if prj_name and po_lang.startswith(prj_name + '-'):
112 po_lang = po_lang[5:]
113 if po_lang not in self.lang:
114 continue
115 new_po = po + '.new'
116 self.spawn(
118 'msgmerge',
119 '--no-location',
120 '--no-wrap',
121 '--no-fuzzy-matching',
122 '--sort-output',
123 '--output-file',
124 new_po,
126 fullname,
129 # force LF line-endings
130 log.info('%s --> %s' % (new_po, po))
131 _force_LF(new_po, po)
132 os.unlink(new_po)
135 def _force_LF(src, dst=None):
136 with open(src, 'rb') as f:
137 content = f.read().decode('utf-8')
138 if dst is None:
139 dst = src
140 f = open(dst, 'wb')
141 try:
142 f.write(build_util.encode(content))
143 finally:
144 f.close()