1# Copyright 2016 The Meson development team 2 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6 7# http://www.apache.org/licenses/LICENSE-2.0 8 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import os 16import subprocess 17import shutil 18import argparse 19from .. import mlog 20from ..mesonlib import has_path_sep 21from . import destdir_join 22from .gettext import read_linguas 23 24parser = argparse.ArgumentParser() 25parser.add_argument('command') 26parser.add_argument('--id', dest='project_id') 27parser.add_argument('--subdir', dest='subdir') 28parser.add_argument('--installdir', dest='install_dir') 29parser.add_argument('--sources', dest='sources') 30parser.add_argument('--media', dest='media', default='') 31parser.add_argument('--langs', dest='langs', default='') 32parser.add_argument('--symlinks', type=bool, dest='symlinks', default=False) 33 34def build_pot(srcdir, project_id, sources): 35 # Must be relative paths 36 sources = [os.path.join('C', source) for source in sources] 37 outfile = os.path.join(srcdir, project_id + '.pot') 38 subprocess.call(['itstool', '-o', outfile] + sources) 39 40def update_po(srcdir, project_id, langs): 41 potfile = os.path.join(srcdir, project_id + '.pot') 42 for lang in langs: 43 pofile = os.path.join(srcdir, lang, lang + '.po') 44 subprocess.call(['msgmerge', '-q', '-o', pofile, pofile, potfile]) 45 46def build_translations(srcdir, blddir, langs): 47 for lang in langs: 48 outdir = os.path.join(blddir, lang) 49 os.makedirs(outdir, exist_ok=True) 50 subprocess.call([ 51 'msgfmt', os.path.join(srcdir, lang, lang + '.po'), 52 '-o', os.path.join(outdir, lang + '.gmo') 53 ]) 54 55def merge_translations(blddir, sources, langs): 56 for lang in langs: 57 subprocess.call([ 58 'itstool', '-m', os.path.join(blddir, lang, lang + '.gmo'), 59 '-o', os.path.join(blddir, lang) 60 ] + sources) 61 62def install_help(srcdir, blddir, sources, media, langs, install_dir, destdir, project_id, symlinks): 63 c_install_dir = os.path.join(install_dir, 'C', project_id) 64 for lang in langs + ['C']: 65 indir = destdir_join(destdir, os.path.join(install_dir, lang, project_id)) 66 os.makedirs(indir, exist_ok=True) 67 for source in sources: 68 infile = os.path.join(srcdir if lang == 'C' else blddir, lang, source) 69 outfile = os.path.join(indir, source) 70 mlog.log('Installing %s to %s' % (infile, outfile)) 71 shutil.copyfile(infile, outfile) 72 shutil.copystat(infile, outfile) 73 for m in media: 74 infile = os.path.join(srcdir, lang, m) 75 outfile = os.path.join(indir, m) 76 c_infile = os.path.join(srcdir, 'C', m) 77 if not os.path.exists(infile): 78 if not os.path.exists(c_infile): 79 mlog.warning('Media file "%s" did not exist in C directory' % m) 80 continue 81 elif symlinks: 82 srcfile = os.path.join(c_install_dir, m) 83 mlog.log('Symlinking %s to %s.' % (outfile, srcfile)) 84 if has_path_sep(m): 85 os.makedirs(os.path.dirname(outfile), exist_ok=True) 86 try: 87 try: 88 os.symlink(srcfile, outfile) 89 except FileExistsError: 90 os.remove(outfile) 91 os.symlink(srcfile, outfile) 92 continue 93 except (NotImplementedError, OSError): 94 mlog.warning('Symlinking not supported, falling back to copying') 95 infile = c_infile 96 else: 97 # Lang doesn't have media file so copy it over 'C' one 98 infile = c_infile 99 mlog.log('Installing %s to %s' % (infile, outfile)) 100 if has_path_sep(m): 101 os.makedirs(os.path.dirname(outfile), exist_ok=True) 102 shutil.copyfile(infile, outfile) 103 shutil.copystat(infile, outfile) 104 105def run(args): 106 options = parser.parse_args(args) 107 langs = options.langs.split('@@') if options.langs else [] 108 media = options.media.split('@@') if options.media else [] 109 sources = options.sources.split('@@') 110 destdir = os.environ.get('DESTDIR', '') 111 src_subdir = os.path.join(os.environ['MESON_SOURCE_ROOT'], options.subdir) 112 build_subdir = os.path.join(os.environ['MESON_BUILD_ROOT'], options.subdir) 113 abs_sources = [os.path.join(src_subdir, 'C', source) for source in sources] 114 115 if not langs: 116 langs = read_linguas(src_subdir) 117 118 if options.command == 'pot': 119 build_pot(src_subdir, options.project_id, sources) 120 elif options.command == 'update-po': 121 build_pot(src_subdir, options.project_id, sources) 122 update_po(src_subdir, options.project_id, langs) 123 elif options.command == 'build': 124 if langs: 125 build_translations(src_subdir, build_subdir, langs) 126 elif options.command == 'install': 127 install_dir = os.path.join(os.environ['MESON_INSTALL_PREFIX'], options.install_dir) 128 if langs: 129 build_translations(src_subdir, build_subdir, langs) 130 merge_translations(build_subdir, abs_sources, langs) 131 install_help(src_subdir, build_subdir, sources, media, langs, install_dir, 132 destdir, options.project_id, options.symlinks) 133