mirror of
https://github.com/encounter/flutter.git
synced 2026-07-10 03:18:48 -07:00
This reverts commit 04ea3183ce.
This commit is contained in:
committed by
Francisco Magdaleno
parent
04ea3183ce
commit
24f39d40a4
@@ -12,5 +12,5 @@ closeComment: >-
|
||||
resolve this issue. We are therefore reluctantly going to close this
|
||||
bug for now. Please don't hesitate to comment on the bug if you have
|
||||
any more information for us; we will reopen it right away!
|
||||
|
||||
|
||||
Thanks for your contribution.
|
||||
|
||||
+3
-3
@@ -33,18 +33,18 @@ If you want to help us triage, you are very welcome to do so!
|
||||
that everyone must be gracious, respectful, and professional. If you're helping out
|
||||
with triage, you are representing the Flutter team, and so you want to make sure to
|
||||
make a good impression!
|
||||
|
||||
|
||||
3. Help out as described in our wiki: https://github.com/flutter/flutter/wiki/Triage
|
||||
You won't be able to add labels at first, so instead start by trying to
|
||||
do the other steps, e.g. trying to reproduce the problem and asking for people to
|
||||
provide enough details that you can reproduce the problem, pointing out duplicates,
|
||||
and so on. Chat on the #hackers-triage channel to let us know what you're up to!
|
||||
|
||||
|
||||
4. Familiarize yourself with our
|
||||
[issue hygiene](https://github.com/flutter/flutter/wiki/Issue-hygiene) wiki page,
|
||||
which covers the meanings of some important GitHub labels and
|
||||
milestones.
|
||||
|
||||
|
||||
5. Once you've been doing this for a while, someone will invite you to the flutter-hackers
|
||||
team on GitHub and you'll be able to add labels too. See the
|
||||
[contributor access](https://github.com/flutter/flutter/wiki/Contributor-access) wiki
|
||||
|
||||
@@ -61,7 +61,7 @@ Flutter works with any development tool (or none at all), but includes editor
|
||||
plug-ins for both [Visual Studio Code] and [IntelliJ / Android Studio]. Flutter
|
||||
provides [thousands of packages][Flutter packages] to speed your development,
|
||||
regardless of your target platform. And accessing other native code is easy,
|
||||
with support for both [FFI] and [platform-specific APIs][platform channels].
|
||||
with support for both [FFI] and [platform-specific APIs][platform channels].
|
||||
|
||||
Flutter is a fully open source project, and we welcome contributions.
|
||||
Information on how to get started can be found at our
|
||||
|
||||
@@ -19,13 +19,13 @@ dependencies:
|
||||
charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
html: 0.14.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http: 0.12.0+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http: 0.12.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http_multi_server: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
image: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
@@ -74,4 +74,4 @@ flutter:
|
||||
assets:
|
||||
- icon/
|
||||
|
||||
# PUBSPEC CHECKSUM: ebc8
|
||||
# PUBSPEC CHECKSUM: b1cb
|
||||
|
||||
@@ -20,4 +20,3 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,12 +46,12 @@ dev_dependencies:
|
||||
archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
html: 0.14.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http: 0.12.0+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http: 0.12.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http_multi_server: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
image: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
@@ -91,4 +91,4 @@ flutter:
|
||||
- packages/flutter_gallery_assets/people/square/ali.png
|
||||
- packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png
|
||||
|
||||
# PUBSPEC CHECKSUM: 4cef
|
||||
# PUBSPEC CHECKSUM: 06f2
|
||||
|
||||
@@ -46,12 +46,12 @@ dev_dependencies:
|
||||
archive: 2.0.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
args: 1.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
boolean_selector: 1.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
html: 0.14.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http: 0.12.0+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http: 0.12.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http_multi_server: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
image: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
@@ -92,4 +92,4 @@ flutter:
|
||||
- packages/flutter_gallery_assets/food/cherry_pie.png
|
||||
- assets/999x1000.png
|
||||
|
||||
# PUBSPEC CHECKSUM: 4cef
|
||||
# PUBSPEC CHECKSUM: 06f2
|
||||
|
||||
@@ -23,14 +23,14 @@ dependencies:
|
||||
charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
dart_style: 1.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
glob: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
html: 0.14.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http: 0.12.0+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http: 0.12.0+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http_multi_server: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
http_parser: 3.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
image: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
@@ -79,4 +79,4 @@ dependencies:
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
|
||||
# PUBSPEC CHECKSUM: e51f
|
||||
# PUBSPEC CHECKSUM: 1d22
|
||||
|
||||
+2
-2
@@ -91,8 +91,8 @@ The typical cycle for editing a recipe is:
|
||||
existing expected output to match the new output. Verify completely new test
|
||||
cases by altering the `GenTests` method of the recipe. The recipe is required
|
||||
to have 100% test coverage.
|
||||
3. Run `led get-builder 'luci.flutter.prod:BUILDER_NAME' | led edit -p 'revision="GIT_HASH"' | led edit-recipe-bundle | led launch`, where `BUILDER_NAME` is the builder name (e.g. `Linux Engine`), and
|
||||
`GIT_HASH` is the hash to build (which is important for the engine but not
|
||||
3. Run `led get-builder 'luci.flutter.prod:BUILDER_NAME' | led edit -p 'revision="GIT_HASH"' | led edit-recipe-bundle | led launch`, where `BUILDER_NAME` is the builder name (e.g. `Linux Engine`), and
|
||||
`GIT_HASH` is the hash to build (which is important for the engine but not
|
||||
for the framework).
|
||||
4. To submit a CL, you need a local branch first (`git checkout -b [some branch name]`).
|
||||
5. Upload the patch (`git commit`, `git cl upload`) and send it to someone in
|
||||
|
||||
+620
-211
File diff suppressed because it is too large
Load Diff
@@ -149,4 +149,3 @@ if [[ -n "$CIRRUS_CI" && -z "$CIRRUS_PR" ]]; then
|
||||
deploy 5 docs-flutter-dev
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -26,5 +26,3 @@ $ANDROID_SDK_ROOT/tools/bin/sdkmanager "platforms;android-28" \
|
||||
"build-tools;27.0.3" \
|
||||
"extras;google;m2repository" \
|
||||
"extras;android;m2repository"
|
||||
|
||||
|
||||
|
||||
+10
-10
@@ -6,16 +6,17 @@ environment:
|
||||
sdk: ">=2.2.2 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
path: 1.6.4
|
||||
args: 1.5.2
|
||||
meta: 1.1.8
|
||||
process: 3.0.12
|
||||
platform: 2.2.1
|
||||
http: 0.12.0+2
|
||||
http_parser: 3.1.3
|
||||
test: 1.9.4
|
||||
crypto: 2.1.3
|
||||
googleapis: 0.54.0
|
||||
googleapis_auth: 0.2.11
|
||||
http: 0.12.0+3
|
||||
http_parser: 3.1.3
|
||||
meta: 1.1.8
|
||||
path: 1.6.4
|
||||
platform: 2.2.1
|
||||
process: 3.0.12
|
||||
test: 1.9.4
|
||||
|
||||
_discoveryapis_commons: 0.1.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
analyzer: 0.38.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
@@ -24,8 +25,7 @@ dependencies:
|
||||
charcode: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
collection: 1.14.11 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
coverage: 0.13.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
crypto: 2.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
coverage: 0.13.3+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
csslib: 0.16.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
file: 5.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
front_end: 0.1.27 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
|
||||
@@ -70,4 +70,4 @@ dev_dependencies:
|
||||
mockito: 4.1.1
|
||||
test_api: 0.2.11
|
||||
|
||||
# PUBSPEC CHECKSUM: 2235
|
||||
# PUBSPEC CHECKSUM: 5e38
|
||||
|
||||
+32
-68
@@ -4,44 +4,14 @@
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:core' hide print;
|
||||
import 'dart:io' hide exit;
|
||||
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
final bool hasColor = stdout.supportsAnsiEscapes;
|
||||
import 'utils.dart';
|
||||
|
||||
final String bold = hasColor ? '\x1B[1m' : ''; // used for shard titles
|
||||
final String red = hasColor ? '\x1B[31m' : ''; // used for errors
|
||||
final String green = hasColor ? '\x1B[32m' : ''; // used for section titles, commands
|
||||
final String yellow = hasColor ? '\x1B[33m' : ''; // unused
|
||||
final String cyan = hasColor ? '\x1B[36m' : ''; // used for paths
|
||||
final String reverse = hasColor ? '\x1B[7m' : ''; // used for clocks
|
||||
final String reset = hasColor ? '\x1B[0m' : '';
|
||||
final String redLine = '$red━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$reset';
|
||||
|
||||
String get clock {
|
||||
final DateTime now = DateTime.now();
|
||||
return '$reverse▌'
|
||||
'${now.hour.toString().padLeft(2, "0")}:'
|
||||
'${now.minute.toString().padLeft(2, "0")}:'
|
||||
'${now.second.toString().padLeft(2, "0")}'
|
||||
'▐$reset';
|
||||
}
|
||||
|
||||
String prettyPrintDuration(Duration duration) {
|
||||
String result = '';
|
||||
final int minutes = duration.inMinutes;
|
||||
if (minutes > 0)
|
||||
result += '${minutes}min ';
|
||||
final int seconds = duration.inSeconds - minutes * 60;
|
||||
final int milliseconds = duration.inMilliseconds - (seconds * 1000 + minutes * 60 * 1000);
|
||||
result += '$seconds.${milliseconds.toString().padLeft(3, "0")}s';
|
||||
return result;
|
||||
}
|
||||
|
||||
void printProgress(String action, String workingDir, String command) {
|
||||
print('$clock $action: cd $cyan$workingDir$reset; $green$command$reset');
|
||||
}
|
||||
// TODO(ianh): These two functions should be refactored into something that avoids all this code duplication.
|
||||
|
||||
Stream<String> runAndGetStdout(String executable, List<String> arguments, {
|
||||
String workingDirectory,
|
||||
@@ -49,11 +19,14 @@ Stream<String> runAndGetStdout(String executable, List<String> arguments, {
|
||||
bool expectNonZeroExit = false,
|
||||
int expectedExitCode,
|
||||
String failureMessage,
|
||||
Function beforeExit,
|
||||
bool skip = false,
|
||||
}) async* {
|
||||
final String commandDescription = '${path.relative(executable, from: workingDirectory)} ${arguments.join(' ')}';
|
||||
final String relativeWorkingDir = path.relative(workingDirectory);
|
||||
|
||||
if (skip) {
|
||||
printProgress('SKIPPING', relativeWorkingDir, commandDescription);
|
||||
return;
|
||||
}
|
||||
printProgress('RUNNING', relativeWorkingDir, commandDescription);
|
||||
|
||||
final Stopwatch time = Stopwatch()..start();
|
||||
@@ -64,26 +37,21 @@ Stream<String> runAndGetStdout(String executable, List<String> arguments, {
|
||||
|
||||
stderr.addStream(process.stderr);
|
||||
final Stream<String> lines = process.stdout.transform(utf8.decoder).transform(const LineSplitter());
|
||||
await for (String line in lines) {
|
||||
await for (String line in lines)
|
||||
yield line;
|
||||
}
|
||||
|
||||
final int exitCode = await process.exitCode;
|
||||
print('$clock ELAPSED TIME: ${prettyPrintDuration(time.elapsed)} for $green$commandDescription$reset in $cyan$relativeWorkingDir$reset');
|
||||
if ((exitCode == 0) == expectNonZeroExit || (expectedExitCode != null && exitCode != expectedExitCode)) {
|
||||
if (failureMessage != null) {
|
||||
print(failureMessage);
|
||||
}
|
||||
print(
|
||||
'$redLine\n'
|
||||
'${bold}ERROR: ${red}Last command exited with $exitCode (expected: ${expectNonZeroExit ? (expectedExitCode ?? 'non-zero') : 'zero'}).$reset\n'
|
||||
'${bold}Command: $green$commandDescription$reset\n'
|
||||
'${bold}Relative working directory: $cyan$relativeWorkingDir$reset\n'
|
||||
'$redLine'
|
||||
);
|
||||
beforeExit?.call();
|
||||
exit(1);
|
||||
exitWithError(<String>[
|
||||
if (failureMessage != null)
|
||||
failureMessage
|
||||
else
|
||||
'${bold}ERROR: ${red}Last command exited with $exitCode (expected: ${expectNonZeroExit ? (expectedExitCode ?? 'non-zero') : 'zero'}).$reset',
|
||||
'${bold}Command: $green$commandDescription$reset',
|
||||
'${bold}Relative working directory: $cyan$relativeWorkingDir$reset',
|
||||
]);
|
||||
}
|
||||
print('$clock ELAPSED TIME: ${prettyPrintDuration(time.elapsed)} for $green$commandDescription$reset in $cyan$relativeWorkingDir$reset');
|
||||
}
|
||||
|
||||
Future<void> runCommand(String executable, List<String> arguments, {
|
||||
@@ -97,9 +65,10 @@ Future<void> runCommand(String executable, List<String> arguments, {
|
||||
bool skip = false,
|
||||
bool Function(String) removeLine,
|
||||
}) async {
|
||||
assert((outputMode == OutputMode.capture) == (output != null),
|
||||
'The output parameter must be non-null with and only with '
|
||||
'OutputMode.capture');
|
||||
assert(
|
||||
(outputMode == OutputMode.capture) == (output != null),
|
||||
'The output parameter must be non-null with and only with OutputMode.capture',
|
||||
);
|
||||
|
||||
final String commandDescription = '${path.relative(executable, from: workingDirectory)} ${arguments.join(' ')}';
|
||||
final String relativeWorkingDir = path.relative(workingDirectory);
|
||||
@@ -137,18 +106,12 @@ Future<void> runCommand(String executable, List<String> arguments, {
|
||||
}
|
||||
|
||||
final int exitCode = await process.exitCode;
|
||||
print('$clock ELAPSED TIME: ${prettyPrintDuration(time.elapsed)} for $green$commandDescription$reset in $cyan$relativeWorkingDir$reset');
|
||||
|
||||
if (output != null) {
|
||||
output.stdout = _flattenToString(await savedStdout);
|
||||
output.stderr = _flattenToString(await savedStderr);
|
||||
}
|
||||
|
||||
if ((exitCode == 0) == expectNonZeroExit || (expectedExitCode != null && exitCode != expectedExitCode)) {
|
||||
if (failureMessage != null) {
|
||||
print(failureMessage);
|
||||
}
|
||||
|
||||
// Print the output when we get unexpected results (unless output was
|
||||
// printed already).
|
||||
switch (outputMode) {
|
||||
@@ -160,15 +123,16 @@ Future<void> runCommand(String executable, List<String> arguments, {
|
||||
stderr.writeln(_flattenToString(await savedStderr));
|
||||
break;
|
||||
}
|
||||
print(
|
||||
'$redLine\n'
|
||||
'${bold}ERROR: ${red}Last command exited with $exitCode (expected: ${expectNonZeroExit ? (expectedExitCode ?? 'non-zero') : 'zero'}).$reset\n'
|
||||
'${bold}Command: $green$commandDescription$reset\n'
|
||||
'${bold}Relative working directory: $cyan$relativeWorkingDir$reset\n'
|
||||
'$redLine'
|
||||
);
|
||||
exit(1);
|
||||
exitWithError(<String>[
|
||||
if (failureMessage != null)
|
||||
failureMessage
|
||||
else
|
||||
'${bold}ERROR: ${red}Last command exited with $exitCode (expected: ${expectNonZeroExit ? (expectedExitCode ?? 'non-zero') : 'zero'}).$reset',
|
||||
'${bold}Command: $green$commandDescription$reset',
|
||||
'${bold}Relative working directory: $cyan$relativeWorkingDir$reset',
|
||||
]);
|
||||
}
|
||||
print('$clock ELAPSED TIME: ${prettyPrintDuration(time.elapsed)} for $green$commandDescription$reset in $cyan$relativeWorkingDir$reset');
|
||||
}
|
||||
|
||||
/// Flattens a nested list of UTF-8 code units into a single string.
|
||||
|
||||
+50
-43
@@ -13,6 +13,7 @@ import 'package:path/path.dart' as path;
|
||||
|
||||
import 'flutter_compact_formatter.dart';
|
||||
import 'run_command.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
typedef ShardRunner = Future<void> Function();
|
||||
|
||||
@@ -98,22 +99,28 @@ const List<String> kWebTestFileBlacklist = <String>[
|
||||
/// SHARD=tool_tests bin/cache/dart-sdk/bin/dart dev/bots/test.dart
|
||||
/// bin/cache/dart-sdk/bin/dart dev/bots/test.dart --local-engine=host_debug_unopt
|
||||
Future<void> main(List<String> args) async {
|
||||
flutterTestArgs.addAll(args);
|
||||
if (Platform.environment.containsKey(CIRRUS_TASK_NAME))
|
||||
print('Running task: ${Platform.environment[CIRRUS_TASK_NAME]}');
|
||||
print('═' * 80);
|
||||
await _runSmokeTests();
|
||||
print('═' * 80);
|
||||
await selectShard(const <String, ShardRunner>{
|
||||
'add_to_app_tests': _runAddToAppTests,
|
||||
'build_tests': _runBuildTests,
|
||||
'framework_coverage': _runFrameworkCoverage,
|
||||
'framework_tests': _runFrameworkTests,
|
||||
'hostonly_devicelab_tests': _runHostOnlyDeviceLabTests,
|
||||
'tool_coverage': _runToolCoverage,
|
||||
'tool_tests': _runToolTests,
|
||||
'web_tests': _runWebTests,
|
||||
});
|
||||
print('$clock STARTING ANALYSIS');
|
||||
try {
|
||||
flutterTestArgs.addAll(args);
|
||||
if (Platform.environment.containsKey(CIRRUS_TASK_NAME))
|
||||
print('Running task: ${Platform.environment[CIRRUS_TASK_NAME]}');
|
||||
print('═' * 80);
|
||||
await _runSmokeTests();
|
||||
print('═' * 80);
|
||||
await selectShard(const <String, ShardRunner>{
|
||||
'add_to_app_tests': _runAddToAppTests,
|
||||
'build_tests': _runBuildTests,
|
||||
'framework_coverage': _runFrameworkCoverage,
|
||||
'framework_tests': _runFrameworkTests,
|
||||
'hostonly_devicelab_tests': _runHostOnlyDeviceLabTests,
|
||||
'tool_coverage': _runToolCoverage,
|
||||
'tool_tests': _runToolTests,
|
||||
'web_tests': _runWebTests,
|
||||
});
|
||||
} on ExitException catch (error) {
|
||||
error.apply();
|
||||
}
|
||||
print('$clock ${bold}Test successful.$reset');
|
||||
}
|
||||
|
||||
Future<void> _runSmokeTests() async {
|
||||
@@ -195,12 +202,8 @@ Future<void> _runSmokeTests() async {
|
||||
|
||||
// Verify that we correctly generated the version file.
|
||||
final String versionError = await verifyVersion(File(path.join(flutterRoot, 'version')));
|
||||
if (versionError != null) {
|
||||
print(redLine);
|
||||
print(versionError);
|
||||
print(redLine);
|
||||
exit(1);
|
||||
}
|
||||
if (versionError != null)
|
||||
exitWithError(<String>[versionError]);
|
||||
}
|
||||
|
||||
Future<bq.BigqueryApi> _getBigqueryApi() async {
|
||||
@@ -624,13 +627,17 @@ Future<void> _pubRunTest(String workingDirectory, {
|
||||
}
|
||||
if (useFlutterTestFormatter) {
|
||||
final FlutterCompactFormatter formatter = FlutterCompactFormatter();
|
||||
final Stream<String> testOutput = runAndGetStdout(
|
||||
pub,
|
||||
args,
|
||||
workingDirectory: workingDirectory,
|
||||
environment: pubEnvironment,
|
||||
beforeExit: formatter.finish,
|
||||
);
|
||||
Stream<String> testOutput;
|
||||
try {
|
||||
testOutput = runAndGetStdout(
|
||||
pub,
|
||||
args,
|
||||
workingDirectory: workingDirectory,
|
||||
environment: pubEnvironment,
|
||||
);
|
||||
} finally {
|
||||
formatter.finish();
|
||||
}
|
||||
await _processTestOutput(formatter, testOutput, tableData);
|
||||
} else {
|
||||
await runCommand(
|
||||
@@ -707,26 +714,26 @@ Future<void> _runFlutterTest(String workingDirectory, {
|
||||
|
||||
if (outputChecker != null) {
|
||||
final String message = outputChecker(output);
|
||||
if (message != null) {
|
||||
print('$redLine');
|
||||
print(message);
|
||||
print('$redLine');
|
||||
exit(1);
|
||||
}
|
||||
if (message != null)
|
||||
exitWithError(<String>[message]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (useFlutterTestFormatter) {
|
||||
final FlutterCompactFormatter formatter = FlutterCompactFormatter();
|
||||
final Stream<String> testOutput = runAndGetStdout(
|
||||
flutter,
|
||||
args,
|
||||
workingDirectory: workingDirectory,
|
||||
expectNonZeroExit: expectFailure,
|
||||
beforeExit: formatter.finish,
|
||||
environment: environment,
|
||||
);
|
||||
Stream<String> testOutput;
|
||||
try {
|
||||
testOutput = runAndGetStdout(
|
||||
flutter,
|
||||
args,
|
||||
workingDirectory: workingDirectory,
|
||||
expectNonZeroExit: expectFailure,
|
||||
environment: environment,
|
||||
);
|
||||
} finally {
|
||||
formatter.finish();
|
||||
}
|
||||
await _processTestOutput(formatter, testOutput, tableData);
|
||||
} else {
|
||||
await runCommand(
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
�
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
Trailing space:
|
||||
^
|
||||
|
||||
Extra blank line:
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'dart:io';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import '../analyze.dart';
|
||||
import '../utils.dart';
|
||||
import 'common.dart';
|
||||
|
||||
typedef AsyncVoidCallback = Future<void> Function();
|
||||
@@ -31,8 +32,10 @@ Future<String> capture(AsyncVoidCallback callback, { int exitCode = 0 }) async {
|
||||
}
|
||||
|
||||
void main() {
|
||||
final String testRootPath = path.join('test', 'analyze-test-input', 'root');
|
||||
|
||||
test('analyze.dart - verifyDeprecations', () async {
|
||||
final String result = await capture(() => verifyDeprecations(path.join('test', 'analyze-test-input', 'root')), exitCode: 1);
|
||||
final String result = await capture(() => verifyDeprecations(testRootPath, minimumMatches: 2), exitCode: 1);
|
||||
expect(result,
|
||||
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'
|
||||
+
|
||||
@@ -50,31 +53,73 @@ void main() {
|
||||
)
|
||||
+
|
||||
'See: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes\n'
|
||||
'\n'
|
||||
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'
|
||||
'\n'
|
||||
);
|
||||
});
|
||||
|
||||
test('analyze.dart - verifyNoMissingLicense', () async {
|
||||
final String result = await capture(() => verifyNoMissingLicense(path.join('test', 'analyze-test-input', 'root')), exitCode: 1);
|
||||
final String result = await capture(() => verifyNoMissingLicense(testRootPath, checkMinimums: false), exitCode: 1);
|
||||
expect(result,
|
||||
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'
|
||||
+
|
||||
(
|
||||
'The following 1 file does not have the right license header:\n'
|
||||
'\n'
|
||||
'test/analyze-test-input/root/packages/foo/foo.dart\n'
|
||||
.replaceAll('/', Platform.isWindows ? '\\' : '/')
|
||||
)
|
||||
+
|
||||
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'
|
||||
'\n'
|
||||
'The expected license header is:\n'
|
||||
'// Copyright 2014 The Flutter Authors. All rights reserved.\n'
|
||||
'// Use of this source code is governed by a BSD-style license that can be\n'
|
||||
'// found in the LICENSE file.\n'
|
||||
'...followed by a blank line.\n'
|
||||
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'
|
||||
);
|
||||
});
|
||||
|
||||
test('analyze.dart - verifyNoTrailingSpaces', () async {
|
||||
final String result = await capture(() => verifyNoTrailingSpaces(testRootPath, minimumMatches: 2), exitCode: 1);
|
||||
expect(result,
|
||||
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'
|
||||
+
|
||||
(
|
||||
'test/analyze-test-input/root/packages/foo/spaces.txt:5: trailing U+0020 space character\n'
|
||||
'test/analyze-test-input/root/packages/foo/spaces.txt:9: trailing blank line\n'
|
||||
.replaceAll('/', Platform.isWindows ? '\\' : '/')
|
||||
)
|
||||
+
|
||||
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'
|
||||
);
|
||||
});
|
||||
|
||||
test('analyze.dart - verifyNoBinaries - positive', () async {
|
||||
final String result = await capture(() => verifyNoBinaries(
|
||||
testRootPath,
|
||||
grandfatheredBinaries: <Hash256>{Hash256(0x39A050CD69434936, 0, 0, 0)},
|
||||
), exitCode: Platform.isWindows ? 0 : 1);
|
||||
if (!Platform.isWindows) {
|
||||
// The output starts with the call to git ls-files, the details of which
|
||||
// change from run to run, so we only check the trailing end of the output.
|
||||
expect(result, endsWith('\n'
|
||||
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'
|
||||
'test/analyze-test-input/root/packages/foo/serviceaccount.enc:0: file is not valid UTF-8\n'
|
||||
'All files in this repository must be UTF-8. In particular, images and other binaries\n'
|
||||
'must not be checked into this repository. This is because we are very sensitive to the\n'
|
||||
'size of the repository as it is distributed to all our developers. If you have a binary\n'
|
||||
'to which you need access, you should consider how to fetch it from another repository;\n'
|
||||
'for example, the "assets-for-api-docs" repository is used for images in API docs.\n'
|
||||
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
test('analyze.dart - verifyNoBinaries - negative', () async {
|
||||
await capture(() => verifyNoBinaries(
|
||||
testRootPath,
|
||||
grandfatheredBinaries: <Hash256>{
|
||||
Hash256(0xA8100AE6AA1940D0, 0xB663BB31CD466142, 0xEBBDBD5187131B92, 0xD93818987832EB89), // sha256("\xff")
|
||||
Hash256(0x155644D3F13D98BF, 0, 0, 0),
|
||||
},
|
||||
), exitCode: 0);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright 2014 The Flutter Authors. 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:core' as core_internals show print;
|
||||
import 'dart:core' hide print;
|
||||
import 'dart:io' as io_internals show exit;
|
||||
import 'dart:io' hide exit;
|
||||
|
||||
final bool hasColor = stdout.supportsAnsiEscapes;
|
||||
|
||||
final String bold = hasColor ? '\x1B[1m' : ''; // used for shard titles
|
||||
final String red = hasColor ? '\x1B[31m' : ''; // used for errors
|
||||
final String green = hasColor ? '\x1B[32m' : ''; // used for section titles, commands
|
||||
final String yellow = hasColor ? '\x1B[33m' : ''; // unused
|
||||
final String cyan = hasColor ? '\x1B[36m' : ''; // used for paths
|
||||
final String reverse = hasColor ? '\x1B[7m' : ''; // used for clocks
|
||||
final String reset = hasColor ? '\x1B[0m' : '';
|
||||
|
||||
class ExitException implements Exception {
|
||||
ExitException(this.exitCode);
|
||||
|
||||
final int exitCode;
|
||||
|
||||
void apply() {
|
||||
io_internals.exit(exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
// We actually reimplement exit() so that it uses exceptions rather
|
||||
// than truly immediately terminating the application, so that we can
|
||||
// test the exit code in unit tests (see test/analyze_test.dart).
|
||||
void exit(int exitCode) {
|
||||
throw ExitException(exitCode);
|
||||
}
|
||||
|
||||
void exitWithError(List<String> messages) {
|
||||
final String redLine = '$red━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$reset';
|
||||
print(redLine);
|
||||
messages.forEach(print);
|
||||
print(redLine);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
typedef PrintCallback = void Function(Object line);
|
||||
|
||||
// Allow print() to be overridden, for tests.
|
||||
PrintCallback print = core_internals.print;
|
||||
|
||||
String get clock {
|
||||
final DateTime now = DateTime.now();
|
||||
return '$reverse▌'
|
||||
'${now.hour.toString().padLeft(2, "0")}:'
|
||||
'${now.minute.toString().padLeft(2, "0")}:'
|
||||
'${now.second.toString().padLeft(2, "0")}'
|
||||
'▐$reset';
|
||||
}
|
||||
|
||||
String prettyPrintDuration(Duration duration) {
|
||||
String result = '';
|
||||
final int minutes = duration.inMinutes;
|
||||
if (minutes > 0)
|
||||
result += '${minutes}min ';
|
||||
final int seconds = duration.inSeconds - minutes * 60;
|
||||
final int milliseconds = duration.inMilliseconds - (seconds * 1000 + minutes * 60 * 1000);
|
||||
result += '$seconds.${milliseconds.toString().padLeft(3, "0")}s';
|
||||
return result;
|
||||
}
|
||||
|
||||
void printProgress(String action, String workingDir, String command) {
|
||||
print('$clock $action: cd $cyan$workingDir$reset; $green$command$reset');
|
||||
}
|
||||
@@ -10,4 +10,3 @@ After setup,
|
||||
* run `./docker_build.sh` to build the container image.
|
||||
* run `./docker_push.sh` to push the image to google cloud registry. This will
|
||||
affect our CI tests.
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user