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

[gen_l10n] Use l10n.yaml file instead of command line arguments if it exists (#72950)

* Reorganize files

* Use l10n.yaml instead of command line args
parent a7030ad9
......@@ -116,6 +116,7 @@ Future<void> main(List<String> args) async {
GenerateCommand(),
GenerateLocalizationsCommand(
fileSystem: globals.fs,
logger: globals.logger,
),
InstallCommand(),
LogsCommand(),
......
......@@ -2,77 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:meta/meta.dart';
import 'package:yaml/yaml.dart';
import '../../base/file_system.dart';
import '../../base/logger.dart';
import '../../convert.dart';
import '../../globals.dart' as globals;
import '../../localizations/gen_l10n.dart';
import '../../localizations/gen_l10n_types.dart';
import '../../localizations/localizations_utils.dart';
import '../../project.dart';
import '../build_system.dart';
import '../depfile.dart';
const String _kDependenciesFileName = 'gen_l10n_inputs_and_outputs.json';
/// Run the localizations generation script with the configuration [options].
void generateLocalizations({
@required Directory projectDir,
@required Directory dependenciesDir,
@required LocalizationOptions options,
@required LocalizationsGenerator localizationsGenerator,
@required Logger logger,
}) {
// If generating a synthetic package, generate a warning if
// flutter: generate is not set.
final FlutterProject flutterProject = FlutterProject.fromDirectory(projectDir);
if (options.useSyntheticPackage && !flutterProject.manifest.generateSyntheticPackage) {
logger.printError(
'Attempted to generate localizations code without having '
'the flutter: generate flag turned on.'
'\n'
'Check pubspec.yaml and ensure that flutter: generate: true has '
'been added and rebuild the project. Otherwise, the localizations '
'source code will not be importable.'
);
throw Exception();
}
precacheLanguageAndRegionTags();
final String inputPathString = options?.arbDirectory?.path ?? globals.fs.path.join('lib', 'l10n');
final String templateArbFileName = options?.templateArbFile?.toFilePath() ?? 'app_en.arb';
final String outputFileString = options?.outputLocalizationsFile?.toFilePath() ?? 'app_localizations.dart';
try {
localizationsGenerator
..initialize(
inputsAndOutputsListPath: dependenciesDir.path,
projectPathString: projectDir.path,
inputPathString: inputPathString,
templateArbFileName: templateArbFileName,
outputFileString: outputFileString,
outputPathString: options?.outputDirectory?.path,
classNameString: options.outputClass ?? 'AppLocalizations',
preferredSupportedLocale: options.preferredSupportedLocales,
headerString: options.header,
headerFile: options?.headerFile?.toFilePath(),
useDeferredLoading: options.deferredLoading ?? false,
useSyntheticPackage: options.useSyntheticPackage ?? true,
areResourceAttributesRequired: options.areResourceAttributesRequired ?? false,
untranslatedMessagesFile: options?.untranslatedMessagesFile?.toFilePath(),
)
..loadResources()
..writeOutputFiles(logger, isFromYaml: true);
} on L10nException catch (e) {
logger.printError(e.message);
throw Exception();
}
}
/// A build step that runs the generate localizations script from
/// dev/tool/localizations.
class GenerateLocalizationsTarget extends Target {
......@@ -138,7 +77,7 @@ class GenerateLocalizationsTarget extends Target {
<File>[
for (dynamic outputFile in dependencies['outputs'] as List<dynamic>)
environment.fileSystem.file(outputFile)
]
],
);
depfileService.writeToFile(
depfile,
......@@ -146,170 +85,3 @@ class GenerateLocalizationsTarget extends Target {
);
}
}
/// Typed configuration from the localizations config file.
class LocalizationOptions {
const LocalizationOptions({
this.arbDirectory,
this.templateArbFile,
this.outputLocalizationsFile,
this.untranslatedMessagesFile,
this.header,
this.outputClass,
this.outputDirectory,
this.preferredSupportedLocales,
this.headerFile,
this.deferredLoading,
this.useSyntheticPackage = true,
this.areResourceAttributesRequired = false,
}) : assert(useSyntheticPackage != null);
/// The `--arb-dir` argument.
///
/// The directory where all input localization files should reside.
final Uri arbDirectory;
/// The `--template-arb-file` argument.
///
/// This URI is relative to [arbDirectory].
final Uri templateArbFile;
/// The `--output-localization-file` argument.
///
/// This URI is relative to [arbDirectory].
final Uri outputLocalizationsFile;
/// The `--untranslated-messages-file` argument.
///
/// This URI is relative to [arbDirectory].
final Uri untranslatedMessagesFile;
/// The `--header` argument.
///
/// The header to prepend to the generated Dart localizations.
final String header;
/// The `--output-class` argument.
final String outputClass;
/// The `--output-dir` argument.
///
/// The directory where all output localization files should be generated.
final Uri outputDirectory;
/// The `--preferred-supported-locales` argument.
final List<String> preferredSupportedLocales;
/// The `--header-file` argument.
///
/// A file containing the header to prepend to the generated
/// Dart localizations.
final Uri headerFile;
/// The `--use-deferred-loading` argument.
///
/// Whether to generate the Dart localization file with locales imported
/// as deferred.
final bool deferredLoading;
/// The `--synthetic-package` argument.
///
/// Whether to generate the Dart localization files in a synthetic package
/// or in a custom directory.
final bool useSyntheticPackage;
/// The `required-resource-attributes` argument.
///
/// Whether to require all resource ids to contain a corresponding
/// resource attribute.
final bool areResourceAttributesRequired;
}
/// Parse the localizations configuration options from [file].
///
/// Throws [Exception] if any of the contents are invalid. Returns a
/// [LocalizationOptions] with all fields as `null` if the config file exists
/// but is empty.
LocalizationOptions parseLocalizationsOptions({
@required File file,
@required Logger logger,
}) {
final String contents = file.readAsStringSync();
if (contents.trim().isEmpty) {
return const LocalizationOptions();
}
final YamlNode yamlNode = loadYamlNode(file.readAsStringSync());
if (yamlNode is! YamlMap) {
logger.printError('Expected ${file.path} to contain a map, instead was $yamlNode');
throw Exception();
}
final YamlMap yamlMap = yamlNode as YamlMap;
return LocalizationOptions(
arbDirectory: _tryReadUri(yamlMap, 'arb-dir', logger),
templateArbFile: _tryReadUri(yamlMap, 'template-arb-file', logger),
outputLocalizationsFile: _tryReadUri(yamlMap, 'output-localization-file', logger),
untranslatedMessagesFile: _tryReadUri(yamlMap, 'untranslated-messages-file', logger),
header: _tryReadString(yamlMap, 'header', logger),
outputClass: _tryReadString(yamlMap, 'output-class', logger),
outputDirectory: _tryReadUri(yamlMap, 'output-dir', logger),
preferredSupportedLocales: _tryReadStringList(yamlMap, 'preferred-supported-locales', logger),
headerFile: _tryReadUri(yamlMap, 'header-file', logger),
deferredLoading: _tryReadBool(yamlMap, 'use-deferred-loading', logger),
useSyntheticPackage: _tryReadBool(yamlMap, 'synthetic-package', logger) ?? true,
areResourceAttributesRequired: _tryReadBool(yamlMap, 'required-resource-attributes', logger) ?? false,
);
}
// Try to read a `bool` value or null from `yamlMap`, otherwise throw.
bool _tryReadBool(YamlMap yamlMap, String key, Logger logger) {
final Object value = yamlMap[key];
if (value == null) {
return null;
}
if (value is! bool) {
logger.printError('Expected "$key" to have a bool value, instead was "$value"');
throw Exception();
}
return value as bool;
}
// Try to read a `String` value or null from `yamlMap`, otherwise throw.
String _tryReadString(YamlMap yamlMap, String key, Logger logger) {
final Object value = yamlMap[key];
if (value == null) {
return null;
}
if (value is! String) {
logger.printError('Expected "$key" to have a String value, instead was "$value"');
throw Exception();
}
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.
Uri _tryReadUri(YamlMap yamlMap, String key, Logger logger) {
final String value = _tryReadString(yamlMap, key, logger);
if (value == null) {
return null;
}
final Uri uri = Uri.tryParse(value);
if (uri == null) {
logger.printError('"$value" must be a relative file URI');
}
return uri;
}
......@@ -4,6 +4,7 @@
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../globals.dart' as globals;
import '../localizations/gen_l10n.dart';
import '../localizations/gen_l10n_types.dart';
......@@ -19,8 +20,10 @@ import '../runner/flutter_command.dart';
class GenerateLocalizationsCommand extends FlutterCommand {
GenerateLocalizationsCommand({
FileSystem fileSystem,
Logger logger,
}) :
_fileSystem = fileSystem {
_fileSystem = fileSystem,
_logger = logger {
argParser.addOption(
'arb-dir',
defaultsTo: globals.fs.path.join('lib', 'l10n'),
......@@ -161,6 +164,7 @@ class GenerateLocalizationsCommand extends FlutterCommand {
}
final FileSystem _fileSystem;
final Logger _logger;
@override
String get description => 'Generate localizations for the current project.';
......@@ -170,8 +174,26 @@ class GenerateLocalizationsCommand extends FlutterCommand {
@override
Future<FlutterCommandResult> runCommand() async {
precacheLanguageAndRegionTags();
if (_fileSystem.file('l10n.yaml').existsSync()) {
final LocalizationOptions options = parseLocalizationsOptions(
file: _fileSystem.file('l10n.yaml'),
logger: _logger,
);
_logger.printStatus(
'Because l10n.yaml exists, the options defined there will be used '
'instead.\n'
'To use the command line arguments, delete the l10n.yaml file in the '
'Flutter project.\n\n'
);
generateLocalizations(
logger: _logger,
options: options,
projectDir: _fileSystem.currentDirectory,
dependenciesDir: null,
localizationsGenerator: LocalizationsGenerator(_fileSystem),
);
return FlutterCommandResult.success();
}
final String inputPathString = stringArg('arb-dir');
final String outputPathString = stringArg('output-dir');
......@@ -179,7 +201,7 @@ class GenerateLocalizationsCommand extends FlutterCommand {
final String templateArbFileName = stringArg('template-arb-file');
final String untranslatedMessagesFile = stringArg('untranslated-messages-file');
final String classNameString = stringArg('output-class');
final List<String> preferredSupportedLocale = stringsArg('preferred-supported-locales');
final List<String> preferredSupportedLocales = stringsArg('preferred-supported-locales');
final String headerString = stringArg('header');
final String headerFile = stringArg('header-file');
final bool useDeferredLoading = boolArg('use-deferred-loading');
......@@ -190,6 +212,8 @@ class GenerateLocalizationsCommand extends FlutterCommand {
final LocalizationsGenerator localizationsGenerator = LocalizationsGenerator(_fileSystem);
precacheLanguageAndRegionTags();
try {
localizationsGenerator
..initialize(
......@@ -198,7 +222,7 @@ class GenerateLocalizationsCommand extends FlutterCommand {
templateArbFileName: templateArbFileName,
outputFileString: outputFileString,
classNameString: classNameString,
preferredSupportedLocale: preferredSupportedLocale,
preferredSupportedLocales: preferredSupportedLocales,
headerString: headerString,
headerFile: headerFile,
useDeferredLoading: useDeferredLoading,
......@@ -209,7 +233,7 @@ class GenerateLocalizationsCommand extends FlutterCommand {
untranslatedMessagesFile: untranslatedMessagesFile,
)
..loadResources()
..writeOutputFiles(globals.logger);
..writeOutputFiles(_logger);
} on L10nException catch (e) {
throwToolExit(e.message);
}
......
......@@ -7,12 +7,72 @@ import 'package:meta/meta.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../convert.dart';
import '../flutter_manifest.dart';
import '../globals.dart' as globals;
import 'gen_l10n_templates.dart';
import 'gen_l10n_types.dart';
import 'localizations_utils.dart';
/// Run the localizations generation script with the configuration [options].
void generateLocalizations({
@required Directory projectDir,
@required Directory dependenciesDir,
@required LocalizationOptions options,
@required LocalizationsGenerator localizationsGenerator,
@required Logger logger,
}) {
// If generating a synthetic package, generate a warning if
// flutter: generate is not set.
final FlutterManifest flutterManifest = FlutterManifest.createFromPath(
projectDir.childFile('pubspec.yaml').path,
fileSystem: projectDir.fileSystem,
logger: logger,
);
if (options.useSyntheticPackage && !flutterManifest.generateSyntheticPackage) {
logger.printError(
'Attempted to generate localizations code without having '
'the flutter: generate flag turned on.'
'\n'
'Check pubspec.yaml and ensure that flutter: generate: true has '
'been added and rebuild the project. Otherwise, the localizations '
'source code will not be importable.'
);
throw Exception();
}
precacheLanguageAndRegionTags();
final String inputPathString = options?.arbDirectory?.path ?? globals.fs.path.join('lib', 'l10n');
final String templateArbFileName = options?.templateArbFile?.toFilePath() ?? 'app_en.arb';
final String outputFileString = options?.outputLocalizationsFile?.toFilePath() ?? 'app_localizations.dart';
try {
localizationsGenerator
..initialize(
inputsAndOutputsListPath: dependenciesDir?.path,
projectPathString: projectDir.path,
inputPathString: inputPathString,
templateArbFileName: templateArbFileName,
outputFileString: outputFileString,
outputPathString: options?.outputDirectory?.path,
classNameString: options.outputClass ?? 'AppLocalizations',
preferredSupportedLocales: options.preferredSupportedLocales,
headerString: options.header,
headerFile: options?.headerFile?.toFilePath(),
useDeferredLoading: options.deferredLoading ?? false,
useSyntheticPackage: options.useSyntheticPackage ?? true,
areResourceAttributesRequired: options.areResourceAttributesRequired ?? false,
untranslatedMessagesFile: options?.untranslatedMessagesFile?.toFilePath(),
)
..loadResources()
..writeOutputFiles(logger, isFromYaml: true);
} on L10nException catch (e) {
logger.printError(e.message);
throw Exception();
}
}
/// The path for the synthetic package.
final String defaultSyntheticPackagePath = globals.fs.path.join('.dart_tool', 'flutter_gen');
......@@ -550,7 +610,7 @@ class LocalizationsGenerator {
String templateArbFileName,
String outputFileString,
String classNameString,
List<String> preferredSupportedLocale,
List<String> preferredSupportedLocales,
String headerString,
String headerFile,
bool useDeferredLoading = false,
......@@ -566,7 +626,7 @@ class LocalizationsGenerator {
setOutputDirectory(outputPathString ?? inputPathString);
setTemplateArbFile(templateArbFileName);
setBaseOutputFile(outputFileString);
setPreferredSupportedLocales(preferredSupportedLocale);
setPreferredSupportedLocales(preferredSupportedLocales);
_setHeader(headerString, headerFile);
_setUseDeferredLoading(useDeferredLoading);
_setUntranslatedMessagesFile(untranslatedMessagesFile);
......
......@@ -3,8 +3,10 @@
// found in the LICENSE file.
import 'package:meta/meta.dart';
import 'package:yaml/yaml.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import 'language_subtag_registry.dart';
typedef HeaderGenerator = String Function(String regenerateInstructions);
......@@ -286,3 +288,170 @@ String generateString(String value) {
return "'$value'";
}
/// Typed configuration from the localizations config file.
class LocalizationOptions {
const LocalizationOptions({
this.arbDirectory,
this.templateArbFile,
this.outputLocalizationsFile,
this.untranslatedMessagesFile,
this.header,
this.outputClass,
this.outputDirectory,
this.preferredSupportedLocales,
this.headerFile,
this.deferredLoading,
this.useSyntheticPackage = true,
this.areResourceAttributesRequired = false,
}) : assert(useSyntheticPackage != null);
/// The `--arb-dir` argument.
///
/// The directory where all input localization files should reside.
final Uri arbDirectory;
/// The `--template-arb-file` argument.
///
/// This URI is relative to [arbDirectory].
final Uri templateArbFile;
/// The `--output-localization-file` argument.
///
/// This URI is relative to [arbDirectory].
final Uri outputLocalizationsFile;
/// The `--untranslated-messages-file` argument.
///
/// This URI is relative to [arbDirectory].
final Uri untranslatedMessagesFile;
/// The `--header` argument.
///
/// The header to prepend to the generated Dart localizations.
final String header;
/// The `--output-class` argument.
final String outputClass;
/// The `--output-dir` argument.
///
/// The directory where all output localization files should be generated.
final Uri outputDirectory;
/// The `--preferred-supported-locales` argument.
final List<String> preferredSupportedLocales;
/// The `--header-file` argument.
///
/// A file containing the header to prepend to the generated
/// Dart localizations.
final Uri headerFile;
/// The `--use-deferred-loading` argument.
///
/// Whether to generate the Dart localization file with locales imported
/// as deferred.
final bool deferredLoading;
/// The `--synthetic-package` argument.
///
/// Whether to generate the Dart localization files in a synthetic package
/// or in a custom directory.
final bool useSyntheticPackage;
/// The `required-resource-attributes` argument.
///
/// Whether to require all resource ids to contain a corresponding
/// resource attribute.
final bool areResourceAttributesRequired;
}
/// Parse the localizations configuration options from [file].
///
/// Throws [Exception] if any of the contents are invalid. Returns a
/// [LocalizationOptions] with all fields as `null` if the config file exists
/// but is empty.
LocalizationOptions parseLocalizationsOptions({
@required File file,
@required Logger logger,
}) {
final String contents = file.readAsStringSync();
if (contents.trim().isEmpty) {
return const LocalizationOptions();
}
final YamlNode yamlNode = loadYamlNode(file.readAsStringSync());
if (yamlNode is! YamlMap) {
logger.printError('Expected ${file.path} to contain a map, instead was $yamlNode');
throw Exception();
}
final YamlMap yamlMap = yamlNode as YamlMap;
return LocalizationOptions(
arbDirectory: _tryReadUri(yamlMap, 'arb-dir', logger),
templateArbFile: _tryReadUri(yamlMap, 'template-arb-file', logger),
outputLocalizationsFile: _tryReadUri(yamlMap, 'output-localization-file', logger),
untranslatedMessagesFile: _tryReadUri(yamlMap, 'untranslated-messages-file', logger),
header: _tryReadString(yamlMap, 'header', logger),
outputClass: _tryReadString(yamlMap, 'output-class', logger),
outputDirectory: _tryReadUri(yamlMap, 'output-dir', logger),
preferredSupportedLocales: _tryReadStringList(yamlMap, 'preferred-supported-locales', logger),
headerFile: _tryReadUri(yamlMap, 'header-file', logger),
deferredLoading: _tryReadBool(yamlMap, 'use-deferred-loading', logger),
useSyntheticPackage: _tryReadBool(yamlMap, 'synthetic-package', logger) ?? true,
areResourceAttributesRequired: _tryReadBool(yamlMap, 'required-resource-attributes', logger) ?? false,
);
}
// Try to read a `bool` value or null from `yamlMap`, otherwise throw.
bool _tryReadBool(YamlMap yamlMap, String key, Logger logger) {
final Object value = yamlMap[key];
if (value == null) {
return null;
}
if (value is! bool) {
logger.printError('Expected "$key" to have a bool value, instead was "$value"');
throw Exception();
}
return value as bool;
}
// Try to read a `String` value or null from `yamlMap`, otherwise throw.
String _tryReadString(YamlMap yamlMap, String key, Logger logger) {
final Object value = yamlMap[key];
if (value == null) {
return null;
}
if (value is! String) {
logger.printError('Expected "$key" to have a String value, instead was "$value"');
throw Exception();
}
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.
Uri _tryReadUri(YamlMap yamlMap, String key, Logger logger) {
final String value = _tryReadString(yamlMap, key, logger);
if (value == null) {
return null;
}
final Uri uri = Uri.tryParse(value);
if (uri == null) {
logger.printError('"$value" must be a relative file URI');
}
return uri;
}
......@@ -5,15 +5,18 @@
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:flutter_tools/src/commands/generate_localizations.dart';
import '../../integration.shard/test_data/basic_project.dart';
import '../../src/common.dart';
import '../../src/context.dart';
void main() {
testUsingContext('default l10n settings', () async {
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
final BufferLogger logger = BufferLogger.test();
final File arbFile = fileSystem.file(fileSystem.path.join('lib', 'l10n', 'app_en.arb'))
..createSync(recursive: true);
arbFile.writeAsStringSync('''
......@@ -23,16 +26,9 @@ void main() {
"description": "Sample description"
}
}''');
fileSystem.file('l10n.yaml').createSync();
final File pubspecFile = fileSystem.file('pubspec.yaml')..createSync();
final String content = pubspecFile.readAsStringSync().replaceFirst(
'\nflutter:\n',
'\nflutter:\n generate: true\n',
);
pubspecFile.writeAsStringSync(content);
final GenerateLocalizationsCommand command = GenerateLocalizationsCommand(
fileSystem: fileSystem,
logger: logger,
);
await createTestCommandRunner(command).run(<String>['gen-l10n']);
......@@ -46,6 +42,7 @@ void main() {
testUsingContext('not using synthetic packages', () async {
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
final BufferLogger logger = BufferLogger.test();
final Directory l10nDirectory = fileSystem.directory(
fileSystem.path.join('lib', 'l10n'),
);
......@@ -60,16 +57,10 @@ void main() {
"description": "Sample description"
}
}''');
fileSystem.file('l10n.yaml').createSync();
final File pubspecFile = fileSystem.file('pubspec.yaml')..createSync();
final String content = pubspecFile.readAsStringSync().replaceFirst(
'\nflutter:\n',
'\nflutter:\n generate: true\n',
);
pubspecFile.writeAsStringSync(content);
final GenerateLocalizationsCommand command = GenerateLocalizationsCommand(
fileSystem: fileSystem,
logger: logger,
);
await createTestCommandRunner(command).run(<String>[
'gen-l10n',
......@@ -85,6 +76,7 @@ void main() {
testUsingContext('throws error when arguments are invalid', () async {
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
final BufferLogger logger = BufferLogger.test();
final File arbFile = fileSystem.file(fileSystem.path.join('lib', 'l10n', 'app_en.arb'))
..createSync(recursive: true);
arbFile.writeAsStringSync('''
......@@ -94,17 +86,11 @@ void main() {
"description": "Sample description"
}
}''');
fileSystem.file('l10n.yaml').createSync();
final File pubspecFile = fileSystem.file('pubspec.yaml')..createSync();
final String content = pubspecFile.readAsStringSync().replaceFirst(
'\nflutter:\n',
'\nflutter:\n generate: true\n',
);
pubspecFile.writeAsStringSync(content);
fileSystem.file('header.txt').writeAsStringSync('a header file');
final GenerateLocalizationsCommand command = GenerateLocalizationsCommand(
fileSystem: fileSystem,
logger: logger,
);
expect(
() => createTestCommandRunner(command).run(<String>[
......@@ -115,4 +101,34 @@ void main() {
throwsA(isA<ToolExit>()),
);
});
testUsingContext('l10n yaml file takes precedence over command line arguments', () async {
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
final BufferLogger logger = BufferLogger.test();
final File arbFile = fileSystem.file(fileSystem.path.join('lib', 'l10n', 'app_en.arb'))
..createSync(recursive: true);
arbFile.writeAsStringSync('''
{
"helloWorld": "Hello, World!",
"@helloWorld": {
"description": "Sample description"
}
}''');
fileSystem.file('l10n.yaml').createSync();
final File pubspecFile = fileSystem.file('pubspec.yaml')..createSync();
pubspecFile.writeAsStringSync(BasicProjectWithFlutterGen().pubspec);
final GenerateLocalizationsCommand command = GenerateLocalizationsCommand(
fileSystem: fileSystem,
logger: logger,
);
await createTestCommandRunner(command).run(<String>['gen-l10n']);
final FlutterCommandResult result = await command.runCommand();
expect(result.exitStatus, ExitStatus.success);
expect(logger.statusText, contains('Because l10n.yaml exists, the options defined there will be used instead.'));
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);
});
}
......@@ -8,6 +8,7 @@ import 'package:flutter_tools/src/base/logger.dart';
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/localizations/gen_l10n.dart';
import 'package:flutter_tools/src/localizations/localizations_utils.dart';
import 'package:mockito/mockito.dart';
import '../../../src/common.dart';
......@@ -58,7 +59,7 @@ void main() {
templateArbFileName: 'example.arb',
outputFileString: 'bar',
classNameString: 'Foo',
preferredSupportedLocale: <String>['en_US'],
preferredSupportedLocales: <String>['en_US'],
headerString: 'HEADER',
headerFile: 'header',
useDeferredLoading: true,
......
......@@ -984,7 +984,7 @@ void main() {
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
preferredSupportedLocale: preferredSupportedLocale,
preferredSupportedLocales: preferredSupportedLocale,
);
generator.loadResources();
} on L10nException catch (e) {
......@@ -1020,7 +1020,7 @@ void main() {
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
preferredSupportedLocale: preferredSupportedLocale,
preferredSupportedLocales: preferredSupportedLocale,
);
generator.loadResources();
} on L10nException catch (e) {
......@@ -1433,7 +1433,7 @@ void main() {
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
preferredSupportedLocale: preferredSupportedLocale,
preferredSupportedLocales: preferredSupportedLocale,
);
generator.loadResources();
generator.writeOutputFiles(BufferLogger.test());
......
......@@ -76,7 +76,7 @@ class BasicProjectWithFlutterGen extends Project {
@override
final String main = r'''
// @dart = 2.8
// generated package does not syupport null safety.
// generated package does not support null safety.
import 'dart:async';
import 'package:flutter_gen/flutter_gen.dart';
......
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