def _CheckGnOutputsRange(gn_lines, start, end, wanted_locales): if not _CheckGnOutputsRangeForLocalizedStrings(gn_lines, start, end): return [] errors = [] locales = set() for pos in xrange(start, end): line = gn_lines[pos] android_locale = _GetAndroidGnOutputLocale(line) assert android_locale != None cr_locale = resource_utils.ToChromiumLocaleName(android_locale) if cr_locale in locales: errors.append('%s: Redefinition of output for "%s" locale' % (pos + 1, android_locale)) locales.add(cr_locale) extra_locales = locales.difference(wanted_locales) if extra_locales: errors.append('%d-%d: Extra locales: %s' % (start + 1, end + 1, sorted(extra_locales))) missing_locales = wanted_locales.difference(locales) if missing_locales: errors.append('%d-%d: Missing locales: %s' % (start + 1, end + 1, sorted(missing_locales))) return errors
def _RenameLocaleResourceDirs(resource_dirs): """Rename locale resource directories into standard names when necessary. This is necessary to deal with the fact that older Android releases only support ISO 639-1 two-letter codes, and sometimes even obsolete versions of them. In practice it means: * 3-letter ISO 639-2 qualifiers are renamed under a corresponding 2-letter one. E.g. for Filipino, strings under values-fil/ will be moved to a new corresponding values-tl/ sub-directory. * Modern ISO 639-1 codes will be renamed to their obsolete variant for Indonesian, Hebrew and Yiddish (e.g. 'values-in/ -> values-id/). * Norwegian macrolanguage strings will be renamed to Bokmål (main Norway language). See http://crbug.com/920960. In practice this means that 'values-no/ -> values-nb/' unless 'values-nb/' already exists. * BCP 47 langauge tags will be renamed to an equivalent ISO 639-1 locale qualifier if possible (e.g. 'values-b+en+US/ -> values-en-rUS'). Though this is not necessary at the moment, because no third-party package that Chromium links against uses these for the current list of supported locales, this may change when the list is extended in the future). Args: resource_dirs: list of top-level resource directories. Returns: A dictionary mapping renamed paths to their original location (e.g. '.../values-tl/strings.xml' -> ' .../values-fil/strings.xml'). """ renamed_paths = dict() for resource_dir in resource_dirs: for path in _IterFiles(resource_dir): locale = resource_utils.FindLocaleInStringResourceFilePath(path) if not locale: continue cr_locale = resource_utils.ToChromiumLocaleName(locale) if not cr_locale: continue # Unsupported Android locale qualifier!? locale2 = resource_utils.ToAndroidLocaleName(cr_locale) if locale != locale2: path2 = path.replace('/values-%s/' % locale, '/values-%s/' % locale2) if path == path2: raise Exception( 'Could not substitute locale %s for %s in %s' % (locale, locale2, path)) if os.path.exists(path2): # This happens sometimes, e.g. some libraries provide both # values-nb/ and values-no/ with the same content. continue build_utils.MakeDirectory(os.path.dirname(path2)) shutil.move(path, path2) renamed_paths[os.path.relpath(path2, resource_dir)] = os.path.relpath( path, resource_dir) return renamed_paths
def _AddMissingLocalesInGnOutputs(gn_lines, wanted_locales): intervals = _BuildIntervalList(gn_lines, _IsAndroidGnOutputLine) # NOTE: Since this may insert new lines to each interval, process the # list in reverse order to maintain valid (start,end) positions during # the iteration. for start, end in reversed(intervals): if not _CheckGnOutputsRangeForLocalizedStrings(gn_lines, start, end): continue locales = set() for pos in xrange(start, end): lang = _GetAndroidGnOutputLocale(gn_lines[pos]) locale = resource_utils.ToChromiumLocaleName(lang) locales.add(locale) missing_locales = wanted_locales.difference(locales) if not missing_locales: continue src_locale = 'bg' src_values = 'values-%s/' % resource_utils.ToAndroidLocaleName( src_locale) src_line = None for pos in xrange(start, end): if src_values in gn_lines[pos]: src_line = gn_lines[pos] break if not src_line: raise Exception('Cannot find output list item with "%s" locale' % src_locale) line_count = end - 1 for locale in missing_locales: if locale == _DEFAULT_LOCALE: dst_line = src_line.replace('values-%s/' % src_locale, 'values/') else: dst_line = src_line.replace( 'values-%s/' % src_locale, 'values-%s/' % resource_utils.ToAndroidLocaleName(locale)) gn_lines.insert(line_count, dst_line) line_count += 1 gn_lines = _SortListSubRange( gn_lines, start, line_count, lambda line: _RE_GN_VALUES_LIST_LINE.match(line).group(1)) return gn_lines
def _RenameLocaleResourceDirs(resource_dirs, path_info): """Rename locale resource directories into standard names when necessary. This is necessary to deal with the fact that older Android releases only support ISO 639-1 two-letter codes, and sometimes even obsolete versions of them. In practice it means: * 3-letter ISO 639-2 qualifiers are renamed under a corresponding 2-letter one. E.g. for Filipino, strings under values-fil/ will be moved to a new corresponding values-tl/ sub-directory. * Modern ISO 639-1 codes will be renamed to their obsolete variant for Indonesian, Hebrew and Yiddish (e.g. 'values-in/ -> values-id/). * Norwegian macrolanguage strings will be renamed to Bokmal (main Norway language). See http://crbug.com/920960. In practice this means that 'values-no/ -> values-nb/' unless 'values-nb/' already exists. * BCP 47 langauge tags will be renamed to an equivalent ISO 639-1 locale qualifier if possible (e.g. 'values-b+en+US/ -> values-en-rUS'). Args: resource_dirs: list of top-level resource directories. """ for resource_dir in resource_dirs: ignore_dirs = {} for path in _IterFiles(resource_dir): locale = resource_utils.FindLocaleInStringResourceFilePath(path) if not locale: continue cr_locale = resource_utils.ToChromiumLocaleName(locale) if not cr_locale: continue # Unsupported Android locale qualifier!? locale2 = resource_utils.ToAndroidLocaleName(cr_locale) if locale != locale2: path2 = path.replace('/values-%s/' % locale, '/values-%s/' % locale2) if path == path2: raise Exception( 'Could not substitute locale %s for %s in %s' % (locale, locale2, path)) # Ignore rather than rename when the destination resources config # already exists. # e.g. some libraries provide both values-nb/ and values-no/. # e.g. material design provides: # * res/values-rUS/values-rUS.xml # * res/values-b+es+419/values-b+es+419.xml config_dir = os.path.dirname(path2) already_has_renamed_config = ignore_dirs.get(config_dir) if already_has_renamed_config is None: # Cache the result of the first time the directory is encountered # since subsequent encounters will find the directory already exists # (due to the rename). already_has_renamed_config = os.path.exists(config_dir) ignore_dirs[config_dir] = already_has_renamed_config if already_has_renamed_config: continue build_utils.MakeDirectory(os.path.dirname(path2)) shutil.move(path, path2) path_info.RegisterRename(os.path.relpath(path, resource_dir), os.path.relpath(path2, resource_dir))