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

[gen_l10n] Create pubspec.yaml in ".dart_tool/flutter_gen" if it does not already exist (#68206)

* Generate pubspec.yaml for synthetic package if it did not exist prior
parent 86e8bf47
...@@ -119,7 +119,6 @@ class GenerateLocalizationsTarget extends Target { ...@@ -119,7 +119,6 @@ class GenerateLocalizationsTarget extends Target {
logger: environment.logger, logger: environment.logger,
fileSystem: environment.fileSystem, fileSystem: environment.fileSystem,
); );
generateLocalizations( generateLocalizations(
logger: environment.logger, logger: environment.logger,
options: options, options: options,
......
...@@ -13,12 +13,15 @@ import 'gen_l10n_templates.dart'; ...@@ -13,12 +13,15 @@ import 'gen_l10n_templates.dart';
import 'gen_l10n_types.dart'; import 'gen_l10n_types.dart';
import 'localizations_utils.dart'; import 'localizations_utils.dart';
/// The default path used when the `useSyntheticPackage` setting is set to true /// The path for the synthetic package.
final String defaultSyntheticPackagePath = globals.fs.path.join('.dart_tool', 'flutter_gen');
/// The default path used when the `_useSyntheticPackage` setting is set to true
/// in [LocalizationsGenerator]. /// in [LocalizationsGenerator].
/// ///
/// See [LocalizationsGenerator.initialize] for where and how it is used by the /// See [LocalizationsGenerator.initialize] for where and how it is used by the
/// localizations tool. /// localizations tool.
final String defaultSyntheticPackagePath = globals.fs.path.join('.dart_tool', 'flutter_gen', 'gen_l10n'); final String syntheticL10nPackagePath = globals.fs.path.join(defaultSyntheticPackagePath, 'gen_l10n');
List<String> generateMethodParameters(Message message) { List<String> generateMethodParameters(Message message) {
assert(message.placeholders.isNotEmpty); assert(message.placeholders.isNotEmpty);
...@@ -405,6 +408,7 @@ class LocalizationsGenerator { ...@@ -405,6 +408,7 @@ class LocalizationsGenerator {
Iterable<Message> _allMessages; Iterable<Message> _allMessages;
AppResourceBundleCollection _allBundles; AppResourceBundleCollection _allBundles;
LocaleInfo _templateArbLocale; LocaleInfo _templateArbLocale;
bool _useSyntheticPackage = true;
/// The directory that contains the project's arb files, as well as the /// The directory that contains the project's arb files, as well as the
/// header file, if specified. /// header file, if specified.
...@@ -538,12 +542,10 @@ class LocalizationsGenerator { ...@@ -538,12 +542,10 @@ class LocalizationsGenerator {
bool useSyntheticPackage = true, bool useSyntheticPackage = true,
String projectPathString, String projectPathString,
}) { }) {
_useSyntheticPackage = useSyntheticPackage;
setProjectDir(projectPathString); setProjectDir(projectPathString);
setInputDirectory(inputPathString); setInputDirectory(inputPathString);
setOutputDirectory( setOutputDirectory(outputPathString ?? inputPathString);
outputPathString: outputPathString ?? inputPathString,
useSyntheticPackage: useSyntheticPackage,
);
setTemplateArbFile(templateArbFileName); setTemplateArbFile(templateArbFileName);
setBaseOutputFile(outputFileString); setBaseOutputFile(outputFileString);
setPreferredSupportedLocales(preferredSupportedLocale); setPreferredSupportedLocales(preferredSupportedLocale);
...@@ -614,15 +616,14 @@ class LocalizationsGenerator { ...@@ -614,15 +616,14 @@ class LocalizationsGenerator {
/// Sets the reference [Directory] for [outputDirectory]. /// Sets the reference [Directory] for [outputDirectory].
@visibleForTesting @visibleForTesting
void setOutputDirectory({ void setOutputDirectory(
String outputPathString, String outputPathString,
bool useSyntheticPackage = true, ) {
}) { if (_useSyntheticPackage) {
if (useSyntheticPackage) {
outputDirectory = _fs.directory( outputDirectory = _fs.directory(
projectDirectory != null projectDirectory != null
? _getAbsoluteProjectPath(defaultSyntheticPackagePath) ? _getAbsoluteProjectPath(syntheticL10nPackagePath)
: defaultSyntheticPackagePath : syntheticL10nPackagePath
); );
} else { } else {
if (outputPathString == null) { if (outputPathString == null) {
...@@ -1004,11 +1005,20 @@ class LocalizationsGenerator { ...@@ -1004,11 +1005,20 @@ class LocalizationsGenerator {
// First, generate the string contents of all necessary files. // First, generate the string contents of all necessary files.
_generateCode(); _generateCode();
// A pubspec.yaml file is required when using a synthetic package. If it does not
// exist, create a blank one.
if (_useSyntheticPackage) {
final Directory syntheticPackageDirectory = _fs.directory(defaultSyntheticPackagePath);
syntheticPackageDirectory.createSync(recursive: true);
final File flutterGenPubspec = syntheticPackageDirectory.childFile('pubspec.yaml');
if (!flutterGenPubspec.existsSync()) {
flutterGenPubspec.writeAsStringSync(emptyPubspecTemplate);
}
}
// Since all validity checks have passed up to this point, // Since all validity checks have passed up to this point,
// write the contents into the directory. // write the contents into the directory.
if (!outputDirectory.existsSync()) { outputDirectory.createSync(recursive: true);
outputDirectory.createSync(recursive: true);
}
// Ensure that the created directory has read/write permissions. // Ensure that the created directory has read/write permissions.
final FileStat fileStat = outputDirectory.statSync(); final FileStat fileStat = outputDirectory.statSync();
......
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
const String emptyPubspecTemplate = '''# Generated by the flutter tool
name: synthetic_package
description: The Flutter application's synthetic package.
''';
const String fileTemplate = ''' const String fileTemplate = '''
@(header) @(header)
import 'dart:async'; import 'dart:async';
......
...@@ -877,7 +877,6 @@ abstract class ResidentRunner { ...@@ -877,7 +877,6 @@ abstract class ResidentRunner {
processManager: globals.processManager, processManager: globals.processManager,
projectDir: globals.fs.currentDirectory, projectDir: globals.fs.currentDirectory,
); );
globals.logger.printTrace('Starting incremental build...');
_lastBuild = await globals.buildSystem.buildIncremental( _lastBuild = await globals.buildSystem.buildIncremental(
const GenerateLocalizationsTarget(), const GenerateLocalizationsTarget(),
_environment, _environment,
......
...@@ -6,6 +6,7 @@ import 'dart:convert'; ...@@ -6,6 +6,7 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:yaml/yaml.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
...@@ -19,7 +20,8 @@ import 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf; // ignor ...@@ -19,7 +20,8 @@ import 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf; // ignor
export 'package:test_core/test_core.dart' hide TypeMatcher, isInstanceOf, test; // Defines a 'package:test' shim. export 'package:test_core/test_core.dart' hide TypeMatcher, isInstanceOf, test; // Defines a 'package:test' shim.
final String defaultL10nPathString = globals.fs.path.join('lib', 'l10n'); final String defaultL10nPathString = globals.fs.path.join('lib', 'l10n');
final String syntheticPackagePath = globals.fs.path.join('.dart_tool', 'flutter_gen', 'gen_l10n'); final String syntheticPackagePath = globals.fs.path.join('.dart_tool', 'flutter_gen');
final String syntheticL10nPackagePath = globals.fs.path.join(syntheticPackagePath, 'gen_l10n');
const String defaultTemplateArbFileName = 'app_en.arb'; const String defaultTemplateArbFileName = 'app_en.arb';
const String defaultOutputFileString = 'output-localization-file.dart'; const String defaultOutputFileString = 'output-localization-file.dart';
const String defaultClassNameString = 'AppLocalizations'; const String defaultClassNameString = 'AppLocalizations';
...@@ -109,10 +111,8 @@ void main() { ...@@ -109,10 +111,8 @@ void main() {
_standardFlutterDirectoryL10nSetup(fs); _standardFlutterDirectoryL10nSetup(fs);
final LocalizationsGenerator generator = LocalizationsGenerator(fs); final LocalizationsGenerator generator = LocalizationsGenerator(fs);
try { try {
generator.setOutputDirectory( generator.initialize(useSyntheticPackage: false);
outputPathString: null, generator.setOutputDirectory(null);
useSyntheticPackage: false,
);
} on L10nException catch (e) { } on L10nException catch (e) {
expect(e.message, contains('cannot be null')); expect(e.message, contains('cannot be null'));
return; return;
...@@ -302,7 +302,7 @@ void main() { ...@@ -302,7 +302,7 @@ void main() {
generator = LocalizationsGenerator(fs); generator = LocalizationsGenerator(fs);
try { try {
generator.setInputDirectory(defaultL10nPathString); generator.setInputDirectory(defaultL10nPathString);
generator.setOutputDirectory(); generator.setOutputDirectory(null);
generator.setTemplateArbFile(defaultTemplateArbFileName); generator.setTemplateArbFile(defaultTemplateArbFileName);
generator.setBaseOutputFile(defaultOutputFileString); generator.setBaseOutputFile(defaultOutputFileString);
} on L10nException catch (e) { } on L10nException catch (e) {
...@@ -433,7 +433,7 @@ void main() { ...@@ -433,7 +433,7 @@ void main() {
fail('Generating output should not fail: \n${e.message}'); fail('Generating output should not fail: \n${e.message}');
} }
final Directory outputDirectory = fs.directory(syntheticPackagePath); final Directory outputDirectory = fs.directory(syntheticL10nPackagePath);
expect(outputDirectory.childFile('output-localization-file.dart').existsSync(), isTrue); expect(outputDirectory.childFile('output-localization-file.dart').existsSync(), isTrue);
expect(outputDirectory.childFile('output-localization-file_en.dart').existsSync(), isTrue); expect(outputDirectory.childFile('output-localization-file_en.dart').existsSync(), isTrue);
expect(outputDirectory.childFile('output-localization-file_es.dart').existsSync(), isTrue); expect(outputDirectory.childFile('output-localization-file_es.dart').existsSync(), isTrue);
...@@ -624,7 +624,7 @@ void main() { ...@@ -624,7 +624,7 @@ void main() {
templateArbFileName: defaultTemplateArbFileName, templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString, outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString, classNameString: defaultClassNameString,
inputsAndOutputsListPath: syntheticPackagePath, inputsAndOutputsListPath: syntheticL10nPackagePath,
) )
..loadResources() ..loadResources()
..writeOutputFiles(); ..writeOutputFiles();
...@@ -633,7 +633,7 @@ void main() { ...@@ -633,7 +633,7 @@ void main() {
} }
final File inputsAndOutputsList = fs.file( final File inputsAndOutputsList = fs.file(
fs.path.join(syntheticPackagePath, 'gen_l10n_inputs_and_outputs.json'), fs.path.join(syntheticL10nPackagePath, 'gen_l10n_inputs_and_outputs.json'),
); );
expect(inputsAndOutputsList.existsSync(), isTrue); expect(inputsAndOutputsList.existsSync(), isTrue);
...@@ -645,9 +645,9 @@ void main() { ...@@ -645,9 +645,9 @@ void main() {
expect(jsonResult.containsKey('outputs'), isTrue); expect(jsonResult.containsKey('outputs'), isTrue);
final List<dynamic> outputList = jsonResult['outputs'] as List<dynamic>; final List<dynamic> outputList = jsonResult['outputs'] as List<dynamic>;
expect(outputList, contains(fs.path.absolute(syntheticPackagePath, 'output-localization-file.dart'))); expect(outputList, contains(fs.path.absolute(syntheticL10nPackagePath, 'output-localization-file.dart')));
expect(outputList, contains(fs.path.absolute(syntheticPackagePath, 'output-localization-file_en.dart'))); expect(outputList, contains(fs.path.absolute(syntheticL10nPackagePath, 'output-localization-file_en.dart')));
expect(outputList, contains(fs.path.absolute(syntheticPackagePath, 'output-localization-file_es.dart'))); expect(outputList, contains(fs.path.absolute(syntheticL10nPackagePath, 'output-localization-file_es.dart')));
}); });
test('setting both a headerString and a headerFile should fail', () { test('setting both a headerString and a headerFile should fail', () {
...@@ -1095,11 +1095,11 @@ void main() { ...@@ -1095,11 +1095,11 @@ void main() {
fail('Generating output files should not fail: $e'); fail('Generating output files should not fail: $e');
} }
expect(fs.isFileSync(fs.path.join(syntheticPackagePath, 'output-localization-file_en.dart')), true); expect(fs.isFileSync(fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart')), true);
expect(fs.isFileSync(fs.path.join(syntheticPackagePath, 'output-localization-file_en_US.dart')), false); expect(fs.isFileSync(fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en_US.dart')), false);
final String englishLocalizationsFile = fs.file( final String englishLocalizationsFile = fs.file(
fs.path.join(syntheticPackagePath, 'output-localization-file_en.dart') fs.path.join(syntheticL10nPackagePath, 'output-localization-file_en.dart')
).readAsStringSync(); ).readAsStringSync();
expect(englishLocalizationsFile, contains('class AppLocalizationsEnCa extends AppLocalizationsEn')); expect(englishLocalizationsFile, contains('class AppLocalizationsEnCa extends AppLocalizationsEn'));
expect(englishLocalizationsFile, contains('class AppLocalizationsEn extends AppLocalizations')); expect(englishLocalizationsFile, contains('class AppLocalizationsEn extends AppLocalizations'));
...@@ -1129,7 +1129,7 @@ void main() { ...@@ -1129,7 +1129,7 @@ void main() {
} }
final String localizationsFile = fs.file( final String localizationsFile = fs.file(
fs.path.join(syntheticPackagePath, defaultOutputFileString), fs.path.join(syntheticL10nPackagePath, defaultOutputFileString),
).readAsStringSync(); ).readAsStringSync();
expect(localizationsFile, contains( expect(localizationsFile, contains(
''' '''
...@@ -1159,7 +1159,7 @@ import 'output-localization-file_zh.dart'; ...@@ -1159,7 +1159,7 @@ import 'output-localization-file_zh.dart';
} }
final String localizationsFile = fs.file( final String localizationsFile = fs.file(
fs.path.join(syntheticPackagePath, defaultOutputFileString), fs.path.join(syntheticL10nPackagePath, defaultOutputFileString),
).readAsStringSync(); ).readAsStringSync();
expect(localizationsFile, contains( expect(localizationsFile, contains(
''' '''
...@@ -1586,4 +1586,62 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e ...@@ -1586,4 +1586,62 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
}); });
}); });
}); });
test('should generate a valid pubspec.yaml file when using synthetic package if it does not already exist', () {
_standardFlutterDirectoryL10nSetup(fs);
LocalizationsGenerator generator;
try {
generator = LocalizationsGenerator(fs);
generator
..initialize(
inputPathString: defaultL10nPathString,
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
)
..loadResources()
..writeOutputFiles();
} on L10nException catch (e) {
fail('Generating output should not fail: \n${e.message}');
}
final Directory outputDirectory = fs.directory(syntheticPackagePath);
final File pubspecFile = outputDirectory.childFile('pubspec.yaml');
expect(pubspecFile.existsSync(), isTrue);
final YamlNode yamlNode = loadYamlNode(pubspecFile.readAsStringSync());
expect(yamlNode, isA<YamlMap>());
final YamlMap yamlMap = yamlNode as YamlMap;
final String pubspecName = yamlMap['name'] as String;
final String pubspecDescription = yamlMap['description'] as String;
expect(pubspecName, 'synthetic_package');
expect(pubspecDescription, "The Flutter application's synthetic package.");
});
test('should not overwrite existing pubspec.yaml file when using synthetic package', () {
_standardFlutterDirectoryL10nSetup(fs);
final File pubspecFile = fs.file(fs.path.join(syntheticPackagePath, 'pubspec.yaml'))
..createSync(recursive: true)
..writeAsStringSync('abcd');
LocalizationsGenerator generator;
try {
generator = LocalizationsGenerator(fs);
generator
..initialize(
inputPathString: defaultL10nPathString,
templateArbFileName: defaultTemplateArbFileName,
outputFileString: defaultOutputFileString,
classNameString: defaultClassNameString,
)
..loadResources()
..writeOutputFiles();
} on L10nException catch (e) {
fail('Generating output should not fail: \n${e.message}');
}
// The original pubspec file should not be overwritten.
expect(pubspecFile.readAsStringSync(), 'abcd');
});
} }
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