Commit e6bafd0b authored by Chris Bracken's avatar Chris Bracken Committed by GitHub

Support space- and backslash-escaped dependencies (#11090)

Snapshot dependency files now backslash-escape dependency paths
containing spaces and backslashes.

See: https://codereview.chromium.org/2966903003/
parent 177cf912
...@@ -44,20 +44,27 @@ class Checksum { ...@@ -44,20 +44,27 @@ class Checksum {
int get hashCode => _checksums.hashCode; int get hashCode => _checksums.hashCode;
} }
final RegExp _separatorExpr = new RegExp(r'([^\\]) ');
final RegExp _escapeExpr = new RegExp(r'\\(.)');
/// Parses a VM snapshot dependency file. /// Parses a VM snapshot dependency file.
/// ///
/// Snapshot dependency files are a single line mapping the output snapshot to a /// Snapshot dependency files are a single line mapping the output snapshot to a
/// space-separated list of input files used to generate that output. e.g, /// space-separated list of input files used to generate that output. Spaces and
/// backslashes are escaped with a backslash. e.g,
///
/// outfile : file1.dart fil\\e2.dart fil\ e3.dart
/// ///
/// outfile : file1.dart file2.dart file3.dart /// will return a set containing: 'file1.dart', 'fil\e2.dart', 'fil e3.dart'.
Future<Set<String>> readDepfile(String depfilePath) async { 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
.split(' ') .replaceAllMapped(_separatorExpr, (Match match) => '${match.group(1)}\n')
.map((String path) => path.trim()) .split('\n')
.map((String path) => path.replaceAllMapped(_escapeExpr, (Match match) => match.group(1)).trim())
.where((String path) => path.isNotEmpty) .where((String path) => path.isNotEmpty)
.toSet(); .toSet();
} }
...@@ -64,4 +64,43 @@ void main() { ...@@ -64,4 +64,43 @@ void main() {
}); });
}); });
}); });
group('readDepfile', () {
MemoryFileSystem fs;
setUp(() {
fs = new MemoryFileSystem();
});
testUsingContext('returns one file if only one is listed', () async {
await fs.file('a.d').writeAsString('snapshot.d: /foo/a.dart');
expect(await readDepfile('a.d'), unorderedEquals(<String>['/foo/a.dart']));
}, overrides: <Type, Generator>{ FileSystem: () => fs});
testUsingContext('returns multiple files', () async {
await fs.file('a.d').writeAsString('snapshot.d: /foo/a.dart /foo/b.dart');
expect(await readDepfile('a.d'), unorderedEquals(<String>[
'/foo/a.dart',
'/foo/b.dart',
]));
}, overrides: <Type, Generator>{ FileSystem: () => fs});
testUsingContext('trims extra spaces between files', () async {
await fs.file('a.d').writeAsString('snapshot.d: /foo/a.dart /foo/b.dart /foo/c.dart');
expect(await readDepfile('a.d'), unorderedEquals(<String>[
'/foo/a.dart',
'/foo/b.dart',
'/foo/c.dart',
]));
}, overrides: <Type, Generator>{ FileSystem: () => fs});
testUsingContext('returns files with spaces and backslashes', () async {
await fs.file('a.d').writeAsString(r'snapshot.d: /foo/a\ a.dart /foo/b\\b.dart /foo/c\\ c.dart');
expect(await readDepfile('a.d'), unorderedEquals(<String>[
r'/foo/a a.dart',
r'/foo/b\b.dart',
r'/foo/c\ c.dart',
]));
}, overrides: <Type, Generator>{ FileSystem: () => fs});
});
} }
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