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.
This commit is contained in:
@@ -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") {
|
||||
main_dart = "bin/fuchsia_tester.dart"
|
||||
|
||||
|
||||
90
packages/flutter_tools/bin/fuchsia_asset_builder.dart
Normal file
90
packages/flutter_tools/bin/fuchsia_asset_builder.dart
Normal file
@@ -0,0 +1,90 @@
|
||||
// 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 @@
|
||||
import 'dart:async';
|
||||
|
||||
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/config.dart';
|
||||
import '../lib/src/base/context.dart';
|
||||
import '../lib/src/base/file_system.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/cache.dart';
|
||||
import '../lib/src/disabled_usage.dart';
|
||||
import '../lib/src/context_runner.dart';
|
||||
import '../lib/src/flx.dart';
|
||||
import '../lib/src/globals.dart';
|
||||
import '../lib/src/usage.dart';
|
||||
|
||||
const String _kOptionPackages = 'packages';
|
||||
const String _kOptionOutput = 'output-file';
|
||||
@@ -40,22 +35,7 @@ const List<String> _kRequiredOptions = const <String>[
|
||||
];
|
||||
|
||||
Future<Null> main(List<String> args) async {
|
||||
final AppContext executableContext = new AppContext();
|
||||
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);
|
||||
});
|
||||
await runInContext(args, run);
|
||||
}
|
||||
|
||||
Future<Null> run(List<String> args) async {
|
||||
@@ -81,15 +61,23 @@ Future<Null> run(List<String> args) async {
|
||||
try {
|
||||
final String snapshotPath = argResults[_kOptionSnapshot];
|
||||
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(
|
||||
assetBundle: assets,
|
||||
outputPath: outputPath,
|
||||
snapshotFile: snapshotPath == null ? null : fs.file(snapshotPath),
|
||||
dylibFile: dylibPath == null ? null : fs.file(dylibPath),
|
||||
workingDirPath: argResults[_kOptionWorking],
|
||||
packagesPath: argResults[_kOptionPackages],
|
||||
manifestPath: argResults[_kOptionManifest] ?? defaultManifestPath,
|
||||
includeDefaultFonts: false,
|
||||
);
|
||||
|
||||
final String depFilePath = argResults[_kOptionDepFile];
|
||||
final int depFileResult = _createDepfile(
|
||||
depFilePath,
|
||||
|
||||
39
packages/flutter_tools/lib/src/context_runner.dart
Normal file
39
packages/flutter_tools/lib/src/context_runner.dart
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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({
|
||||
kernelContent = new DevFSFileContent(fs.file(kernelBinaryFilename));
|
||||
}
|
||||
|
||||
return assemble(
|
||||
final AssetBundle assets = await buildAssets(
|
||||
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,
|
||||
snapshotFile: snapshotFile,
|
||||
outputPath: outputPath,
|
||||
privateKeyPath: privateKeyPath,
|
||||
workingDirPath: workingDirPath,
|
||||
packagesPath: packagesPath,
|
||||
reportLicensedPackages: reportLicensedPackages
|
||||
).then((_) => null);
|
||||
}
|
||||
|
||||
Future<List<String>> assemble({
|
||||
Future<AssetBundle> buildAssets({
|
||||
String manifestPath,
|
||||
DevFSContent kernelContent,
|
||||
File snapshotFile,
|
||||
File dylibFile,
|
||||
String outputPath,
|
||||
String privateKeyPath: defaultPrivateKeyPath,
|
||||
String workingDirPath,
|
||||
String packagesPath,
|
||||
bool includeDefaultFonts: true,
|
||||
bool reportLicensedPackages: false
|
||||
}) async {
|
||||
outputPath ??= defaultFlxOutputPath;
|
||||
workingDirPath ??= getAssetBuildDirectory();
|
||||
packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
|
||||
printTrace('Building $outputPath');
|
||||
|
||||
// Build the asset bundle.
|
||||
final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle();
|
||||
@@ -121,7 +121,23 @@ Future<List<String>> assemble({
|
||||
reportLicensedPackages: reportLicensedPackages
|
||||
);
|
||||
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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user