Commit 58438fca authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Provide specific field to accept depfiles in target class (#44481)

* add depfile slot to Target class

* Update source.dart

* Update source.dart
parent d026f2d9
...@@ -123,6 +123,9 @@ abstract class Target { ...@@ -123,6 +123,9 @@ abstract class Target {
/// The output [Source]s which we attempt to verify are correctly produced. /// The output [Source]s which we attempt to verify are correctly produced.
List<Source> get outputs; List<Source> get outputs;
/// A list of zero or more depfiles, located directly under {BUILD_DIR}.
List<String> get depfiles => const <String>[];
/// The action which performs this build step. /// The action which performs this build step.
Future<void> build(Environment environment); Future<void> build(Environment environment);
...@@ -177,7 +180,7 @@ abstract class Target { ...@@ -177,7 +180,7 @@ abstract class Target {
/// Resolve the set of input patterns and functions into a concrete list of /// Resolve the set of input patterns and functions into a concrete list of
/// files. /// files.
ResolvedFiles resolveInputs(Environment environment) { ResolvedFiles resolveInputs(Environment environment) {
return _resolveConfiguration(inputs, environment, implicit: true, inputs: true); return _resolveConfiguration(inputs, depfiles, environment, implicit: true, inputs: true);
} }
/// Find the current set of declared outputs, including wildcard directories. /// Find the current set of declared outputs, including wildcard directories.
...@@ -185,7 +188,7 @@ abstract class Target { ...@@ -185,7 +188,7 @@ abstract class Target {
/// The [implicit] flag controls whether it is safe to evaluate [Source]s /// The [implicit] flag controls whether it is safe to evaluate [Source]s
/// which uses functions, behaviors, or patterns. /// which uses functions, behaviors, or patterns.
ResolvedFiles resolveOutputs(Environment environment) { ResolvedFiles resolveOutputs(Environment environment) {
return _resolveConfiguration(outputs, environment, inputs: false); return _resolveConfiguration(outputs, depfiles, environment, inputs: false);
} }
/// Performs a fold across this target and its dependencies. /// Performs a fold across this target and its dependencies.
...@@ -222,13 +225,14 @@ abstract class Target { ...@@ -222,13 +225,14 @@ abstract class Target {
return environment.buildDir.childFile(fileName); return environment.buildDir.childFile(fileName);
} }
static ResolvedFiles _resolveConfiguration(List<Source> config, Environment environment, { static ResolvedFiles _resolveConfiguration(List<Source> config,
bool implicit = true, bool inputs = true, List<String> depfiles, Environment environment, { bool implicit = true, bool inputs = true,
}) { }) {
final SourceVisitor collector = SourceVisitor(environment, inputs); final SourceVisitor collector = SourceVisitor(environment, inputs);
for (Source source in config) { for (Source source in config) {
source.accept(collector); source.accept(collector);
} }
depfiles.forEach(collector.visitDepfile);
return collector; return collector;
} }
} }
......
...@@ -190,16 +190,6 @@ abstract class Source { ...@@ -190,16 +190,6 @@ abstract class Source {
/// If [artifact] points to a directory then all child files are included. /// If [artifact] points to a directory then all child files are included.
const factory Source.artifact(Artifact artifact, {TargetPlatform platform, BuildMode mode}) = _ArtifactSource; const factory Source.artifact(Artifact artifact, {TargetPlatform platform, BuildMode mode}) = _ArtifactSource;
/// The source is provided by a depfile generated at runtime.
///
/// The `name` is of the file, and is expected to be output relative to the
/// build directory.
///
/// Before the first build, the depfile is expected to be missing. Its
/// absence is interpreted as the build needing to run. Afterwards, both
/// input and output file hashes are updated.
const factory Source.depfile(String name) = _DepfileSource;
/// Visit the particular source type. /// Visit the particular source type.
void accept(SourceVisitor visitor); void accept(SourceVisitor visitor);
...@@ -239,15 +229,3 @@ class _ArtifactSource implements Source { ...@@ -239,15 +229,3 @@ class _ArtifactSource implements Source {
@override @override
bool get implicit => false; bool get implicit => false;
} }
class _DepfileSource implements Source {
const _DepfileSource(this.name);
final String name;
@override
void accept(SourceVisitor visitor) => visitor.visitDepfile(name);
@override
bool get implicit => false;
}
...@@ -24,12 +24,14 @@ abstract class AndroidAssetBundle extends Target { ...@@ -24,12 +24,14 @@ abstract class AndroidAssetBundle extends Target {
@override @override
List<Source> get inputs => const <Source>[ List<Source> get inputs => const <Source>[
Source.pattern('{BUILD_DIR}/app.dill'), Source.pattern('{BUILD_DIR}/app.dill'),
Source.depfile('flutter_assets.d'),
]; ];
@override @override
List<Source> get outputs => const <Source>[ List<Source> get outputs => const <Source>[];
Source.depfile('flutter_assets.d'),
@override
List<String> get depfiles => const <String>[
'flutter_assets.d',
]; ];
@override @override
......
...@@ -64,12 +64,14 @@ class CopyAssets extends Target { ...@@ -64,12 +64,14 @@ class CopyAssets extends Target {
@override @override
List<Source> get inputs => const <Source>[ List<Source> get inputs => const <Source>[
Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/assets.dart'), Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/assets.dart'),
Source.depfile('flutter_assets.d'),
]; ];
@override @override
List<Source> get outputs => const <Source>[ List<Source> get outputs => const <Source>[];
Source.depfile('flutter_assets.d'),
@override
List<String> get depfiles => const <String>[
'flutter_assets.d'
]; ];
@override @override
......
...@@ -75,7 +75,6 @@ class CopyFlutterBundle extends Target { ...@@ -75,7 +75,6 @@ class CopyFlutterBundle extends Target {
Source.artifact(Artifact.vmSnapshotData, mode: BuildMode.debug), Source.artifact(Artifact.vmSnapshotData, mode: BuildMode.debug),
Source.artifact(Artifact.isolateSnapshotData, mode: BuildMode.debug), Source.artifact(Artifact.isolateSnapshotData, mode: BuildMode.debug),
Source.pattern('{BUILD_DIR}/app.dill'), Source.pattern('{BUILD_DIR}/app.dill'),
Source.depfile('flutter_assets.d'),
]; ];
@override @override
...@@ -83,7 +82,11 @@ class CopyFlutterBundle extends Target { ...@@ -83,7 +82,11 @@ class CopyFlutterBundle extends Target {
Source.pattern('{OUTPUT_DIR}/vm_snapshot_data'), Source.pattern('{OUTPUT_DIR}/vm_snapshot_data'),
Source.pattern('{OUTPUT_DIR}/isolate_snapshot_data'), Source.pattern('{OUTPUT_DIR}/isolate_snapshot_data'),
Source.pattern('{OUTPUT_DIR}/kernel_blob.bin'), Source.pattern('{OUTPUT_DIR}/kernel_blob.bin'),
Source.depfile('flutter_assets.d'), ];
@override
List<String> get depfiles => <String>[
'flutter_assets.d'
]; ];
@override @override
...@@ -123,13 +126,14 @@ class ReleaseCopyFlutterBundle extends CopyFlutterBundle { ...@@ -123,13 +126,14 @@ class ReleaseCopyFlutterBundle extends CopyFlutterBundle {
String get name => 'release_flutter_bundle'; String get name => 'release_flutter_bundle';
@override @override
List<Source> get inputs => const <Source>[ List<Source> get inputs => const <Source>[];
Source.depfile('flutter_assets.d'),
];
@override @override
List<Source> get outputs => const <Source>[ List<Source> get outputs => const <Source>[];
Source.depfile('flutter_assets.d'),
@override
List<String> get depfiles => const <String>[
'flutter_assets.d',
]; ];
@override @override
...@@ -151,12 +155,14 @@ class KernelSnapshot extends Target { ...@@ -151,12 +155,14 @@ class KernelSnapshot extends Target {
Source.artifact(Artifact.platformKernelDill), Source.artifact(Artifact.platformKernelDill),
Source.artifact(Artifact.engineDartBinary), Source.artifact(Artifact.engineDartBinary),
Source.artifact(Artifact.frontendServerSnapshotForEngineDartSdk), Source.artifact(Artifact.frontendServerSnapshotForEngineDartSdk),
Source.depfile('kernel_snapshot.d'),
]; ];
@override @override
List<Source> get outputs => const <Source>[ List<Source> get outputs => const <Source>[];
Source.depfile('kernel_snapshot.d'),
@override
List<String> get depfiles => <String>[
'kernel_snapshot.d',
]; ];
@override @override
......
...@@ -33,12 +33,14 @@ class UnpackLinuxDebug extends Target { ...@@ -33,12 +33,14 @@ class UnpackLinuxDebug extends Target {
@override @override
List<Source> get inputs => const <Source>[ List<Source> get inputs => const <Source>[
Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/linux.dart'), Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/linux.dart'),
Source.depfile('linux_engine_sources.d'),
]; ];
@override @override
List<Source> get outputs => const <Source>[ List<Source> get outputs => const <Source>[];
Source.depfile('linux_engine_sources.d'),
@override
List<String> get depfiles => <String>[
'linux_engine_sources.d'
]; ];
@override @override
...@@ -116,16 +118,19 @@ class DebugBundleLinuxAssets extends Target { ...@@ -116,16 +118,19 @@ class DebugBundleLinuxAssets extends Target {
List<Source> get inputs => const <Source>[ List<Source> get inputs => const <Source>[
Source.pattern('{BUILD_DIR}/app.dill'), Source.pattern('{BUILD_DIR}/app.dill'),
Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/linux.dart'), Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/linux.dart'),
Source.depfile('flutter_assets.d'),
Source.pattern('{PROJECT_DIR}/pubspec.yaml'), Source.pattern('{PROJECT_DIR}/pubspec.yaml'),
]; ];
@override @override
List<Source> get outputs => const <Source>[ List<Source> get outputs => const <Source>[
Source.depfile('flutter_assets.d'),
Source.pattern('{OUTPUT_DIR}/flutter_assets/kernel_blob.bin'), Source.pattern('{OUTPUT_DIR}/flutter_assets/kernel_blob.bin'),
]; ];
@override
List<String> get depfiles => const <String>[
'flutter_assets.d',
];
@override @override
Future<void> build(Environment environment) async { Future<void> build(Environment environment) async {
if (environment.defines[kBuildMode] == null) { if (environment.defines[kBuildMode] == null) {
......
...@@ -245,14 +245,17 @@ abstract class MacOSBundleFlutterAssets extends Target { ...@@ -245,14 +245,17 @@ abstract class MacOSBundleFlutterAssets extends Target {
@override @override
List<Source> get inputs => const <Source>[ List<Source> get inputs => const <Source>[
Source.pattern('{BUILD_DIR}/App.framework/App'), Source.pattern('{BUILD_DIR}/App.framework/App'),
Source.depfile('flutter_assets.d'),
]; ];
@override @override
List<Source> get outputs => const <Source>[ List<Source> get outputs => const <Source>[
Source.pattern('{OUTPUT_DIR}/App.framework/Versions/A/App'), Source.pattern('{OUTPUT_DIR}/App.framework/Versions/A/App'),
Source.pattern('{OUTPUT_DIR}/App.framework/Versions/A/Resources/Info.plist'), Source.pattern('{OUTPUT_DIR}/App.framework/Versions/A/Resources/Info.plist'),
Source.depfile('flutter_assets.d'), ];
@override
List<String> get depfiles => const <String>[
'flutter_assets.d',
]; ];
@override @override
......
...@@ -113,12 +113,14 @@ class Dart2JSTarget extends Target { ...@@ -113,12 +113,14 @@ class Dart2JSTarget extends Target {
Source.artifact(Artifact.engineDartBinary), Source.artifact(Artifact.engineDartBinary),
Source.pattern('{BUILD_DIR}/main.dart'), Source.pattern('{BUILD_DIR}/main.dart'),
Source.pattern('{PROJECT_DIR}/.packages'), Source.pattern('{PROJECT_DIR}/.packages'),
Source.depfile('dart2js.d'),
]; ];
@override @override
List<Source> get outputs => const <Source>[ List<Source> get outputs => const <Source>[];
Source.depfile('dart2js.d'),
@override
List<String> get depfiles => const <String>[
'dart2js.d',
]; ];
@override @override
...@@ -187,14 +189,17 @@ class WebReleaseBundle extends Target { ...@@ -187,14 +189,17 @@ class WebReleaseBundle extends Target {
Source.pattern('{BUILD_DIR}/main.dart.js'), Source.pattern('{BUILD_DIR}/main.dart.js'),
Source.pattern('{PROJECT_DIR}/pubspec.yaml'), Source.pattern('{PROJECT_DIR}/pubspec.yaml'),
Source.pattern('{PROJECT_DIR}/web/index.html'), Source.pattern('{PROJECT_DIR}/web/index.html'),
Source.depfile('flutter_assets.d'),
]; ];
@override @override
List<Source> get outputs => const <Source>[ List<Source> get outputs => const <Source>[
Source.pattern('{OUTPUT_DIR}/main.dart.js'), Source.pattern('{OUTPUT_DIR}/main.dart.js'),
Source.pattern('{OUTPUT_DIR}/index.html'), Source.pattern('{OUTPUT_DIR}/index.html'),
Source.depfile('flutter_assets.d'), ];
@override
List<String> get depfiles => const <String>[
'dart2js.d',
]; ];
@override @override
......
...@@ -319,8 +319,7 @@ void main() { ...@@ -319,8 +319,7 @@ void main() {
fs.file('a.txt').writeAsStringSync('a'); fs.file('a.txt').writeAsStringSync('a');
called += 1; called += 1;
}) })
..inputs = const <Source>[Source.depfile('example.d')] ..depfiles = <String>['example.d'];
..outputs = const <Source>[Source.depfile('example.d')];
fs.file('b.txt').writeAsStringSync('b'); fs.file('b.txt').writeAsStringSync('b');
await buildSystem.build(target, environment); await buildSystem.build(target, environment);
...@@ -356,8 +355,7 @@ void main() { ...@@ -356,8 +355,7 @@ void main() {
} }
called += 1; called += 1;
}) })
..inputs = const <Source>[Source.depfile('example.d')] ..depfiles = const <String>['example.d'];
..outputs = const <Source>[Source.depfile('example.d')];
fs.file('b.txt').writeAsStringSync('b'); fs.file('b.txt').writeAsStringSync('b');
await buildSystem.build(target, environment); await buildSystem.build(target, environment);
...@@ -395,6 +393,9 @@ class TestTarget extends Target { ...@@ -395,6 +393,9 @@ class TestTarget extends Target {
@override @override
List<Source> inputs = <Source>[]; List<Source> inputs = <Source>[];
@override
List<String> depfiles = <String>[];
@override @override
String name = 'test'; String name = 'test';
......
...@@ -160,45 +160,41 @@ void main() { ...@@ -160,45 +160,41 @@ void main() {
})); }));
test('can resolve a missing depfile', () => testbed.run(() { test('can resolve a missing depfile', () => testbed.run(() {
const Source depfile = Source.depfile('foo.d'); visitor.visitDepfile('foo.d');
depfile.accept(visitor);
expect(visitor.sources, isEmpty); expect(visitor.sources, isEmpty);
expect(visitor.containsNewDepfile, true); expect(visitor.containsNewDepfile, true);
})); }));
test('can resolve a populated depfile', () => testbed.run(() { test('can resolve a populated depfile', () => testbed.run(() {
const Source depfile = Source.depfile('foo.d');
environment.buildDir.childFile('foo.d') environment.buildDir.childFile('foo.d')
.writeAsStringSync('a.dart : c.dart'); .writeAsStringSync('a.dart : c.dart');
depfile.accept(visitor); visitor.visitDepfile('foo.d');
expect(visitor.sources.single.path, 'c.dart'); expect(visitor.sources.single.path, 'c.dart');
expect(visitor.containsNewDepfile, false); expect(visitor.containsNewDepfile, false);
final SourceVisitor outputVisitor = SourceVisitor(environment, false); final SourceVisitor outputVisitor = SourceVisitor(environment, false);
depfile.accept(outputVisitor); outputVisitor.visitDepfile('foo.d');
expect(outputVisitor.sources.single.path, 'a.dart'); expect(outputVisitor.sources.single.path, 'a.dart');
expect(outputVisitor.containsNewDepfile, false); expect(outputVisitor.containsNewDepfile, false);
})); }));
test('does not crash on completely invalid depfile', () => testbed.run(() { test('does not crash on completely invalid depfile', () => testbed.run(() {
const Source depfile = Source.depfile('foo.d');
environment.buildDir.childFile('foo.d') environment.buildDir.childFile('foo.d')
.writeAsStringSync('hello, world'); .writeAsStringSync('hello, world');
depfile.accept(visitor); visitor.visitDepfile('foo.d');
expect(visitor.sources, isEmpty); expect(visitor.sources, isEmpty);
expect(visitor.containsNewDepfile, false); expect(visitor.containsNewDepfile, false);
})); }));
test('can parse depfile with windows paths', () => testbed.run(() { test('can parse depfile with windows paths', () => testbed.run(() {
const Source depfile = Source.depfile('foo.d');
environment.buildDir.childFile('foo.d') environment.buildDir.childFile('foo.d')
.writeAsStringSync(r'a.dart: C:\\foo\\bar.txt'); .writeAsStringSync(r'a.dart: C:\\foo\\bar.txt');
depfile.accept(visitor); visitor.visitDepfile('foo.d');
expect(visitor.sources.single.path, r'C:\foo\bar.txt'); expect(visitor.sources.single.path, r'C:\foo\bar.txt');
expect(visitor.containsNewDepfile, false); expect(visitor.containsNewDepfile, false);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -206,11 +202,10 @@ void main() { ...@@ -206,11 +202,10 @@ void main() {
})); }));
test('can parse depfile with spaces in paths', () => testbed.run(() { test('can parse depfile with spaces in paths', () => testbed.run(() {
const Source depfile = Source.depfile('foo.d');
environment.buildDir.childFile('foo.d') environment.buildDir.childFile('foo.d')
.writeAsStringSync(r'a.dart: foo\ bar.txt'); .writeAsStringSync(r'a.dart: foo\ bar.txt');
depfile.accept(visitor); visitor.visitDepfile('foo.d');
expect(visitor.sources.single.path, r'foo bar.txt'); expect(visitor.sources.single.path, r'foo bar.txt');
expect(visitor.containsNewDepfile, false); expect(visitor.containsNewDepfile, false);
})); }));
......
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