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