Revert "Revert "Add many more global analyses. (#47875)" (#48080)" (#48081)

This reverts commit 04ea3183ce.
This commit is contained in:
Dan Field
2020-01-02 11:47:28 -08:00
committed by Francisco Magdaleno
parent 04ea3183ce
commit 24f39d40a4
85 changed files with 994 additions and 513 deletions
+1 -1
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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 @@
]
}
}
+3 -3
View File
@@ -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
+3 -3
View File
@@ -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
+3 -3
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -149,4 +149,3 @@ if [[ -n "$CIRRUS_CI" && -z "$CIRRUS_PR" ]]; then
deploy 5 docs-flutter-dev
fi
fi
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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,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:
+52 -7
View File
@@ -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);
});
}
+72
View File
@@ -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');
}
-1
View File
@@ -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