-
Notifications
You must be signed in to change notification settings - Fork 43
/
releaseutils.py
executable file
·218 lines (180 loc) · 6.72 KB
/
releaseutils.py
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#!/usr/bin/python -tt
# Copyright Red Hat Inc 2013-2015
# Licensed under the terms of the LGPLv2+
from __future__ import print_function
import glob
import os
import shutil
import sys
import textwrap
from contextlib import contextmanager
from distutils.sysconfig import get_python_lib
from kitchen.pycompat27 import subprocess
import pkg_resources
import fedora.release
from six.moves import configparser, map
#
# Helper functions
#
@contextmanager
def pushd(dirname):
'''Contextmanager so that we can switch directories that the script is
running in and have the current working directory restored afterwards.
'''
curdir = os.getcwd()
os.chdir(dirname)
try:
yield curdir
finally:
os.chdir(curdir)
class MsgFmt(object):
def run(self, args):
cmd = subprocess.Popen(args, shell=False)
cmd.wait()
def setup_message_compiler():
# Look for msgfmt
try:
# Prefer msgfmt because it will throw errors on misformatted messages
subprocess.Popen(['msgfmt', '-h'], stdout=subprocess.PIPE)
except OSError:
import babel.messages.frontend
return (
babel.messages.frontend.CommandLineInterface(),
'pybabel compile -D %(domain)s -d locale -i %(pofile)s -l %(lang)s'
)
else:
return (
MsgFmt(),
'msgfmt -c -o locale/%(lang)s/LC_MESSAGES/%(domain)s.mo %(pofile)s'
)
def build_catalogs():
# Get the directory with message catalogs
# Reuse transifex's config file first as it will know this
cfg = configparser.SafeConfigParser()
cfg.read('.tx/config')
cmd, args = setup_message_compiler()
try:
shutil.rmtree('locale')
except OSError as e:
# If the error is that locale does not exist, we're okay. We're
# deleting it here, afterall
if e.errno != 2:
raise
for section in [s for s in cfg.sections() if s != 'main']:
try:
file_filter = cfg.get(section, 'file_filter')
source_file = cfg.get(section, 'source_file')
except configparser.NoOptionError:
continue
glob_pattern = file_filter.replace('<lang>', '*')
pot = os.path.basename(source_file)
if pot.endswith('.pot'):
pot = pot[:-4]
arg_values = {'domain': pot}
for po_file in glob.glob(glob_pattern):
file_pattern = os.path.basename(po_file)
lang = file_pattern.replace('.po', '')
os.makedirs(os.path.join('locale', lang, 'LC_MESSAGES'))
arg_values['pofile'] = po_file
arg_values['lang'] = lang
compile_args = args % arg_values
compile_args = compile_args.split(' ')
cmd.run(compile_args)
def _add_destdir(path):
if ENVVARS['DESTDIR'] is not None:
if path.startswith('/'):
path = path[1:]
path = os.path.join(ENVVARS['DESTDIR'], path)
return path
def _install_catalogs(localedir):
with pushd('locale'):
for catalog in glob.glob('*/LC_MESSAGES/*.mo'):
# Make the directory for the locale
dirname = os.path.dirname(catalog)
dst = os.path.join(localedir, dirname)
try:
os.makedirs(dst, 0o755)
except OSError as e:
# Only allow file exists to pass
if e.errno != 17:
raise
shutil.copy2(catalog, dst)
def install_catalogs():
# First try to install the messages to an FHS location
if ENVVARS['INSTALLSTRATEGY'] == 'EGG':
localedir = get_python_lib()
# Need certain info from the user
if ENVVARS['PACKAGENAME'] is None:
print ('Set the PACKAGENAME environment variable and try again')
sys.exit(2)
if ENVVARS['MODULENAME'] is None:
print ('Set the MODULENAME environment variable and try again')
sys.exit(2)
# Get teh egg name from pkg_resources
dist = pkg_resources.Distribution(project_name=ENVVARS['PACKAGENAME'],
version=fedora.release.VERSION)
# Set the localedir to be inside the egg directory
localedir = os.path.join(localedir, '{}.egg'.format(dist.egg_name()),
ENVVARS['MODULENAME'], 'locale')
# Tack on DESTDIR if needed
localedir = _add_destdir(localedir)
_install_catalogs(localedir)
elif ENVVARS['INSTALLSTRATEGY'] == 'SITEPACKAGES':
# For a generic utility to be used with other modules, this would also
# need to handle arch-specific locations (get_python_lib(1))
# Retrieve the site-packages directory
localedir = get_python_lib()
# Set the install path to be inside of the module in site-packages
if ENVVARS['MODULENAME'] is None:
print ('Set the MODULENAME environment variable and try again')
sys.exit(2)
localedir = os.path.join(localedir, ENVVARS['MODULENAME'], 'locale')
localedir = _add_destdir(localedir)
_install_catalogs(localedir)
else:
# FHS
localedir = _add_destdir('/usr/share/locale')
_install_catalogs(localedir)
def usage():
print ('Subcommands:')
for command in sorted(SUBCOMMANDS.keys()):
print('%-15s %s' % (command, SUBCOMMANDS[command][1]))
print()
print('This script can be customized by setting the following ENV VARS:')
for var in sorted(ENVVARDESC.keys()):
lines = textwrap.wrap(
'%-15s %s' % (var, ENVVARDESC[var]),
subsequent_indent=' '*8
)
for line in lines:
print(line.rstrip())
sys.exit(1)
SUBCOMMANDS = {
'build_catalogs': (
build_catalogs, 'Compile the message catalogs from po files'
),
'install_catalogs': (
install_catalogs,
'Install the message catalogs to the system'
),
}
ENVVARDESC = {
'DESTDIR': 'Alternate root directory hierarchy to install into',
'PACKAGENAME': 'Pypi packagename (commonly the setup.py name field)',
'MODULENAME': 'Python module name (commonly used with import NAME)',
'INSTALLSTRATEGY': 'One of FHS, EGG, SITEPACKAGES. FHS will work'
' for system packages installed using'
' --single-version-externally-managed. EGG install into an egg'
' directory. SITEPACKAGES will install into a $PACKAGENAME'
' directory directly in site-packages. Default FHS'
}
ENVVARS = dict(map(lambda k: (k, os.environ.get(k)), ENVVARDESC.keys()))
if __name__ == '__main__':
if len(sys.argv) < 2:
print('At least one subcommand is needed\n')
usage()
try:
SUBCOMMANDS[sys.argv[1]][0]()
except KeyError:
print ('Unknown subcommand: %s\n' % sys.argv[1])
usage()