mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
🐛 Treat empty ARB content as empty map when decoding (#131242)
Fixes #128932.
This commit is contained in:
parent
d250fa62a1
commit
f2db93df01
@ -566,13 +566,18 @@ class Message {
|
||||
}
|
||||
}
|
||||
|
||||
// Represents the contents of one ARB file.
|
||||
/// Represents the contents of one ARB file.
|
||||
class AppResourceBundle {
|
||||
/// Assuming that the caller has verified that the file exists and is readable.
|
||||
factory AppResourceBundle(File file) {
|
||||
// Assuming that the caller has verified that the file exists and is readable.
|
||||
Map<String, Object?> resources;
|
||||
final Map<String, Object?> resources;
|
||||
try {
|
||||
resources = json.decode(file.readAsStringSync()) as Map<String, Object?>;
|
||||
final String content = file.readAsStringSync().trim();
|
||||
if (content.isEmpty) {
|
||||
resources = <String, Object?>{};
|
||||
} else {
|
||||
resources = json.decode(content) as Map<String, Object?>;
|
||||
}
|
||||
} on FormatException catch (e) {
|
||||
throw L10nException(
|
||||
'The arb file ${file.path} has the following formatting issue: \n'
|
||||
@ -657,20 +662,26 @@ class AppResourceBundleCollection {
|
||||
final RegExp filenameRE = RegExp(r'(\w+)\.arb$');
|
||||
final Map<LocaleInfo, AppResourceBundle> localeToBundle = <LocaleInfo, AppResourceBundle>{};
|
||||
final Map<String, List<LocaleInfo>> languageToLocales = <String, List<LocaleInfo>>{};
|
||||
final List<File> files = directory.listSync().whereType<File>().toList()..sort(sortFilesByPath);
|
||||
// We require the list of files to be sorted so that
|
||||
// "languageToLocales[bundle.locale.languageCode]" is not null
|
||||
// by the time we handle locales with country codes.
|
||||
final List<File> files = directory
|
||||
.listSync()
|
||||
.whereType<File>()
|
||||
.where((File e) => filenameRE.hasMatch(e.path))
|
||||
.toList()
|
||||
..sort(sortFilesByPath);
|
||||
for (final File file in files) {
|
||||
if (filenameRE.hasMatch(file.path)) {
|
||||
final AppResourceBundle bundle = AppResourceBundle(file);
|
||||
if (localeToBundle[bundle.locale] != null) {
|
||||
throw L10nException(
|
||||
"Multiple arb files with the same '${bundle.locale}' locale detected. \n"
|
||||
'Ensure that there is exactly one arb file for each locale.'
|
||||
);
|
||||
}
|
||||
localeToBundle[bundle.locale] = bundle;
|
||||
languageToLocales[bundle.locale.languageCode] ??= <LocaleInfo>[];
|
||||
languageToLocales[bundle.locale.languageCode]!.add(bundle.locale);
|
||||
final AppResourceBundle bundle = AppResourceBundle(file);
|
||||
if (localeToBundle[bundle.locale] != null) {
|
||||
throw L10nException(
|
||||
"Multiple arb files with the same '${bundle.locale}' locale detected. \n"
|
||||
'Ensure that there is exactly one arb file for each locale.'
|
||||
);
|
||||
}
|
||||
localeToBundle[bundle.locale] = bundle;
|
||||
languageToLocales[bundle.locale.languageCode] ??= <LocaleInfo>[];
|
||||
languageToLocales[bundle.locale.languageCode]!.add(bundle.locale);
|
||||
}
|
||||
|
||||
languageToLocales.forEach((String language, List<LocaleInfo> listOfCorrespondingLocales) {
|
||||
|
@ -10,6 +10,7 @@ import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/localizations.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/generate_localizations.dart';
|
||||
import 'package:flutter_tools/src/localizations/gen_l10n_types.dart';
|
||||
|
||||
import '../../integration.shard/test_data/basic_project.dart';
|
||||
import '../../src/common.dart';
|
||||
@ -501,4 +502,33 @@ format: true
|
||||
throwsToolExit(message: 'Unexpected positional argument "false".')
|
||||
);
|
||||
});
|
||||
|
||||
group(AppResourceBundle, () {
|
||||
testWithoutContext("can be parsed without FormatException when it's content is empty", () {
|
||||
final File arbFile = fileSystem.file(fileSystem.path.join('lib', 'l10n', 'app_en.arb'))
|
||||
..createSync(recursive: true);
|
||||
expect(AppResourceBundle(arbFile), isA<AppResourceBundle>());
|
||||
});
|
||||
|
||||
testUsingContext("would not fail the gen-l10n command when it's content is empty", () async {
|
||||
fileSystem.file(fileSystem.path.join('lib', 'l10n', 'app_en.arb')).createSync(recursive: true);
|
||||
final File pubspecFile = fileSystem.file('pubspec.yaml')..createSync();
|
||||
pubspecFile.writeAsStringSync(BasicProjectWithFlutterGen().pubspec);
|
||||
final GenerateLocalizationsCommand command = GenerateLocalizationsCommand(
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
);
|
||||
await createTestCommandRunner(command).run(<String>['gen-l10n']);
|
||||
|
||||
final Directory outputDirectory = fileSystem.directory(fileSystem.path.join('.dart_tool', 'flutter_gen', 'gen_l10n'));
|
||||
expect(outputDirectory.existsSync(), true);
|
||||
expect(outputDirectory.childFile('app_localizations_en.dart').existsSync(), true);
|
||||
expect(outputDirectory.childFile('app_localizations.dart').existsSync(), true);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user