Commit ec76c652 authored by Justin's avatar Justin Committed by Todd Volkert

Add support for assets in Fuchsia packages (#14654)

Pull code out of flx.dart:assemble() to make flx.dart:buildAssets
which creates the AssetBundle. This will allow us to create just
this instead of an entire FLX.
parent a4489945
...@@ -49,6 +49,16 @@ dart_tool("fuchsia_builder") { ...@@ -49,6 +49,16 @@ dart_tool("fuchsia_builder") {
] ]
} }
dart_tool("fuchsia_asset_builder") {
main_dart = "bin/fuchsia_asset_builder.dart"
disable_analysis = true
deps = [
":flutter_tools",
]
}
dart_tool("fuchsia_tester") { dart_tool("fuchsia_tester") {
main_dart = "bin/fuchsia_tester.dart" main_dart = "bin/fuchsia_tester.dart"
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:args/args.dart';
import '../lib/src/asset.dart';
import '../lib/src/base/file_system.dart' as libfs;
import '../lib/src/base/io.dart';
import '../lib/src/base/platform.dart';
import '../lib/src/cache.dart';
import '../lib/src/context_runner.dart';
import '../lib/src/devfs.dart';
import '../lib/src/flx.dart';
import '../lib/src/globals.dart';
const String _kOptionPackages = 'packages';
const String _kOptionWorking = 'working-dir';
const String _kOptionManifest = 'manifest';
const String _kOptionAssetManifestOut = 'asset-manifest-out';
const List<String> _kRequiredOptions = const <String>[
_kOptionPackages,
_kOptionWorking,
_kOptionAssetManifestOut,
];
Future<Null> main(List<String> args) async {
await runInContext(args, run);
}
Future<Null> writeFile(libfs.File outputFile, DevFSContent content) async {
outputFile.createSync(recursive: true);
final List<int> data = await content.contentsAsBytes();
outputFile.writeAsBytesSync(data);
return null;
}
Future<Null> run(List<String> args) async {
final ArgParser parser = new ArgParser()
..addOption(_kOptionPackages, help: 'The .packages file')
..addOption(_kOptionWorking,
help: 'The directory where to put temporary files')
..addOption(_kOptionManifest, help: 'The manifest file')
..addOption(_kOptionAssetManifestOut);
final ArgResults argResults = parser.parse(args);
if (_kRequiredOptions
.any((String option) => !argResults.options.contains(option))) {
printError('Missing option! All options must be specified.');
exit(1);
}
Cache.flutterRoot = platform.environment['FLUTTER_ROOT'];
final String workingDir = argResults[_kOptionWorking];
final AssetBundle assets = await buildAssets(
manifestPath: argResults[_kOptionManifest] ?? defaultManifestPath,
workingDirPath: workingDir,
packagesPath: argResults[_kOptionPackages],
includeDefaultFonts: false,
);
if (assets == null) {
print('Unable to find assets.');
exit(1);
}
final List<Future<Null>> calls = <Future<Null>>[];
assets.entries.forEach((String fileName, DevFSContent content) {
final libfs.File outputFile = libfs.fs.file(libfs.fs.path.join(workingDir, fileName));
calls.add(writeFile(outputFile, content));
});
await Future.wait(calls);
final String outputMan = argResults[_kOptionAssetManifestOut];
await writeFuchsiaManifest(assets, argResults[_kOptionWorking], outputMan);
}
Future<Null> writeFuchsiaManifest(AssetBundle assets, String outputBase, String fileDest) async {
final libfs.File destFile = libfs.fs.file(fileDest);
await destFile.create(recursive: true);
final libfs.IOSink outFile = destFile.openWrite();
for (String path in assets.entries.keys) {
outFile.write('data/$path=$outputBase/$path\n');
}
await outFile.flush();
await outFile.close();
}
...@@ -5,21 +5,16 @@ ...@@ -5,21 +5,16 @@
import 'dart:async'; import 'dart:async';
import 'package:args/args.dart'; import 'package:args/args.dart';
import 'package:process/process.dart';
import '../lib/src/asset.dart';
import '../lib/src/base/common.dart'; import '../lib/src/base/common.dart';
import '../lib/src/base/config.dart';
import '../lib/src/base/context.dart';
import '../lib/src/base/file_system.dart'; import '../lib/src/base/file_system.dart';
import '../lib/src/base/io.dart'; import '../lib/src/base/io.dart';
import '../lib/src/base/logger.dart';
import '../lib/src/base/os.dart';
import '../lib/src/base/platform.dart'; import '../lib/src/base/platform.dart';
import '../lib/src/cache.dart'; import '../lib/src/cache.dart';
import '../lib/src/disabled_usage.dart'; import '../lib/src/context_runner.dart';
import '../lib/src/flx.dart'; import '../lib/src/flx.dart';
import '../lib/src/globals.dart'; import '../lib/src/globals.dart';
import '../lib/src/usage.dart';
const String _kOptionPackages = 'packages'; const String _kOptionPackages = 'packages';
const String _kOptionOutput = 'output-file'; const String _kOptionOutput = 'output-file';
...@@ -40,22 +35,7 @@ const List<String> _kRequiredOptions = const <String>[ ...@@ -40,22 +35,7 @@ const List<String> _kRequiredOptions = const <String>[
]; ];
Future<Null> main(List<String> args) async { Future<Null> main(List<String> args) async {
final AppContext executableContext = new AppContext(); await runInContext(args, run);
executableContext.setVariable(Logger, new StdoutLogger());
await executableContext.runInZone(() {
// Initialize the context with some defaults.
// This list must be kept in sync with lib/executable.dart.
context.putIfAbsent(Stdio, () => const Stdio());
context.putIfAbsent(Platform, () => const LocalPlatform());
context.putIfAbsent(FileSystem, () => const LocalFileSystem());
context.putIfAbsent(ProcessManager, () => const LocalProcessManager());
context.putIfAbsent(Logger, () => new StdoutLogger());
context.putIfAbsent(Cache, () => new Cache());
context.putIfAbsent(Config, () => new Config());
context.putIfAbsent(OperatingSystemUtils, () => new OperatingSystemUtils());
context.putIfAbsent(Usage, () => new DisabledUsage());
return run(args);
});
} }
Future<Null> run(List<String> args) async { Future<Null> run(List<String> args) async {
...@@ -81,15 +61,23 @@ Future<Null> run(List<String> args) async { ...@@ -81,15 +61,23 @@ Future<Null> run(List<String> args) async {
try { try {
final String snapshotPath = argResults[_kOptionSnapshot]; final String snapshotPath = argResults[_kOptionSnapshot];
final String dylibPath = argResults[_kOptionDylib]; final String dylibPath = argResults[_kOptionDylib];
final AssetBundle assets = await buildAssets(
manifestPath: argResults[_kOptionManifest] ?? defaultManifestPath,
workingDirPath: argResults[_kOptionWorking],
packagesPath: argResults[_kOptionPackages],
includeDefaultFonts: false,
);
if (assets == null)
throwToolExit('Error building assets for $outputPath', exitCode: 1);
final List<String> dependencies = await assemble( final List<String> dependencies = await assemble(
assetBundle: assets,
outputPath: outputPath, outputPath: outputPath,
snapshotFile: snapshotPath == null ? null : fs.file(snapshotPath), snapshotFile: snapshotPath == null ? null : fs.file(snapshotPath),
dylibFile: dylibPath == null ? null : fs.file(dylibPath), dylibFile: dylibPath == null ? null : fs.file(dylibPath),
workingDirPath: argResults[_kOptionWorking], workingDirPath: argResults[_kOptionWorking],
packagesPath: argResults[_kOptionPackages],
manifestPath: argResults[_kOptionManifest] ?? defaultManifestPath,
includeDefaultFonts: false,
); );
final String depFilePath = argResults[_kOptionDepFile]; final String depFilePath = argResults[_kOptionDepFile];
final int depFileResult = _createDepfile( final int depFileResult = _createDepfile(
depFilePath, depFilePath,
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:process/process.dart';
import 'base/config.dart';
import 'base/context.dart';
import 'base/file_system.dart';
import 'base/io.dart';
import 'base/logger.dart';
import 'base/os.dart';
import 'base/platform.dart';
import 'cache.dart';
import 'disabled_usage.dart';
import 'usage.dart';
typedef Future<Null> Runner(List<String> args);
Future<Null> runInContext(List<String> args, Runner runner) {
final AppContext executableContext = new AppContext();
executableContext.setVariable(Logger, new StdoutLogger());
return executableContext.runInZone(() {
// Initialize the context with some defaults.
// This list must be kept in sync with lib/executable.dart.
context.putIfAbsent(Stdio, () => const Stdio());
context.putIfAbsent(Platform, () => const LocalPlatform());
context.putIfAbsent(FileSystem, () => const LocalFileSystem());
context.putIfAbsent(ProcessManager, () => const LocalProcessManager());
context.putIfAbsent(Logger, () => new StdoutLogger());
context.putIfAbsent(Cache, () => new Cache());
context.putIfAbsent(Config, () => new Config());
context.putIfAbsent(OperatingSystemUtils, () => new OperatingSystemUtils());
context.putIfAbsent(Usage, () => new DisabledUsage());
return runner(args);
});
}
...@@ -82,34 +82,34 @@ Future<Null> build({ ...@@ -82,34 +82,34 @@ Future<Null> build({
kernelContent = new DevFSFileContent(fs.file(kernelBinaryFilename)); kernelContent = new DevFSFileContent(fs.file(kernelBinaryFilename));
} }
return assemble( final AssetBundle assets = await buildAssets(
manifestPath: manifestPath, manifestPath: manifestPath,
workingDirPath: workingDirPath,
packagesPath: packagesPath,
reportLicensedPackages: reportLicensedPackages,
);
if (assets == null)
throwToolExit('Error building assets for $outputPath', exitCode: 1);
return assemble(
assetBundle: assets,
kernelContent: kernelContent, kernelContent: kernelContent,
snapshotFile: snapshotFile, snapshotFile: snapshotFile,
outputPath: outputPath, outputPath: outputPath,
privateKeyPath: privateKeyPath, privateKeyPath: privateKeyPath,
workingDirPath: workingDirPath, workingDirPath: workingDirPath,
packagesPath: packagesPath,
reportLicensedPackages: reportLicensedPackages
).then((_) => null); ).then((_) => null);
} }
Future<List<String>> assemble({ Future<AssetBundle> buildAssets({
String manifestPath, String manifestPath,
DevFSContent kernelContent,
File snapshotFile,
File dylibFile,
String outputPath,
String privateKeyPath: defaultPrivateKeyPath,
String workingDirPath, String workingDirPath,
String packagesPath, String packagesPath,
bool includeDefaultFonts: true, bool includeDefaultFonts: true,
bool reportLicensedPackages: false bool reportLicensedPackages: false
}) async { }) async {
outputPath ??= defaultFlxOutputPath;
workingDirPath ??= getAssetBuildDirectory(); workingDirPath ??= getAssetBuildDirectory();
packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath); packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
printTrace('Building $outputPath');
// Build the asset bundle. // Build the asset bundle.
final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle(); final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle();
...@@ -121,7 +121,23 @@ Future<List<String>> assemble({ ...@@ -121,7 +121,23 @@ Future<List<String>> assemble({
reportLicensedPackages: reportLicensedPackages reportLicensedPackages: reportLicensedPackages
); );
if (result != 0) if (result != 0)
throwToolExit('Error building $outputPath: $result', exitCode: result); return null;
return assetBundle;
}
Future<List<String>> assemble({
AssetBundle assetBundle,
DevFSContent kernelContent,
File snapshotFile,
File dylibFile,
String outputPath,
String privateKeyPath: defaultPrivateKeyPath,
String workingDirPath,
}) async {
outputPath ??= defaultFlxOutputPath;
workingDirPath ??= getAssetBuildDirectory();
printTrace('Building $outputPath');
final ZipBuilder zipBuilder = new ZipBuilder(); final ZipBuilder zipBuilder = new ZipBuilder();
......
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