// Copyright 2019 The Flutter team. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:grinder/grinder.dart'; import 'package:path/path.dart' as path; void main(List args) => grind(args); @Task('Get packages') Future pubGet({String directory}) async { await _runProcess( 'flutter', ['pub', 'get', if (directory != null) directory], ); } @Task('Format dart files') Future format({String path = '.'}) async { await _runProcess('flutter', ['format', path]); } @Task('Generate localizations files') Future generateLocalizations() async { final l10nScriptFile = path.join( _flutterRootPath(), 'dev', 'tools', 'localization', 'bin', 'gen_l10n.dart', ); Dart.run(l10nScriptFile, arguments: [ '--template-arb-file=intl_en_US.arb', '--output-localization-file=gallery_localizations.dart', '--output-class=GalleryLocalizations', '--preferred-supported-locales=["en_US"]' ]); await format(path: path.join('lib', 'l10n')); } @Task('Transform arb to xml for English') @Depends(generateLocalizations) Future l10n() async { final l10nPath = path.join(Directory.current.path, 'tool', 'l10n_cli', 'main.dart'); Dart.run(l10nPath); } @Task('Verify xml localizations') Future verifyL10n() async { final l10nPath = path.join(Directory.current.path, 'tool', 'l10n_cli', 'main.dart'); // Run the tool to transform arb to xml, and write the output to stdout. final xmlOutput = Dart.run(l10nPath, arguments: ['--dry-run'], quiet: true); // Read the original xml file. final xmlPath = path.join(Directory.current.path, 'lib', 'l10n', 'intl_en_US.xml'); final expectedXmlOutput = await File(xmlPath).readAsString(); if (xmlOutput.trim() != expectedXmlOutput.trim()) { stderr.writeln( 'The contents of $xmlPath are different from that produced by ' 'l10n_cli. Did you forget to run `flutter pub run grinder ' 'l10n` after updating an .arb file?', ); exit(1); } } @Task('Update code segments') Future updateCodeSegments() async { final codeviewerPath = path.join(Directory.current.path, 'tool', 'codeviewer_cli', 'main.dart'); Dart.run(codeviewerPath); final codeSegmentsPath = path.join('lib', 'codeviewer', 'code_segments.dart'); await format(path: codeSegmentsPath); } @Task('Verify code segments') Future verifyCodeSegments() async { final codeviewerPath = path.join(Directory.current.path, 'tool', 'codeviewer_cli', 'main.dart'); // We use stdin and stdout to write and format the code segments, to avoid // creating any files. final codeSegmentsUnformatted = Dart.run(codeviewerPath, arguments: ['--dry-run'], quiet: true); final codeSegmentsFormatted = await _startProcess( path.normalize(path.join(dartVM.path, '../dartfmt')), input: codeSegmentsUnformatted, ); // Read the original code segments file. final codeSegmentsPath = path.join( Directory.current.path, 'lib', 'codeviewer', 'code_segments.dart'); final expectedCodeSegmentsOutput = await File(codeSegmentsPath).readAsString(); if (codeSegmentsFormatted.trim() != expectedCodeSegmentsOutput.trim()) { stderr.writeln( 'The contents of $codeSegmentsPath are different from that produced by ' 'codeviewer_cli. Did you forget to run `flutter pub run grinder ' 'update-code-segments` after updating a demo?', ); exit(1); } } Future _runProcess(String executable, List arguments) async { final result = await Process.run(executable, arguments); stdout.write(result.stdout); stderr.write(result.stderr); } // Function to make sure we capture all of the stdout. // Reference: https://github.com/dart-lang/sdk/issues/31666 Future _startProcess(String executable, {List arguments = const [], String input}) async { final output = []; final completer = Completer(); final process = await Process.start(executable, arguments); process.stdin.writeln(input); process.stdout.listen( (event) { output.addAll(event); }, onDone: () async => completer.complete(await process.exitCode), ); await process.stdin.close(); final exitCode = await completer.future; if (exitCode != 0) { stderr.write( 'Running "$executable ${arguments.join(' ')}" failed with $exitCode.\n', ); exit(exitCode); } return Future.value(utf8.decoder.convert(output)); } /// Return the flutter root path from the environment variables. String _flutterRootPath() { final separator = (Platform.isWindows) ? ';' : ':'; final flutterBinPath = Platform.environment['PATH'].split(separator).lastWhere((setting) { return path.canonicalize(setting).endsWith(path.join('flutter', 'bin')); }); return Directory(flutterBinPath).parent.path; }