core: handle utf-8 paths when LC_ALL=C
[git-cola.git] / extras / build_pot.py
bloba231476ca2792dbbf334ae0c9c28fce60efeace2
1 """build_pot command for setup.py"""
3 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
12 def encode(string):
13 try:
14 result = string.encode('utf-8')
15 except:
16 result = string
17 return result
20 class build_pot(Command):
21 """Distutils command build_pot"""
23 description = 'extract strings from python sources for translation'
25 # List of options:
26 # - long name,
27 # - short name (None if no short name),
28 # - help string.
29 user_options = [(str('build-dir='), str('d'),
30 'Directory to put POT file'),
31 (str('output='), str('o'),
32 'POT filename'),
33 (str('lang='), None,
34 'Comma-separated list of languages to update po-files'),
35 (str('no-lang'), str('N'),
36 "Don't update po-files"),
37 (str('english'), str('E'),
38 'Regenerate English PO file')]
39 boolean_options = ['no-lang', 'english']
41 def initialize_options(self):
42 self.build_dir = None
43 self.output = None
44 self.lang = None
45 self.no_lang = False
46 self.english = False
48 def finalize_options(self):
49 if self.build_dir is None:
50 self.build_dir = 'po'
51 if not self.output:
52 self.output = (self.distribution.get_name() or 'messages')+'.pot'
53 if self.lang is not None:
54 self.lang = [i.strip() for i in self.lang.split(',') if i.strip()]
55 if self.lang and self.no_lang:
56 raise DistutilsOptionError("You can't use options "
57 "--lang=XXX and --no-lang in the same time.")
59 def _force_LF(self, src, dst=None):
60 f = open(src, 'rU')
61 try:
62 content = f.read()
63 finally:
64 f.close()
65 if dst is None:
66 dst = src
67 f = open(dst, 'wb')
68 try:
69 f.write(encode(content))
70 finally:
71 f.close()
73 def run(self):
74 """Run xgettext for project sources"""
75 # project name based on `name` argument in setup() call
76 prj_name = self.distribution.get_name()
77 # output file
78 if self.build_dir != '.':
79 fullname = os.path.join(self.build_dir, self.output)
80 else:
81 fullname = self.output
82 log.info('Generate POT file: ' + fullname)
83 if not os.path.isdir(self.build_dir):
84 log.info('Make directory: ' + self.build_dir)
85 os.makedirs(self.build_dir)
86 self.spawn(['xgettext',
87 '--keyword=N_',
88 '-p', self.build_dir,
89 '-o', self.output] +
90 glob.glob('cola/*.py') +
91 glob.glob('cola/*/*.py'))
92 self._force_LF(fullname)
93 # regenerate english PO
94 if self.english:
95 log.info('Regenerating English PO file...')
96 if prj_name:
97 en_po = prj_name + '-' + 'en.po'
98 else:
99 en_po = 'en.po'
100 self.spawn(['msginit',
101 '--no-translator',
102 '-l', 'en',
103 '-i', os.path.join(self.build_dir, self.output),
104 '-o', os.path.join(self.build_dir, en_po),
106 # search and update all po-files
107 if self.no_lang:
108 return
109 for po in glob.glob(os.path.join(self.build_dir,'*.po')):
110 if self.lang is not None:
111 po_lang = os.path.splitext(os.path.basename(po))[0]
112 if prj_name and po_lang.startswith(prj_name+'-'):
113 po_lang = po_lang[5:]
114 if po_lang not in self.lang:
115 continue
116 new_po = po + ".new"
117 cmd = "msgmerge %s %s -o %s" % (po, fullname, new_po)
118 self.spawn(cmd.split())
119 # force LF line-endings
120 log.info("%s --> %s" % (new_po, po))
121 self._force_LF(new_po, po)
122 os.unlink(new_po)