9
9
///
10
10
/// For any use other than CI, use test.dart instead.
11
11
////////////////////////////////////////////////////////////////////////////////
12
- import 'dart:io' show Platform, exit ;
12
+ import 'dart:io' ;
13
13
14
+ import 'package:path/path.dart' as p;
15
+
16
+ import 'shared/generation.dart' ;
14
17
import 'shared/test_runner.dart' ;
15
18
import 'shared/test_suites.dart' ;
16
19
@@ -29,6 +32,77 @@ void _validateTestCoverage(List<List<String>> shards) {
29
32
}
30
33
}
31
34
35
+ Future <void > _validateGeneratedTestFiles () async {
36
+ final String baseDir = p.dirname (p.dirname (Platform .script.toFilePath ()));
37
+ final String repositoryRoot = p.dirname (p.dirname (baseDir));
38
+ final String relativePigeonPath = p.relative (baseDir, from: repositoryRoot);
39
+
40
+ print ('Validating generated files:' );
41
+ print (' Generating output...' );
42
+ final int generateExitCode = await generatePigeons (baseDir: baseDir);
43
+ if (generateExitCode != 0 ) {
44
+ print ('Generation failed; see above for errors.' );
45
+ exit (generateExitCode);
46
+ }
47
+
48
+ print (' Formatting output...' );
49
+ final int formatExitCode =
50
+ await formatAllFiles (repositoryRoot: repositoryRoot);
51
+ if (formatExitCode != 0 ) {
52
+ print ('Formatting failed; see above for errors.' );
53
+ exit (formatExitCode);
54
+ }
55
+
56
+ print (' Checking for changes...' );
57
+ final List <String > modifiedFiles = await _modifiedFiles (
58
+ repositoryRoot: repositoryRoot, relativePigeonPath: relativePigeonPath);
59
+
60
+ if (modifiedFiles.isEmpty) {
61
+ return ;
62
+ }
63
+
64
+ print ('The following files are not updated, or not formatted correctly:' );
65
+ modifiedFiles.map ((String line) => ' $line ' ).forEach (print);
66
+
67
+ print ('\n To fix run "dart run tool/generate.dart --format" from the pigeon/ '
68
+ 'directory, or apply the diff with the command below.\n ' );
69
+
70
+ final ProcessResult diffResult = await Process .run (
71
+ 'git' ,
72
+ < String > ['diff' , relativePigeonPath],
73
+ workingDirectory: repositoryRoot,
74
+ );
75
+ if (diffResult.exitCode != 0 ) {
76
+ print ('Unable to determine diff.' );
77
+ exit (1 );
78
+ }
79
+ print ('patch -p1 <<DONE' );
80
+ print (diffResult.stdout);
81
+ print ('DONE' );
82
+ exit (1 );
83
+ }
84
+
85
+ Future <List <String >> _modifiedFiles (
86
+ {required String repositoryRoot,
87
+ required String relativePigeonPath}) async {
88
+ final ProcessResult result = await Process .run (
89
+ 'git' ,
90
+ < String > ['ls-files' , '--modified' , relativePigeonPath],
91
+ workingDirectory: repositoryRoot,
92
+ );
93
+ if (result.exitCode != 0 ) {
94
+ print ('Unable to determine changed files.' );
95
+ print (result.stdout);
96
+ print (result.stderr);
97
+ exit (1 );
98
+ }
99
+ return (result.stdout as String )
100
+ .split ('\n ' )
101
+ .map ((String line) => line.trim ())
102
+ .where ((String line) => line.isNotEmpty)
103
+ .toList ();
104
+ }
105
+
32
106
Future <void > main (List <String > args) async {
33
107
// Run most tests on Linux, since Linux tends to be the easiest and cheapest.
34
108
const List <String > linuxHostTests = < String > [
@@ -85,6 +159,14 @@ Future<void> main(List<String> args) async {
85
159
],
86
160
]);
87
161
162
+ // Ensure that all generated files are up to date. This is run only on Linux
163
+ // both to avoid duplication of work, and to avoid issues if different CI
164
+ // configurations have different setups (e.g., different clang-format versions
165
+ // or no clang-format at all).
166
+ if (Platform .isLinux) {
167
+ await _validateGeneratedTestFiles ();
168
+ }
169
+
88
170
final List <String > testsToRun;
89
171
if (Platform .isMacOS) {
90
172
if (Platform .environment['LUCI_CI' ] != null ) {
0 commit comments