Unverified Commit 5c44b1df authored by Tae Hyung Kim's avatar Tae Hyung Kim Committed by GitHub

Refactor "gen-l10n" command to use same code path when "l10n.yaml" is present...

Refactor "gen-l10n" command to use same code path when "l10n.yaml" is present or not present (#125429)

I think this is a long needed change to the `gen-l10n` command.
Essentially, the arguments to `flutter gen-l10n` can be provided by two
different methods: via command line arguments or via the `l10n.yaml`
file. The existence of a `l10n.yaml` file causes the latter approach to
take precedence.

However, currently, there's several differences in how the two
approaches are handled, and most of the default arguments are all over
the place, causing unexpected issues such as #120457 or #120023.

This PR refactors the command so that
* `LocalizationOptions` are more consistent with the actual argument
names/yaml options.
* All default values are determined in `LocalizationOptions`'s
constructor (or in `argParser.addOption(...)` in the case a boolean
value needs to be explicitly true).
* New `parseLocalizationsOptionsFromCommand` function to parse
arguments.
* Parse `LocalizationOptions` at the beginning of `runCommand()` and
pass it to `generateLocalizations`.

Fixes #120023.
parent 89c76989
...@@ -45,9 +45,17 @@ class GenerateLocalizationsTarget extends Target { ...@@ -45,9 +45,17 @@ class GenerateLocalizationsTarget extends Target {
final File configFile = environment.projectDir.childFile('l10n.yaml'); final File configFile = environment.projectDir.childFile('l10n.yaml');
assert(configFile.existsSync()); assert(configFile.existsSync());
final LocalizationOptions options = parseLocalizationsOptions( // Keep in mind that this is also defined in the following locations:
// 1. flutter_tools/lib/src/commands/generate_localizations.dart
// 2. flutter_tools/test/general.shard/build_system/targets/localizations_test.dart
// Keep the value consistent in all three locations to ensure behavior is the
// same across "flutter gen-l10n" and "flutter run".
final String defaultArbDir = environment.fileSystem.path.join('lib', 'l10n');
final LocalizationOptions options = parseLocalizationsOptionsFromYAML(
file: configFile, file: configFile,
logger: environment.logger, logger: environment.logger,
defaultArbDir: defaultArbDir,
); );
final DepfileService depfileService = DepfileService( final DepfileService depfileService = DepfileService(
logger: environment.logger, logger: environment.logger,
......
...@@ -9,9 +9,7 @@ import '../base/common.dart'; ...@@ -9,9 +9,7 @@ import '../base/common.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/logger.dart'; import '../base/logger.dart';
import '../globals.dart' as globals;
import '../localizations/gen_l10n.dart'; import '../localizations/gen_l10n.dart';
import '../localizations/gen_l10n_types.dart';
import '../localizations/localizations_utils.dart'; import '../localizations/localizations_utils.dart';
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
...@@ -34,7 +32,6 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -34,7 +32,6 @@ class GenerateLocalizationsCommand extends FlutterCommand {
_processManager = processManager { _processManager = processManager {
argParser.addOption( argParser.addOption(
'arb-dir', 'arb-dir',
defaultsTo: globals.fs.path.join('lib', 'l10n'),
help: 'The directory where the template and translated arb files are located.', help: 'The directory where the template and translated arb files are located.',
); );
argParser.addOption( argParser.addOption(
...@@ -51,13 +48,11 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -51,13 +48,11 @@ class GenerateLocalizationsCommand extends FlutterCommand {
); );
argParser.addOption( argParser.addOption(
'template-arb-file', 'template-arb-file',
defaultsTo: 'app_en.arb',
help: 'The template arb file that will be used as the basis for ' help: 'The template arb file that will be used as the basis for '
'generating the Dart localization and messages files.', 'generating the Dart localization and messages files.',
); );
argParser.addOption( argParser.addOption(
'output-localization-file', 'output-localization-file',
defaultsTo: 'app_localizations.dart',
help: 'The filename for the output localization and localizations ' help: 'The filename for the output localization and localizations '
'delegate classes.', 'delegate classes.',
); );
...@@ -224,15 +219,19 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -224,15 +219,19 @@ class GenerateLocalizationsCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final List<String> outputFileList; // Keep in mind that this is also defined in the following locations:
File? untranslatedMessagesFile; // 1. flutter_tools/lib/src/build_system/targets/localizations.dart
// 2. flutter_tools/test/general.shard/build_system/targets/localizations_test.dart
bool format = boolArg('format'); // Keep the value consistent in all three locations to ensure behavior is the
// same across "flutter gen-l10n" and "flutter run".
final String defaultArbDir = _fileSystem.path.join('lib', 'l10n');
// Get all options associated with gen-l10n.
final LocalizationOptions options;
if (_fileSystem.file('l10n.yaml').existsSync()) { if (_fileSystem.file('l10n.yaml').existsSync()) {
final LocalizationOptions options = parseLocalizationsOptions( options = parseLocalizationsOptionsFromYAML(
file: _fileSystem.file('l10n.yaml'), file: _fileSystem.file('l10n.yaml'),
logger: _logger, logger: _logger,
defaultArbDir: defaultArbDir,
); );
_logger.printStatus( _logger.printStatus(
'Because l10n.yaml exists, the options defined there will be used ' 'Because l10n.yaml exists, the options defined there will be used '
...@@ -240,69 +239,25 @@ class GenerateLocalizationsCommand extends FlutterCommand { ...@@ -240,69 +239,25 @@ class GenerateLocalizationsCommand extends FlutterCommand {
'To use the command line arguments, delete the l10n.yaml file in the ' 'To use the command line arguments, delete the l10n.yaml file in the '
'Flutter project.\n\n' 'Flutter project.\n\n'
); );
final LocalizationsGenerator generator = generateLocalizations(
logger: _logger,
options: options,
projectDir: _fileSystem.currentDirectory,
fileSystem: _fileSystem,
);
outputFileList = generator.outputFileList;
untranslatedMessagesFile = generator.untranslatedMessagesFile;
format = format || options.format;
} else { } else {
final String inputPathString = stringArg('arb-dir')!; // Has default value, cannot be null. options = parseLocalizationsOptionsFromCommand(
final String? outputPathString = stringArg('output-dir'); command: this,
final String outputFileString = stringArg('output-localization-file')!; // Has default value, cannot be null. defaultArbDir: defaultArbDir
final String templateArbFileName = stringArg('template-arb-file')!; // Has default value, cannot be null. );
final String? untranslatedMessagesFilePath = stringArg('untranslated-messages-file');
final String classNameString = stringArg('output-class')!; // Has default value, cannot be null.
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');
final String? inputsAndOutputsListPath = stringArg('gen-inputs-and-outputs-list');
final bool useSyntheticPackage = boolArg('synthetic-package');
final String? projectPathString = stringArg('project-dir');
final bool areResourceAttributesRequired = boolArg('required-resource-attributes');
final bool usesNullableGetter = boolArg('nullable-getter');
final bool useEscaping = boolArg('use-escaping');
final bool suppressWarnings = boolArg('suppress-warnings');
precacheLanguageAndRegionTags();
try {
final LocalizationsGenerator generator = LocalizationsGenerator(
fileSystem: _fileSystem,
inputPathString: inputPathString,
outputPathString: outputPathString,
templateArbFileName: templateArbFileName,
outputFileString: outputFileString,
classNameString: classNameString,
preferredSupportedLocales: preferredSupportedLocales,
headerString: headerString,
headerFile: headerFile,
useDeferredLoading: useDeferredLoading,
inputsAndOutputsListPath: inputsAndOutputsListPath,
useSyntheticPackage: useSyntheticPackage,
projectPathString: projectPathString,
areResourceAttributesRequired: areResourceAttributesRequired,
untranslatedMessagesFile: untranslatedMessagesFilePath,
usesNullableGetter: usesNullableGetter,
useEscaping: useEscaping,
logger: _logger,
suppressWarnings: suppressWarnings,
)
..loadResources()
..writeOutputFiles();
outputFileList = generator.outputFileList;
untranslatedMessagesFile = generator.untranslatedMessagesFile;
} on L10nException catch (e) {
throwToolExit(e.message);
}
} }
// Run the localizations generator.
final LocalizationsGenerator generator = generateLocalizations(
logger: _logger,
options: options,
projectDir: _fileSystem.currentDirectory,
fileSystem: _fileSystem,
);
final List<String> outputFileList = generator.outputFileList;
final File? untranslatedMessagesFile = generator.untranslatedMessagesFile;
// All other post processing. // All other post processing.
if (format) { if (options.format) {
if (outputFileList.isEmpty) { if (outputFileList.isEmpty) {
return FlutterCommandResult.success(); return FlutterCommandResult.success();
} }
......
...@@ -30,7 +30,7 @@ LocalizationsGenerator generateLocalizations({ ...@@ -30,7 +30,7 @@ LocalizationsGenerator generateLocalizations({
fileSystem: projectDir.fileSystem, fileSystem: projectDir.fileSystem,
logger: logger, logger: logger,
); );
if (options.useSyntheticPackage && (flutterManifest == null || !flutterManifest.generateSyntheticPackage)) { if (options.syntheticPackage && (flutterManifest == null || !flutterManifest.generateSyntheticPackage)) {
throwToolExit( throwToolExit(
'Attempted to generate localizations code without having ' 'Attempted to generate localizations code without having '
'the flutter: generate flag turned on.' 'the flutter: generate flag turned on.'
...@@ -43,28 +43,25 @@ LocalizationsGenerator generateLocalizations({ ...@@ -43,28 +43,25 @@ LocalizationsGenerator generateLocalizations({
precacheLanguageAndRegionTags(); precacheLanguageAndRegionTags();
final String inputPathString = options.arbDirectory?.path ?? fileSystem.path.join('lib', 'l10n');
final String templateArbFileName = options.templateArbFile?.toFilePath() ?? 'app_en.arb';
final String outputFileString = options.outputLocalizationsFile?.toFilePath() ?? 'app_localizations.dart';
LocalizationsGenerator generator; LocalizationsGenerator generator;
try { try {
generator = LocalizationsGenerator( generator = LocalizationsGenerator(
fileSystem: fileSystem, fileSystem: fileSystem,
inputsAndOutputsListPath: dependenciesDir?.path, inputsAndOutputsListPath: dependenciesDir?.path,
projectPathString: projectDir.path, projectPathString: projectDir.path,
inputPathString: inputPathString, inputPathString: options.arbDir,
templateArbFileName: templateArbFileName, templateArbFileName: options.templateArbFile,
outputFileString: outputFileString, outputFileString: options.outputLocalizationFile,
outputPathString: options.outputDirectory?.path, outputPathString: options.outputDir,
classNameString: options.outputClass ?? 'AppLocalizations', classNameString: options.outputClass,
preferredSupportedLocales: options.preferredSupportedLocales, preferredSupportedLocales: options.preferredSupportedLocales,
headerString: options.header, headerString: options.header,
headerFile: options.headerFile?.toFilePath(), headerFile: options.headerFile,
useDeferredLoading: options.deferredLoading ?? false, useDeferredLoading: options.useDeferredLoading,
useSyntheticPackage: options.useSyntheticPackage, useSyntheticPackage: options.syntheticPackage,
areResourceAttributesRequired: options.areResourceAttributesRequired, areResourceAttributesRequired: options.requiredResourceAttributes,
untranslatedMessagesFile: options.untranslatedMessagesFile?.toFilePath(), untranslatedMessagesFile: options.untranslatedMessagesFile,
usesNullableGetter: options.usesNullableGetter, usesNullableGetter: options.nullableGetter,
useEscaping: options.useEscaping, useEscaping: options.useEscaping,
logger: logger, logger: logger,
suppressWarnings: options.suppressWarnings, suppressWarnings: options.suppressWarnings,
......
...@@ -8,6 +8,7 @@ import 'package:yaml/yaml.dart'; ...@@ -8,6 +8,7 @@ import 'package:yaml/yaml.dart';
import '../base/common.dart'; import '../base/common.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/logger.dart'; import '../base/logger.dart';
import '../runner/flutter_command.dart';
import 'gen_l10n_types.dart'; import 'gen_l10n_types.dart';
import 'language_subtag_registry.dart'; import 'language_subtag_registry.dart';
...@@ -334,89 +335,111 @@ String generateReturnExpr(List<String> expressions, { bool isSingleStringVar = f ...@@ -334,89 +335,111 @@ String generateReturnExpr(List<String> expressions, { bool isSingleStringVar = f
/// Typed configuration from the localizations config file. /// Typed configuration from the localizations config file.
class LocalizationOptions { class LocalizationOptions {
const LocalizationOptions({ LocalizationOptions({
this.arbDirectory, required this.arbDir,
this.templateArbFile, this.outputDir,
this.outputLocalizationsFile, String? templateArbFile,
String? outputLocalizationFile,
this.untranslatedMessagesFile, this.untranslatedMessagesFile,
this.header, String? outputClass,
this.outputClass,
this.outputDirectory,
this.preferredSupportedLocales, this.preferredSupportedLocales,
this.header,
this.headerFile, this.headerFile,
this.deferredLoading, bool? useDeferredLoading,
this.useSyntheticPackage = true, this.genInputsAndOutputsList,
this.areResourceAttributesRequired = false, bool? syntheticPackage,
this.usesNullableGetter = true, this.projectDir,
this.format = false, bool? requiredResourceAttributes,
this.useEscaping = false, bool? nullableGetter,
this.suppressWarnings = false, bool? format,
}); bool? useEscaping,
bool? suppressWarnings,
}) : templateArbFile = templateArbFile ?? 'app_en.arb',
outputLocalizationFile = outputLocalizationFile ?? 'app_localizations.dart',
outputClass = outputClass ?? 'AppLocalizations',
useDeferredLoading = useDeferredLoading ?? false,
syntheticPackage = syntheticPackage ?? true,
requiredResourceAttributes = requiredResourceAttributes ?? false,
nullableGetter = nullableGetter ?? true,
format = format ?? false,
useEscaping = useEscaping ?? false,
suppressWarnings = suppressWarnings ?? false;
/// The `--arb-dir` argument. /// The `--arb-dir` argument.
/// ///
/// The directory where all input localization files should reside. /// The directory where all input localization files should reside.
final Uri? arbDirectory; final String arbDir;
/// The `--output-dir` argument.
///
/// The directory where all output localization files should be generated.
final String? outputDir;
/// The `--template-arb-file` argument. /// The `--template-arb-file` argument.
/// ///
/// This URI is relative to [arbDirectory]. /// This path is relative to [arbDirectory].
final Uri? templateArbFile; final String templateArbFile;
/// The `--output-localization-file` argument. /// The `--output-localization-file` argument.
/// ///
/// This URI is relative to [arbDirectory]. /// This path is relative to [arbDir].
final Uri? outputLocalizationsFile; final String outputLocalizationFile;
/// The `--untranslated-messages-file` argument. /// The `--untranslated-messages-file` argument.
/// ///
/// This URI is relative to [arbDirectory]. /// This path is relative to [arbDir].
final Uri? untranslatedMessagesFile; final String? untranslatedMessagesFile;
/// The `--header` argument.
///
/// The header to prepend to the generated Dart localizations.
final String? header;
/// The `--output-class` argument. /// The `--output-class` argument.
final String? outputClass; 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. /// The `--preferred-supported-locales` argument.
final List<String>? preferredSupportedLocales; final List<String>? preferredSupportedLocales;
/// The `--header` argument.
///
/// The header to prepend to the generated Dart localizations.
final String? header;
/// The `--header-file` argument. /// The `--header-file` argument.
/// ///
/// A file containing the header to prepend to the generated /// A file containing the header to prepend to the generated
/// Dart localizations. /// Dart localizations.
final Uri? headerFile; final String? headerFile;
/// The `--use-deferred-loading` argument. /// The `--use-deferred-loading` argument.
/// ///
/// Whether to generate the Dart localization file with locales imported /// Whether to generate the Dart localization file with locales imported
/// as deferred. /// as deferred.
final bool? deferredLoading; final bool useDeferredLoading;
/// The `--gen-inputs-and-outputs-list` argument.
///
/// This path is relative to [arbDir].
final String? genInputsAndOutputsList;
/// The `--synthetic-package` argument. /// The `--synthetic-package` argument.
/// ///
/// Whether to generate the Dart localization files in a synthetic package /// Whether to generate the Dart localization files in a synthetic package
/// or in a custom directory. /// or in a custom directory.
final bool useSyntheticPackage; final bool syntheticPackage;
/// The `--project-dir` argument.
///
/// This path is relative to [arbDir].
final String? projectDir;
/// The `required-resource-attributes` argument. /// The `required-resource-attributes` argument.
/// ///
/// Whether to require all resource ids to contain a corresponding /// Whether to require all resource ids to contain a corresponding
/// resource attribute. /// resource attribute.
final bool areResourceAttributesRequired; final bool requiredResourceAttributes;
/// The `nullable-getter` argument. /// The `nullable-getter` argument.
/// ///
/// Whether or not the localizations class getter is nullable. /// Whether or not the localizations class getter is nullable.
final bool usesNullableGetter; final bool nullableGetter;
/// The `format` argument. /// The `format` argument.
/// ///
...@@ -439,13 +462,14 @@ class LocalizationOptions { ...@@ -439,13 +462,14 @@ class LocalizationOptions {
/// Throws [Exception] if any of the contents are invalid. Returns a /// Throws [Exception] if any of the contents are invalid. Returns a
/// [LocalizationOptions] with all fields as `null` if the config file exists /// [LocalizationOptions] with all fields as `null` if the config file exists
/// but is empty. /// but is empty.
LocalizationOptions parseLocalizationsOptions({ LocalizationOptions parseLocalizationsOptionsFromYAML({
required File file, required File file,
required Logger logger, required Logger logger,
required String defaultArbDir,
}) { }) {
final String contents = file.readAsStringSync(); final String contents = file.readAsStringSync();
if (contents.trim().isEmpty) { if (contents.trim().isEmpty) {
return const LocalizationOptions(); return LocalizationOptions(arbDir: defaultArbDir);
} }
final YamlNode yamlNode; final YamlNode yamlNode;
try { try {
...@@ -458,22 +482,48 @@ LocalizationOptions parseLocalizationsOptions({ ...@@ -458,22 +482,48 @@ LocalizationOptions parseLocalizationsOptions({
throw Exception(); throw Exception();
} }
return LocalizationOptions( return LocalizationOptions(
arbDirectory: _tryReadUri(yamlNode, 'arb-dir', logger), arbDir: _tryReadUri(yamlNode, 'arb-dir', logger)?.path ?? defaultArbDir,
templateArbFile: _tryReadUri(yamlNode, 'template-arb-file', logger), outputDir: _tryReadUri(yamlNode, 'output-dir', logger)?.path,
outputLocalizationsFile: _tryReadUri(yamlNode, 'output-localization-file', logger), templateArbFile: _tryReadUri(yamlNode, 'template-arb-file', logger)?.path,
untranslatedMessagesFile: _tryReadUri(yamlNode, 'untranslated-messages-file', logger), outputLocalizationFile: _tryReadUri(yamlNode, 'output-localization-file', logger)?.path,
header: _tryReadString(yamlNode, 'header', logger), untranslatedMessagesFile: _tryReadUri(yamlNode, 'untranslated-messages-file', logger)?.path,
outputClass: _tryReadString(yamlNode, 'output-class', logger), outputClass: _tryReadString(yamlNode, 'output-class', logger),
outputDirectory: _tryReadUri(yamlNode, 'output-dir', logger), header: _tryReadString(yamlNode, 'header', logger),
headerFile: _tryReadUri(yamlNode, 'header-file', logger)?.path,
useDeferredLoading: _tryReadBool(yamlNode, 'use-deferred-loading', logger),
preferredSupportedLocales: _tryReadStringList(yamlNode, 'preferred-supported-locales', logger), preferredSupportedLocales: _tryReadStringList(yamlNode, 'preferred-supported-locales', logger),
headerFile: _tryReadUri(yamlNode, 'header-file', logger), syntheticPackage: _tryReadBool(yamlNode, 'synthetic-package', logger),
deferredLoading: _tryReadBool(yamlNode, 'use-deferred-loading', logger), requiredResourceAttributes: _tryReadBool(yamlNode, 'required-resource-attributes', logger),
useSyntheticPackage: _tryReadBool(yamlNode, 'synthetic-package', logger) ?? true, nullableGetter: _tryReadBool(yamlNode, 'nullable-getter', logger),
areResourceAttributesRequired: _tryReadBool(yamlNode, 'required-resource-attributes', logger) ?? false, format: _tryReadBool(yamlNode, 'format', logger),
usesNullableGetter: _tryReadBool(yamlNode, 'nullable-getter', logger) ?? true, useEscaping: _tryReadBool(yamlNode, 'use-escaping', logger),
format: _tryReadBool(yamlNode, 'format', logger) ?? false, suppressWarnings: _tryReadBool(yamlNode, 'suppress-warnings', logger),
useEscaping: _tryReadBool(yamlNode, 'use-escaping', logger) ?? false, );
suppressWarnings: _tryReadBool(yamlNode, 'suppress-warnings', logger) ?? false, }
/// Parse the localizations configuration from [FlutterCommand].
LocalizationOptions parseLocalizationsOptionsFromCommand({
required FlutterCommand command,
required String defaultArbDir,
}) {
return LocalizationOptions(
arbDir: command.stringArg('arb-dir') ?? defaultArbDir,
outputDir: command.stringArg('output-dir'),
outputLocalizationFile: command.stringArg('output-localization-file'),
templateArbFile: command.stringArg('template-arb-file'),
untranslatedMessagesFile: command.stringArg('untranslated-messages-file'),
outputClass: command.stringArg('output-class'),
header: command.stringArg('header'),
headerFile: command.stringArg('header-file'),
useDeferredLoading: command.boolArg('use-deferred-loading'),
genInputsAndOutputsList: command.stringArg('gen-inputs-and-outputs-list'),
syntheticPackage: command.boolArg('synthetic-package'),
projectDir: command.stringArg('project-dir'),
requiredResourceAttributes: command.boolArg('required-resource-attributes'),
nullableGetter: command.boolArg('nullable-getter'),
format: command.boolArg('format'),
useEscaping: command.boolArg('use-escaping'),
suppressWarnings: command.boolArg('suppress-warnings'),
); );
} }
......
...@@ -42,6 +42,8 @@ void main() { ...@@ -42,6 +42,8 @@ void main() {
"description": "Sample description" "description": "Sample description"
} }
}'''); }''');
final File pubspecFile = fileSystem.file('pubspec.yaml')..createSync();
pubspecFile.writeAsStringSync(BasicProjectWithFlutterGen().pubspec);
final GenerateLocalizationsCommand command = GenerateLocalizationsCommand( final GenerateLocalizationsCommand command = GenerateLocalizationsCommand(
fileSystem: fileSystem, fileSystem: fileSystem,
logger: logger, logger: logger,
...@@ -192,6 +194,8 @@ void main() { ...@@ -192,6 +194,8 @@ void main() {
"description": "Sample description" "description": "Sample description"
} }
}'''); }''');
final File pubspecFile = fileSystem.file('pubspec.yaml')..createSync();
pubspecFile.writeAsStringSync(BasicProjectWithFlutterGen().pubspec);
processManager.addCommand( processManager.addCommand(
const FakeCommand( const FakeCommand(
command: <String>[ command: <String>[
...@@ -351,4 +355,83 @@ untranslated-messages-file: lib/l10n/untranslated.json ...@@ -351,4 +355,83 @@ untranslated-messages-file: lib/l10n/untranslated.json
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
}); });
testUsingContext('throw when generate: false and uses synthetic package when run with l10n.yaml', () async {
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('''
name: test
environment:
sdk: '>=3.0.0-0 <4.0.0'
dependencies:
flutter:
sdk: flutter
flutter:
generate: false
''');
final GenerateLocalizationsCommand command = GenerateLocalizationsCommand(
fileSystem: fileSystem,
logger: logger,
artifacts: artifacts,
processManager: processManager,
);
expect(
() async => createTestCommandRunner(command).run(<String>['gen-l10n']),
throwsToolExit(message: 'Attempted to generate localizations code without having the flutter: generate flag turned on.')
);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('throw when generate: false and uses synthetic package when run via commandline options', () async {
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"
}
}''');
final File pubspecFile = fileSystem.file('pubspec.yaml')..createSync();
pubspecFile.writeAsStringSync('''
name: test
environment:
sdk: '>=3.0.0-0 <4.0.0'
dependencies:
flutter:
sdk: flutter
flutter:
generate: false
''');
final GenerateLocalizationsCommand command = GenerateLocalizationsCommand(
fileSystem: fileSystem,
logger: logger,
artifacts: artifacts,
processManager: processManager,
);
expect(
() async => createTestCommandRunner(command).run(<String>['gen-l10n', '--synthetic-package']),
throwsToolExit(message: 'Attempted to generate localizations code without having the flutter: generate flag turned on.')
);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
} }
...@@ -49,23 +49,24 @@ required-resource-attributes: false ...@@ -49,23 +49,24 @@ required-resource-attributes: false
nullable-getter: false nullable-getter: false
'''); ''');
final LocalizationOptions options = parseLocalizationsOptions( final LocalizationOptions options = parseLocalizationsOptionsFromYAML(
file: configFile, file: configFile,
logger: BufferLogger.test(), logger: BufferLogger.test(),
defaultArbDir: fileSystem.path.join('lib', 'l10n'),
); );
expect(options.arbDirectory, Uri.parse('arb')); expect(options.arbDir, Uri.parse('arb').path);
expect(options.templateArbFile, Uri.parse('example.arb')); expect(options.templateArbFile, Uri.parse('example.arb').path);
expect(options.outputLocalizationsFile, Uri.parse('bar')); expect(options.outputLocalizationFile, Uri.parse('bar').path);
expect(options.untranslatedMessagesFile, Uri.parse('untranslated')); expect(options.untranslatedMessagesFile, Uri.parse('untranslated').path);
expect(options.outputClass, 'Foo'); expect(options.outputClass, 'Foo');
expect(options.headerFile, Uri.parse('header')); expect(options.headerFile, Uri.parse('header').path);
expect(options.header, 'HEADER'); expect(options.header, 'HEADER');
expect(options.deferredLoading, true); expect(options.useDeferredLoading, true);
expect(options.preferredSupportedLocales, <String>['en_US']); expect(options.preferredSupportedLocales, <String>['en_US']);
expect(options.useSyntheticPackage, false); expect(options.syntheticPackage, false);
expect(options.areResourceAttributesRequired, false); expect(options.requiredResourceAttributes, false);
expect(options.usesNullableGetter, false); expect(options.nullableGetter, false);
}); });
testWithoutContext('parseLocalizationsOptions handles preferredSupportedLocales as list', () async { testWithoutContext('parseLocalizationsOptions handles preferredSupportedLocales as list', () async {
...@@ -74,9 +75,10 @@ nullable-getter: false ...@@ -74,9 +75,10 @@ nullable-getter: false
preferred-supported-locales: ['en_US', 'de'] preferred-supported-locales: ['en_US', 'de']
'''); ''');
final LocalizationOptions options = parseLocalizationsOptions( final LocalizationOptions options = parseLocalizationsOptionsFromYAML(
file: configFile, file: configFile,
logger: BufferLogger.test(), logger: BufferLogger.test(),
defaultArbDir: fileSystem.path.join('lib', 'l10n'),
); );
expect(options.preferredSupportedLocales, <String>['en_US', 'de']); expect(options.preferredSupportedLocales, <String>['en_US', 'de']);
...@@ -91,9 +93,10 @@ use-deferred-loading: string ...@@ -91,9 +93,10 @@ use-deferred-loading: string
'''); ''');
expect( expect(
() => parseLocalizationsOptions( () => parseLocalizationsOptionsFromYAML(
file: configFile, file: configFile,
logger: BufferLogger.test(), logger: BufferLogger.test(),
defaultArbDir: fileSystem.path.join('lib', 'l10n'),
), ),
throwsException, throwsException,
); );
...@@ -106,9 +109,10 @@ template-arb-file: {name}_en.arb ...@@ -106,9 +109,10 @@ template-arb-file: {name}_en.arb
'''); ''');
expect( expect(
() => parseLocalizationsOptions( () => parseLocalizationsOptionsFromYAML(
file: configFile, file: configFile,
logger: BufferLogger.test(), logger: BufferLogger.test(),
defaultArbDir: fileSystem.path.join('lib', 'l10n'),
), ),
throwsToolExit(), throwsToolExit(),
); );
......
...@@ -796,10 +796,10 @@ void main() { ...@@ -796,10 +796,10 @@ void main() {
generateLocalizations( generateLocalizations(
fileSystem: fs, fileSystem: fs,
options: LocalizationOptions( options: LocalizationOptions(
arbDirectory: Uri.directory(defaultL10nPathString), arbDir: Uri.directory(defaultL10nPathString).path,
outputDirectory: Uri.directory(defaultL10nPathString, windows: false), outputDir: Uri.directory(defaultL10nPathString, windows: false).path,
templateArbFile: Uri.file(defaultTemplateArbFileName, windows: false), templateArbFile: Uri.file(defaultTemplateArbFileName, windows: false).path,
useSyntheticPackage: false, syntheticPackage: false,
), ),
logger: logger, logger: logger,
projectDir: fs.currentDirectory, projectDir: fs.currentDirectory,
...@@ -811,17 +811,17 @@ void main() { ...@@ -811,17 +811,17 @@ void main() {
_standardFlutterDirectoryL10nSetup(fs); _standardFlutterDirectoryL10nSetup(fs);
final LocalizationOptions options = LocalizationOptions( final LocalizationOptions options = LocalizationOptions(
header: 'HEADER', header: 'HEADER',
arbDirectory: Uri.directory(defaultL10nPathString), arbDir: Uri.directory(defaultL10nPathString).path,
deferredLoading: true, useDeferredLoading: true,
outputClass: 'Foo', outputClass: 'Foo',
outputLocalizationsFile: Uri.file('bar.dart', windows: false), outputLocalizationFile: Uri.file('bar.dart', windows: false).path,
outputDirectory: Uri.directory(defaultL10nPathString, windows: false), outputDir: Uri.directory(defaultL10nPathString, windows: false).path,
preferredSupportedLocales: <String>['es'], preferredSupportedLocales: <String>['es'],
templateArbFile: Uri.file(defaultTemplateArbFileName, windows: false), templateArbFile: Uri.file(defaultTemplateArbFileName, windows: false).path,
untranslatedMessagesFile: Uri.file('untranslated', windows: false), untranslatedMessagesFile: Uri.file('untranslated', windows: false).path,
useSyntheticPackage: false, syntheticPackage: false,
areResourceAttributesRequired: true, requiredResourceAttributes: true,
usesNullableGetter: false, nullableGetter: false,
); );
// Verify that values are correctly passed through the localizations target. // Verify that values are correctly passed through the localizations target.
...@@ -877,14 +877,14 @@ flutter: ...@@ -877,14 +877,14 @@ flutter:
final LocalizationOptions options = LocalizationOptions( final LocalizationOptions options = LocalizationOptions(
header: 'HEADER', header: 'HEADER',
headerFile: Uri.file('header', windows: false), headerFile: Uri.file('header', windows: false).path,
arbDirectory: Uri.file('arb', windows: false), arbDir: Uri.file('arb', windows: false).path,
deferredLoading: true, useDeferredLoading: true,
outputClass: 'Foo', outputClass: 'Foo',
outputLocalizationsFile: Uri.file('bar', windows: false), outputLocalizationFile: Uri.file('bar', windows: false).path,
preferredSupportedLocales: <String>['en_US'], preferredSupportedLocales: <String>['en_US'],
templateArbFile: Uri.file('example.arb', windows: false), templateArbFile: Uri.file('example.arb', windows: false).path,
untranslatedMessagesFile: Uri.file('untranslated', windows: false), untranslatedMessagesFile: Uri.file('untranslated', windows: false).path,
); );
expect( expect(
...@@ -909,10 +909,10 @@ flutter: ...@@ -909,10 +909,10 @@ flutter:
generateLocalizations( generateLocalizations(
fileSystem: fs, fileSystem: fs,
options: LocalizationOptions( options: LocalizationOptions(
arbDirectory: Uri.directory(defaultL10nPathString), arbDir: Uri.directory(defaultL10nPathString).path,
outputDirectory: Uri.directory(defaultL10nPathString, windows: false), outputDir: Uri.directory(defaultL10nPathString, windows: false).path,
templateArbFile: Uri.file(defaultTemplateArbFileName, windows: false), templateArbFile: Uri.file(defaultTemplateArbFileName, windows: false).path,
useSyntheticPackage: false, syntheticPackage: false,
), ),
logger: BufferLogger.test(), logger: BufferLogger.test(),
projectDir: fs.currentDirectory, projectDir: fs.currentDirectory,
...@@ -936,10 +936,10 @@ class AppLocalizationsEn extends AppLocalizations { ...@@ -936,10 +936,10 @@ class AppLocalizationsEn extends AppLocalizations {
fileSystem: fs, fileSystem: fs,
options: LocalizationOptions( options: LocalizationOptions(
header: 'HEADER', header: 'HEADER',
arbDirectory: Uri.directory(defaultL10nPathString), arbDir: Uri.directory(defaultL10nPathString).path,
outputDirectory: Uri.directory(defaultL10nPathString, windows: false), outputDir: Uri.directory(defaultL10nPathString, windows: false).path,
templateArbFile: Uri.file(defaultTemplateArbFileName, windows: false), templateArbFile: Uri.file(defaultTemplateArbFileName, windows: false).path,
useSyntheticPackage: false, syntheticPackage: false,
), ),
logger: logger, logger: logger,
projectDir: fs.currentDirectory, projectDir: fs.currentDirectory,
......
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