git-cola v3.3
[git-cola.git] / extras / build_pot.py
blobd012bddd7c0fcab9cbfa9c9d5353b94dcbd6c291
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 = [('build-dir=', 'd', 'Directory to put POT file'),
24 ('output=', 'o', 'POT filename'),
25 ('lang=', None,
26 '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')]
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 "
49 "--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', self.build_dir,
74 '--output', self.output,
76 cmd.extend(glob.glob('bin/git-*'))
77 cmd.extend(glob.glob('share/git-cola/bin/git-*'))
78 cmd.extend(glob.glob('cola/*.py'))
79 cmd.extend(glob.glob('cola/*/*.py'))
80 self.spawn(cmd)
82 _force_LF(fullname)
83 # regenerate english PO
84 if self.english:
85 log.info('Regenerating English PO file...')
86 if prj_name:
87 en_po = prj_name + '-' + 'en.po'
88 else:
89 en_po = 'en.po'
90 self.spawn([
91 'msginit',
92 '--no-translator',
93 '--locale', 'en',
94 '--input', os.path.join(self.build_dir, self.output),
95 '--output-file', os.path.join(self.build_dir, en_po)])
96 # search and update all po-files
97 if self.no_lang:
98 return
99 for po in glob.glob(os.path.join(self.build_dir, '*.po')):
100 if self.lang is not None:
101 po_lang = os.path.splitext(os.path.basename(po))[0]
102 if prj_name and po_lang.startswith(prj_name+'-'):
103 po_lang = po_lang[5:]
104 if po_lang not in self.lang:
105 continue
106 new_po = po + '.new'
107 self.spawn([
108 'msgmerge',
109 '--no-location',
110 '--no-wrap',
111 '--sort-output',
112 '--output-file', new_po,
113 po, fullname])
114 # force LF line-endings
115 log.info('%s --> %s' % (new_po, po))
116 _force_LF(new_po, po)
117 os.unlink(new_po)
120 def _force_LF(src, dst=None):
121 f = open(src, 'rU')
122 try:
123 content = f.read()
124 finally:
125 f.close()
126 if dst is None:
127 dst = src
128 f = open(dst, 'wb')
129 try:
130 f.write(build_util.encode(content))
131 finally:
132 f.close()