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.
This commit is contained in:
Chris Bracken 2018-05-09 10:55:23 -07:00 committed by GitHub
parent 4b6e574466
commit e4f553324a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 3 deletions

View File

@ -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();
}
}

View File

@ -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', () {