mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

In https://github.com/flutter/flutter/pull/103771, we rolled dependencies in Flutter, which triggered an update of package:coverage to v1.3.1. The new version includes https://github.com/dart-lang/coverage/pull/370 in which two deprecations landed: * The `Resolver` default constructor was deprecated and replaced with the `Resolver.create` static factory method, which unfortunately happens to be async. * The `packagesPath` parameter to `HitMap.parseJson`, which takes the path to the `.packages` file of the package for which coverage is to be collected, was deprecated. This parameter was replaced with `packagePath` in https://github.com/dart-lang/coverage/pull/370 which was part of the overall deprecation of the .packages file in Dart itself https://github.com/dart-lang/sdk/issues/48272. The overall goal being that end-user code shouldn't need to know about implementation details such as whether dependency information is stored in a .packages file or a package_info.json file, but rather use the package_config package to obtain the package metadata and perform other functions such as resolving its dependencies to filesystem paths. packagesPath was replaced by packagePath, which takes the path to the package directory itself. Internally, package:coverage then uses package_config to do the rest of the package/script URI resolution to filesystem paths. This migrates off the deprecated `packagesPath` parameter to the replacement `packagePath` paramter. Issue: https://github.com/flutter/flutter/issues/103830
178 lines
7.6 KiB
Dart
178 lines
7.6 KiB
Dart
// 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.
|
|
|
|
// @dart = 2.8
|
|
|
|
import 'dart:convert' show json;
|
|
import 'dart:math' as math;
|
|
|
|
import 'package:args/args.dart';
|
|
import 'package:flutter_tools/src/artifacts.dart';
|
|
import 'package:flutter_tools/src/base/common.dart';
|
|
import 'package:flutter_tools/src/base/context.dart';
|
|
import 'package:flutter_tools/src/base/file_system.dart';
|
|
import 'package:flutter_tools/src/base/io.dart';
|
|
import 'package:flutter_tools/src/build_info.dart';
|
|
import 'package:flutter_tools/src/cache.dart';
|
|
import 'package:flutter_tools/src/context_runner.dart';
|
|
import 'package:flutter_tools/src/device.dart';
|
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
|
import 'package:flutter_tools/src/project.dart';
|
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
|
import 'package:flutter_tools/src/test/coverage_collector.dart';
|
|
import 'package:flutter_tools/src/test/runner.dart';
|
|
import 'package:flutter_tools/src/test/test_wrapper.dart';
|
|
|
|
const String _kOptionPackages = 'packages';
|
|
const String _kOptionShell = 'shell';
|
|
const String _kOptionTestDirectory = 'test-directory';
|
|
const String _kOptionSdkRoot = 'sdk-root';
|
|
const String _kOptionIcudtl = 'icudtl';
|
|
const String _kOptionTests = 'tests';
|
|
const String _kOptionCoverageDirectory = 'coverage-directory';
|
|
const List<String> _kRequiredOptions = <String>[
|
|
_kOptionPackages,
|
|
_kOptionShell,
|
|
_kOptionSdkRoot,
|
|
_kOptionIcudtl,
|
|
_kOptionTests,
|
|
];
|
|
const String _kOptionCoverage = 'coverage';
|
|
const String _kOptionCoveragePath = 'coverage-path';
|
|
|
|
void main(List<String> args) {
|
|
runInContext<void>(() => run(args), overrides: <Type, Generator>{
|
|
Usage: () => DisabledUsage(),
|
|
});
|
|
}
|
|
|
|
Future<void> run(List<String> args) async {
|
|
final ArgParser parser = ArgParser()
|
|
..addOption(_kOptionPackages, help: 'The .packages file')
|
|
..addOption(_kOptionShell, help: 'The Flutter shell binary')
|
|
..addOption(_kOptionTestDirectory, help: 'Directory containing the tests')
|
|
..addOption(_kOptionSdkRoot, help: 'Path to the SDK platform files')
|
|
..addOption(_kOptionIcudtl, help: 'Path to the ICU data file')
|
|
..addOption(_kOptionTests, help: 'Path to json file that maps Dart test files to precompiled dill files')
|
|
..addOption(_kOptionCoverageDirectory, help: 'The path to the directory that will have coverage collected')
|
|
..addFlag(_kOptionCoverage,
|
|
defaultsTo: false,
|
|
negatable: false,
|
|
help: 'Whether to collect coverage information.',
|
|
)
|
|
..addOption(_kOptionCoveragePath,
|
|
defaultsTo: 'coverage/lcov.info',
|
|
help: 'Where to store coverage information (if coverage is enabled).',
|
|
);
|
|
final ArgResults argResults = parser.parse(args);
|
|
if (_kRequiredOptions
|
|
.any((String option) => !argResults.options.contains(option))) {
|
|
throwToolExit('Missing option! All options must be specified.');
|
|
}
|
|
final Directory tempDir =
|
|
globals.fs.systemTempDirectory.createTempSync('flutter_fuchsia_tester.');
|
|
try {
|
|
Cache.flutterRoot = tempDir.path;
|
|
|
|
final String shellPath = globals.fs.file(argResults[_kOptionShell]).resolveSymbolicLinksSync();
|
|
if (!globals.fs.isFileSync(shellPath)) {
|
|
throwToolExit('Cannot find Flutter shell at $shellPath');
|
|
}
|
|
|
|
final Directory sdkRootSrc = globals.fs.directory(argResults[_kOptionSdkRoot]);
|
|
if (!globals.fs.isDirectorySync(sdkRootSrc.path)) {
|
|
throwToolExit('Cannot find SDK files at ${sdkRootSrc.path}');
|
|
}
|
|
Directory coverageDirectory;
|
|
final String coverageDirectoryPath = argResults[_kOptionCoverageDirectory] as String;
|
|
if (coverageDirectoryPath != null) {
|
|
if (!globals.fs.isDirectorySync(coverageDirectoryPath)) {
|
|
throwToolExit('Cannot find coverage directory at $coverageDirectoryPath');
|
|
}
|
|
coverageDirectory = globals.fs.directory(coverageDirectoryPath);
|
|
}
|
|
|
|
// Put the tester shell where runTests expects it.
|
|
// TODO(garymm): Switch to a Fuchsia-specific Artifacts impl.
|
|
final Link testerDestLink =
|
|
globals.fs.link(globals.artifacts.getArtifactPath(Artifact.flutterTester));
|
|
testerDestLink.parent.createSync(recursive: true);
|
|
testerDestLink.createSync(globals.fs.path.absolute(shellPath));
|
|
|
|
final Directory sdkRootDest =
|
|
globals.fs.directory(globals.artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath));
|
|
sdkRootDest.createSync(recursive: true);
|
|
for (final FileSystemEntity artifact in sdkRootSrc.listSync()) {
|
|
globals.fs.link(sdkRootDest.childFile(artifact.basename).path).createSync(artifact.path);
|
|
}
|
|
// TODO(tvolkert): Remove once flutter_tester no longer looks for this.
|
|
globals.fs.link(sdkRootDest.childFile('platform.dill').path).createSync('platform_strong.dill');
|
|
|
|
Directory testDirectory;
|
|
CoverageCollector collector;
|
|
if (argResults['coverage'] as bool) {
|
|
// If we have a specified coverage directory then accept all libraries by
|
|
// setting libraryNames to null.
|
|
final Set<String> libraryNames = coverageDirectory != null ? null :
|
|
<String>{FlutterProject.current().manifest.appName};
|
|
collector = CoverageCollector(
|
|
packagesPath: globals.fs.path.normalize(globals.fs.path.absolute(argResults[_kOptionPackages] as String)),
|
|
libraryNames: libraryNames);
|
|
if (!argResults.options.contains(_kOptionTestDirectory)) {
|
|
throwToolExit('Use of --coverage requires setting --test-directory');
|
|
}
|
|
testDirectory = globals.fs.directory(argResults[_kOptionTestDirectory]);
|
|
}
|
|
|
|
|
|
final Map<String, String> tests = <String, String>{};
|
|
final List<Map<String, dynamic>> jsonList = List<Map<String, dynamic>>.from(
|
|
(json.decode(globals.fs.file(argResults[_kOptionTests]).readAsStringSync()) as List<dynamic>).cast<Map<String, dynamic>>());
|
|
for (final Map<String, dynamic> map in jsonList) {
|
|
final String source = globals.fs.file(map['source']).resolveSymbolicLinksSync();
|
|
final String dill = globals.fs.file(map['dill']).resolveSymbolicLinksSync();
|
|
tests[source] = dill;
|
|
}
|
|
|
|
// TODO(dnfield): This should be injected.
|
|
exitCode = await const FlutterTestRunner().runTests(
|
|
const TestWrapper(),
|
|
tests.keys.toList(),
|
|
debuggingOptions: DebuggingOptions.enabled(
|
|
BuildInfo(
|
|
BuildMode.debug,
|
|
'',
|
|
treeShakeIcons: false,
|
|
packagesPath: globals.fs.path.normalize(globals.fs.path.absolute(argResults[_kOptionPackages] as String)),
|
|
),
|
|
),
|
|
watcher: collector,
|
|
enableObservatory: collector != null,
|
|
precompiledDillFiles: tests,
|
|
concurrency: math.max(1, globals.platform.numberOfProcessors - 2),
|
|
icudtlPath: globals.fs.path.absolute(argResults[_kOptionIcudtl] as String),
|
|
coverageDirectory: coverageDirectory,
|
|
);
|
|
|
|
if (collector != null) {
|
|
// collector expects currentDirectory to be the root of the dart
|
|
// package (i.e. contains lib/ and test/ sub-dirs). In some cases,
|
|
// test files may appear to be in the root directory.
|
|
if (coverageDirectory == null) {
|
|
globals.fs.currentDirectory = testDirectory.parent;
|
|
} else {
|
|
globals.fs.currentDirectory = testDirectory;
|
|
}
|
|
if (!await collector.collectCoverageData(argResults[_kOptionCoveragePath] as String, coverageDirectory: coverageDirectory)) {
|
|
throwToolExit('Failed to collect coverage data');
|
|
}
|
|
}
|
|
} finally {
|
|
tempDir.deleteSync(recursive: true);
|
|
}
|
|
// TODO(ianh): There's apparently some sort of lost async task keeping the
|
|
// process open. Remove the next line once that's been resolved.
|
|
exit(exitCode);
|
|
}
|