Unverified Commit e4f55332 authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Add pathFilter to Fingerprinter (#17412)

Allows users of Fingerprinter to filter the set of paths collected from
the explicitly-specified paths and those collected from depfiles.

In some cases, depfiles are emitted with files that are not present on
the local disk (e.g. the frontend compiler currently emits buildbot
paths for the dart core libraries and dart:ui). These files will not
materially affect whether we need to re-run a build action for which
they are inputs, since they're not present in the filesystem and
therefore cannot change.
parent 4b6e5744
......@@ -13,6 +13,8 @@ import '../globals.dart';
import '../version.dart';
import 'file_system.dart';
typedef bool FingerprintPathFilter(String path);
/// A tool that can be used to compute, compare, and write [Fingerprint]s for a
/// set of input files and associated build settings.
///
......@@ -25,10 +27,12 @@ class Fingerprinter {
@required this.fingerprintPath,
@required Iterable<String> paths,
@required Map<String, String> properties,
Iterable<String> depfilePaths: const <String>[]
Iterable<String> depfilePaths: const <String>[],
FingerprintPathFilter pathFilter,
}) : _paths = paths.toList(),
_properties = new Map<String, String>.from(properties),
_depfilePaths = depfilePaths.toList(),
_pathFilter = pathFilter,
assert(fingerprintPath != null),
assert(paths != null && paths.every((String path) => path != null)),
assert(properties != null),
......@@ -38,6 +42,7 @@ class Fingerprinter {
final List<String> _paths;
final Map<String, String> _properties;
final List<String> _depfilePaths;
final FingerprintPathFilter _pathFilter;
Future<Fingerprint> buildFingerprint() async {
final List<String> paths = await _getPaths();
......@@ -81,7 +86,8 @@ class Fingerprinter {
final Set<String> paths = _paths.toSet();
for (String depfilePath in _depfilePaths)
paths.addAll(await readDepfile(depfilePath));
return paths.toList()..sort();
final FingerprintPathFilter filter = _pathFilter ?? (String path) => true;
return paths.where(filter).toList()..sort();
}
}
......
......@@ -52,10 +52,12 @@ void main() {
testUsingContext('creates fingerprint with file checksums', () async {
await fs.file('a.dart').create();
await fs.file('b.dart').create();
await fs.file('depfile').writeAsString('depfile : b.dart');
final Fingerprinter fingerprinter = new Fingerprinter(
fingerprintPath: 'out.fingerprint',
paths: <String>['a.dart', 'b.dart'],
paths: <String>['a.dart'],
depfilePaths: <String>['depfile'],
properties: <String, String>{
'bar': 'baz',
'wobble': 'womble',
......@@ -123,6 +125,38 @@ void main() {
await fingerprinter.writeFingerprint();
expect(await fingerprinter.doesFingerprintMatch(), isTrue);
}, overrides: contextOverrides);
testUsingContext('fails to write fingerprint if inputs are missing', () async {
final Fingerprinter fingerprinter = new Fingerprinter(
fingerprintPath: 'out.fingerprint',
paths: <String>['a.dart'],
properties: <String, String>{
'foo': 'bar',
'wibble': 'wobble',
},
);
await fingerprinter.writeFingerprint();
expect(fs.file('out.fingerprint').existsSync(), isFalse);
}, overrides: contextOverrides);
testUsingContext('applies path filter to inputs paths', () async {
await fs.file('a.dart').create();
await fs.file('ab.dart').create();
await fs.file('depfile').writeAsString('depfile : ab.dart c.dart');
final Fingerprinter fingerprinter = new Fingerprinter(
fingerprintPath: 'out.fingerprint',
paths: <String>['a.dart'],
depfilePaths: <String>['depfile'],
properties: <String, String>{
'foo': 'bar',
'wibble': 'wobble',
},
pathFilter: (String path) => path.startsWith('a'),
);
await fingerprinter.writeFingerprint();
expect(fs.file('out.fingerprint').existsSync(), isTrue);
}, overrides: contextOverrides);
});
group('Fingerprint', () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment