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 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. """ 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) path_info.RegisterRename(os.path.relpath(path, resource_dir), os.path.relpath(path2, resource_dir))
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/). * 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. the Android support library comes # with both values-sr/ and values-b+sr+Latn/. 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 _RemoveUnwantedLocalizedStrings(dep_subdirs, options): """Remove localized strings that should not go into the final output. Args: dep_subdirs: List of resource dependency directories. options: Command-line options namespace. """ if (not options.locale_whitelist and not options.shared_resources_whitelist_locales): # Keep everything, there is nothing to do. return # Collect locale and file paths from the existing subdirs. # The following variable maps Android locale names to # sets of corresponding xml file paths. locale_to_files_map = collections.defaultdict(set) for directory in dep_subdirs: for f in _IterFiles(directory): locale = resource_utils.FindLocaleInStringResourceFilePath(f) if locale: locale_to_files_map[locale].add(f) all_locales = set(locale_to_files_map) # Set A: wanted locales, either all of them or the # list provided by --locale-whitelist. wanted_locales = all_locales if options.locale_whitelist: wanted_locales = _ToAndroidLocales(options.locale_whitelist, options.support_zh_hk) # Set B: shared resources locales, which is either set A # or the list provided by --shared-resources-whitelist-locales shared_resources_locales = wanted_locales shared_names_whitelist = set() if options.shared_resources_whitelist_locales: shared_names_whitelist = set( resource_utils.GetRTxtStringResourceNames( options.shared_resources_whitelist)) shared_resources_locales = _ToAndroidLocales( options.shared_resources_whitelist_locales, options.support_zh_hk) # Remove any file that belongs to a locale not covered by # either A or B. removable_locales = (all_locales - wanted_locales - shared_resources_locales) for locale in removable_locales: for path in locale_to_files_map[locale]: os.remove(path) # For any locale in B but not in A, only keep the shared # resource strings in each file. for locale in shared_resources_locales - wanted_locales: for path in locale_to_files_map[locale]: resource_utils.FilterAndroidResourceStringsXml( path, lambda x: x in shared_names_whitelist) # For any locale in A but not in B, only keep the strings # that are _not_ from shared resources in the file. for locale in wanted_locales - shared_resources_locales: for path in locale_to_files_map[locale]: resource_utils.FilterAndroidResourceStringsXml( path, lambda x: x not in shared_names_whitelist)
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))
def is_bad_locale(path): """Return true iff |path| is a resource for a non-whitelisted locale.""" locale = resource_utils.FindLocaleInStringResourceFilePath(path) return locale and locale not in android_locale_whitelist