Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Commit

Permalink
Cleaner test.dart output. (#109206)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hixie committed Aug 14, 2022
1 parent d50c5b1 commit 97901da
Show file tree
Hide file tree
Showing 8 changed files with 573 additions and 742 deletions.
118 changes: 54 additions & 64 deletions dev/bots/analyze.dart
Expand Up @@ -44,13 +44,13 @@ Future<void> main(List<String> arguments) async {
);
dart = path.join(dartSdk, 'bin', Platform.isWindows ? 'dart.exe' : 'dart');
pub = path.join(dartSdk, 'bin', Platform.isWindows ? 'pub.bat' : 'pub');
print('$clock STARTING ANALYSIS');
printProgress('STARTING ANALYSIS');
await run(arguments);
if (hasError) {
print('$clock ${bold}Test failed.$reset');
printProgress('${bold}Test failed.$reset');
reportErrorsAndExit();
}
print('$clock ${bold}Analysis successful.$reset');
printProgress('${bold}Analysis successful.$reset');
}

/// Scans [arguments] for an argument of the form `--dart-sdk` or
Expand Down Expand Up @@ -88,85 +88,85 @@ Future<void> run(List<String> arguments) async {
foundError(<String>['The analyze.dart script must be run with --enable-asserts.']);
}

print('$clock No Double.clamp');
printProgress('No Double.clamp');
await verifyNoDoubleClamp(flutterRoot);

print('$clock All tool test files end in _test.dart...');
printProgress('All tool test files end in _test.dart...');
await verifyToolTestsEndInTestDart(flutterRoot);

print('$clock No sync*/async*');
printProgress('No sync*/async*');
await verifyNoSyncAsyncStar(flutterPackages);
await verifyNoSyncAsyncStar(flutterExamples, minimumMatches: 200);

print('$clock No runtimeType in toString...');
printProgress('No runtimeType in toString...');
await verifyNoRuntimeTypeInToString(flutterRoot);

print('$clock Debug mode instead of checked mode...');
printProgress('Debug mode instead of checked mode...');
await verifyNoCheckedMode(flutterRoot);

print('$clock Links for creating GitHub issues');
printProgress('Links for creating GitHub issues');
await verifyIssueLinks(flutterRoot);

print('$clock Unexpected binaries...');
printProgress('Unexpected binaries...');
await verifyNoBinaries(flutterRoot);

print('$clock Trailing spaces...');
printProgress('Trailing spaces...');
await verifyNoTrailingSpaces(flutterRoot); // assumes no unexpected binaries, so should be after verifyNoBinaries

print('$clock Deprecations...');
printProgress('Deprecations...');
await verifyDeprecations(flutterRoot);

print('$clock Goldens...');
printProgress('Goldens...');
await verifyGoldenTags(flutterPackages);

print('$clock Skip test comments...');
printProgress('Skip test comments...');
await verifySkipTestComments(flutterRoot);

print('$clock Licenses...');
printProgress('Licenses...');
await verifyNoMissingLicense(flutterRoot);

print('$clock Test imports...');
printProgress('Test imports...');
await verifyNoTestImports(flutterRoot);

print('$clock Bad imports (framework)...');
printProgress('Bad imports (framework)...');
await verifyNoBadImportsInFlutter(flutterRoot);

print('$clock Bad imports (tools)...');
printProgress('Bad imports (tools)...');
await verifyNoBadImportsInFlutterTools(flutterRoot);

print('$clock Internationalization...');
printProgress('Internationalization...');
await verifyInternationalizations(flutterRoot, dart);

print('$clock Integration test timeouts...');
printProgress('Integration test timeouts...');
await verifyIntegrationTestTimeouts(flutterRoot);

print('$clock null initialized debug fields...');
printProgress('null initialized debug fields...');
await verifyNullInitializedDebugExpensiveFields(flutterRoot);

// Ensure that all package dependencies are in sync.
print('$clock Package dependencies...');
printProgress('Package dependencies...');
await runCommand(flutter, <String>['update-packages', '--verify-only'],
workingDirectory: flutterRoot,
);

/// Ensure that no new dependencies have been accidentally
/// added to core packages.
print('$clock Package Allowlist...');
printProgress('Package Allowlist...');
await _checkConsumerDependencies();

// Analyze all the Dart code in the repo.
print('$clock Dart analysis...');
printProgress('Dart analysis...');
await _runFlutterAnalyze(flutterRoot, options: <String>[
'--flutter-repo',
...arguments,
]);

print('$clock Executable allowlist...');
printProgress('Executable allowlist...');
await _checkForNewExecutables();

// Try with the --watch analyzer, to make sure it returns success also.
// The --benchmark argument exits after one run.
print('$clock Dart analysis (with --watch)...');
printProgress('Dart analysis (with --watch)...');
await _runFlutterAnalyze(flutterRoot, options: <String>[
'--flutter-repo',
'--watch',
Expand All @@ -175,14 +175,14 @@ Future<void> run(List<String> arguments) async {
]);

// Analyze the code in `{@tool snippet}` sections in the repo.
print('$clock Snippet code...');
printProgress('Snippet code...');
await runCommand(dart,
<String>['--enable-asserts', path.join(flutterRoot, 'dev', 'bots', 'analyze_snippet_code.dart'), '--verbose'],
workingDirectory: flutterRoot,
);

// Try analysis against a big version of the gallery; generate into a temporary directory.
print('$clock Dart analysis (mega gallery)...');
printProgress('Dart analysis (mega gallery)...');
final Directory outDir = Directory.systemTemp.createTempSync('flutter_mega_gallery.');
try {
await runCommand(dart,
Expand Down Expand Up @@ -548,27 +548,23 @@ String _generateLicense(String prefix) {

Future<void> verifyNoMissingLicense(String workingDirectory, { bool checkMinimums = true }) async {
final int? overrideMinimumMatches = checkMinimums ? null : 0;
int failed = 0;
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'dart', overrideMinimumMatches ?? 2000, _generateLicense('// '));
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'java', overrideMinimumMatches ?? 39, _generateLicense('// '));
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'h', overrideMinimumMatches ?? 30, _generateLicense('// '));
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'm', overrideMinimumMatches ?? 30, _generateLicense('// '));
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'cpp', overrideMinimumMatches ?? 0, _generateLicense('// '));
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'swift', overrideMinimumMatches ?? 10, _generateLicense('// '));
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'gradle', overrideMinimumMatches ?? 80, _generateLicense('// '));
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'gn', overrideMinimumMatches ?? 0, _generateLicense('# '));
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'sh', overrideMinimumMatches ?? 1, _generateLicense('# '), header: r'#!/usr/bin/env bash\n',);
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'bat', overrideMinimumMatches ?? 1, _generateLicense('REM '), header: r'@ECHO off\n');
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'ps1', overrideMinimumMatches ?? 1, _generateLicense('# '));
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'html', overrideMinimumMatches ?? 1, '<!-- ${_generateLicense('')} -->', trailingBlank: false, header: r'<!DOCTYPE HTML>\n');
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'xml', overrideMinimumMatches ?? 1, '<!-- ${_generateLicense('')} -->', header: r'(<\?xml version="1.0" encoding="utf-8"\?>\n)?');
failed += await _verifyNoMissingLicenseForExtension(workingDirectory, 'frag', overrideMinimumMatches ?? 1, _generateLicense('// '), header: r'#version 320 es(\n)+');
if (failed > 0) {
foundError(<String>['License check failed.']);
}
await _verifyNoMissingLicenseForExtension(workingDirectory, 'dart', overrideMinimumMatches ?? 2000, _generateLicense('// '));
await _verifyNoMissingLicenseForExtension(workingDirectory, 'java', overrideMinimumMatches ?? 39, _generateLicense('// '));
await _verifyNoMissingLicenseForExtension(workingDirectory, 'h', overrideMinimumMatches ?? 30, _generateLicense('// '));
await _verifyNoMissingLicenseForExtension(workingDirectory, 'm', overrideMinimumMatches ?? 30, _generateLicense('// '));
await _verifyNoMissingLicenseForExtension(workingDirectory, 'cpp', overrideMinimumMatches ?? 0, _generateLicense('// '));
await _verifyNoMissingLicenseForExtension(workingDirectory, 'swift', overrideMinimumMatches ?? 10, _generateLicense('// '));
await _verifyNoMissingLicenseForExtension(workingDirectory, 'gradle', overrideMinimumMatches ?? 80, _generateLicense('// '));
await _verifyNoMissingLicenseForExtension(workingDirectory, 'gn', overrideMinimumMatches ?? 0, _generateLicense('# '));
await _verifyNoMissingLicenseForExtension(workingDirectory, 'sh', overrideMinimumMatches ?? 1, _generateLicense('# '), header: r'#!/usr/bin/env bash\n',);
await _verifyNoMissingLicenseForExtension(workingDirectory, 'bat', overrideMinimumMatches ?? 1, _generateLicense('REM '), header: r'@ECHO off\n');
await _verifyNoMissingLicenseForExtension(workingDirectory, 'ps1', overrideMinimumMatches ?? 1, _generateLicense('# '));
await _verifyNoMissingLicenseForExtension(workingDirectory, 'html', overrideMinimumMatches ?? 1, '<!-- ${_generateLicense('')} -->', trailingBlank: false, header: r'<!DOCTYPE HTML>\n');
await _verifyNoMissingLicenseForExtension(workingDirectory, 'xml', overrideMinimumMatches ?? 1, '<!-- ${_generateLicense('')} -->', header: r'(<\?xml version="1.0" encoding="utf-8"\?>\n)?');
await _verifyNoMissingLicenseForExtension(workingDirectory, 'frag', overrideMinimumMatches ?? 1, _generateLicense('// '), header: r'#version 320 es(\n)+');
}

Future<int> _verifyNoMissingLicenseForExtension(
Future<void> _verifyNoMissingLicenseForExtension(
String workingDirectory,
String extension,
int minimumMatches,
Expand All @@ -592,22 +588,17 @@ Future<int> _verifyNoMissingLicenseForExtension(
}
// Fail if any errors
if (errors.isNotEmpty) {
final String redLine = '$red━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$reset';
final String fileDoes = errors.length == 1 ? 'file does' : '${errors.length} files do';
print(<String>[
redLine,
foundError(<String>[
'${bold}The following $fileDoes not have the right license header for $extension files:$reset',
...errors.map<String>((String error) => ' $error'),
'The expected license header is:',
if (header.isNotEmpty) 'A header matching the regular expression "$header",',
if (header.isNotEmpty) 'followed by the following license text:',
license,
if (trailingBlank) '...followed by a blank line.',
redLine,
].join('\n'));
return 1;
]);
}
return 0;
}

class _Line {
Expand Down Expand Up @@ -1650,7 +1641,7 @@ Future<EvalResult> _evalCommand(String executable, List<String> arguments, {
final String relativeWorkingDir = path.relative(workingDirectory);

if (!runSilently) {
printProgress('RUNNING', relativeWorkingDir, commandDescription);
print('RUNNING: cd $cyan$relativeWorkingDir$reset; $green$commandDescription$reset');
}

final Stopwatch time = Stopwatch()..start();
Expand All @@ -1669,12 +1660,12 @@ Future<EvalResult> _evalCommand(String executable, List<String> arguments, {
);

if (!runSilently) {
print('$clock ELAPSED TIME: $bold${prettyPrintDuration(time.elapsed)}$reset for $commandDescription in $relativeWorkingDir');
print('ELAPSED TIME: $bold${prettyPrintDuration(time.elapsed)}$reset for $commandDescription in $relativeWorkingDir');
}

if (exitCode != 0 && !allowNonZeroExit) {
stderr.write(result.stderr);
foundError(<String>[
result.stderr,
'${bold}ERROR:$red Last command exited with $exitCode.$reset',
'${bold}Command:$red $commandDescription$reset',
'${bold}Relative working directory:$red $relativeWorkingDir$reset',
Expand Down Expand Up @@ -1838,9 +1829,8 @@ const Set<String> kExecutableAllowlist = <String>{
Future<void> _checkForNewExecutables() async {
// 0b001001001
const int executableBitMask = 0x49;

final List<File> files = await _gitFiles(flutterRoot);
int unexpectedExecutableCount = 0;
final List<String> errors = <String>[];
for (final File file in files) {
final String relativePath = path.relative(
file.path,
Expand All @@ -1849,14 +1839,14 @@ Future<void> _checkForNewExecutables() async {
final FileStat stat = file.statSync();
final bool isExecutable = stat.mode & executableBitMask != 0x0;
if (isExecutable && !kExecutableAllowlist.contains(relativePath)) {
unexpectedExecutableCount += 1;
print('$relativePath is executable: ${(stat.mode & 0x1FF).toRadixString(2)}');
errors.add('$relativePath is executable: ${(stat.mode & 0x1FF).toRadixString(2)}');
}
}
if (unexpectedExecutableCount > 0) {
if (errors.isNotEmpty) {
throw Exception(
'found $unexpectedExecutableCount unexpected executable file'
'${unexpectedExecutableCount == 1 ? '' : 's'}! If this was intended, you '
'${errors.join('\n')}\n'
'found ${errors.length} unexpected executable file'
'${errors.length == 1 ? '' : 's'}! If this was intended, you '
'must add this file to kExecutableAllowlist in dev/bots/analyze.dart',
);
}
Expand Down

0 comments on commit 97901da

Please sign in to comment.