Unverified Commit 173322dc authored by Shi-Hao Hong's avatar Shi-Hao Hong Committed by GitHub

Support preferred locales for gen_l10n (#47845)

* Add preferred-supported-locales option to gen_l10n.dart executable
parent 659dc812
......@@ -46,6 +46,15 @@ Future<void> main(List<String> arguments) async {
help: 'The Dart class name to use for the output localization and '
'localizations delegate classes.',
);
parser.addOption(
'preferred-supported-locales',
help: 'The list of preferred supported locales for the application. '
'By default, the tool will generate the supported locales list in '
'alphabetical order. Use this flag if you would like to default to '
'a different locale. \n\n'
'For example, pass in [\'en_US\'] if you would like your app to '
'default to American English if a device supports it.',
);
final argslib.ArgResults results = parser.parse(arguments);
if (results['help'] == true) {
......@@ -57,6 +66,7 @@ Future<void> main(List<String> arguments) async {
final String outputFileString = results['output-localization-file'] as String;
final String templateArbFileName = results['template-arb-file'] as String;
final String classNameString = results['output-class'] as String;
final String preferredSupportedLocaleString = results['preferred-supported-locales'] as String;
const local.LocalFileSystem fs = local.LocalFileSystem();
final LocalizationsGenerator localizationsGenerator = LocalizationsGenerator(fs);
......@@ -67,6 +77,7 @@ Future<void> main(List<String> arguments) async {
templateArbFileName: templateArbFileName,
outputFileString: outputFileString,
classNameString: classNameString,
preferredSupportedLocaleString: preferredSupportedLocaleString,
)
..parseArbFiles()
..generateClassMethods()
......
......@@ -534,8 +534,21 @@ class LocalizationsGenerator {
/// The class name is specified with the [initialize] method.
String get className => _className;
String _className;
/// Sets the [className] for the localizations and localizations delegate
/// classes.
/// The list of preferred supported locales.
///
/// By default, the list of supported locales in the localizations class
/// will be sorted in alphabetical order. However, this option
/// allows for a set of preferred locales to appear at the top of the
/// list.
///
/// The order of locales in this list will also be the order of locale
/// priority. For example, if a device supports 'en' and 'es' and
/// ['es', 'en'] is passed in, the 'es' locale will take priority over 'en'.
///
/// The list of preferred locales is specified with the [initialize] method.
List<LocaleInfo> get preferredSupportedLocales => _preferredSupportedLocales;
List<LocaleInfo> _preferredSupportedLocales;
/// The list of all arb path strings in [l10nDirectory].
final List<String> arbPathStrings = <String>[];
......@@ -564,10 +577,12 @@ class LocalizationsGenerator {
String templateArbFileName,
String outputFileString,
String classNameString,
String preferredSupportedLocaleString,
}) {
setL10nDirectory(l10nDirectoryPath);
setTemplateArbFile(templateArbFileName);
setOutputFile(outputFileString);
setPreferredSupportedLocales(preferredSupportedLocaleString);
className = classNameString;
}
......@@ -616,6 +631,8 @@ class LocalizationsGenerator {
outputFile = _fs.file(path.join(l10nDirectory.path, outputFileString));
}
/// Sets the [className] for the localizations and localizations delegate
/// classes.
@visibleForTesting
set className(String classNameString) {
if (classNameString == null)
......@@ -627,6 +644,21 @@ class LocalizationsGenerator {
_className = classNameString;
}
/// Sets [preferredSupportedLocales] so that this particular list of locales
/// will take priority over the other locales.
@visibleForTesting
void setPreferredSupportedLocales(String inputLocales) {
if (inputLocales != null) {
final List<dynamic> preferredLocalesStringList = json.decode(inputLocales) as List<dynamic>;
_preferredSupportedLocales = preferredLocalesStringList.map((dynamic localeString) {
if (localeString.runtimeType != String) {
throw L10nException('Incorrect runtime type for $localeString');
}
return LocaleInfo.fromString(localeString.toString());
}).toList();
}
}
/// Scans [l10nDirectory] for arb files and parses them for language and locale
/// information.
void parseArbFiles() {
......@@ -668,10 +700,27 @@ class LocalizationsGenerator {
arbPathStrings.sort();
localeInfoList.sort();
supportedLocales.addAll(localeInfoList);
supportedLanguageCodes.addAll(localeInfoList.map((LocaleInfo localeInfo) {
return '\'${localeInfo.languageCode}\'';
}));
if (preferredSupportedLocales != null) {
for (LocaleInfo preferredLocale in preferredSupportedLocales) {
if (!localeInfoList.contains(preferredLocale)) {
throw L10nException(
'The preferred supported locale, \'$preferredLocale\', cannot be '
'added. Please make sure that there is a corresponding arb file '
'with translations for the locale, or remove the locale from the '
'preferred supported locale list if there is no intent to support '
'it.'
);
}
localeInfoList.removeWhere((LocaleInfo localeInfo) => localeInfo == preferredLocale);
}
localeInfoList.insertAll(0, preferredSupportedLocales);
}
supportedLocales.addAll(localeInfoList);
}
/// Generates the methods for the localizations class.
......
......@@ -294,6 +294,118 @@ void main() {
expect(generator.supportedLocales.elementAt(2), LocaleInfo.fromString('zh'));
});
test('adds preferred locales to the top of supportedLocales and supportedLanguageCodes', () {
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true);
l10nDirectory.childFile('app_en_US.arb')
.writeAsStringSync(singleMessageArbFileString);
l10nDirectory.childFile('app_es.arb')
.writeAsStringSync(singleEsMessageArbFileString);
l10nDirectory.childFile('app_zh.arb')
.writeAsStringSync(singleZhMessageArbFileString);
const String preferredSupportedLocaleString = '["zh", "es"]';
LocalizationsGenerator generator;
try {
generator = LocalizationsGenerator(fs);
generator.initialize(
l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
preferredSupportedLocaleString: preferredSupportedLocaleString,
);
generator.parseArbFiles();
} on L10nException catch (e) {
fail('Setting language and locales should not fail: \n$e');
}
expect(generator.supportedLocales.first, LocaleInfo.fromString('zh'));
expect(generator.supportedLocales.elementAt(1), LocaleInfo.fromString('es'));
expect(generator.supportedLocales.elementAt(2), LocaleInfo.fromString('en_US'));
});
test(
'throws an error attempting to add preferred locales '
'with incorrect runtime type',
() {
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true);
l10nDirectory.childFile('app_en_US.arb')
.writeAsStringSync(singleMessageArbFileString);
l10nDirectory.childFile('app_es.arb')
.writeAsStringSync(singleEsMessageArbFileString);
l10nDirectory.childFile('app_zh.arb')
.writeAsStringSync(singleZhMessageArbFileString);
const String preferredSupportedLocaleString = '[44, "en_US"]';
LocalizationsGenerator generator;
try {
generator = LocalizationsGenerator(fs);
generator.initialize(
l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
preferredSupportedLocaleString: preferredSupportedLocaleString,
);
generator.parseArbFiles();
} on L10nException catch (e) {
expect(
e.message,
contains('Incorrect runtime type'),
);
return;
}
fail(
'Should fail since an incorrect runtime type was used '
'in the preferredSupportedLocales list.'
);
},
);
test(
'throws an error attempting to add preferred locales '
'when there is no corresponding arb file for that '
'locale',
() {
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true);
l10nDirectory.childFile('app_en_US.arb')
.writeAsStringSync(singleMessageArbFileString);
l10nDirectory.childFile('app_es.arb')
.writeAsStringSync(singleEsMessageArbFileString);
l10nDirectory.childFile('app_zh.arb')
.writeAsStringSync(singleZhMessageArbFileString);
const String preferredSupportedLocaleString = '["am", "es"]';
LocalizationsGenerator generator;
try {
generator = LocalizationsGenerator(fs);
generator.initialize(
l10nDirectoryPath: defaultArbPathString,
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
preferredSupportedLocaleString: preferredSupportedLocaleString,
);
generator.parseArbFiles();
} on L10nException catch (e) {
expect(
e.message,
contains("The preferred supported locale, 'am', cannot be added."),
);
return;
}
fail(
'Should fail since an unsupported locale was added '
'to the preferredSupportedLocales list.'
);
},
);
test('correctly sorts arbPathString alphabetically', () {
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
..createSync(recursive: true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment