From e4f553324a6636bd2d4d8b15311013eb4e606842 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Wed, 9 May 2018 10:55:23 -0700 Subject: [PATCH] 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. --- .../lib/src/base/fingerprint.dart | 10 ++++-- .../test/base/fingerprint_test.dart | 36 ++++++++++++++++++- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/packages/flutter_tools/lib/src/base/fingerprint.dart b/packages/flutter_tools/lib/src/base/fingerprint.dart index e1643b911cb..d8fee1c1c19 100644 --- a/packages/flutter_tools/lib/src/base/fingerprint.dart +++ b/packages/flutter_tools/lib/src/base/fingerprint.dart @@ -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 paths, @required Map properties, - Iterable depfilePaths: const [] + Iterable depfilePaths: const [], + FingerprintPathFilter pathFilter, }) : _paths = paths.toList(), _properties = new Map.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 _paths; final Map _properties; final List _depfilePaths; + final FingerprintPathFilter _pathFilter; Future buildFingerprint() async { final List paths = await _getPaths(); @@ -81,7 +86,8 @@ class Fingerprinter { final Set 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(); } } diff --git a/packages/flutter_tools/test/base/fingerprint_test.dart b/packages/flutter_tools/test/base/fingerprint_test.dart index 5d6fb9d2289..fcfff848b4f 100644 --- a/packages/flutter_tools/test/base/fingerprint_test.dart +++ b/packages/flutter_tools/test/base/fingerprint_test.dart @@ -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: ['a.dart', 'b.dart'], + paths: ['a.dart'], + depfilePaths: ['depfile'], properties: { '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: ['a.dart'], + properties: { + '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: ['a.dart'], + depfilePaths: ['depfile'], + properties: { + 'foo': 'bar', + 'wibble': 'wobble', + }, + pathFilter: (String path) => path.startsWith('a'), + ); + await fingerprinter.writeFingerprint(); + expect(fs.file('out.fingerprint').existsSync(), isTrue); + }, overrides: contextOverrides); }); group('Fingerprint', () {