Skip to content

Commit 9436b3c

Browse files
authored
Fix out of sync templates files and add a check (#145747)
### Description - Add a check to verify template code in the Material library is synced with `gen_defaults` - Sync the changes to pass the new check.
1 parent ac5be2d commit 9436b3c

File tree

10 files changed

+538
-13
lines changed

10 files changed

+538
-13
lines changed

dev/bots/analyze.dart

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import 'package:analyzer/dart/analysis/results.dart';
1212
import 'package:analyzer/dart/analysis/utilities.dart';
1313
import 'package:analyzer/dart/ast/ast.dart';
1414
import 'package:analyzer/dart/ast/visitor.dart';
15+
import 'package:collection/equality.dart';
1516
import 'package:crypto/crypto.dart';
1617
import 'package:meta/meta.dart';
1718
import 'package:path/path.dart' as path;
@@ -252,6 +253,10 @@ Future<void> run(List<String> arguments) async {
252253
printProgress('Correct file names in gen_defaults.dart...');
253254
await verifyTokenTemplatesUpdateCorrectFiles(flutterRoot);
254255

256+
// Ensure material library files are up-to-date with the token template files.
257+
printProgress('Material library files are up-to-date with token template files...');
258+
await verifyMaterialFilesAreUpToDateWithTemplateFiles(flutterRoot, dart);
259+
255260
// Ensure integration test files are up-to-date with the app template.
256261
printProgress('Up to date integration test template files...');
257262
await verifyIntegrationTestTemplateFiles(flutterRoot);
@@ -399,6 +404,78 @@ Future<void> verifyTokenTemplatesUpdateCorrectFiles(String workingDirectory) asy
399404
}
400405
}
401406

407+
/// Verify Material library files are up-to-date with the token template files
408+
/// when running /dev/tools/gen_defaults/bin/gen_defaults.dart.
409+
Future<void> verifyMaterialFilesAreUpToDateWithTemplateFiles(String workingDirectory, String dartExecutable) async {
410+
final List<String> errors = <String>[];
411+
const String beginGeneratedComment = '// BEGIN GENERATED TOKEN PROPERTIES';
412+
413+
String getMaterialDirPath(List<String> lines) {
414+
final String line = lines.firstWhere((String line) => line.contains('String materialLib'));
415+
final String relativePath = line.substring(line.indexOf("'") + 1, line.lastIndexOf("'"));
416+
return path.join(workingDirectory, relativePath);
417+
}
418+
419+
String getFileName(String line) {
420+
const String materialLibString = r"'$materialLib/";
421+
final String leftClamp = line.substring(line.indexOf(materialLibString) + materialLibString.length);
422+
return leftClamp.substring(0, leftClamp.indexOf("'"));
423+
}
424+
425+
// Get the template generated code from the file.
426+
List<String> getGeneratedCode(List<String> lines) {
427+
return lines.skipWhile((String line) => !line.contains(beginGeneratedComment)).toList();
428+
}
429+
430+
final String genDefaultsBinDir = '$workingDirectory/dev/tools/gen_defaults/bin';
431+
final File file = File(path.join(genDefaultsBinDir, 'gen_defaults.dart'));
432+
final List<String> lines = file.readAsLinesSync();
433+
final String materialDirPath = getMaterialDirPath(lines);
434+
final Map<String, List<String>> beforeGeneratedCode = <String, List<String>>{};
435+
final Map<String, List<String>> afterGeneratedCode = <String, List<String>>{};
436+
437+
for (final String line in lines) {
438+
if (line.contains('updateFile();')) {
439+
final String fileName = getFileName(line);
440+
final String filePath = path.join(materialDirPath, fileName);
441+
final File file = File(filePath);
442+
beforeGeneratedCode[fileName] = getGeneratedCode(file.readAsLinesSync());
443+
}
444+
}
445+
446+
// Run gen_defaults.dart to generate the token template files.
447+
await runCommand(dartExecutable,
448+
<String>['--enable-asserts', path.join('dev', 'tools', 'gen_defaults', 'bin', 'gen_defaults.dart')],
449+
workingDirectory: workingDirectory,
450+
);
451+
452+
for (final String line in lines) {
453+
if (line.contains('updateFile();')) {
454+
final String fileName = getFileName(line);
455+
final String filePath = path.join(materialDirPath, fileName);
456+
final File file = File(filePath);
457+
afterGeneratedCode[fileName] = getGeneratedCode(file.readAsLinesSync());
458+
}
459+
}
460+
461+
// Compare the generated code before and after running gen_defaults.dart.
462+
for (final String fileName in beforeGeneratedCode.keys) {
463+
final List<String> before = beforeGeneratedCode[fileName]!;
464+
final List<String> after = afterGeneratedCode[fileName]!;
465+
if (!const IterableEquality<String>().equals(before, after)) {
466+
errors.add('$fileName is not up-to-date with the token template file.');
467+
}
468+
}
469+
470+
// Fail if any errors.
471+
if (errors.isNotEmpty) {
472+
foundError(<String>[
473+
...errors,
474+
'${bold}See: https://github.com/flutter/flutter/blob/master/dev/tools/gen_defaults to update the token template files.$reset',
475+
]);
476+
}
477+
}
478+
402479
/// Verify tool test files end in `_test.dart`.
403480
///
404481
/// The test runner will only recognize files ending in `_test.dart` as tests to
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'template.dart';
6+
7+
class ChipTemplate extends TokenTemplate {
8+
const ChipTemplate(super.blockName, super.fileName, super.tokens);
9+
10+
@override
11+
String generate() => '''
12+
class _${blockName}DefaultsM3 {
13+
final String testString = 'This is chip_template.dart class.';
14+
}
15+
''';
16+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'chip_template.dart';
6+
7+
const String materialLib = 'packages/flutter/lib/src/material';
8+
9+
Future<void> main(List<String> args) async {
10+
final Map<String, dynamic> tokens = <String, dynamic>{};
11+
ChipTemplate('Chip', '$materialLib/chip.dart', tokens).updateFile();
12+
}

0 commit comments

Comments
 (0)