mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Support preferred locales for gen_l10n (#47845)
* Add preferred-supported-locales option to gen_l10n.dart executable
This commit is contained in:
parent
659dc8129d
commit
173322dc78
@ -46,6 +46,15 @@ Future<void> main(List<String> arguments) async {
|
|||||||
help: 'The Dart class name to use for the output localization and '
|
help: 'The Dart class name to use for the output localization and '
|
||||||
'localizations delegate classes.',
|
'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);
|
final argslib.ArgResults results = parser.parse(arguments);
|
||||||
if (results['help'] == true) {
|
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 outputFileString = results['output-localization-file'] as String;
|
||||||
final String templateArbFileName = results['template-arb-file'] as String;
|
final String templateArbFileName = results['template-arb-file'] as String;
|
||||||
final String classNameString = results['output-class'] 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();
|
const local.LocalFileSystem fs = local.LocalFileSystem();
|
||||||
final LocalizationsGenerator localizationsGenerator = LocalizationsGenerator(fs);
|
final LocalizationsGenerator localizationsGenerator = LocalizationsGenerator(fs);
|
||||||
@ -67,6 +77,7 @@ Future<void> main(List<String> arguments) async {
|
|||||||
templateArbFileName: templateArbFileName,
|
templateArbFileName: templateArbFileName,
|
||||||
outputFileString: outputFileString,
|
outputFileString: outputFileString,
|
||||||
classNameString: classNameString,
|
classNameString: classNameString,
|
||||||
|
preferredSupportedLocaleString: preferredSupportedLocaleString,
|
||||||
)
|
)
|
||||||
..parseArbFiles()
|
..parseArbFiles()
|
||||||
..generateClassMethods()
|
..generateClassMethods()
|
||||||
|
@ -534,8 +534,21 @@ class LocalizationsGenerator {
|
|||||||
/// The class name is specified with the [initialize] method.
|
/// The class name is specified with the [initialize] method.
|
||||||
String get className => _className;
|
String get className => _className;
|
||||||
String _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].
|
/// The list of all arb path strings in [l10nDirectory].
|
||||||
final List<String> arbPathStrings = <String>[];
|
final List<String> arbPathStrings = <String>[];
|
||||||
@ -564,10 +577,12 @@ class LocalizationsGenerator {
|
|||||||
String templateArbFileName,
|
String templateArbFileName,
|
||||||
String outputFileString,
|
String outputFileString,
|
||||||
String classNameString,
|
String classNameString,
|
||||||
|
String preferredSupportedLocaleString,
|
||||||
}) {
|
}) {
|
||||||
setL10nDirectory(l10nDirectoryPath);
|
setL10nDirectory(l10nDirectoryPath);
|
||||||
setTemplateArbFile(templateArbFileName);
|
setTemplateArbFile(templateArbFileName);
|
||||||
setOutputFile(outputFileString);
|
setOutputFile(outputFileString);
|
||||||
|
setPreferredSupportedLocales(preferredSupportedLocaleString);
|
||||||
className = classNameString;
|
className = classNameString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,6 +631,8 @@ class LocalizationsGenerator {
|
|||||||
outputFile = _fs.file(path.join(l10nDirectory.path, outputFileString));
|
outputFile = _fs.file(path.join(l10nDirectory.path, outputFileString));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the [className] for the localizations and localizations delegate
|
||||||
|
/// classes.
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
set className(String classNameString) {
|
set className(String classNameString) {
|
||||||
if (classNameString == null)
|
if (classNameString == null)
|
||||||
@ -627,6 +644,21 @@ class LocalizationsGenerator {
|
|||||||
_className = classNameString;
|
_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
|
/// Scans [l10nDirectory] for arb files and parses them for language and locale
|
||||||
/// information.
|
/// information.
|
||||||
void parseArbFiles() {
|
void parseArbFiles() {
|
||||||
@ -668,10 +700,27 @@ class LocalizationsGenerator {
|
|||||||
|
|
||||||
arbPathStrings.sort();
|
arbPathStrings.sort();
|
||||||
localeInfoList.sort();
|
localeInfoList.sort();
|
||||||
supportedLocales.addAll(localeInfoList);
|
|
||||||
supportedLanguageCodes.addAll(localeInfoList.map((LocaleInfo localeInfo) {
|
supportedLanguageCodes.addAll(localeInfoList.map((LocaleInfo localeInfo) {
|
||||||
return '\'${localeInfo.languageCode}\'';
|
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.
|
/// Generates the methods for the localizations class.
|
||||||
|
@ -294,6 +294,118 @@ void main() {
|
|||||||
expect(generator.supportedLocales.elementAt(2), LocaleInfo.fromString('zh'));
|
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', () {
|
test('correctly sorts arbPathString alphabetically', () {
|
||||||
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
|
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
|
||||||
..createSync(recursive: true);
|
..createSync(recursive: true);
|
||||||
|
Loading…
Reference in New Issue
Block a user