Unverified Commit 4db7daf7 authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Handle malformed depfiles in Fingerprinter (#18321)

Fingerprinter.doesFingerprintMatch() now returns false rather than
throwing if a depfile is malformed.
parent 3daebd05
...@@ -50,18 +50,18 @@ class Fingerprinter { ...@@ -50,18 +50,18 @@ class Fingerprinter {
} }
Future<bool> doesFingerprintMatch() async { Future<bool> doesFingerprintMatch() async {
final File fingerprintFile = fs.file(fingerprintPath); try {
if (!fingerprintFile.existsSync()) final File fingerprintFile = fs.file(fingerprintPath);
return false; if (!fingerprintFile.existsSync())
return false;
if (!_depfilePaths.every(fs.isFileSync)) if (!_depfilePaths.every(fs.isFileSync))
return false; return false;
final List<String> paths = await _getPaths(); final List<String> paths = await _getPaths();
if (!paths.every(fs.isFileSync)) if (!paths.every(fs.isFileSync))
return false; return false;
try {
final Fingerprint oldFingerprint = new Fingerprint.fromJson(await fingerprintFile.readAsString()); final Fingerprint oldFingerprint = new Fingerprint.fromJson(await fingerprintFile.readAsString());
final Fingerprint newFingerprint = await buildFingerprint(); final Fingerprint newFingerprint = await buildFingerprint();
return oldFingerprint == newFingerprint; return oldFingerprint == newFingerprint;
...@@ -153,6 +153,9 @@ class Fingerprint { ...@@ -153,6 +153,9 @@ class Fingerprint {
// Ignore map entries here to avoid becoming inconsistent with equals // Ignore map entries here to avoid becoming inconsistent with equals
// due to differences in map entry order. // due to differences in map entry order.
int get hashCode => hash2(_properties.length, _checksums.length); int get hashCode => hash2(_properties.length, _checksums.length);
@override
String toString() => '{checksums: $_checksums, properties: $_properties}';
} }
final RegExp _separatorExpr = new RegExp(r'([^\\]) '); final RegExp _separatorExpr = new RegExp(r'([^\\]) ');
...@@ -171,6 +174,7 @@ Future<Set<String>> readDepfile(String depfilePath) async { ...@@ -171,6 +174,7 @@ Future<Set<String>> readDepfile(String depfilePath) async {
// Depfile format: // Depfile format:
// outfile1 outfile2 : file1.dart file2.dart file3.dart // outfile1 outfile2 : file1.dart file2.dart file3.dart
final String contents = await fs.file(depfilePath).readAsString(); final String contents = await fs.file(depfilePath).readAsString();
final String dependencies = contents.split(': ')[1]; final String dependencies = contents.split(': ')[1];
return dependencies return dependencies
.replaceAllMapped(_separatorExpr, (Match match) => '${match.group(1)}\n') .replaceAllMapped(_separatorExpr, (Match match) => '${match.group(1)}\n')
......
...@@ -31,6 +31,23 @@ void main() { ...@@ -31,6 +31,23 @@ void main() {
FileSystem: () => fs, FileSystem: () => fs,
}; };
testUsingContext('throws when depfile is malformed', () async {
await fs.file('a.dart').create();
await fs.file('b.dart').create();
await fs.file('depfile').create();
final Fingerprinter fingerprinter = new Fingerprinter(
fingerprintPath: 'out.fingerprint',
paths: <String>['a.dart'],
depfilePaths: <String>['depfile'],
properties: <String, String>{
'bar': 'baz',
'wobble': 'womble',
},
);
expect(() async => await fingerprinter.buildFingerprint(), throwsA(anything));
}, overrides: contextOverrides);
testUsingContext('creates fingerprint with specified properties and files', () async { testUsingContext('creates fingerprint with specified properties and files', () async {
await fs.file('a.dart').create(); await fs.file('a.dart').create();
...@@ -110,6 +127,55 @@ void main() { ...@@ -110,6 +127,55 @@ void main() {
expect(await fingerprinter2.doesFingerprintMatch(), isFalse); expect(await fingerprinter2.doesFingerprintMatch(), isFalse);
}, overrides: contextOverrides); }, overrides: contextOverrides);
testUsingContext('fingerprint does not match if depfile is malformed', () async {
await fs.file('a.dart').create();
await fs.file('b.dart').create();
await fs.file('depfile').writeAsString('depfile : b.dart');
// Write a valid fingerprint
final Fingerprinter fingerprinter = new Fingerprinter(
fingerprintPath: 'out.fingerprint',
paths: <String>['a.dart', 'b.dart'],
depfilePaths: <String>['depfile'],
properties: <String, String>{
'bar': 'baz',
'wobble': 'womble',
},
);
await fingerprinter.writeFingerprint();
// Write a corrupt depfile.
await fs.file('depfile').writeAsString('');
final Fingerprinter badFingerprinter = new Fingerprinter(
fingerprintPath: 'out.fingerprint',
paths: <String>['a.dart', 'b.dart'],
depfilePaths: <String>['depfile'],
properties: <String, String>{
'bar': 'baz',
'wobble': 'womble',
},
);
expect(await badFingerprinter.doesFingerprintMatch(), isFalse);
}, overrides: contextOverrides);
testUsingContext('fingerprint does not match if previous fingerprint is malformed', () async {
await fs.file('a.dart').create();
await fs.file('b.dart').create();
await fs.file('out.fingerprint').writeAsString('** not JSON **');
final Fingerprinter fingerprinter = new Fingerprinter(
fingerprintPath: 'out.fingerprint',
paths: <String>['a.dart', 'b.dart'],
depfilePaths: <String>['depfile'],
properties: <String, String>{
'bar': 'baz',
'wobble': 'womble',
},
);
expect(await fingerprinter.doesFingerprintMatch(), isFalse);
}, overrides: contextOverrides);
testUsingContext('fingerprint does match if identical', () async { testUsingContext('fingerprint does match if identical', () async {
await fs.file('a.dart').create(); await fs.file('a.dart').create();
await fs.file('b.dart').create(); await fs.file('b.dart').create();
......
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