Unverified Commit 8dfd42f6 authored by Herbert Poul's avatar Herbert Poul Committed by GitHub

[gen_l10n] Support string list as preferred-supported-locales (#63649)

* [gen_l10n] Support string list as preferred-supported-locales, as documented.

* [gen_l10n] Convert preferredSupportedLocale to a list of strings. 

* [gen_l10n] Accept a multi option instead of a json string in the command line.
parent 6d1c244b
...@@ -56,7 +56,7 @@ void generateLocalizations({ ...@@ -56,7 +56,7 @@ void generateLocalizations({
templateArbFileName: templateArbFileName, templateArbFileName: templateArbFileName,
outputFileString: outputFileString, outputFileString: outputFileString,
classNameString: options.outputClass ?? 'AppLocalizations', classNameString: options.outputClass ?? 'AppLocalizations',
preferredSupportedLocaleString: options.preferredSupportedLocales, preferredSupportedLocale: options.preferredSupportedLocales,
headerString: options.header, headerString: options.header,
headerFile: options?.headerFile?.toFilePath(), headerFile: options?.headerFile?.toFilePath(),
useDeferredLoading: options.deferredLoading ?? false, useDeferredLoading: options.deferredLoading ?? false,
...@@ -193,7 +193,7 @@ class LocalizationOptions { ...@@ -193,7 +193,7 @@ class LocalizationOptions {
final String outputClass; final String outputClass;
/// The `--preferred-supported-locales` argument. /// The `--preferred-supported-locales` argument.
final String preferredSupportedLocales; final List<String> preferredSupportedLocales;
/// The `--header-file` argument. /// The `--header-file` argument.
/// ///
...@@ -240,7 +240,7 @@ LocalizationOptions parseLocalizationsOptions({ ...@@ -240,7 +240,7 @@ LocalizationOptions parseLocalizationsOptions({
untranslatedMessagesFile: _tryReadUri(yamlMap, 'untranslated-messages-file', logger), untranslatedMessagesFile: _tryReadUri(yamlMap, 'untranslated-messages-file', logger),
header: _tryReadString(yamlMap, 'header', logger), header: _tryReadString(yamlMap, 'header', logger),
outputClass: _tryReadString(yamlMap, 'output-class', logger), outputClass: _tryReadString(yamlMap, 'output-class', logger),
preferredSupportedLocales: _tryReadString(yamlMap, 'preferred-supported-locales', logger), preferredSupportedLocales: _tryReadStringList(yamlMap, 'preferred-supported-locales', logger),
headerFile: _tryReadUri(yamlMap, 'header-file', logger), headerFile: _tryReadUri(yamlMap, 'header-file', logger),
deferredLoading: _tryReadBool(yamlMap, 'use-deferred-loading', logger), deferredLoading: _tryReadBool(yamlMap, 'use-deferred-loading', logger),
useSyntheticPackage: _tryReadBool(yamlMap, 'synthetic-package', logger) ?? true, useSyntheticPackage: _tryReadBool(yamlMap, 'synthetic-package', logger) ?? true,
...@@ -273,6 +273,21 @@ String _tryReadString(YamlMap yamlMap, String key, Logger logger) { ...@@ -273,6 +273,21 @@ String _tryReadString(YamlMap yamlMap, String key, Logger logger) {
return value as String; return value as String;
} }
List<String> _tryReadStringList(YamlMap yamlMap, String key, Logger logger) {
final Object value = yamlMap[key];
if (value == null) {
return null;
}
if (value is String) {
return <String>[value];
}
if (value is Iterable) {
return value.map((dynamic e) => e.toString()).toList();
}
logger.printError('"$value" must be String or List.');
throw Exception();
}
// Try to read a valid `Uri` or null from `yamlMap`, otherwise throw. // Try to read a valid `Uri` or null from `yamlMap`, otherwise throw.
Uri _tryReadUri(YamlMap yamlMap, String key, Logger logger) { Uri _tryReadUri(YamlMap yamlMap, String key, Logger logger) {
final String value = _tryReadString(yamlMap, key, logger); final String value = _tryReadString(yamlMap, key, logger);
......
...@@ -65,14 +65,16 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -65,14 +65,16 @@ class GenerateLocalizationsCommand extends FlutterCommand {
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.',
); );
argParser.addOption( argParser.addMultiOption(
'preferred-supported-locales', 'preferred-supported-locales',
valueHelp: 'locale',
help: 'The list of preferred supported locales for the application. ' help: 'The list of preferred supported locales for the application. '
'By default, the tool will generate the supported locales list in ' 'By default, the tool will generate the supported locales list in '
'alphabetical order. Use this flag if you would like to default to ' 'alphabetical order. Use this flag if you would like to default to '
'a different locale. \n\n' 'a different locale. \n\n'
"For example, pass in ['en_US'] if you would like your app to " 'For example, pass in `en_US` if you would like your app to '
'default to American English if a device supports it.', 'default to American English if a device supports it.'
'(Pass this option multiple times for defining multiple items',
); );
argParser.addOption( argParser.addOption(
'header', 'header',
...@@ -169,7 +171,7 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -169,7 +171,7 @@ class GenerateLocalizationsCommand extends FlutterCommand {
final String templateArbFileName = stringArg('template-arb-file'); final String templateArbFileName = stringArg('template-arb-file');
final String untranslatedMessagesFile = stringArg('untranslated-messages-file'); final String untranslatedMessagesFile = stringArg('untranslated-messages-file');
final String classNameString = stringArg('output-class'); final String classNameString = stringArg('output-class');
final String preferredSupportedLocaleString = stringArg('preferred-supported-locales'); final List<String> preferredSupportedLocale = stringsArg('preferred-supported-locales');
final String headerString = stringArg('header'); final String headerString = stringArg('header');
final String headerFile = stringArg('header-file'); final String headerFile = stringArg('header-file');
final bool useDeferredLoading = boolArg('use-deferred-loading'); final bool useDeferredLoading = boolArg('use-deferred-loading');
...@@ -187,7 +189,7 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -187,7 +189,7 @@ class GenerateLocalizationsCommand extends FlutterCommand {
templateArbFileName: templateArbFileName, templateArbFileName: templateArbFileName,
outputFileString: outputFileString, outputFileString: outputFileString,
classNameString: classNameString, classNameString: classNameString,
preferredSupportedLocaleString: preferredSupportedLocaleString, preferredSupportedLocale: preferredSupportedLocale,
headerString: headerString, headerString: headerString,
headerFile: headerFile, headerFile: headerFile,
useDeferredLoading: useDeferredLoading, useDeferredLoading: useDeferredLoading,
......
...@@ -530,7 +530,7 @@ class LocalizationsGenerator { ...@@ -530,7 +530,7 @@ class LocalizationsGenerator {
String templateArbFileName, String templateArbFileName,
String outputFileString, String outputFileString,
String classNameString, String classNameString,
String preferredSupportedLocaleString, List<String> preferredSupportedLocale,
String headerString, String headerString,
String headerFile, String headerFile,
bool useDeferredLoading = false, bool useDeferredLoading = false,
...@@ -546,7 +546,7 @@ class LocalizationsGenerator { ...@@ -546,7 +546,7 @@ class LocalizationsGenerator {
); );
setTemplateArbFile(templateArbFileName); setTemplateArbFile(templateArbFileName);
setBaseOutputFile(outputFileString); setBaseOutputFile(outputFileString);
setPreferredSupportedLocales(preferredSupportedLocaleString); setPreferredSupportedLocales(preferredSupportedLocale);
_setHeader(headerString, headerFile); _setHeader(headerString, headerFile);
_setUseDeferredLoading(useDeferredLoading); _setUseDeferredLoading(useDeferredLoading);
className = classNameString; className = classNameString;
...@@ -707,18 +707,12 @@ class LocalizationsGenerator { ...@@ -707,18 +707,12 @@ class LocalizationsGenerator {
/// Sets [preferredSupportedLocales] so that this particular list of locales /// Sets [preferredSupportedLocales] so that this particular list of locales
/// will take priority over the other locales. /// will take priority over the other locales.
@visibleForTesting @visibleForTesting
void setPreferredSupportedLocales(String inputLocales) { void setPreferredSupportedLocales(List<String> inputLocales) {
if (inputLocales == null || inputLocales.trim().isEmpty) { if (inputLocales == null || inputLocales.isEmpty) {
_preferredSupportedLocales = const <LocaleInfo>[]; _preferredSupportedLocales = const <LocaleInfo>[];
} else { } else {
final List<dynamic> preferredLocalesStringList = json.decode(inputLocales) as List<dynamic>; _preferredSupportedLocales = inputLocales.map((String localeString) {
_preferredSupportedLocales = preferredLocalesStringList.map((dynamic localeString) { return LocaleInfo.fromString(localeString);
if (localeString.runtimeType != String) {
throw L10nException('Incorrect runtime type for $localeString');
}
return LocaleInfo.fromString(
localeString.toString(),
);
}).toList(); }).toList();
} }
} }
......
...@@ -35,7 +35,7 @@ void main() { ...@@ -35,7 +35,7 @@ void main() {
deferredLoading: true, deferredLoading: true,
outputClass: 'Foo', outputClass: 'Foo',
outputLocalizationsFile: Uri.file('bar'), outputLocalizationsFile: Uri.file('bar'),
preferredSupportedLocales: 'en_US', preferredSupportedLocales: <String>['en_US'],
templateArbFile: Uri.file('example.arb'), templateArbFile: Uri.file('example.arb'),
untranslatedMessagesFile: Uri.file('untranslated'), untranslatedMessagesFile: Uri.file('untranslated'),
useSyntheticPackage: false, useSyntheticPackage: false,
...@@ -57,7 +57,7 @@ void main() { ...@@ -57,7 +57,7 @@ void main() {
templateArbFileName: 'example.arb', templateArbFileName: 'example.arb',
outputFileString: 'bar', outputFileString: 'bar',
classNameString: 'Foo', classNameString: 'Foo',
preferredSupportedLocaleString: 'en_US', preferredSupportedLocale: <String>['en_US'],
headerString: 'HEADER', headerString: 'HEADER',
headerFile: 'header', headerFile: 'header',
useDeferredLoading: true, useDeferredLoading: true,
...@@ -92,7 +92,7 @@ flutter: ...@@ -92,7 +92,7 @@ flutter:
deferredLoading: true, deferredLoading: true,
outputClass: 'Foo', outputClass: 'Foo',
outputLocalizationsFile: Uri.file('bar'), outputLocalizationsFile: Uri.file('bar'),
preferredSupportedLocales: 'en_US', preferredSupportedLocales: <String>['en_US'],
templateArbFile: Uri.file('example.arb'), templateArbFile: Uri.file('example.arb'),
untranslatedMessagesFile: Uri.file('untranslated'), untranslatedMessagesFile: Uri.file('untranslated'),
// Set synthetic package to true. // Set synthetic package to true.
...@@ -161,13 +161,28 @@ preferred-supported-locales: en_US ...@@ -161,13 +161,28 @@ preferred-supported-locales: en_US
expect(options.headerFile, Uri.parse('header')); expect(options.headerFile, Uri.parse('header'));
expect(options.header, 'HEADER'); expect(options.header, 'HEADER');
expect(options.deferredLoading, true); expect(options.deferredLoading, true);
expect(options.preferredSupportedLocales, 'en_US'); expect(options.preferredSupportedLocales, <String>['en_US']);
}); });
testWithoutContext('parseLocalizationsOptions throws exception on invalid yaml configuration', () async { testWithoutContext('parseLocalizationsOptions handles preferredSupportedLocales as list', () async {
final FileSystem fileSystem = MemoryFileSystem.test(); final FileSystem fileSystem = MemoryFileSystem.test();
final File configFile = fileSystem.file('l10n.yaml') final File configFile = fileSystem.file('l10n.yaml')..writeAsStringSync('''
..writeAsStringSync(''' preferred-supported-locales: ['en_US', 'de']
''');
final LocalizationOptions options = parseLocalizationsOptions(
file: configFile,
logger: BufferLogger.test(),
);
expect(options.preferredSupportedLocales, <String>['en_US', 'de']);
});
testWithoutContext(
'parseLocalizationsOptions throws exception on invalid yaml configuration',
() async {
final FileSystem fileSystem = MemoryFileSystem.test();
final File configFile = fileSystem.file('l10n.yaml')..writeAsStringSync('''
use-deferred-loading: string use-deferred-loading: string
'''); ''');
......
...@@ -793,7 +793,7 @@ void main() { ...@@ -793,7 +793,7 @@ void main() {
l10nDirectory.childFile('app_zh.arb') l10nDirectory.childFile('app_zh.arb')
.writeAsStringSync(singleZhMessageArbFileString); .writeAsStringSync(singleZhMessageArbFileString);
const String preferredSupportedLocaleString = '["zh", "es"]'; const List<String> preferredSupportedLocale = <String>['zh', 'es'];
LocalizationsGenerator generator; LocalizationsGenerator generator;
try { try {
generator = LocalizationsGenerator(fs); generator = LocalizationsGenerator(fs);
...@@ -803,7 +803,7 @@ void main() { ...@@ -803,7 +803,7 @@ void main() {
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
preferredSupportedLocaleString: preferredSupportedLocaleString, preferredSupportedLocale: preferredSupportedLocale,
); );
generator.loadResources(); generator.loadResources();
} on L10nException catch (e) { } on L10nException catch (e) {
...@@ -815,47 +815,6 @@ void main() { ...@@ -815,47 +815,6 @@ void main() {
expect(generator.supportedLocales.elementAt(2), LocaleInfo.fromString('en')); expect(generator.supportedLocales.elementAt(2), LocaleInfo.fromString('en'));
}); });
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.arb')
.writeAsStringSync(singleMessageArbFileString);
l10nDirectory.childFile('app_es.arb')
.writeAsStringSync(singleEsMessageArbFileString);
l10nDirectory.childFile('app_zh.arb')
.writeAsStringSync(singleZhMessageArbFileString);
const String preferredSupportedLocaleString = '[44, "en"]';
LocalizationsGenerator generator;
try {
generator = LocalizationsGenerator(fs);
generator.initialize(
inputPathString: defaultL10nPathString,
outputPathString: defaultL10nPathString,
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
preferredSupportedLocaleString: preferredSupportedLocaleString,
);
generator.loadResources();
} 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( test(
'throws an error attempting to add preferred locales ' 'throws an error attempting to add preferred locales '
'when there is no corresponding arb file for that ' 'when there is no corresponding arb file for that '
...@@ -870,7 +829,7 @@ void main() { ...@@ -870,7 +829,7 @@ void main() {
l10nDirectory.childFile('app_zh.arb') l10nDirectory.childFile('app_zh.arb')
.writeAsStringSync(singleZhMessageArbFileString); .writeAsStringSync(singleZhMessageArbFileString);
const String preferredSupportedLocaleString = '["am", "es"]'; const List<String> preferredSupportedLocale = <String>['am', 'es'];
LocalizationsGenerator generator; LocalizationsGenerator generator;
try { try {
generator = LocalizationsGenerator(fs); generator = LocalizationsGenerator(fs);
...@@ -880,7 +839,7 @@ void main() { ...@@ -880,7 +839,7 @@ void main() {
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
preferredSupportedLocaleString: preferredSupportedLocaleString, preferredSupportedLocale: preferredSupportedLocale,
); );
generator.loadResources(); generator.loadResources();
} on L10nException catch (e) { } on L10nException catch (e) {
...@@ -1152,7 +1111,7 @@ void main() { ...@@ -1152,7 +1111,7 @@ void main() {
..childFile('app_zh.arb').writeAsStringSync(singleZhMessageArbFileString) ..childFile('app_zh.arb').writeAsStringSync(singleZhMessageArbFileString)
..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString); ..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString);
const String preferredSupportedLocaleString = '["zh"]'; const List<String> preferredSupportedLocale = <String>['zh'];
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.initialize( generator.initialize(
...@@ -1161,7 +1120,7 @@ void main() { ...@@ -1161,7 +1120,7 @@ void main() {
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
preferredSupportedLocaleString: preferredSupportedLocaleString, preferredSupportedLocale: preferredSupportedLocale,
); );
generator.loadResources(); generator.loadResources();
generator.writeOutputFiles(); generator.writeOutputFiles();
......
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