def main(): p = argparse.ArgumentParser( description='Validate localizable strings', epilog=epilog, ) p.add_argument('l10n_toml') p.add_argument('--version', action='version', version='%(prog)s ' + version) p.add_argument('-W', action='store_true', help='error on warnings') p.add_argument( '--l10n-reference', dest='l10n_reference', metavar='PATH', help='check for conflicts against an l10n-only reference repository ' 'like gecko-strings', ) p.add_argument( '--reference-project', dest='ref_project', metavar='PATH', help='check for conflicts against a reference project like ' 'android-l10n', ) args = p.parse_args() if args.l10n_reference: l10n_base, locale = \ os.path.split(os.path.abspath(args.l10n_reference)) if not locale or not os.path.isdir(args.l10n_reference): p.error('Pass an existing l10n reference') else: l10n_base = '.' locale = None pc = paths.TOMLParser().parse(args.l10n_toml, env={'l10n_base': l10n_base}) if locale: pc.set_locales([locale], deep=True) files = paths.ProjectFiles(locale, [pc]) get_reference_and_tests = default_reference_and_tests if args.l10n_reference: get_reference_and_tests = l10n_base_reference_and_tests(files) elif args.ref_project: get_reference_and_tests = mirror_reference_and_tests( files, args.ref_project) linter = L10nLinter() results = linter.lint( (f for f, _, _, _ in files.iter_reference() if parser.hasParser(f)), get_reference_and_tests) rv = 0 if results: rv = 1 if all(r['level'] == 'warning' for r in results) and not args.W: rv = 0 for result in results: print('{} ({}:{}): {}'.format(mozpath.relpath(result['path'], '.'), result.get('lineno', 0), result.get('column', 0), result['message'])) return rv
def compareProjects(project_configs, stat_observer=None, file_stats=False, merge_stage=None, clobber_merge=False): locales = set() observers = [] for project in project_configs: observers.append(Observer(filter=project.filter, file_stats=file_stats)) locales.update(project.locales) if stat_observer is not None: stat_observers = [stat_observer] else: stat_observers = None comparer = ContentComparer(observers, stat_observers=stat_observers) for locale in sorted(locales): files = paths.ProjectFiles(locale, project_configs, mergebase=merge_stage) root = mozpath.commonprefix([m['l10n'].prefix for m in files.matchers]) if merge_stage is not None: if clobber_merge: mergematchers = set(_m.get('merge') for _m in files.matchers) mergematchers.discard(None) for matcher in mergematchers: clobberdir = matcher.prefix if os.path.exists(clobberdir): shutil.rmtree(clobberdir) print "clobbered " + clobberdir for l10npath, refpath, mergepath, extra_tests in files: # module and file path are needed for legacy filter.py support module = None fpath = mozpath.relpath(l10npath, root) for _m in files.matchers: if _m['l10n'].match(l10npath): if _m['module']: # legacy ini support, set module, and resolve # local path against the matcher prefix, # which includes the module module = _m['module'] fpath = mozpath.relpath(l10npath, _m['l10n'].prefix) break reffile = paths.File(refpath, fpath or refpath, module=module) l10n = paths.File(l10npath, fpath or l10npath, module=module, locale=locale) if not os.path.exists(l10npath): comparer.add(reffile, l10n) continue if not os.path.exists(refpath): comparer.remove(l10n) continue comparer.compare(reffile, l10n, mergepath, extra_tests) return observers
def extractStrings(self): """Extract strings from all locales.""" basedir = os.path.dirname(self.toml_path) project_config = paths.TOMLParser().parse(self.toml_path, env={"l10n_base": ""}) basedir = os.path.join(basedir, project_config.root) reference_cache = {} self.translations[self.reference_locale] = {} for locale in project_config.all_locales: files = paths.ProjectFiles(locale, [project_config]) self.translations[locale] = {} for l10n_file, reference_file, _, _ in files: if not os.path.exists(l10n_file): # File not available in localization continue if not os.path.exists(reference_file): # File not available in reference continue key_path = os.path.relpath(reference_file, basedir) try: p = getParser(reference_file) except UserWarning: continue if key_path not in reference_cache: p.readFile(reference_file) reference_cache[key_path] = set(p.parse().keys()) self.translations[self.reference_locale].update(( "{}/{}:{}".format(self.repository_name, key_path, entity.key), entity.raw_val, ) for entity in p.parse()) p.readFile(l10n_file) self.translations[locale].update(( "{}/{}:{}".format(self.repository_name, key_path, entity.key), entity.raw_val, ) for entity in p.parse())
def compareProjects( project_configs, l10n_base_dir, stat_observer=None, merge_stage=None, clobber_merge=False, quiet=0, ): locales = set() comparer = ContentComparer(quiet) observers = comparer.observers for project in project_configs: # disable filter if we're in validation mode if None in project.locales: filter = None else: filter = project.filter observers.append(Observer( quiet=quiet, filter=filter, )) locales.update(project.locales) for locale in sorted(locales): files = paths.ProjectFiles(locale, project_configs, mergebase=merge_stage) if merge_stage is not None: if clobber_merge: mergematchers = set(_m.get('merge') for _m in files.matchers) mergematchers.discard(None) for matcher in mergematchers: clobberdir = matcher.prefix if os.path.exists(clobberdir): shutil.rmtree(clobberdir) print("clobbered " + clobberdir) for l10npath, refpath, mergepath, extra_tests in files: # module and file path are needed for legacy filter.py support module = None fpath = mozpath.relpath(l10npath, l10n_base_dir) for _m in files.matchers: if _m['l10n'].match(l10npath): if _m['module']: # legacy ini support, set module, and resolve # local path against the matcher prefix, # which includes the module module = _m['module'] fpath = mozpath.relpath(l10npath, _m['l10n'].prefix) break reffile = paths.File(refpath, fpath or refpath, module=module) if locale is None: # When validating the reference files, set locale # to a private subtag. This only shows in the output. locale = paths.REFERENCE_LOCALE l10n = paths.File(l10npath, fpath or l10npath, module=module, locale=locale) if not os.path.exists(l10npath): comparer.add(reffile, l10n, mergepath) continue if not os.path.exists(refpath): comparer.remove(reffile, l10n, mergepath) continue comparer.compare(reffile, l10n, mergepath, extra_tests) return observers