Unverified Commit 4443e4d4 authored by Sarah Zakarias's avatar Sarah Zakarias Committed by GitHub

Cleanup FLX related code (#16416)

parent 1ba43364
...@@ -16,5 +16,4 @@ flutter_app("flutter_gallery") { ...@@ -16,5 +16,4 @@ flutter_app("flutter_gallery") {
"//third_party/dart-pkg/pub/url_launcher", "//third_party/dart-pkg/pub/url_launcher",
] ]
# TODO(chinmaygarde): Assets must be packaged in the FLX.
} }
...@@ -13,17 +13,17 @@ import 'package:flutter_tools/src/cache.dart'; ...@@ -13,17 +13,17 @@ import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/context_runner.dart'; import 'package:flutter_tools/src/context_runner.dart';
import 'package:flutter_tools/src/devfs.dart'; import 'package:flutter_tools/src/devfs.dart';
import 'package:flutter_tools/src/disabled_usage.dart'; import 'package:flutter_tools/src/disabled_usage.dart';
import 'package:flutter_tools/src/flx.dart'; import 'package:flutter_tools/src/bundle.dart';
import 'package:flutter_tools/src/globals.dart'; import 'package:flutter_tools/src/globals.dart';
import 'package:flutter_tools/src/usage.dart'; import 'package:flutter_tools/src/usage.dart';
const String _kOptionPackages = 'packages'; const String _kOptionPackages = 'packages';
const String _kOptionWorking = 'working-dir'; const String _kOptionAsset = 'asset-dir';
const String _kOptionManifest = 'manifest'; const String _kOptionManifest = 'manifest';
const String _kOptionAssetManifestOut = 'asset-manifest-out'; const String _kOptionAssetManifestOut = 'asset-manifest-out';
const List<String> _kRequiredOptions = const <String>[ const List<String> _kRequiredOptions = const <String>[
_kOptionPackages, _kOptionPackages,
_kOptionWorking, _kOptionAsset,
_kOptionAssetManifestOut, _kOptionAssetManifestOut,
]; ];
...@@ -43,7 +43,7 @@ Future<Null> writeFile(libfs.File outputFile, DevFSContent content) async { ...@@ -43,7 +43,7 @@ Future<Null> writeFile(libfs.File outputFile, DevFSContent content) async {
Future<Null> run(List<String> args) async { Future<Null> run(List<String> args) async {
final ArgParser parser = new ArgParser() final ArgParser parser = new ArgParser()
..addOption(_kOptionPackages, help: 'The .packages file') ..addOption(_kOptionPackages, help: 'The .packages file')
..addOption(_kOptionWorking, ..addOption(_kOptionAsset,
help: 'The directory where to put temporary files') help: 'The directory where to put temporary files')
..addOption(_kOptionManifest, help: 'The manifest file') ..addOption(_kOptionManifest, help: 'The manifest file')
..addOption(_kOptionAssetManifestOut); ..addOption(_kOptionAssetManifestOut);
...@@ -55,10 +55,10 @@ Future<Null> run(List<String> args) async { ...@@ -55,10 +55,10 @@ Future<Null> run(List<String> args) async {
} }
Cache.flutterRoot = platform.environment['FLUTTER_ROOT']; Cache.flutterRoot = platform.environment['FLUTTER_ROOT'];
final String workingDir = argResults[_kOptionWorking]; final String assetDir = argResults[_kOptionAsset];
final AssetBundle assets = await buildAssets( final AssetBundle assets = await buildAssets(
manifestPath: argResults[_kOptionManifest] ?? defaultManifestPath, manifestPath: argResults[_kOptionManifest] ?? defaultManifestPath,
workingDirPath: workingDir, assetDirPath: assetDir,
packagesPath: argResults[_kOptionPackages], packagesPath: argResults[_kOptionPackages],
includeDefaultFonts: false, includeDefaultFonts: false,
); );
...@@ -70,13 +70,13 @@ Future<Null> run(List<String> args) async { ...@@ -70,13 +70,13 @@ Future<Null> run(List<String> args) async {
final List<Future<Null>> calls = <Future<Null>>[]; final List<Future<Null>> calls = <Future<Null>>[];
assets.entries.forEach((String fileName, DevFSContent content) { assets.entries.forEach((String fileName, DevFSContent content) {
final libfs.File outputFile = libfs.fs.file(libfs.fs.path.join(workingDir, fileName)); final libfs.File outputFile = libfs.fs.file(libfs.fs.path.join(assetDir, fileName));
calls.add(writeFile(outputFile, content)); calls.add(writeFile(outputFile, content));
}); });
await Future.wait(calls); await Future.wait(calls);
final String outputMan = argResults[_kOptionAssetManifestOut]; final String outputMan = argResults[_kOptionAssetManifestOut];
await writeFuchsiaManifest(assets, argResults[_kOptionWorking], outputMan); await writeFuchsiaManifest(assets, argResults[_kOptionAsset], outputMan);
} }
Future<Null> writeFuchsiaManifest(AssetBundle assets, String outputBase, String fileDest) async { Future<Null> writeFuchsiaManifest(AssetBundle assets, String outputBase, String fileDest) async {
......
// Copyright 2016 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 'package:flutter_tools/src/asset.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/context_runner.dart';
import 'package:flutter_tools/src/disabled_usage.dart';
import 'package:flutter_tools/src/flx.dart';
import 'package:flutter_tools/src/globals.dart';
import 'package:flutter_tools/src/usage.dart';
const String _kOptionPackages = 'packages';
const String _kOptionOutput = 'output-file';
const String _kOptionHeader = 'header';
const String _kOptionSnapshot = 'snapshot';
const String _kOptionDylib = 'dylib';
const String _kOptionWorking = 'working-dir';
const String _kOptionManifest = 'manifest';
const String _kOptionDepFile = 'depfile';
const String _kOptionBuildRoot = 'build-root';
const List<String> _kRequiredOptions = const <String>[
_kOptionPackages,
_kOptionOutput,
_kOptionHeader,
_kOptionWorking,
_kOptionDepFile,
_kOptionBuildRoot,
];
Future<Null> main(List<String> args) {
return runInContext<Null>(() => run(args), overrides: <Type, dynamic>{
Usage: new DisabledUsage(),
});
}
Future<Null> run(List<String> args) async {
final ArgParser parser = new ArgParser()
..addOption(_kOptionPackages, help: 'The .packages file')
..addOption(_kOptionOutput, help: 'The generated flx file')
..addOption(_kOptionHeader, help: 'The header of the flx file')
..addOption(_kOptionDylib, help: 'The generated AOT dylib file')
..addOption(_kOptionSnapshot, help: 'The generated snapshot file')
..addOption(_kOptionWorking,
help: 'The directory where to put temporary files')
..addOption(_kOptionManifest, help: 'The manifest file')
..addOption(_kOptionDepFile, help: 'The generated depfile')
..addOption(_kOptionBuildRoot, help: 'The build\'s root directory');
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 outputPath = argResults[_kOptionOutput];
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],
);
final String depFilePath = argResults[_kOptionDepFile];
final int depFileResult = _createDepfile(
depFilePath,
fs.path.relative(argResults[_kOptionOutput],
from: argResults[_kOptionBuildRoot]),
dependencies);
if (depFileResult != 0) {
printError('Error creating depfile $depFilePath: $depFileResult.');
exit(depFileResult);
}
} on ToolExit catch (e) {
printError(e.message);
exit(e.exitCode);
}
final int headerResult = _addHeader(outputPath, argResults[_kOptionHeader]);
if (headerResult != 0) {
printError('Error adding header to $outputPath: $headerResult.');
}
exit(headerResult);
}
int _createDepfile(
String depFilePath, String target, List<String> dependencies) {
try {
final File depFile = fs.file(depFilePath);
depFile.writeAsStringSync('$target: ${dependencies.join(' ')}\n');
return 0;
} catch (_) {
return 1;
}
}
int _addHeader(String outputPath, String header) {
try {
final File outputFile = fs.file(outputPath);
final List<int> content = outputFile.readAsBytesSync();
outputFile.writeAsStringSync('$header\n');
outputFile.writeAsBytesSync(content, mode: FileMode.APPEND);
return 0;
} catch (_) {
return 1;
}
}
...@@ -85,7 +85,6 @@ BuildApp() { ...@@ -85,7 +85,6 @@ BuildApp() {
RunCommand rm -rf -- "${derived_dir}/Flutter.framework" RunCommand rm -rf -- "${derived_dir}/Flutter.framework"
RunCommand rm -rf -- "${derived_dir}/App.framework" RunCommand rm -rf -- "${derived_dir}/App.framework"
RunCommand rm -f -- "${derived_dir}/app.flx"
RunCommand cp -r -- "${framework_path}/Flutter.framework" "${derived_dir}" RunCommand cp -r -- "${framework_path}/Flutter.framework" "${derived_dir}"
RunCommand find "${derived_dir}/Flutter.framework" -type f -exec chmod a-w "{}" \; RunCommand find "${derived_dir}/Flutter.framework" -type f -exec chmod a-w "{}" \;
RunCommand pushd "${project_path}" > /dev/null RunCommand pushd "${project_path}" > /dev/null
...@@ -146,14 +145,13 @@ BuildApp() { ...@@ -146,14 +145,13 @@ BuildApp() {
fi fi
StreamOutput " ├─Assembling Flutter resources..." StreamOutput " ├─Assembling Flutter resources..."
RunCommand "${FLUTTER_ROOT}/bin/flutter" --suppress-analytics build flx \ RunCommand "${FLUTTER_ROOT}/bin/flutter" --suppress-analytics build bundle \
--target="${target_path}" \ --target="${target_path}" \
--output-file="${derived_dir}/app.flx" \ --snapshot="${build_dir}/snapshot_blob.bin" \
--snapshot="${build_dir}/snapshot_blob.bin" \ --depfile="${build_dir}/snapshot_blob.bin.d" \
--depfile="${build_dir}/snapshot_blob.bin.d" \ --asset-dir="${derived_dir}/flutter_assets" \
--working-dir="${derived_dir}/flutter_assets" \ ${precompilation_flag} \
${precompilation_flag} \ ${local_engine_flag} \
${local_engine_flag} \
${preview_dart_2_flag} ${preview_dart_2_flag}
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
......
...@@ -302,27 +302,7 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -302,27 +302,7 @@ class FlutterPlugin implements Plugin<Project> {
} }
} }
GenerateDependencies dependenciesTask = project.tasks.create(name: "flutterDependencies${variant.name.capitalize()}", type: GenerateDependencies) {
flutterRoot this.flutterRoot
flutterExecutable this.flutterExecutable
buildMode flutterBuildMode
localEngine this.localEngine
localEngineSrcPath this.localEngineSrcPath
targetPath target
previewDart2 previewDart2Value
fileSystemRoots fileSystemRootsValue
fileSystemScheme fileSystemSchemeValue
trackWidgetCreation trackWidgetCreationValue
preferSharedLibrary preferSharedLibraryValue
targetPlatform targetPlatformValue
sourceDir project.file(project.flutter.source)
intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}")
extraFrontEndOptions extraFrontEndOptionsValue
extraGenSnapshotOptions extraGenSnapshotOptionsValue
}
FlutterTask flutterTask = project.tasks.create(name: "flutterBuild${variant.name.capitalize()}", type: FlutterTask) { FlutterTask flutterTask = project.tasks.create(name: "flutterBuild${variant.name.capitalize()}", type: FlutterTask) {
dependsOn dependenciesTask
flutterRoot this.flutterRoot flutterRoot this.flutterRoot
flutterExecutable this.flutterExecutable flutterExecutable this.flutterExecutable
buildMode flutterBuildMode buildMode flutterBuildMode
...@@ -341,14 +321,14 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -341,14 +321,14 @@ class FlutterPlugin implements Plugin<Project> {
extraGenSnapshotOptions extraGenSnapshotOptionsValue extraGenSnapshotOptions extraGenSnapshotOptionsValue
} }
Task copyFlxTask = project.tasks.create(name: "copyFlutterAssets${variant.name.capitalize()}", type: Copy) { Task copyFlutterAssetsTask = project.tasks.create(name: "copyFlutterAssets${variant.name.capitalize()}", type: Copy) {
dependsOn flutterTask dependsOn flutterTask
dependsOn variant.mergeAssets dependsOn variant.mergeAssets
dependsOn "clean${variant.mergeAssets.name.capitalize()}" dependsOn "clean${variant.mergeAssets.name.capitalize()}"
into variant.mergeAssets.outputDir into variant.mergeAssets.outputDir
with flutterTask.assets with flutterTask.assets
} }
variant.outputs[0].processResources.dependsOn(copyFlxTask) variant.outputs[0].processResources.dependsOn(copyFlutterAssetsTask)
} }
if (project.android.hasProperty("applicationVariants")) { if (project.android.hasProperty("applicationVariants")) {
project.android.applicationVariants.all addFlutterDeps project.android.applicationVariants.all addFlutterDeps
...@@ -398,7 +378,7 @@ abstract class BaseFlutterTask extends DefaultTask { ...@@ -398,7 +378,7 @@ abstract class BaseFlutterTask extends DefaultTask {
return project.file("${intermediateDir}/snapshot_blob.bin.d") return project.file("${intermediateDir}/snapshot_blob.bin.d")
} }
void buildFlx() { void buildBundle() {
if (!sourceDir.isDirectory()) { if (!sourceDir.isDirectory()) {
throw new GradleException("Invalid Flutter source directory: ${sourceDir}") throw new GradleException("Invalid Flutter source directory: ${sourceDir}")
} }
...@@ -450,7 +430,7 @@ abstract class BaseFlutterTask extends DefaultTask { ...@@ -450,7 +430,7 @@ abstract class BaseFlutterTask extends DefaultTask {
args "--local-engine", localEngine args "--local-engine", localEngine
args "--local-engine-src-path", localEngineSrcPath args "--local-engine-src-path", localEngineSrcPath
} }
args "build", "flx" args "build", "bundle"
args "--suppress-analytics" args "--suppress-analytics"
args "--target", targetPath args "--target", targetPath
if (previewDart2) { if (previewDart2) {
...@@ -469,7 +449,6 @@ abstract class BaseFlutterTask extends DefaultTask { ...@@ -469,7 +449,6 @@ abstract class BaseFlutterTask extends DefaultTask {
if (trackWidgetCreation) { if (trackWidgetCreation) {
args "--track-widget-creation" args "--track-widget-creation"
} }
args "--output-file", "${intermediateDir}/app.flx"
if (buildMode != "debug") { if (buildMode != "debug") {
args "--precompiled" args "--precompiled"
} else { } else {
...@@ -478,17 +457,7 @@ abstract class BaseFlutterTask extends DefaultTask { ...@@ -478,17 +457,7 @@ abstract class BaseFlutterTask extends DefaultTask {
args "--snapshot", "${intermediateDir}/snapshot_blob.bin" args "--snapshot", "${intermediateDir}/snapshot_blob.bin"
} }
} }
args "--working-dir", "${intermediateDir}/flutter_assets" args "--asset-dir", "${intermediateDir}/flutter_assets"
}
}
}
class GenerateDependencies extends BaseFlutterTask {
@TaskAction
void build() {
File dependenciesFile = getDependenciesFile();
if (!dependenciesFile.exists()) {
buildFlx()
} }
} }
} }
...@@ -565,6 +534,6 @@ class FlutterTask extends BaseFlutterTask { ...@@ -565,6 +534,6 @@ class FlutterTask extends BaseFlutterTask {
@TaskAction @TaskAction
void build() { void build() {
buildFlx() buildBundle()
} }
} }
...@@ -39,7 +39,7 @@ abstract class AssetBundle { ...@@ -39,7 +39,7 @@ abstract class AssetBundle {
/// Returns 0 for success; non-zero for failure. /// Returns 0 for success; non-zero for failure.
Future<int> build({ Future<int> build({
String manifestPath: _ManifestAssetBundle.defaultManifestPath, String manifestPath: _ManifestAssetBundle.defaultManifestPath,
String workingDirPath, String assetDirPath,
String packagesPath, String packagesPath,
bool includeDefaultFonts: true, bool includeDefaultFonts: true,
bool reportLicensedPackages: false bool reportLicensedPackages: false
...@@ -87,12 +87,12 @@ class _ManifestAssetBundle implements AssetBundle { ...@@ -87,12 +87,12 @@ class _ManifestAssetBundle implements AssetBundle {
@override @override
Future<int> build({ Future<int> build({
String manifestPath: defaultManifestPath, String manifestPath: defaultManifestPath,
String workingDirPath, String assetDirPath,
String packagesPath, String packagesPath,
bool includeDefaultFonts: true, bool includeDefaultFonts: true,
bool reportLicensedPackages: false bool reportLicensedPackages: false
}) async { }) async {
workingDirPath ??= getAssetBuildDirectory(); assetDirPath ??= getAssetBuildDirectory();
packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath); packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
FlutterManifest flutterManifest; FlutterManifest flutterManifest;
try { try {
...@@ -124,7 +124,7 @@ class _ManifestAssetBundle implements AssetBundle { ...@@ -124,7 +124,7 @@ class _ManifestAssetBundle implements AssetBundle {
packageMap, packageMap,
flutterManifest, flutterManifest,
assetBasePath, assetBasePath,
excludeDirs: <String>[workingDirPath, getBuildDirectory()] excludeDirs: <String>[assetDirPath, getBuildDirectory()]
); );
if (assetVariants == null) if (assetVariants == null)
......
...@@ -14,12 +14,10 @@ import 'compile.dart'; ...@@ -14,12 +14,10 @@ import 'compile.dart';
import 'dart/package_map.dart'; import 'dart/package_map.dart';
import 'devfs.dart'; import 'devfs.dart';
import 'globals.dart'; import 'globals.dart';
import 'zip.dart';
const String defaultMainPath = 'lib/main.dart'; const String defaultMainPath = 'lib/main.dart';
const String defaultAssetBasePath = '.'; const String defaultAssetBasePath = '.';
const String defaultManifestPath = 'pubspec.yaml'; const String defaultManifestPath = 'pubspec.yaml';
String get defaultFlxOutputPath => fs.path.join(getBuildDirectory(), 'app.flx');
String get defaultSnapshotPath => fs.path.join(getBuildDirectory(), 'snapshot_blob.bin'); String get defaultSnapshotPath => fs.path.join(getBuildDirectory(), 'snapshot_blob.bin');
String get defaultDepfilePath => fs.path.join(getBuildDirectory(), 'snapshot_blob.bin.d'); String get defaultDepfilePath => fs.path.join(getBuildDirectory(), 'snapshot_blob.bin.d');
String get defaultApplicationKernelPath => fs.path.join(getBuildDirectory(), 'app.dill'); String get defaultApplicationKernelPath => fs.path.join(getBuildDirectory(), 'app.dill');
...@@ -30,15 +28,14 @@ const String _kSnapshotKey = 'snapshot_blob.bin'; ...@@ -30,15 +28,14 @@ const String _kSnapshotKey = 'snapshot_blob.bin';
const String _kDylibKey = 'libapp.so'; const String _kDylibKey = 'libapp.so';
const String _kPlatformKernelKey = 'platform.dill'; const String _kPlatformKernelKey = 'platform.dill';
Future<Null> build({ Future<void> build({
String mainPath: defaultMainPath, String mainPath: defaultMainPath,
String manifestPath: defaultManifestPath, String manifestPath: defaultManifestPath,
String outputPath,
String snapshotPath, String snapshotPath,
String applicationKernelFilePath, String applicationKernelFilePath,
String depfilePath, String depfilePath,
String privateKeyPath: defaultPrivateKeyPath, String privateKeyPath: defaultPrivateKeyPath,
String workingDirPath, String assetDirPath,
String packagesPath, String packagesPath,
bool previewDart2 : false, bool previewDart2 : false,
bool precompiledSnapshot: false, bool precompiledSnapshot: false,
...@@ -47,10 +44,9 @@ Future<Null> build({ ...@@ -47,10 +44,9 @@ Future<Null> build({
List<String> fileSystemRoots, List<String> fileSystemRoots,
String fileSystemScheme, String fileSystemScheme,
}) async { }) async {
outputPath ??= defaultFlxOutputPath;
snapshotPath ??= defaultSnapshotPath; snapshotPath ??= defaultSnapshotPath;
depfilePath ??= defaultDepfilePath; depfilePath ??= defaultDepfilePath;
workingDirPath ??= getAssetBuildDirectory(); assetDirPath ??= getAssetBuildDirectory();
packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath); packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
applicationKernelFilePath ??= defaultApplicationKernelPath; applicationKernelFilePath ??= defaultApplicationKernelPath;
File snapshotFile; File snapshotFile;
...@@ -142,38 +138,37 @@ Future<Null> build({ ...@@ -142,38 +138,37 @@ Future<Null> build({
final AssetBundle assets = await buildAssets( final AssetBundle assets = await buildAssets(
manifestPath: manifestPath, manifestPath: manifestPath,
workingDirPath: workingDirPath, assetDirPath: assetDirPath,
packagesPath: packagesPath, packagesPath: packagesPath,
reportLicensedPackages: reportLicensedPackages, reportLicensedPackages: reportLicensedPackages,
); );
if (assets == null) if (assets == null)
throwToolExit('Error building assets for $outputPath', exitCode: 1); throwToolExit('Error building assets', exitCode: 1);
return assemble( await assemble(
assetBundle: assets, assetBundle: assets,
kernelContent: kernelContent, kernelContent: kernelContent,
snapshotFile: snapshotFile, snapshotFile: snapshotFile,
outputPath: outputPath,
privateKeyPath: privateKeyPath, privateKeyPath: privateKeyPath,
workingDirPath: workingDirPath, assetDirPath: assetDirPath,
).then((_) => null); );
} }
Future<AssetBundle> buildAssets({ Future<AssetBundle> buildAssets({
String manifestPath, String manifestPath,
String workingDirPath, String assetDirPath,
String packagesPath, String packagesPath,
bool includeDefaultFonts: true, bool includeDefaultFonts: true,
bool reportLicensedPackages: false bool reportLicensedPackages: false
}) async { }) async {
workingDirPath ??= getAssetBuildDirectory(); assetDirPath ??= getAssetBuildDirectory();
packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath); packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
// Build the asset bundle. // Build the asset bundle.
final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle(); final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle();
final int result = await assetBundle.build( final int result = await assetBundle.build(
manifestPath: manifestPath, manifestPath: manifestPath,
workingDirPath: workingDirPath, assetDirPath: assetDirPath,
packagesPath: packagesPath, packagesPath: packagesPath,
includeDefaultFonts: includeDefaultFonts, includeDefaultFonts: includeDefaultFonts,
reportLicensedPackages: reportLicensedPackages reportLicensedPackages: reportLicensedPackages
...@@ -184,48 +179,48 @@ Future<AssetBundle> buildAssets({ ...@@ -184,48 +179,48 @@ Future<AssetBundle> buildAssets({
return assetBundle; return assetBundle;
} }
Future<List<String>> assemble({ Future<void> assemble({
AssetBundle assetBundle, AssetBundle assetBundle,
DevFSContent kernelContent, DevFSContent kernelContent,
File snapshotFile, File snapshotFile,
File dylibFile, File dylibFile,
String outputPath,
String privateKeyPath: defaultPrivateKeyPath, String privateKeyPath: defaultPrivateKeyPath,
String workingDirPath, String assetDirPath,
}) async { }) async {
outputPath ??= defaultFlxOutputPath; assetDirPath ??= getAssetBuildDirectory();
workingDirPath ??= getAssetBuildDirectory(); printTrace('Building bundle');
printTrace('Building $outputPath');
final ZipBuilder zipBuilder = new ZipBuilder();
// Add all entries from the asset bundle. final Map<String, DevFSContent> assetEntries = new Map<String, DevFSContent>.from(assetBundle.entries);
zipBuilder.entries.addAll(assetBundle.entries);
final List<String> fileDependencies = assetBundle.entries.values
.expand((DevFSContent content) => content.fileDependencies)
.toList();
if (kernelContent != null) { if (kernelContent != null) {
final String platformKernelDill = artifacts.getArtifactPath(Artifact.platformKernelDill); final String platformKernelDill = artifacts.getArtifactPath(Artifact.platformKernelDill);
zipBuilder.entries[_kKernelKey] = kernelContent; assetEntries[_kKernelKey] = kernelContent;
zipBuilder.entries[_kPlatformKernelKey] = new DevFSFileContent(fs.file(platformKernelDill)); assetEntries[_kPlatformKernelKey] = new DevFSFileContent(fs.file(platformKernelDill));
} }
if (snapshotFile != null) if (snapshotFile != null)
zipBuilder.entries[_kSnapshotKey] = new DevFSFileContent(snapshotFile); assetEntries[_kSnapshotKey] = new DevFSFileContent(snapshotFile);
if (dylibFile != null) if (dylibFile != null)
zipBuilder.entries[_kDylibKey] = new DevFSFileContent(dylibFile); assetEntries[_kDylibKey] = new DevFSFileContent(dylibFile);
ensureDirectoryExists(outputPath);
printTrace('Encoding zip file to $outputPath'); printTrace('Writing asset files to $assetDirPath');
ensureDirectoryExists(assetDirPath);
// TODO(zarah): Remove the zipBuilder and write the files directly once FLX await writeBundle(fs.directory(assetDirPath), assetEntries);
// is deprecated. printTrace('Wrote $assetDirPath');
}
await zipBuilder.createZip(fs.file(outputPath), fs.directory(workingDirPath)); Future<void> writeBundle(
Directory bundleDir, Map<String, DevFSContent> assetEntries) async {
if (bundleDir.existsSync())
bundleDir.deleteSync(recursive: true);
bundleDir.createSync(recursive: true);
await Future.wait(
assetEntries.entries.map((MapEntry<String, DevFSContent> entry) async {
final File file = fs.file(fs.path.join(bundleDir.path, entry.key));
file.parent.createSync(recursive: true);
await file.writeAsBytes(await entry.value.contentsAsBytes());
}));
}
printTrace('Built $outputPath.');
return fileDependencies;
}
...@@ -12,6 +12,7 @@ import '../globals.dart'; ...@@ -12,6 +12,7 @@ import '../globals.dart';
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
import 'build_aot.dart'; import 'build_aot.dart';
import 'build_apk.dart'; import 'build_apk.dart';
import 'build_bundle.dart';
import 'build_flx.dart'; import 'build_flx.dart';
import 'build_ios.dart'; import 'build_ios.dart';
...@@ -21,6 +22,7 @@ class BuildCommand extends FlutterCommand { ...@@ -21,6 +22,7 @@ class BuildCommand extends FlutterCommand {
addSubcommand(new BuildAotCommand(verboseHelp: verboseHelp)); addSubcommand(new BuildAotCommand(verboseHelp: verboseHelp));
addSubcommand(new BuildIOSCommand(verboseHelp: verboseHelp)); addSubcommand(new BuildIOSCommand(verboseHelp: verboseHelp));
addSubcommand(new BuildFlxCommand(verboseHelp: verboseHelp)); addSubcommand(new BuildFlxCommand(verboseHelp: verboseHelp));
addSubcommand(new BuildBundleCommand(verboseHelp: verboseHelp));
} }
@override @override
......
// 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 '../build_info.dart';
import '../bundle.dart';
import 'build.dart';
class BuildBundleCommand extends BuildSubCommand {
BuildBundleCommand({bool verboseHelp: false}) {
usesTargetOption();
argParser
..addFlag('precompiled', negatable: false)
// This option is still referenced by the iOS build scripts. We should
// remove it once we've updated those build scripts.
..addOption('asset-base', help: 'Ignored. Will be removed.', hide: !verboseHelp)
..addOption('manifest', defaultsTo: defaultManifestPath)
..addOption('private-key', defaultsTo: defaultPrivateKeyPath)
..addOption('snapshot', defaultsTo: defaultSnapshotPath)
..addOption('depfile', defaultsTo: defaultDepfilePath)
..addOption('kernel-file', defaultsTo: defaultApplicationKernelPath)
..addFlag('preview-dart-2',
defaultsTo: true,
hide: !verboseHelp,
help: 'Preview Dart 2.0 functionality.',
)
..addFlag('track-widget-creation',
hide: !verboseHelp,
help: 'Track widget creation locations. Requires Dart 2.0 functionality.',
)
..addOption('asset-dir', defaultsTo: getAssetBuildDirectory())
..addFlag('report-licensed-packages',
help: 'Whether to report the names of all the packages that are included '
'in the application\'s LICENSE file.',
defaultsTo: false)
..addMultiOption('filesystem-root',
hide: !verboseHelp,
help: 'Specify the path, that is used as root in a virtual file system\n'
'for compilation. Input file name should be specified as Uri in\n'
'filesystem-scheme scheme. Use only in Dart 2 mode.\n'
'Requires --output-dill option to be explicitly specified.\n')
..addOption('filesystem-scheme',
defaultsTo: 'org-dartlang-root',
hide: !verboseHelp,
help: 'Specify the scheme that is used for virtual file system used in\n'
'compilation. See more details on filesystem-root option.\n');
usesPubOption();
}
@override
final String name = 'bundle';
@override
final String description = 'Build the Flutter assets directory from your app.';
@override
final String usageFooter = 'The Flutter assets directory contains your '
'application code and resources; they are used by some Flutter Android and'
' iOS runtimes.';
@override
Future<Null> runCommand() async {
await super.runCommand();
await build(
mainPath: targetFile,
manifestPath: argResults['manifest'],
snapshotPath: argResults['snapshot'],
applicationKernelFilePath: argResults['kernel-file'],
depfilePath: argResults['depfile'],
privateKeyPath: argResults['private-key'],
assetDirPath: argResults['asset-dir'],
previewDart2: argResults['preview-dart-2'],
precompiledSnapshot: argResults['precompiled'],
reportLicensedPackages: argResults['report-licensed-packages'],
trackWidgetCreation: argResults['track-widget-creation'],
fileSystemScheme: argResults['filesystem-scheme'],
fileSystemRoots: argResults['filesystem-root'],
);
}
}
...@@ -4,82 +4,27 @@ ...@@ -4,82 +4,27 @@
import 'dart:async'; import 'dart:async';
import '../build_info.dart'; import '../globals.dart';
import '../flx.dart';
import 'build.dart'; import 'build.dart';
class BuildFlxCommand extends BuildSubCommand { class BuildFlxCommand extends BuildSubCommand {
BuildFlxCommand({bool verboseHelp: false}) {
usesTargetOption();
argParser
..addFlag('precompiled', negatable: false)
// This option is still referenced by the iOS build scripts. We should
// remove it once we've updated those build scripts.
..addOption('asset-base', help: 'Ignored. Will be removed.', hide: !verboseHelp)
..addOption('manifest', defaultsTo: defaultManifestPath)
..addOption('private-key', defaultsTo: defaultPrivateKeyPath)
..addOption('output-file', abbr: 'o', defaultsTo: defaultFlxOutputPath)
..addOption('snapshot', defaultsTo: defaultSnapshotPath)
..addOption('depfile', defaultsTo: defaultDepfilePath)
..addOption('kernel-file', defaultsTo: defaultApplicationKernelPath)
..addFlag('preview-dart-2',
defaultsTo: true,
hide: !verboseHelp,
help: 'Preview Dart 2.0 functionality.',
)
..addFlag('track-widget-creation',
hide: !verboseHelp,
help: 'Track widget creation locations. Requires Dart 2.0 functionality.',
)
..addOption('working-dir', defaultsTo: getAssetBuildDirectory())
..addFlag('report-licensed-packages',
help: 'Whether to report the names of all the packages that are included '
'in the application\'s LICENSE file.',
defaultsTo: false)
..addMultiOption('filesystem-root',
hide: !verboseHelp,
help: 'Specify the path, that is used as root in a virtual file system\n'
'for compilation. Input file name should be specified as Uri in\n'
'filesystem-scheme scheme. Use only in Dart 2 mode.\n'
'Requires --output-dill option to be explicitly specified.\n')
..addOption('filesystem-scheme',
defaultsTo: 'org-dartlang-root',
hide: !verboseHelp,
help: 'Specify the scheme that is used for virtual file system used in\n'
'compilation. See more details on filesystem-root option.\n');
usesPubOption();
}
BuildFlxCommand({bool verboseHelp: false});
@override @override
final String name = 'flx'; final String name = 'flx';
@override @override
final String description = 'Build a Flutter FLX file from your app.'; final String description = 'Deprecated';
@override @override
final String usageFooter = 'FLX files are archives of your application code and resources; ' final String usageFooter = 'FLX archives are deprecated.';
'they are used by some Flutter Android and iOS runtimes.';
@override @override
Future<Null> runCommand() async { Future<Null> runCommand() async {
await super.runCommand(); await super.runCommand();
final String outputPath = argResults['output-file'];
await build( printError("'build flx' is no longer supported. Instead, use 'build "
mainPath: targetFile, "bundle' to build and assemble the application code and resources "
manifestPath: argResults['manifest'], 'for your app.');
outputPath: outputPath,
snapshotPath: argResults['snapshot'],
applicationKernelFilePath: argResults['kernel-file'],
depfilePath: argResults['depfile'],
privateKeyPath: argResults['private-key'],
workingDirPath: argResults['working-dir'],
previewDart2: argResults['preview-dart-2'],
precompiledSnapshot: argResults['precompiled'],
reportLicensedPackages: argResults['report-licensed-packages'],
trackWidgetCreation: argResults['track-widget-creation'],
fileSystemScheme: argResults['filesystem-scheme'],
fileSystemRoots: argResults['filesystem-root'],
);
} }
} }
...@@ -11,9 +11,9 @@ import '../base/file_system.dart'; ...@@ -11,9 +11,9 @@ import '../base/file_system.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/process_manager.dart'; import '../base/process_manager.dart';
import '../base/utils.dart'; import '../base/utils.dart';
import '../bundle.dart' as bundle;
import '../cache.dart'; import '../cache.dart';
import '../device.dart'; import '../device.dart';
import '../flx.dart' as flx;
import '../fuchsia/fuchsia_device.dart'; import '../fuchsia/fuchsia_device.dart';
import '../globals.dart'; import '../globals.dart';
import '../resident_runner.dart'; import '../resident_runner.dart';
...@@ -59,7 +59,7 @@ class FuchsiaReloadCommand extends FlutterCommand { ...@@ -59,7 +59,7 @@ class FuchsiaReloadCommand extends FlutterCommand {
help: 'Preview Dart 2.0 functionality.'); help: 'Preview Dart 2.0 functionality.');
argParser.addOption('target', argParser.addOption('target',
abbr: 't', abbr: 't',
defaultsTo: flx.defaultMainPath, defaultsTo: bundle.defaultMainPath,
help: 'Target app path / main entry-point file. ' help: 'Target app path / main entry-point file. '
'Relative to --gn-target path, e.g. lib/main.dart.'); 'Relative to --gn-target path, e.g. lib/main.dart.');
} }
......
...@@ -19,7 +19,7 @@ import '../base/process.dart'; ...@@ -19,7 +19,7 @@ import '../base/process.dart';
import '../base/process_manager.dart'; import '../base/process_manager.dart';
import '../base/utils.dart'; import '../base/utils.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../flx.dart' as flx; import '../bundle.dart' as bundle;
import '../globals.dart'; import '../globals.dart';
import '../plugins.dart'; import '../plugins.dart';
import '../services.dart'; import '../services.dart';
...@@ -180,7 +180,7 @@ class Xcode { ...@@ -180,7 +180,7 @@ class Xcode {
Future<XcodeBuildResult> buildXcodeProject({ Future<XcodeBuildResult> buildXcodeProject({
BuildableIOSApp app, BuildableIOSApp app,
BuildInfo buildInfo, BuildInfo buildInfo,
String target: flx.defaultMainPath, String target: bundle.defaultMainPath,
bool buildForDevice, bool buildForDevice,
bool codesign: true, bool codesign: true,
bool usesTerminalUi: true, bool usesTerminalUi: true,
......
...@@ -15,8 +15,8 @@ import '../base/platform.dart'; ...@@ -15,8 +15,8 @@ import '../base/platform.dart';
import '../base/process.dart'; import '../base/process.dart';
import '../base/process_manager.dart'; import '../base/process_manager.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../bundle.dart' as bundle;
import '../device.dart'; import '../device.dart';
import '../flx.dart' as flx;
import '../globals.dart'; import '../globals.dart';
import '../protocol_discovery.dart'; import '../protocol_discovery.dart';
import 'ios_workflow.dart'; import 'ios_workflow.dart';
...@@ -416,7 +416,7 @@ class IOSSimulator extends Device { ...@@ -416,7 +416,7 @@ class IOSSimulator extends Device {
Future<Null> _sideloadUpdatedAssetsForInstalledApplicationBundle(ApplicationPackage app, BuildInfo buildInfo) { Future<Null> _sideloadUpdatedAssetsForInstalledApplicationBundle(ApplicationPackage app, BuildInfo buildInfo) {
// When running in previewDart2 mode, we still need to run compiler to // When running in previewDart2 mode, we still need to run compiler to
// produce kernel file for the application. // produce kernel file for the application.
return flx.build( return bundle.build(
precompiledSnapshot: !buildInfo.previewDart2, precompiledSnapshot: !buildInfo.previewDart2,
previewDart2: buildInfo.previewDart2, previewDart2: buildInfo.previewDart2,
trackWidgetCreation: buildInfo.trackWidgetCreation, trackWidgetCreation: buildInfo.trackWidgetCreation,
......
...@@ -13,8 +13,8 @@ import '../base/process.dart'; ...@@ -13,8 +13,8 @@ import '../base/process.dart';
import '../base/process_manager.dart'; import '../base/process_manager.dart';
import '../base/utils.dart'; import '../base/utils.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../bundle.dart' as bundle;
import '../cache.dart'; import '../cache.dart';
import '../flx.dart' as flx;
import '../globals.dart'; import '../globals.dart';
final RegExp _settingExpr = new RegExp(r'(\w+)\s*=\s*(.*)$'); final RegExp _settingExpr = new RegExp(r'(\w+)\s*=\s*(.*)$');
...@@ -36,7 +36,7 @@ void generateXcodeProperties(String projectPath) { ...@@ -36,7 +36,7 @@ void generateXcodeProperties(String projectPath) {
updateGeneratedXcodeProperties( updateGeneratedXcodeProperties(
projectPath: projectPath, projectPath: projectPath,
buildInfo: BuildInfo.debug, buildInfo: BuildInfo.debug,
target: flx.defaultMainPath, target: bundle.defaultMainPath,
previewDart2: false, previewDart2: false,
); );
} }
......
...@@ -15,11 +15,11 @@ import '../base/context.dart'; ...@@ -15,11 +15,11 @@ import '../base/context.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/utils.dart'; import '../base/utils.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../bundle.dart' as bundle;
import '../dart/package_map.dart'; import '../dart/package_map.dart';
import '../dart/pub.dart'; import '../dart/pub.dart';
import '../device.dart'; import '../device.dart';
import '../doctor.dart'; import '../doctor.dart';
import '../flx.dart' as flx;
import '../globals.dart'; import '../globals.dart';
import '../project.dart'; import '../project.dart';
import '../usage.dart'; import '../usage.dart';
...@@ -98,7 +98,7 @@ abstract class FlutterCommand extends Command<Null> { ...@@ -98,7 +98,7 @@ abstract class FlutterCommand extends Command<Null> {
void usesTargetOption() { void usesTargetOption() {
argParser.addOption('target', argParser.addOption('target',
abbr: 't', abbr: 't',
defaultsTo: flx.defaultMainPath, defaultsTo: bundle.defaultMainPath,
help: 'The main entry-point file of the application, as run on the device.\n' help: 'The main entry-point file of the application, as run on the device.\n'
'If the --target option is omitted, but a file name is provided on\n' 'If the --target option is omitted, but a file name is provided on\n'
'the command line, then that is used instead.', 'the command line, then that is used instead.',
...@@ -112,7 +112,7 @@ abstract class FlutterCommand extends Command<Null> { ...@@ -112,7 +112,7 @@ abstract class FlutterCommand extends Command<Null> {
else if (argResults.rest.isNotEmpty) else if (argResults.rest.isNotEmpty)
return argResults.rest.first; return argResults.rest.first;
else else
return flx.defaultMainPath; return bundle.defaultMainPath;
} }
void usesPubOption() { void usesPubOption() {
......
// Copyright 2016 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:archive/archive.dart';
import 'base/file_system.dart';
import 'base/process.dart';
import 'devfs.dart';
abstract class ZipBuilder {
factory ZipBuilder() {
if (exitsHappy(<String>['which', 'zip'])) {
return new _ZipToolBuilder();
} else {
return new _ArchiveZipBuilder();
}
}
ZipBuilder._();
Map<String, DevFSContent> entries = <String, DevFSContent>{};
Future<Null> createZip(File outFile, Directory zipBuildDir);
}
class _ArchiveZipBuilder extends ZipBuilder {
_ArchiveZipBuilder() : super._();
@override
Future<Null> createZip(File outFile, Directory zipBuildDir) async {
final Archive archive = new Archive();
if (zipBuildDir.existsSync())
zipBuildDir.deleteSync(recursive: true);
zipBuildDir.createSync(recursive: true);
final Completer<Null> finished = new Completer<Null>();
int count = entries.length;
entries.forEach((String archivePath, DevFSContent content) {
content.contentsAsBytes().then<Null>((List<int> data) {
archive.addFile(new ArchiveFile.noCompress(archivePath, data.length, data));
final File file = fs.file(fs.path.join(zipBuildDir.path, archivePath));
file.parent.createSync(recursive: true);
file.writeAsBytes(data).then<Null>((File value) {
count -= 1;
if (count == 0)
finished.complete();
});
});
});
await finished.future;
final List<int> zipData = new ZipEncoder().encode(archive);
await outFile.writeAsBytes(zipData);
}
}
class _ZipToolBuilder extends ZipBuilder {
_ZipToolBuilder() : super._();
@override
Future<Null> createZip(File outFile, Directory zipBuildDir) async {
// If there are no assets, then create an empty zip file.
if (entries.isEmpty) {
final List<int> zipData = new ZipEncoder().encode(new Archive());
await outFile.writeAsBytes(zipData);
return;
}
final File tmpFile = fs.file('${outFile.path}.tmp');
if (tmpFile.existsSync())
tmpFile.deleteSync();
if (zipBuildDir.existsSync())
zipBuildDir.deleteSync(recursive: true);
zipBuildDir.createSync(recursive: true);
final Completer<Null> finished = new Completer<Null>();
int count = entries.length;
entries.forEach((String archivePath, DevFSContent content) {
content.contentsAsBytes().then<Null>((List<int> data) {
final File file = fs.file(fs.path.join(zipBuildDir.path, archivePath));
file.parent.createSync(recursive: true);
file.writeAsBytes(data).then<Null>((File value) {
count -= 1;
if (count == 0)
finished.complete();
});
});
});
await finished.future;
final Iterable<String> compressedNames = _getCompressedNames();
if (compressedNames.isNotEmpty) {
await runCheckedAsync(
<String>['zip', '-q', tmpFile.absolute.path]..addAll(compressedNames),
workingDirectory: zipBuildDir.path
);
}
final Iterable<String> storedNames = _getStoredNames();
if (storedNames.isNotEmpty) {
await runCheckedAsync(
<String>['zip', '-q', '-0', tmpFile.absolute.path]..addAll(storedNames),
workingDirectory: zipBuildDir.path
);
}
tmpFile.renameSync(outFile.absolute.path);
}
static const List<String> _kNoCompressFileExtensions = const <String>['.png', '.jpg'];
bool isAssetCompressed(String archivePath) {
return !_kNoCompressFileExtensions.any(
(String extension) => archivePath.endsWith(extension)
);
}
Iterable<String> _getCompressedNames() => entries.keys.where(isAssetCompressed);
Iterable<String> _getStoredNames() => entries.keys
.where((String archivePath) => !isAssetCompressed(archivePath));
}
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