@@ -7,188 +7,80 @@ import 'dart:convert';
77import 'dart:io' ;
88import 'dart:typed_data' ;
99
10- import 'package:args/args.dart' ;
1110import 'package:dir_contents_diff/dir_contents_diff.dart' show dirContentsDiff;
1211import 'package:engine_repo_tools/engine_repo_tools.dart' ;
1312import 'package:path/path.dart' ;
1413import 'package:process/process.dart' ;
1514import 'package:skia_gold_client/skia_gold_client.dart' ;
1615
1716import 'utils/adb_logcat_filtering.dart' ;
17+ import 'utils/environment.dart' ;
1818import 'utils/logs.dart' ;
19+ import 'utils/options.dart' ;
1920import 'utils/process_manager_extension.dart' ;
2021import 'utils/screenshot_transformer.dart' ;
2122
22- void _withTemporaryCwd (String path, void Function () callback) {
23- final String originalCwd = Directory .current.path;
24- Directory .current = Directory (path).parent.path;
23+ // If you update the arguments, update the documentation in the README.md file.
24+ void main (List <String > args) async {
25+ // Get some basic environment information to guide the rest of the program.
26+ final Environment environment = Environment (
27+ isCi: Platform .environment['LUCI_CONTEXT' ] != null ,
28+ showVerbose: Options .showVerbose (args),
29+ logsDir: Platform .environment['FLUTTER_LOGS_DIR' ],
30+ );
2531
26- try {
27- callback ();
28- } finally {
29- Directory .current = originalCwd;
32+ // Determine if the CWD is within an engine checkout.
33+ final Engine ? localEngineDir = Engine .tryFindWithin ();
34+
35+ // Show usage if requested.
36+ if (Options .showUsage (args)) {
37+ stdout.writeln (Options .usage (
38+ environment: environment,
39+ localEngineDir: localEngineDir,
40+ ));
41+ return ;
3042 }
31- }
3243
33- // If you update the arguments, update the documentation in the README.md file.
34- void main (List <String > args) async {
35- final Engine ? engine = Engine .tryFindWithin ();
36- final ArgParser parser = ArgParser ()
37- ..addFlag (
38- 'help' ,
39- help: 'Prints usage information' ,
40- negatable: false ,
41- )
42- ..addFlag (
43- 'verbose' ,
44- help: 'Prints verbose output' ,
45- negatable: false ,
46- )
47- ..addOption (
48- 'adb' ,
49- help: 'Path to the adb tool' ,
50- defaultsTo: engine != null
51- ? join (
52- engine.srcDir.path,
53- 'third_party' ,
54- 'android_tools' ,
55- 'sdk' ,
56- 'platform-tools' ,
57- 'adb' ,
58- )
59- : null ,
60- )
61- ..addOption (
62- 'ndk-stack' ,
63- help: 'Path to the ndk-stack tool' ,
64- defaultsTo: engine != null
65- ? join (
66- engine.srcDir.path,
67- 'third_party' ,
68- 'android_tools' ,
69- 'ndk' ,
70- 'prebuilt' ,
71- () {
72- if (Platform .isLinux) {
73- return 'linux-x86_64' ;
74- } else if (Platform .isMacOS) {
75- return 'darwin-x86_64' ;
76- } else if (Platform .isWindows) {
77- return 'windows-x86_64' ;
78- } else {
79- throw UnsupportedError ('Unsupported platform: ${Platform .operatingSystem }' );
80- }
81- }(),
82- 'bin' ,
83- 'ndk-stack' ,
84- )
85- : null ,
86- )
87- ..addOption (
88- 'out-dir' ,
89- help: 'Out directory' ,
90- defaultsTo: engine
91- ? .outputs ()
92- .where ((Output o) => basename (o.path.path).startsWith ('android_' ))
93- .firstOrNull
94- ? .path
95- .path,
96- )
97- ..addOption (
98- 'smoke-test' ,
99- help: 'Runs a single test to verify the setup' ,
100- )
101- ..addFlag (
102- 'use-skia-gold' ,
103- help: 'Use Skia Gold to compare screenshots.' ,
104- defaultsTo: isLuciEnv,
105- )
106- ..addFlag (
107- 'enable-impeller' ,
108- help: 'Enable Impeller for the Android app.' ,
109- )
110- ..addOption (
111- 'output-contents-golden' ,
112- help: 'Path to a file that contains the expected filenames of golden files.' ,
113- defaultsTo: engine != null
114- ? join (
115- engine.srcDir.path,
116- 'flutter' ,
117- 'testing' ,
118- 'scenario_app' ,
119- 'android' ,
120- 'expected_golden_output.txt' ,
121- )
122- : null ,
123- )
124- ..addOption (
125- 'impeller-backend' ,
126- help: 'The Impeller backend to use for the Android app.' ,
127- allowed: < String > ['vulkan' , 'opengles' ],
128- defaultsTo: 'vulkan' ,
129- )
130- ..addOption (
131- 'logs-dir' ,
132- help: 'The directory to store the logs and screenshots. Defaults to '
133- 'the value of the FLUTTER_LOGS_DIR environment variable, if set, '
134- 'otherwise it defaults to a path within out-dir.' ,
135- defaultsTo: Platform .environment['FLUTTER_LOGS_DIR' ],
44+ // Parse the command line arguments.
45+ final Options options;
46+ try {
47+ options = Options .parse (
48+ args,
49+ environment: environment,
50+ localEngine: localEngineDir,
13651 );
52+ } on FormatException catch (error) {
53+ stderr.writeln (error);
54+ stderr.writeln (Options .usage (
55+ environment: environment,
56+ localEngineDir: localEngineDir,
57+ ));
58+ exitCode = 1 ;
59+ return ;
60+ }
13761
13862 runZonedGuarded (
13963 () async {
140- final ArgResults results = parser.parse (args);
141- if (results['help' ] as bool ) {
142- stdout.writeln (parser.usage);
143- return ;
144- }
145-
146- if (results['out-dir' ] == null ) {
147- panic (< String > ['--out-dir is required' ]);
148- }
149- if (results['adb' ] == null ) {
150- panic (< String > ['--adb is required' ]);
151- }
152-
153- final bool verbose = results['verbose' ] as bool ;
154- final Directory outDir = Directory (results['out-dir' ] as String );
155- final File adb = File (results['adb' ] as String );
156- final bool useSkiaGold = results['use-skia-gold' ] as bool ;
157- final String ? smokeTest = results['smoke-test' ] as String ? ;
158- final bool enableImpeller = results['enable-impeller' ] as bool ;
159- final String ? contentsGolden = results['output-contents-golden' ] as String ? ;
160- final _ImpellerBackend ? impellerBackend = _ImpellerBackend .tryParse (results['impeller-backend' ] as String ? );
161- if (enableImpeller && impellerBackend == null ) {
162- panic (< String > [
163- 'invalid graphics-backend' ,
164- results['impeller-backend' ] as String ? ?? '<null>'
165- ]);
166- }
167- final Directory logsDir = Directory (results['logs-dir' ] as String ? ?? join (outDir.path, 'scenario_app' , 'logs' ));
168- final String ? ndkStack = results['ndk-stack' ] as String ? ;
169- if (ndkStack == null ) {
170- panic (< String > ['--ndk-stack is required' ]);
171- }
17264 await _run (
173- verbose: verbose,
174- outDir: outDir,
175- adb: adb,
176- smokeTestFullPath: smokeTest,
177- useSkiaGold: useSkiaGold,
178- enableImpeller: enableImpeller,
179- impellerBackend: impellerBackend,
180- logsDir: logsDir,
181- contentsGolden: contentsGolden ,
182- ndkStack: ndkStack,
65+ verbose: options. verbose,
66+ outDir: Directory (options. outDir) ,
67+ adb: File (options. adb) ,
68+ smokeTestFullPath: options. smokeTest,
69+ useSkiaGold: options. useSkiaGold,
70+ enableImpeller: options. enableImpeller,
71+ impellerBackend: _ImpellerBackend . tryParse (options. impellerBackend) ,
72+ logsDir: Directory (options. logsDir) ,
73+ contentsGolden: options.outputContentsGolden ,
74+ ndkStack: options. ndkStack,
18375 );
18476 exit (0 );
18577 },
18678 (Object error, StackTrace stackTrace) {
18779 if (error is ! Panic ) {
188- stderr.writeln (error);
80+ stderr.writeln ('Unhandled error: $ error ' );
18981 stderr.writeln (stackTrace);
19082 }
191- exit ( 1 ) ;
83+ exitCode = 1 ;
19284 },
19385 );
19486}
@@ -222,18 +114,6 @@ Future<void> _run({
222114 required String ndkStack,
223115}) async {
224116 const ProcessManager pm = LocalProcessManager ();
225-
226- if (! outDir.existsSync ()) {
227- panic (< String > [
228- 'out-dir does not exist: $outDir ' ,
229- 'make sure to build the selected engine variant'
230- ]);
231- }
232-
233- if (! adb.existsSync ()) {
234- panic (< String > ['cannot find adb: $adb ' , 'make sure to run gclient sync' ]);
235- }
236-
237117 final String scenarioAppPath = join (outDir.path, 'scenario_app' );
238118 final String logcatPath = join (logsDir.path, 'logcat.txt' );
239119
@@ -521,7 +401,7 @@ Future<void> _run({
521401 // TODO(matanlurey): Resolve this in a better way. On CI this file always exists.
522402 File (join (screenshotPath, 'noop.txt' )).writeAsStringSync ('' );
523403 // TODO(gaaclarke): We should move this into dir_contents_diff.
524- _withTemporaryCwd (contentsGolden, () {
404+ _withTemporaryCwd (dirname ( contentsGolden) , () {
525405 final int exitCode = dirContentsDiff (basename (contentsGolden), screenshotPath);
526406 if (exitCode != 0 ) {
527407 panic (< String > ['Output contents incorrect.' ]);
@@ -531,3 +411,14 @@ Future<void> _run({
531411 }
532412 }
533413}
414+
415+ void _withTemporaryCwd (String path, void Function () callback) {
416+ final String originalCwd = Directory .current.path;
417+ Directory .current = Directory (path).path;
418+
419+ try {
420+ callback ();
421+ } finally {
422+ Directory .current = originalCwd;
423+ }
424+ }
0 commit comments