mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
Validate the @foo resources in material_en.arb (#12824)
This commit is contained in:
parent
e023e89b8e
commit
5c1320e5b9
|
@ -44,7 +44,7 @@ Future<Null> main(List<String> rawArgs) async {
|
|||
final bool dotPackagesExists = dotPackagesFile.existsSync();
|
||||
|
||||
if (!dotPackagesExists) {
|
||||
fatal(
|
||||
exitWithError(
|
||||
'File not found: ${dotPackagesFile.path}. $_kCommandName must be run '
|
||||
'after a successful "flutter update-packages".'
|
||||
);
|
||||
|
@ -56,7 +56,7 @@ Future<Null> main(List<String> rawArgs) async {
|
|||
.firstWhere(
|
||||
(String line) => line.startsWith('intl:'),
|
||||
orElse: () {
|
||||
fatal('intl dependency not found in ${dotPackagesFile.path}');
|
||||
exitWithError('intl dependency not found in ${dotPackagesFile.path}');
|
||||
},
|
||||
)
|
||||
.split(':')
|
||||
|
|
|
@ -142,6 +142,10 @@ void main(List<String> rawArgs) {
|
|||
final Directory directory = new Directory(pathlib.join('packages', 'flutter_localizations', 'lib', 'src', 'l10n'));
|
||||
final RegExp filenameRE = new RegExp(r'material_(\w+)\.arb$');
|
||||
|
||||
exitWithError(
|
||||
validateEnglishLocalizations(new File(pathlib.join(directory.path, 'material_en.arb')))
|
||||
);
|
||||
|
||||
for (FileSystemEntity entity in directory.listSync()) {
|
||||
final String path = entity.path;
|
||||
if (FileSystemEntity.isFileSync(path) && filenameRE.hasMatch(path)) {
|
||||
|
@ -149,7 +153,10 @@ void main(List<String> rawArgs) {
|
|||
processBundle(new File(path), locale);
|
||||
}
|
||||
}
|
||||
validateLocalizations(localeToResources, localeToResourceAttributes);
|
||||
|
||||
exitWithError(
|
||||
validateLocalizations(localeToResources, localeToResourceAttributes)
|
||||
);
|
||||
|
||||
final String regenerate = 'dart dev/tools/gen_localizations.dart --overwrite';
|
||||
final StringBuffer buffer = new StringBuffer();
|
||||
|
|
|
@ -7,8 +7,10 @@ import 'dart:io';
|
|||
import 'package:args/args.dart' as argslib;
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
void fatal(String message) {
|
||||
stderr.writeln(message);
|
||||
void exitWithError(String errorMessage) {
|
||||
if (errorMessage == null)
|
||||
return;
|
||||
stderr.writeln('Fatal Error: $errorMessage');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -16,7 +18,7 @@ void checkCwdIsRepoRoot(String commandName) {
|
|||
final bool isRepoRoot = new Directory('.git').existsSync();
|
||||
|
||||
if (!isRepoRoot) {
|
||||
fatal(
|
||||
exitWithError(
|
||||
'$commandName must be run from the root of the Flutter repository. The '
|
||||
'current working directory is: ${Directory.current.path}'
|
||||
);
|
||||
|
@ -32,7 +34,7 @@ GeneratorOptions parseArgs(List<String> rawArgs) {
|
|||
);
|
||||
final argslib.ArgResults args = argParser.parse(rawArgs);
|
||||
final bool writeToFile = args['overwrite'];
|
||||
|
||||
|
||||
return new GeneratorOptions(writeToFile: writeToFile);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,19 +2,67 @@
|
|||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:convert' show JSON;
|
||||
import 'dart:io';
|
||||
|
||||
/// Sanity checking of the @foo metadata in the English translations,
|
||||
/// material_en.arb.
|
||||
///
|
||||
/// - For each @foo resource, there must be a corresponding foo, except
|
||||
/// for plurals, for which there must be a fooOther.
|
||||
/// - Each @foo resource must have a Map value with a String valued
|
||||
/// description entry.
|
||||
///
|
||||
/// Returns an error message upon failure, null on success.
|
||||
String validateEnglishLocalizations(File file) {
|
||||
final StringBuffer errorMessages = new StringBuffer();
|
||||
|
||||
if (!file.existsSync()) {
|
||||
errorMessages.writeln('English localizations do not exist: $file');
|
||||
return errorMessages.toString();
|
||||
}
|
||||
|
||||
final Map<String, dynamic> bundle = JSON.decode(file.readAsStringSync());
|
||||
for (String atResourceId in bundle.keys) {
|
||||
if (!atResourceId.startsWith('@'))
|
||||
continue;
|
||||
|
||||
final dynamic atResourceValue = bundle[atResourceId];
|
||||
final Map<String, String> atResource = atResourceValue is Map ? atResourceValue : null;
|
||||
if (atResource == null) {
|
||||
errorMessages.writeln('A map value was not specified for $atResourceId');
|
||||
continue;
|
||||
}
|
||||
|
||||
final String description = atResource['description'];
|
||||
if (description == null)
|
||||
errorMessages.writeln('No description specified for $atResourceId');
|
||||
|
||||
final String plural = atResource['plural'];
|
||||
final String resourceId = atResourceId.substring(1);
|
||||
if (plural != null) {
|
||||
final String resourceIdOther = '${resourceId}Other';
|
||||
if (!bundle.containsKey(resourceIdOther))
|
||||
errorMessages.writeln('Default plural resource $resourceIdOther undefined');
|
||||
} else {
|
||||
if (!bundle.containsKey(resourceId))
|
||||
errorMessages.writeln('No matching $resourceId defined for $atResourceId');
|
||||
}
|
||||
}
|
||||
|
||||
return errorMessages.isEmpty ? null : errorMessages.toString();
|
||||
}
|
||||
|
||||
/// Enforces the following invariants in our localizations:
|
||||
///
|
||||
///
|
||||
/// - Resource keys are valid, i.e. they appear in the canonical list.
|
||||
/// - Resource keys are complete for language-level locales, e.g. "es", "he".
|
||||
///
|
||||
///
|
||||
/// Uses "en" localizations as the canonical source of locale keys that other
|
||||
/// locales are compared against.
|
||||
///
|
||||
/// If validation fails, print an error message to STDERR and quit with exit
|
||||
/// code 1.
|
||||
void validateLocalizations(
|
||||
///
|
||||
/// If validation fails, return an error message, otherwise return null.
|
||||
String validateLocalizations(
|
||||
Map<String, Map<String, String>> localeToResources,
|
||||
Map<String, Map<String, dynamic>> localeToAttributes,
|
||||
) {
|
||||
|
@ -33,7 +81,7 @@ void validateLocalizations(
|
|||
bool isPluralVariation(String key) {
|
||||
final RegExp pluralRegexp = new RegExp(r'(\w*)(Zero|One|Two|Few|Many)$');
|
||||
final Match pluralMatch = pluralRegexp.firstMatch(key);
|
||||
|
||||
|
||||
if (pluralMatch == null)
|
||||
return false;
|
||||
|
||||
|
@ -83,9 +131,7 @@ void validateLocalizations(
|
|||
..writeln(' "notUsed": "Sindhi time format does not use a.m. indicator"')
|
||||
..writeln('}');
|
||||
}
|
||||
|
||||
stderr.writeln('ERROR:');
|
||||
stderr.writeln(errorMessages);
|
||||
exit(1);
|
||||
return errorMessages.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue