[flutter_tools] remove globals from depfile usage (#50710)
This commit is contained in:
parent
8769f94cf6
commit
9431229e4c
@ -2,22 +2,54 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import '../base/file_system.dart';
|
import 'package:meta/meta.dart';
|
||||||
import '../globals.dart' as globals;
|
import 'package:platform/platform.dart';
|
||||||
|
|
||||||
/// A class for representing depfile formats.
|
import '../base/file_system.dart';
|
||||||
class Depfile {
|
import '../base/logger.dart';
|
||||||
/// Create a [Depfile] from a list of [input] files and [output] files.
|
|
||||||
const Depfile(this.inputs, this.outputs);
|
/// A service for creating and parsing [Depfile]s.
|
||||||
|
class DepfileService {
|
||||||
|
DepfileService({
|
||||||
|
@required Logger logger,
|
||||||
|
@required FileSystem fileSystem,
|
||||||
|
@required Platform platform,
|
||||||
|
}) : _logger = logger,
|
||||||
|
_fileSystem = fileSystem,
|
||||||
|
_platform = platform;
|
||||||
|
|
||||||
|
final Logger _logger;
|
||||||
|
final FileSystem _fileSystem;
|
||||||
|
final Platform _platform;
|
||||||
|
static final RegExp _separatorExpr = RegExp(r'([^\\]) ');
|
||||||
|
static final RegExp _escapeExpr = RegExp(r'\\(.)');
|
||||||
|
|
||||||
|
/// Given an [depfile] File, write the depfile contents.
|
||||||
|
///
|
||||||
|
/// If either [inputs] or [outputs] is empty, ensures the file does not
|
||||||
|
/// exist.
|
||||||
|
void writeToFile(Depfile depfile, File output) {
|
||||||
|
if (depfile.inputs.isEmpty || depfile.outputs.isEmpty) {
|
||||||
|
if (output.existsSync()) {
|
||||||
|
output.deleteSync();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final StringBuffer buffer = StringBuffer();
|
||||||
|
_writeFilesToBuffer(depfile.outputs, buffer);
|
||||||
|
buffer.write(': ');
|
||||||
|
_writeFilesToBuffer(depfile.inputs, buffer);
|
||||||
|
output.writeAsStringSync(buffer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse the depfile contents from [file].
|
/// Parse the depfile contents from [file].
|
||||||
///
|
///
|
||||||
/// If the syntax is invalid, returns an empty [Depfile].
|
/// If the syntax is invalid, returns an empty [Depfile].
|
||||||
factory Depfile.parse(File file) {
|
Depfile parse(File file) {
|
||||||
final String contents = file.readAsStringSync();
|
final String contents = file.readAsStringSync();
|
||||||
final List<String> colonSeparated = contents.split(': ');
|
final List<String> colonSeparated = contents.split(': ');
|
||||||
if (colonSeparated.length != 2) {
|
if (colonSeparated.length != 2) {
|
||||||
globals.printError('Invalid depfile: ${file.path}');
|
_logger.printError('Invalid depfile: ${file.path}');
|
||||||
return const Depfile(<File>[], <File>[]);
|
return const Depfile(<File>[], <File>[]);
|
||||||
}
|
}
|
||||||
final List<File> inputs = _processList(colonSeparated[1].trim());
|
final List<File> inputs = _processList(colonSeparated[1].trim());
|
||||||
@ -25,11 +57,12 @@ class Depfile {
|
|||||||
return Depfile(inputs, outputs);
|
return Depfile(inputs, outputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Parse the output of dart2js's used dependencies.
|
/// Parse the output of dart2js's used dependencies.
|
||||||
///
|
///
|
||||||
/// The [file] contains a list of newline separated file URIs. The output
|
/// The [file] contains a list of newline separated file URIs. The output
|
||||||
/// file must be manually specified.
|
/// file must be manually specified.
|
||||||
factory Depfile.parseDart2js(File file, File output) {
|
Depfile parseDart2js(File file, File output) {
|
||||||
final List<File> inputs = <File>[];
|
final List<File> inputs = <File>[];
|
||||||
for (final String rawUri in file.readAsLinesSync()) {
|
for (final String rawUri in file.readAsLinesSync()) {
|
||||||
if (rawUri.trim().isEmpty) {
|
if (rawUri.trim().isEmpty) {
|
||||||
@ -42,38 +75,14 @@ class Depfile {
|
|||||||
if (fileUri.scheme != 'file') {
|
if (fileUri.scheme != 'file') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
inputs.add(globals.fs.file(fileUri));
|
inputs.add(_fileSystem.file(fileUri));
|
||||||
}
|
}
|
||||||
return Depfile(inputs, <File>[output]);
|
return Depfile(inputs, <File>[output]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The input files for this depfile.
|
|
||||||
final List<File> inputs;
|
|
||||||
|
|
||||||
/// The output files for this depfile.
|
|
||||||
final List<File> outputs;
|
|
||||||
|
|
||||||
/// Given an [depfile] File, write the depfile contents.
|
|
||||||
///
|
|
||||||
/// If either [inputs] or [outputs] is empty, ensures the file does not
|
|
||||||
/// exist.
|
|
||||||
void writeToFile(File depfile) {
|
|
||||||
if (inputs.isEmpty || outputs.isEmpty) {
|
|
||||||
if (depfile.existsSync()) {
|
|
||||||
depfile.deleteSync();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final StringBuffer buffer = StringBuffer();
|
|
||||||
_writeFilesToBuffer(outputs, buffer);
|
|
||||||
buffer.write(': ');
|
|
||||||
_writeFilesToBuffer(inputs, buffer);
|
|
||||||
depfile.writeAsStringSync(buffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void _writeFilesToBuffer(List<File> files, StringBuffer buffer) {
|
void _writeFilesToBuffer(List<File> files, StringBuffer buffer) {
|
||||||
for (final File outputFile in files) {
|
for (final File outputFile in files) {
|
||||||
if (globals.platform.isWindows) {
|
if (_platform.isWindows) {
|
||||||
// Foward slashes and spaces in a depfile have to be escaped on windows.
|
// Foward slashes and spaces in a depfile have to be escaped on windows.
|
||||||
final String path = outputFile.path
|
final String path = outputFile.path
|
||||||
.replaceAll(r'\', r'\\')
|
.replaceAll(r'\', r'\\')
|
||||||
@ -87,10 +96,7 @@ class Depfile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final RegExp _separatorExpr = RegExp(r'([^\\]) ');
|
List<File> _processList(String rawText) {
|
||||||
static final RegExp _escapeExpr = RegExp(r'\\(.)');
|
|
||||||
|
|
||||||
static List<File> _processList(String rawText) {
|
|
||||||
return rawText
|
return rawText
|
||||||
// Put every file on right-hand side on the separate line
|
// Put every file on right-hand side on the separate line
|
||||||
.replaceAllMapped(_separatorExpr, (Match match) => '${match.group(1)}\n')
|
.replaceAllMapped(_separatorExpr, (Match match) => '${match.group(1)}\n')
|
||||||
@ -101,7 +107,19 @@ class Depfile {
|
|||||||
// The tool doesn't write duplicates to these lists. This call is an attempt to
|
// The tool doesn't write duplicates to these lists. This call is an attempt to
|
||||||
// be resillient to the outputs of other tools which write or user edits to depfiles.
|
// be resillient to the outputs of other tools which write or user edits to depfiles.
|
||||||
.toSet()
|
.toSet()
|
||||||
.map((String path) => globals.fs.file(path))
|
.map(_fileSystem.file)
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A class for representing depfile formats.
|
||||||
|
class Depfile {
|
||||||
|
/// Create a [Depfile] from a list of [input] files and [output] files.
|
||||||
|
const Depfile(this.inputs, this.outputs);
|
||||||
|
|
||||||
|
/// The input files for this depfile.
|
||||||
|
final List<File> inputs;
|
||||||
|
|
||||||
|
/// The output files for this depfile.
|
||||||
|
final List<File> outputs;
|
||||||
|
}
|
||||||
|
@ -63,7 +63,15 @@ abstract class AndroidAssetBundle extends Target {
|
|||||||
}
|
}
|
||||||
if (_copyAssets) {
|
if (_copyAssets) {
|
||||||
final Depfile assetDepfile = await copyAssets(environment, outputDirectory);
|
final Depfile assetDepfile = await copyAssets(environment, outputDirectory);
|
||||||
assetDepfile.writeToFile(environment.buildDir.childFile('flutter_assets.d'));
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
depfileService.writeToFile(
|
||||||
|
assetDepfile,
|
||||||
|
environment.buildDir.childFile('flutter_assets.d'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,15 @@ class CopyAssets extends Target {
|
|||||||
.childDirectory('flutter_assets');
|
.childDirectory('flutter_assets');
|
||||||
output.createSync(recursive: true);
|
output.createSync(recursive: true);
|
||||||
final Depfile depfile = await copyAssets(environment, output);
|
final Depfile depfile = await copyAssets(environment, output);
|
||||||
depfile.writeToFile(environment.buildDir.childFile('flutter_assets.d'));
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
depfileService.writeToFile(
|
||||||
|
depfile,
|
||||||
|
environment.buildDir.childFile('flutter_assets.d'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,15 @@ class CopyFlutterBundle extends Target {
|
|||||||
.copySync(environment.outputDir.childFile('isolate_snapshot_data').path);
|
.copySync(environment.outputDir.childFile('isolate_snapshot_data').path);
|
||||||
}
|
}
|
||||||
final Depfile assetDepfile = await copyAssets(environment, environment.outputDir);
|
final Depfile assetDepfile = await copyAssets(environment, environment.outputDir);
|
||||||
assetDepfile.writeToFile(environment.buildDir.childFile('flutter_assets.d'));
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
depfileService.writeToFile(
|
||||||
|
assetDepfile,
|
||||||
|
environment.buildDir.childFile('flutter_assets.d'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -284,7 +284,15 @@ abstract class IosAssetBundle extends Target {
|
|||||||
|
|
||||||
// Copy the assets.
|
// Copy the assets.
|
||||||
final Depfile assetDepfile = await copyAssets(environment, assetDirectory);
|
final Depfile assetDepfile = await copyAssets(environment, assetDirectory);
|
||||||
assetDepfile.writeToFile(environment.buildDir.childFile('flutter_assets.d'));
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
depfileService.writeToFile(
|
||||||
|
assetDepfile,
|
||||||
|
environment.buildDir.childFile('flutter_assets.d'),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Copy the plist from either the project or module.
|
// Copy the plist from either the project or module.
|
||||||
|
@ -98,7 +98,15 @@ class UnpackLinuxDebug extends Target {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Depfile depfile = Depfile(inputs, outputs);
|
final Depfile depfile = Depfile(inputs, outputs);
|
||||||
depfile.writeToFile(environment.buildDir.childFile('linux_engine_sources.d'));
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
depfileService.writeToFile(
|
||||||
|
depfile,
|
||||||
|
environment.buildDir.childFile('linux_engine_sources.d'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,6 +159,14 @@ class DebugBundleLinuxAssets extends Target {
|
|||||||
.copySync(outputDirectory.childFile('kernel_blob.bin').path);
|
.copySync(outputDirectory.childFile('kernel_blob.bin').path);
|
||||||
}
|
}
|
||||||
final Depfile depfile = await copyAssets(environment, outputDirectory);
|
final Depfile depfile = await copyAssets(environment, outputDirectory);
|
||||||
depfile.writeToFile(environment.buildDir.childFile('flutter_assets.d'));
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
depfileService.writeToFile(
|
||||||
|
depfile,
|
||||||
|
environment.buildDir.childFile('flutter_assets.d'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,15 @@ abstract class MacOSBundleFlutterAssets extends Target {
|
|||||||
.childDirectory('flutter_assets');
|
.childDirectory('flutter_assets');
|
||||||
assetDirectory.createSync(recursive: true);
|
assetDirectory.createSync(recursive: true);
|
||||||
final Depfile depfile = await copyAssets(environment, assetDirectory);
|
final Depfile depfile = await copyAssets(environment, assetDirectory);
|
||||||
depfile.writeToFile(environment.buildDir.childFile('flutter_assets.d'));
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
depfileService.writeToFile(
|
||||||
|
depfile,
|
||||||
|
environment.buildDir.childFile('flutter_assets.d'),
|
||||||
|
);
|
||||||
|
|
||||||
// Copy Info.plist template.
|
// Copy Info.plist template.
|
||||||
assetDirectory.parent.childFile('Info.plist')
|
assetDirectory.parent.childFile('Info.plist')
|
||||||
|
@ -191,11 +191,19 @@ class Dart2JSTarget extends Target {
|
|||||||
'${dart2jsDeps.path}');
|
'${dart2jsDeps.path}');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Depfile depfile = Depfile.parseDart2js(
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
final Depfile depfile = depfileService.parseDart2js(
|
||||||
environment.buildDir.childFile('main.dart.js.deps'),
|
environment.buildDir.childFile('main.dart.js.deps'),
|
||||||
outputFile,
|
outputFile,
|
||||||
);
|
);
|
||||||
depfile.writeToFile(environment.buildDir.childFile('dart2js.d'));
|
depfileService.writeToFile(
|
||||||
|
depfile,
|
||||||
|
environment.buildDir.childFile('dart2js.d'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +255,15 @@ class WebReleaseBundle extends Target {
|
|||||||
final Directory outputDirectory = environment.outputDir.childDirectory('assets');
|
final Directory outputDirectory = environment.outputDir.childDirectory('assets');
|
||||||
outputDirectory.createSync(recursive: true);
|
outputDirectory.createSync(recursive: true);
|
||||||
final Depfile depfile = await copyAssets(environment, environment.outputDir.childDirectory('assets'));
|
final Depfile depfile = await copyAssets(environment, environment.outputDir.childDirectory('assets'));
|
||||||
depfile.writeToFile(environment.buildDir.childFile('flutter_assets.d'));
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
depfileService.writeToFile(
|
||||||
|
depfile,
|
||||||
|
environment.buildDir.childFile('flutter_assets.d'),
|
||||||
|
);
|
||||||
|
|
||||||
final Directory webResources = environment.projectDir
|
final Directory webResources = environment.projectDir
|
||||||
.childDirectory('web');
|
.childDirectory('web');
|
||||||
@ -269,8 +285,10 @@ class WebReleaseBundle extends Target {
|
|||||||
outputResourcesFiles.add(outputFile);
|
outputResourcesFiles.add(outputFile);
|
||||||
}
|
}
|
||||||
final Depfile resourceFile = Depfile(inputResourceFiles, outputResourcesFiles);
|
final Depfile resourceFile = Depfile(inputResourceFiles, outputResourcesFiles);
|
||||||
resourceFile.writeToFile(environment.buildDir.childFile('web_resources.d'));
|
depfileService.writeToFile(
|
||||||
|
resourceFile,
|
||||||
|
environment.buildDir.childFile('web_resources.d'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +338,15 @@ class WebServiceWorker extends Target {
|
|||||||
final String serviceWorker = generateServiceWorker(uriToHash);
|
final String serviceWorker = generateServiceWorker(uriToHash);
|
||||||
serviceWorkerFile
|
serviceWorkerFile
|
||||||
.writeAsStringSync(serviceWorker);
|
.writeAsStringSync(serviceWorker);
|
||||||
depfile.writeToFile(environment.buildDir.childFile('service_worker.d'));
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
depfileService.writeToFile(
|
||||||
|
depfile,
|
||||||
|
environment.buildDir.childFile('service_worker.d'),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,12 @@ Future<void> buildWithAssemble({
|
|||||||
if (!outputDepfile.parent.existsSync()) {
|
if (!outputDepfile.parent.existsSync()) {
|
||||||
outputDepfile.parent.createSync(recursive: true);
|
outputDepfile.parent.createSync(recursive: true);
|
||||||
}
|
}
|
||||||
depfile.writeToFile(outputDepfile);
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
depfileService.writeToFile(depfile, outputDepfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +202,12 @@ class AssembleCommand extends FlutterCommand {
|
|||||||
if (argResults.wasParsed('depfile')) {
|
if (argResults.wasParsed('depfile')) {
|
||||||
final File depfileFile = globals.fs.file(stringArg('depfile'));
|
final File depfileFile = globals.fs.file(stringArg('depfile'));
|
||||||
final Depfile depfile = Depfile(result.inputFiles, result.outputFiles);
|
final Depfile depfile = Depfile(result.inputFiles, result.outputFiles);
|
||||||
depfile.writeToFile(globals.fs.file(depfileFile));
|
final DepfileService depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
|
depfileService.writeToFile(depfile, globals.fs.file(depfileFile));
|
||||||
}
|
}
|
||||||
return FlutterCommandResult.success();
|
return FlutterCommandResult.success();
|
||||||
}
|
}
|
||||||
|
@ -4,34 +4,40 @@
|
|||||||
|
|
||||||
import 'package:file/memory.dart';
|
import 'package:file/memory.dart';
|
||||||
import 'package:flutter_tools/src/base/file_system.dart';
|
import 'package:flutter_tools/src/base/file_system.dart';
|
||||||
|
import 'package:flutter_tools/src/base/logger.dart';
|
||||||
import 'package:flutter_tools/src/build_system/depfile.dart';
|
import 'package:flutter_tools/src/build_system/depfile.dart';
|
||||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
import 'package:mockito/mockito.dart';
|
||||||
import 'package:platform/platform.dart';
|
import 'package:platform/platform.dart';
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
import '../../src/testbed.dart';
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
Testbed testbed;
|
FileSystem fileSystem;
|
||||||
|
DepfileService depfileService;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
testbed = Testbed();
|
fileSystem = MemoryFileSystem.test();
|
||||||
|
depfileService = DepfileService(
|
||||||
|
logger: MockLogger(),
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
platform: FakePlatform(operatingSystem: 'linux'),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
test('Can parse depfile from file', () => testbed.run(() {
|
testWithoutContext('Can parse depfile from file', () {
|
||||||
final File depfileSource = globals.fs.file('example.d')..writeAsStringSync('''
|
final File depfileSource = fileSystem.file('example.d')..writeAsStringSync('''
|
||||||
a.txt: b.txt
|
a.txt: b.txt
|
||||||
''');
|
''');
|
||||||
final Depfile depfile = Depfile.parse(depfileSource);
|
final Depfile depfile = depfileService.parse(depfileSource);
|
||||||
|
|
||||||
expect(depfile.inputs.single.path, 'b.txt');
|
expect(depfile.inputs.single.path, 'b.txt');
|
||||||
expect(depfile.outputs.single.path, 'a.txt');
|
expect(depfile.outputs.single.path, 'a.txt');
|
||||||
}));
|
});
|
||||||
|
|
||||||
test('Can parse depfile with multiple inputs', () => testbed.run(() {
|
testWithoutContext('Can parse depfile with multiple inputs', () {
|
||||||
final File depfileSource = globals.fs.file('example.d')..writeAsStringSync('''
|
final File depfileSource = fileSystem.file('example.d')..writeAsStringSync('''
|
||||||
a.txt: b.txt c.txt d.txt
|
a.txt: b.txt c.txt d.txt
|
||||||
''');
|
''');
|
||||||
final Depfile depfile = Depfile.parse(depfileSource);
|
final Depfile depfile = depfileService.parse(depfileSource);
|
||||||
|
|
||||||
expect(depfile.inputs.map((File file) => file.path), <String>[
|
expect(depfile.inputs.map((File file) => file.path), <String>[
|
||||||
'b.txt',
|
'b.txt',
|
||||||
@ -39,13 +45,13 @@ a.txt: b.txt c.txt d.txt
|
|||||||
'd.txt',
|
'd.txt',
|
||||||
]);
|
]);
|
||||||
expect(depfile.outputs.single.path, 'a.txt');
|
expect(depfile.outputs.single.path, 'a.txt');
|
||||||
}));
|
});
|
||||||
|
|
||||||
test('Can parse depfile with multiple outputs', () => testbed.run(() {
|
testWithoutContext('Can parse depfile with multiple outputs', () {
|
||||||
final File depfileSource = globals.fs.file('example.d')..writeAsStringSync('''
|
final File depfileSource = fileSystem.file('example.d')..writeAsStringSync('''
|
||||||
a.txt c.txt d.txt: b.txt
|
a.txt c.txt d.txt: b.txt
|
||||||
''');
|
''');
|
||||||
final Depfile depfile = Depfile.parse(depfileSource);
|
final Depfile depfile = depfileService.parse(depfileSource);
|
||||||
|
|
||||||
expect(depfile.inputs.single.path, 'b.txt');
|
expect(depfile.inputs.single.path, 'b.txt');
|
||||||
expect(depfile.outputs.map((File file) => file.path), <String>[
|
expect(depfile.outputs.map((File file) => file.path), <String>[
|
||||||
@ -53,120 +59,122 @@ a.txt c.txt d.txt: b.txt
|
|||||||
'c.txt',
|
'c.txt',
|
||||||
'd.txt',
|
'd.txt',
|
||||||
]);
|
]);
|
||||||
}));
|
});
|
||||||
|
|
||||||
test('Can parse depfile with windows file paths', () => testbed.run(() {
|
testWithoutContext('Can parse depfile with windows file paths', () {
|
||||||
final File depfileSource = globals.fs.file('example.d')..writeAsStringSync(r'''
|
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
|
||||||
|
depfileService = DepfileService(
|
||||||
|
logger: MockLogger(),
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
platform: FakePlatform(operatingSystem: 'windows'),
|
||||||
|
);
|
||||||
|
final File depfileSource = fileSystem.file('example.d')..writeAsStringSync(r'''
|
||||||
C:\\a.txt: C:\\b.txt
|
C:\\a.txt: C:\\b.txt
|
||||||
''');
|
''');
|
||||||
final Depfile depfile = Depfile.parse(depfileSource);
|
final Depfile depfile = depfileService.parse(depfileSource);
|
||||||
|
|
||||||
expect(depfile.inputs.single.path, r'C:\b.txt');
|
expect(depfile.inputs.single.path, r'C:\b.txt');
|
||||||
expect(depfile.outputs.single.path, r'C:\a.txt');
|
expect(depfile.outputs.single.path, r'C:\a.txt');
|
||||||
}, overrides: <Type, Generator>{
|
});
|
||||||
FileSystem: () => MemoryFileSystem(style: FileSystemStyle.windows),
|
|
||||||
}));
|
|
||||||
|
|
||||||
test('Can escape depfile with windows file paths and spaces in directory names', () => testbed.run(() {
|
testWithoutContext('Can escape depfile with windows file paths and spaces in directory names', () {
|
||||||
final File inputFile = globals.fs.directory(r'Hello Flutter').childFile('a.txt').absolute
|
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
|
||||||
|
depfileService = DepfileService(
|
||||||
|
logger: MockLogger(),
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
platform: FakePlatform(operatingSystem: 'windows'),
|
||||||
|
);
|
||||||
|
final File inputFile = fileSystem.directory(r'Hello Flutter').childFile('a.txt').absolute
|
||||||
..createSync(recursive: true);
|
..createSync(recursive: true);
|
||||||
final File outputFile = globals.fs.directory(r'Hello Flutter').childFile('b.txt').absolute
|
final File outputFile = fileSystem.directory(r'Hello Flutter').childFile('b.txt').absolute
|
||||||
..createSync();
|
..createSync();
|
||||||
final Depfile depfile = Depfile(<File>[inputFile], <File>[outputFile]);
|
final Depfile depfile = Depfile(<File>[inputFile], <File>[outputFile]);
|
||||||
final File outputDepfile = globals.fs.file('depfile');
|
final File outputDepfile = fileSystem.file('depfile');
|
||||||
depfile.writeToFile(outputDepfile);
|
depfileService.writeToFile(depfile, outputDepfile);
|
||||||
|
|
||||||
expect(outputDepfile.readAsStringSync(), contains(r'C:\\Hello\ Flutter\\a.txt'));
|
expect(outputDepfile.readAsStringSync(), contains(r'C:\\Hello\ Flutter\\a.txt'));
|
||||||
expect(outputDepfile.readAsStringSync(), contains(r'C:\\Hello\ Flutter\\b.txt'));
|
expect(outputDepfile.readAsStringSync(), contains(r'C:\\Hello\ Flutter\\b.txt'));
|
||||||
}, overrides: <Type, Generator>{
|
});
|
||||||
FileSystem: () => MemoryFileSystem(style: FileSystemStyle.windows),
|
|
||||||
Platform: () => FakePlatform(operatingSystem: 'windows'),
|
|
||||||
}));
|
|
||||||
|
|
||||||
test('Can escape depfile with spaces in directory names', () => testbed.run(() {
|
testWithoutContext('Can escape depfile with spaces in directory names', () {
|
||||||
final File inputFile = globals.fs.directory(r'Hello Flutter').childFile('a.txt').absolute
|
final File inputFile = fileSystem.directory(r'Hello Flutter').childFile('a.txt').absolute
|
||||||
..createSync(recursive: true);
|
..createSync(recursive: true);
|
||||||
final File outputFile = globals.fs.directory(r'Hello Flutter').childFile('b.txt').absolute
|
final File outputFile = fileSystem.directory(r'Hello Flutter').childFile('b.txt').absolute
|
||||||
..createSync();
|
..createSync();
|
||||||
final Depfile depfile = Depfile(<File>[inputFile], <File>[outputFile]);
|
final Depfile depfile = Depfile(<File>[inputFile], <File>[outputFile]);
|
||||||
final File outputDepfile = globals.fs.file('depfile');
|
final File outputDepfile = fileSystem.file('depfile');
|
||||||
depfile.writeToFile(outputDepfile);
|
depfileService.writeToFile(depfile, outputDepfile);
|
||||||
|
|
||||||
expect(outputDepfile.readAsStringSync(), contains(r'/Hello\ Flutter/a.txt'));
|
expect(outputDepfile.readAsStringSync(), contains(r'/Hello\ Flutter/a.txt'));
|
||||||
expect(outputDepfile.readAsStringSync(), contains(r'/Hello\ Flutter/b.txt'));
|
expect(outputDepfile.readAsStringSync(), contains(r'/Hello\ Flutter/b.txt'));
|
||||||
}, overrides: <Type, Generator>{
|
});
|
||||||
FileSystem: () => MemoryFileSystem(style: FileSystemStyle.posix),
|
|
||||||
Platform: () => FakePlatform(operatingSystem: 'linux'),
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
test('Resillient to weird whitespace', () => testbed.run(() {
|
testWithoutContext('Resillient to weird whitespace', () {
|
||||||
final File depfileSource = globals.fs.file('example.d')..writeAsStringSync(r'''
|
final File depfileSource = fileSystem.file('example.d')..writeAsStringSync(r'''
|
||||||
a.txt
|
a.txt
|
||||||
: b.txt c.txt
|
: b.txt c.txt
|
||||||
|
|
||||||
|
|
||||||
''');
|
''');
|
||||||
final Depfile depfile = Depfile.parse(depfileSource);
|
final Depfile depfile = depfileService.parse(depfileSource);
|
||||||
|
|
||||||
expect(depfile.inputs, hasLength(2));
|
expect(depfile.inputs, hasLength(2));
|
||||||
expect(depfile.outputs.single.path, 'a.txt');
|
expect(depfile.outputs.single.path, 'a.txt');
|
||||||
}));
|
});
|
||||||
|
|
||||||
test('Resillient to duplicate files', () => testbed.run(() {
|
testWithoutContext('Resillient to duplicate files', () {
|
||||||
final File depfileSource = globals.fs.file('example.d')..writeAsStringSync(r'''
|
final File depfileSource = fileSystem.file('example.d')..writeAsStringSync(r'''
|
||||||
a.txt: b.txt b.txt
|
a.txt: b.txt b.txt
|
||||||
''');
|
''');
|
||||||
final Depfile depfile = Depfile.parse(depfileSource);
|
final Depfile depfile = depfileService.parse(depfileSource);
|
||||||
|
|
||||||
expect(depfile.inputs.single.path, 'b.txt');
|
expect(depfile.inputs.single.path, 'b.txt');
|
||||||
expect(depfile.outputs.single.path, 'a.txt');
|
expect(depfile.outputs.single.path, 'a.txt');
|
||||||
}));
|
});
|
||||||
|
|
||||||
test('Resillient to malformed file, missing :', () => testbed.run(() {
|
testWithoutContext('Resillient to malformed file, missing :', () {
|
||||||
final File depfileSource = globals.fs.file('example.d')..writeAsStringSync(r'''
|
final File depfileSource = fileSystem.file('example.d')..writeAsStringSync(r'''
|
||||||
a.text b.txt
|
a.text b.txt
|
||||||
''');
|
''');
|
||||||
final Depfile depfile = Depfile.parse(depfileSource);
|
final Depfile depfile = depfileService.parse(depfileSource);
|
||||||
|
|
||||||
expect(depfile.inputs, isEmpty);
|
expect(depfile.inputs, isEmpty);
|
||||||
expect(depfile.outputs, isEmpty);
|
expect(depfile.outputs, isEmpty);
|
||||||
}));
|
});
|
||||||
|
|
||||||
test('Can parse dart2js output format', () => testbed.run(() {
|
testWithoutContext('Can parse dart2js output format', () {
|
||||||
final File dart2jsDependencyFile = globals.fs.file('main.dart.js.deps')..writeAsStringSync(r'''
|
final File dart2jsDependencyFile = fileSystem.file('main.dart.js.deps')..writeAsStringSync(r'''
|
||||||
file:///Users/foo/collection.dart
|
file:///Users/foo/collection.dart
|
||||||
file:///Users/foo/algorithms.dart
|
file:///Users/foo/algorithms.dart
|
||||||
file:///Users/foo/canonicalized_map.dart
|
file:///Users/foo/canonicalized_map.dart
|
||||||
''');
|
''');
|
||||||
|
|
||||||
final Depfile depfile = Depfile.parseDart2js(dart2jsDependencyFile, globals.fs.file('foo.dart.js'));
|
final Depfile depfile = depfileService.parseDart2js(dart2jsDependencyFile, fileSystem.file('foo.dart.js'));
|
||||||
|
|
||||||
expect(depfile.inputs.map((File file) => file.path), <String>[
|
expect(depfile.inputs.map((File file) => file.path), <String>[
|
||||||
globals.fs.path.absolute(globals.fs.path.join('Users', 'foo', 'collection.dart')),
|
fileSystem.path.absolute(fileSystem.path.join('Users', 'foo', 'collection.dart')),
|
||||||
globals.fs.path.absolute(globals.fs.path.join('Users', 'foo', 'algorithms.dart')),
|
fileSystem.path.absolute(fileSystem.path.join('Users', 'foo', 'algorithms.dart')),
|
||||||
globals.fs.path.absolute(globals.fs.path.join('Users', 'foo', 'canonicalized_map.dart')),
|
fileSystem.path.absolute(fileSystem.path.join('Users', 'foo', 'canonicalized_map.dart')),
|
||||||
]);
|
]);
|
||||||
expect(depfile.outputs.single.path, 'foo.dart.js');
|
expect(depfile.outputs.single.path, 'foo.dart.js');
|
||||||
}, overrides: <Type, Generator>{
|
});
|
||||||
FileSystem: () => MemoryFileSystem(style: FileSystemStyle.posix)
|
|
||||||
}));
|
|
||||||
|
|
||||||
test('Can parse handle invalid uri', () => testbed.run(() {
|
testWithoutContext('Can parse handle invalid uri', () {
|
||||||
final File dart2jsDependencyFile = globals.fs.file('main.dart.js.deps')..writeAsStringSync('''
|
final File dart2jsDependencyFile = fileSystem.file('main.dart.js.deps')..writeAsStringSync('''
|
||||||
file:///Users/foo/collection.dart
|
file:///Users/foo/collection.dart
|
||||||
abcdevf
|
abcdevf
|
||||||
file:///Users/foo/canonicalized_map.dart
|
file:///Users/foo/canonicalized_map.dart
|
||||||
''');
|
''');
|
||||||
|
|
||||||
final Depfile depfile = Depfile.parseDart2js(dart2jsDependencyFile, globals.fs.file('foo.dart.js'));
|
final Depfile depfile = depfileService.parseDart2js(dart2jsDependencyFile, fileSystem.file('foo.dart.js'));
|
||||||
|
|
||||||
expect(depfile.inputs.map((File file) => file.path), <String>[
|
expect(depfile.inputs.map((File file) => file.path), <String>[
|
||||||
globals.fs.path.absolute(globals.fs.path.join('Users', 'foo', 'collection.dart')),
|
fileSystem.path.absolute(fileSystem.path.join('Users', 'foo', 'collection.dart')),
|
||||||
globals.fs.path.absolute(globals.fs.path.join('Users', 'foo', 'canonicalized_map.dart')),
|
fileSystem.path.absolute(fileSystem.path.join('Users', 'foo', 'canonicalized_map.dart')),
|
||||||
]);
|
]);
|
||||||
expect(depfile.outputs.single.path, 'foo.dart.js');
|
expect(depfile.outputs.single.path, 'foo.dart.js');
|
||||||
}, overrides: <Type, Generator>{
|
});
|
||||||
FileSystem: () => MemoryFileSystem(style: FileSystemStyle.posix)
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MockLogger extends Mock implements Logger {}
|
@ -24,6 +24,7 @@ void main() {
|
|||||||
Environment environment;
|
Environment environment;
|
||||||
MockPlatform mockPlatform;
|
MockPlatform mockPlatform;
|
||||||
MockPlatform mockWindowsPlatform;
|
MockPlatform mockWindowsPlatform;
|
||||||
|
DepfileService depfileService;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
mockPlatform = MockPlatform();
|
mockPlatform = MockPlatform();
|
||||||
@ -53,6 +54,11 @@ void main() {
|
|||||||
kTargetFile: globals.fs.path.join('foo', 'lib', 'main.dart'),
|
kTargetFile: globals.fs.path.join('foo', 'lib', 'main.dart'),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
depfileService = DepfileService(
|
||||||
|
fileSystem: globals.fs,
|
||||||
|
logger: globals.logger,
|
||||||
|
platform: globals.platform,
|
||||||
|
);
|
||||||
environment.buildDir.createSync(recursive: true);
|
environment.buildDir.createSync(recursive: true);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Platform: () => mockPlatform,
|
Platform: () => mockPlatform,
|
||||||
@ -315,7 +321,7 @@ void main() {
|
|||||||
await const Dart2JSTarget().build(environment);
|
await const Dart2JSTarget().build(environment);
|
||||||
|
|
||||||
expect(environment.buildDir.childFile('dart2js.d').existsSync(), true);
|
expect(environment.buildDir.childFile('dart2js.d').existsSync(), true);
|
||||||
final Depfile depfile = Depfile.parse(environment.buildDir.childFile('dart2js.d'));
|
final Depfile depfile = depfileService.parse(environment.buildDir.childFile('dart2js.d'));
|
||||||
|
|
||||||
expect(depfile.inputs.single.path, globals.fs.path.absolute('a.dart'));
|
expect(depfile.inputs.single.path, globals.fs.path.absolute('a.dart'));
|
||||||
expect(depfile.outputs.single.path,
|
expect(depfile.outputs.single.path,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user