From f512ebfd06b1b950a600e3648d342d3a84396ba2 Mon Sep 17 00:00:00 2001 From: Jay Zhuang Date: Tue, 18 May 2021 23:24:04 -0400 Subject: [PATCH] [fuchsia_asset_builder] Write depfile (#82469) --- .../bin/fuchsia_asset_builder.dart | 24 +++++++++++++++- packages/flutter_tools/lib/src/asset.dart | 12 +++++++- .../test/general.shard/asset_test.dart | 28 +++++++++++++++++-- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/packages/flutter_tools/bin/fuchsia_asset_builder.dart b/packages/flutter_tools/bin/fuchsia_asset_builder.dart index 86b620e13c4..574daa0a8bd 100644 --- a/packages/flutter_tools/bin/fuchsia_asset_builder.dart +++ b/packages/flutter_tools/bin/fuchsia_asset_builder.dart @@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/context.dart'; import 'package:flutter_tools/src/base/file_system.dart' as libfs; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/build_info.dart'; +import 'package:flutter_tools/src/build_system/depfile.dart'; import 'package:flutter_tools/src/bundle.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/context_runner.dart'; @@ -22,6 +23,7 @@ const String _kOptionAsset = 'asset-dir'; const String _kOptionManifest = 'manifest'; const String _kOptionAssetManifestOut = 'asset-manifest-out'; const String _kOptionComponentName = 'component-name'; +const String _kOptionDepfile = 'depfile'; const List _kRequiredOptions = [ _kOptionPackages, _kOptionAsset, @@ -48,7 +50,8 @@ Future run(List args) async { help: 'The directory where to put temporary files') ..addOption(_kOptionManifest, help: 'The manifest file') ..addOption(_kOptionAssetManifestOut) - ..addOption(_kOptionComponentName); + ..addOption(_kOptionComponentName) + ..addOption(_kOptionDepfile); final ArgResults argResults = parser.parse(args); if (_kRequiredOptions .any((String option) => !argResults.options.contains(option))) { @@ -79,6 +82,25 @@ Future run(List args) async { final String outputMan = argResults[_kOptionAssetManifestOut] as String; await writeFuchsiaManifest(assets, argResults[_kOptionAsset] as String, outputMan, argResults[_kOptionComponentName] as String); + + if (argResults.options.contains(_kOptionDepfile)) { + await writeDepfile(assets, outputMan, argResults[_kOptionDepfile] as String); + } +} + +Future writeDepfile(AssetBundle assets, String outputManifest, String depfilePath) async { + final Depfile depfileContent = Depfile( + assets.inputFiles, + [globals.fs.file(outputManifest)], + ); + final DepfileService depfileService = DepfileService( + fileSystem: globals.fs, + logger: globals.logger, + ); + + final libfs.File depfile = globals.fs.file(depfilePath); + await depfile.create(recursive: true); + depfileService.writeToFile(depfileContent, depfile); } Future writeFuchsiaManifest(AssetBundle assets, String outputBase, String fileDest, String componentName) async { diff --git a/packages/flutter_tools/lib/src/asset.dart b/packages/flutter_tools/lib/src/asset.dart index c11234c4d4e..d195dce426e 100644 --- a/packages/flutter_tools/lib/src/asset.dart +++ b/packages/flutter_tools/lib/src/asset.dart @@ -72,6 +72,9 @@ abstract class AssetBundle { /// output result. List get additionalDependencies; + /// Input files used to build this asset bundle. + List get inputFiles; + bool wasBuiltOnce(); bool needsBuild({ String manifestPath = defaultManifestPath }); @@ -133,6 +136,9 @@ class ManifestAssetBundle implements AssetBundle { @override final Map> deferredComponentsEntries = >{}; + @override + final List inputFiles = []; + // If an asset corresponds to a wildcard directory, then it may have been // updated without changes to the manifest. These are only tracked for // the current project. @@ -213,8 +219,10 @@ class ManifestAssetBundle implements AssetBundle { } final String assetBasePath = _fileSystem.path.dirname(_fileSystem.path.absolute(manifestPath)); + final File packageConfigFile = _fileSystem.file(packagesPath); + inputFiles.add(packageConfigFile); final PackageConfig packageConfig = await loadPackageConfigWithLogging( - _fileSystem.file(packagesPath), + packageConfigFile, logger: _logger, ); final List wildcardDirectories = []; @@ -279,6 +287,7 @@ class ManifestAssetBundle implements AssetBundle { final Uri packageUri = package.packageUriRoot; if (packageUri != null && packageUri.scheme == 'file') { final String packageManifestPath = _fileSystem.path.fromUri(packageUri.resolve('../pubspec.yaml')); + inputFiles.add(_fileSystem.file(packageManifestPath)); final FlutterManifest packageFlutterManifest = FlutterManifest.createFromPath( packageManifestPath, logger: _logger, @@ -417,6 +426,7 @@ class ManifestAssetBundle implements AssetBundle { } additionalDependencies = licenseResult.dependencies; + inputFiles.addAll(additionalDependencies); if (wildcardDirectories.isNotEmpty) { // Force the depfile to contain missing files so that Gradle does not skip diff --git a/packages/flutter_tools/test/general.shard/asset_test.dart b/packages/flutter_tools/test/general.shard/asset_test.dart index 68008e1e83c..703a757e201 100644 --- a/packages/flutter_tools/test/general.shard/asset_test.dart +++ b/packages/flutter_tools/test/general.shard/asset_test.dart @@ -5,6 +5,7 @@ // @dart = 2.8 import 'package:flutter_tools/src/asset.dart'; +import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/globals_null_migrated.dart' as globals; @@ -30,9 +31,13 @@ void main() { // that AssetBundle with fonts also works on Windows. testUsingContext('app font uses local font file', () async { final AssetBundle asset = AssetBundleFactory.instance.createBundle(); + final String manifestPath = + globals.fs.path.join(dataPath, 'main', 'pubspec.yaml'); + final String packagesPath = + globals.fs.path.join(dataPath, 'main', '.packages'); await asset.build( - manifestPath : globals.fs.path.join(dataPath, 'main', 'pubspec.yaml'), - packagesPath: globals.fs.path.join(dataPath, 'main', '.packages'), + manifestPath: manifestPath, + packagesPath: packagesPath, ); expect(asset.entries.containsKey('FontManifest.json'), isTrue); @@ -41,6 +46,16 @@ void main() { '[{"family":"packages/font/test_font","fonts":[{"asset":"packages/font/test_font_file"}]}]', ); expect(asset.wasBuiltOnce(), true); + expect( + asset.inputFiles.map((File f) { + return f.path; + }), + [ + packagesPath, + globals.fs.path.join(dataPath, 'font', 'pubspec.yaml'), + manifestPath, + ], + ); }); testUsingContext('handles empty pubspec with .packages', () async { @@ -54,10 +69,17 @@ void main() { ); final AssetBundle asset = AssetBundleFactory.instance.createBundle(); await asset.build( - manifestPath : globals.fs.path.join(dataPath, 'main', 'pubspec.yaml'), // file doesn't exist + manifestPath: globals.fs.path + .join(dataPath, 'main', 'pubspec.yaml'), // file doesn't exist packagesPath: globals.fs.path.join(dataPath, 'main', '.packages'), ); expect(asset.wasBuiltOnce(), true); + expect( + asset.inputFiles.map((File f) { + return f.path; + }), + [], + ); }); }); }