Unverified Commit 29207e4f authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] split application package factory dependencies (#79461)

parent 671926db
......@@ -28,6 +28,7 @@ import '../protocol_discovery.dart';
import 'android.dart';
import 'android_console.dart';
import 'android_sdk.dart';
import 'application_package.dart';
/// Whether the [AndroidDevice] is believed to be a physical device or an emulator.
enum HardwareType { emulator, physical }
......
......@@ -7,7 +7,6 @@
import 'package:file/file.dart';
import 'package:meta/meta.dart';
import '../application_package.dart';
import '../base/analyze_size.dart';
import '../base/common.dart';
import '../base/logger.dart';
......@@ -16,6 +15,7 @@ import '../base/utils.dart';
import '../build_info.dart';
import '../convert.dart';
import '../globals.dart' as globals;
import '../ios/application_package.dart';
import '../ios/mac.dart';
import '../runner/flutter_command.dart';
import 'build.dart';
......
......@@ -37,6 +37,7 @@ import 'devtools_launcher.dart';
import 'doctor.dart';
import 'emulator.dart';
import 'features.dart';
import 'flutter_application_package.dart';
import 'flutter_device_manager.dart';
import 'fuchsia/fuchsia_device.dart' show FuchsiaDeviceTools;
import 'fuchsia/fuchsia_sdk.dart' show FuchsiaSdk, FuchsiaArtifacts;
......@@ -117,7 +118,7 @@ Future<T> runInContext<T>(
featureFlags: featureFlags,
operatingSystemUtils: globals.os,
),
ApplicationPackageFactory: () => ApplicationPackageFactory(
ApplicationPackageFactory: () => FlutterApplicationPackageFactory(
userMessages: globals.userMessages,
processManager: globals.processManager,
logger: globals.logger,
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:meta/meta.dart';
import 'package:process/process.dart';
import 'android/android_sdk.dart';
import 'android/application_package.dart';
import 'application_package.dart';
import 'base/file_system.dart';
import 'base/logger.dart';
import 'base/process.dart';
import 'base/user_messages.dart';
import 'build_info.dart';
import 'fuchsia/application_package.dart';
import 'globals.dart' as globals;
import 'ios/application_package.dart';
import 'linux/application_package.dart';
import 'macos/application_package.dart';
import 'project.dart';
import 'tester/flutter_tester.dart';
import 'web/web_device.dart';
import 'windows/application_package.dart';
/// A package factory that supports all Flutter target platforms.
class FlutterApplicationPackageFactory extends ApplicationPackageFactory {
FlutterApplicationPackageFactory({
@required AndroidSdk androidSdk,
@required ProcessManager processManager,
@required Logger logger,
@required UserMessages userMessages,
@required FileSystem fileSystem,
}) : _androidSdk = androidSdk,
_processManager = processManager,
_logger = logger,
_userMessages = userMessages,
_fileSystem = fileSystem,
_processUtils = ProcessUtils(logger: logger, processManager: processManager);
final AndroidSdk _androidSdk;
final ProcessManager _processManager;
final Logger _logger;
final ProcessUtils _processUtils;
final UserMessages _userMessages;
final FileSystem _fileSystem;
@override
Future<ApplicationPackage> getPackageForPlatform(
TargetPlatform platform, {
BuildInfo buildInfo,
File applicationBinary,
}) async {
switch (platform) {
case TargetPlatform.android:
case TargetPlatform.android_arm:
case TargetPlatform.android_arm64:
case TargetPlatform.android_x64:
case TargetPlatform.android_x86:
if (applicationBinary == null) {
return AndroidApk.fromAndroidProject(
FlutterProject.current().android,
processManager: _processManager,
processUtils: _processUtils,
logger: _logger,
androidSdk: _androidSdk,
userMessages: _userMessages,
fileSystem: _fileSystem,
);
}
return AndroidApk.fromApk(
applicationBinary,
processManager: _processManager,
logger: _logger,
androidSdk: _androidSdk,
userMessages: _userMessages,
);
case TargetPlatform.ios:
return applicationBinary == null
? await IOSApp.fromIosProject(FlutterProject.current().ios, buildInfo)
: IOSApp.fromPrebuiltApp(applicationBinary);
case TargetPlatform.tester:
return FlutterTesterApp.fromCurrentDirectory(globals.fs);
case TargetPlatform.darwin_x64:
return applicationBinary == null
? MacOSApp.fromMacOSProject(FlutterProject.current().macos)
: MacOSApp.fromPrebuiltApp(applicationBinary);
case TargetPlatform.web_javascript:
if (!FlutterProject.current().web.existsSync()) {
return null;
}
return WebApplicationPackage(FlutterProject.current());
case TargetPlatform.linux_x64:
case TargetPlatform.linux_arm64:
return applicationBinary == null
? LinuxApp.fromLinuxProject(FlutterProject.current().linux)
: LinuxApp.fromPrebuiltApp(applicationBinary);
case TargetPlatform.windows_x64:
return applicationBinary == null
? WindowsApp.fromWindowsProject(FlutterProject.current().windows)
: WindowsApp.fromPrebuiltApp(applicationBinary);
case TargetPlatform.fuchsia_arm64:
case TargetPlatform.fuchsia_x64:
return applicationBinary == null
? FuchsiaApp.fromFuchsiaProject(FlutterProject.current().fuchsia)
: FuchsiaApp.fromPrebuiltApp(applicationBinary);
case TargetPlatform.windows_uwp_x64:
throw UnsupportedError('Cannot build for windows_uwp_x64');
}
assert(platform != null);
return null;
}
}
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:meta/meta.dart';
import '../application_package.dart';
import '../base/file_system.dart';
import '../build_info.dart';
import '../globals.dart' as globals;
import '../project.dart';
import 'plist_parser.dart';
/// Tests whether a [Directory] is an iOS bundle directory.
bool _isBundleDirectory(Directory dir) => dir.path.endsWith('.app');
abstract class IOSApp extends ApplicationPackage {
IOSApp({@required String projectBundleId}) : super(id: projectBundleId);
/// Creates a new IOSApp from an existing app bundle or IPA.
factory IOSApp.fromPrebuiltApp(FileSystemEntity applicationBinary) {
final FileSystemEntityType entityType = globals.fs.typeSync(applicationBinary.path);
if (entityType == FileSystemEntityType.notFound) {
globals.printError(
'File "${applicationBinary.path}" does not exist. Use an app bundle or an ipa.');
return null;
}
Directory bundleDir;
if (entityType == FileSystemEntityType.directory) {
final Directory directory = globals.fs.directory(applicationBinary);
if (!_isBundleDirectory(directory)) {
globals.printError('Folder "${applicationBinary.path}" is not an app bundle.');
return null;
}
bundleDir = globals.fs.directory(applicationBinary);
} else {
// Try to unpack as an ipa.
final Directory tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_app.');
globals.os.unzip(globals.fs.file(applicationBinary), tempDir);
final Directory payloadDir = globals.fs.directory(
globals.fs.path.join(tempDir.path, 'Payload'),
);
if (!payloadDir.existsSync()) {
globals.printError(
'Invalid prebuilt iOS ipa. Does not contain a "Payload" directory.');
return null;
}
try {
bundleDir = payloadDir.listSync().whereType<Directory>().singleWhere(_isBundleDirectory);
} on StateError {
globals.printError(
'Invalid prebuilt iOS ipa. Does not contain a single app bundle.');
return null;
}
}
final String plistPath = globals.fs.path.join(bundleDir.path, 'Info.plist');
if (!globals.fs.file(plistPath).existsSync()) {
globals.printError('Invalid prebuilt iOS app. Does not contain Info.plist.');
return null;
}
final String id = globals.plistParser.getValueFromFile(
plistPath,
PlistParser.kCFBundleIdentifierKey,
);
if (id == null) {
globals.printError('Invalid prebuilt iOS app. Info.plist does not contain bundle identifier');
return null;
}
return PrebuiltIOSApp(
bundleDir: bundleDir,
bundleName: globals.fs.path.basename(bundleDir.path),
projectBundleId: id,
);
}
static Future<IOSApp> fromIosProject(IosProject project, BuildInfo buildInfo) {
if (!globals.platform.isMacOS) {
return null;
}
if (!project.exists) {
// If the project doesn't exist at all the current hint to run flutter
// create is accurate.
return null;
}
if (!project.xcodeProject.existsSync()) {
globals.printError('Expected ios/Runner.xcodeproj but this file is missing.');
return null;
}
if (!project.xcodeProjectInfoFile.existsSync()) {
globals.printError('Expected ios/Runner.xcodeproj/project.pbxproj but this file is missing.');
return null;
}
return BuildableIOSApp.fromProject(project, buildInfo);
}
@override
String get displayName => id;
String get simulatorBundlePath;
String get deviceBundlePath;
/// Directory used by ios-deploy to store incremental installation metadata for
/// faster second installs.
Directory get appDeltaDirectory;
}
class BuildableIOSApp extends IOSApp {
BuildableIOSApp(this.project, String projectBundleId, String hostAppBundleName)
: _hostAppBundleName = hostAppBundleName,
super(projectBundleId: projectBundleId);
static Future<BuildableIOSApp> fromProject(IosProject project, BuildInfo buildInfo) async {
final String projectBundleId = await project.productBundleIdentifier(buildInfo);
final String hostAppBundleName = await project.hostAppBundleName(buildInfo);
return BuildableIOSApp(project, projectBundleId, hostAppBundleName);
}
final IosProject project;
final String _hostAppBundleName;
@override
String get name => _hostAppBundleName;
@override
String get simulatorBundlePath => _buildAppPath('iphonesimulator');
@override
String get deviceBundlePath => _buildAppPath('iphoneos');
@override
Directory get appDeltaDirectory => globals.fs.directory(globals.fs.path.join(getIosBuildDirectory(), 'app-delta'));
// Xcode uses this path for the final archive bundle location,
// not a top-level output directory.
// Specifying `build/ios/archive/Runner` will result in `build/ios/archive/Runner.xcarchive`.
String get archiveBundlePath
=> globals.fs.path.join(getIosBuildDirectory(), 'archive', globals.fs.path.withoutExtension(_hostAppBundleName));
// The output xcarchive bundle path `build/ios/archive/Runner.xcarchive`.
String get archiveBundleOutputPath =>
globals.fs.path.setExtension(archiveBundlePath, '.xcarchive');
String get ipaOutputPath =>
globals.fs.path.join(getIosBuildDirectory(), 'ipa');
String _buildAppPath(String type) {
return globals.fs.path.join(getIosBuildDirectory(), type, _hostAppBundleName);
}
}
class PrebuiltIOSApp extends IOSApp {
PrebuiltIOSApp({
this.bundleDir,
this.bundleName,
@required String projectBundleId,
}) : super(projectBundleId: projectBundleId);
final Directory bundleDir;
final String bundleName;
@override
final Directory appDeltaDirectory = null;
@override
String get name => bundleName;
@override
String get simulatorBundlePath => _bundlePath;
@override
String get deviceBundlePath => _bundlePath;
String get _bundlePath => bundleDir.path;
}
......@@ -10,7 +10,6 @@ import 'package:meta/meta.dart';
import 'package:process/process.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
import '../application_package.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
......@@ -27,6 +26,7 @@ import '../macos/xcode.dart';
import '../project.dart';
import '../protocol_discovery.dart';
import '../vmservice.dart';
import 'application_package.dart';
import 'ios_deploy.dart';
import 'ios_workflow.dart';
import 'iproxy.dart';
......
......@@ -7,7 +7,6 @@
import 'package:meta/meta.dart';
import 'package:process/process.dart';
import '../application_package.dart';
import '../artifacts.dart';
import '../base/common.dart';
import '../base/file_system.dart';
......@@ -24,6 +23,7 @@ import '../macos/cocoapod_utils.dart';
import '../macos/xcode.dart';
import '../project.dart';
import '../reporting/reporting.dart';
import 'application_package.dart';
import 'code_signing.dart';
import 'devices.dart';
import 'migrations/project_base_configuration_migration.dart';
......
......@@ -26,6 +26,7 @@ import '../globals.dart' as globals;
import '../macos/xcode.dart';
import '../project.dart';
import '../protocol_discovery.dart';
import 'application_package.dart';
import 'mac.dart';
import 'plist_parser.dart';
......
......@@ -5,11 +5,13 @@
// @dart = 2.8
import 'package:file/file.dart';
import 'package:flutter_tools/src/android/application_package.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/install.dart';
import 'package:flutter_tools/src/ios/application_package.dart';
import 'package:mockito/mockito.dart';
import '../../src/common.dart';
......
......@@ -7,7 +7,7 @@
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_device.dart';
import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/android/application_package.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
......
......@@ -7,7 +7,7 @@
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_device.dart';
import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/android/application_package.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
......
......@@ -7,6 +7,7 @@
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/android/application_package.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
......@@ -17,6 +18,7 @@ import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/fuchsia/application_package.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/ios/application_package.dart';
import 'package:flutter_tools/src/ios/plist_parser.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:mockito/mockito.dart';
......
......@@ -8,7 +8,6 @@ import 'dart:async';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
......@@ -19,6 +18,7 @@ import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/device_port_forwader.dart';
import 'package:flutter_tools/src/ios/application_package.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/ios_deploy.dart';
import 'package:flutter_tools/src/ios/ios_workflow.dart';
......
......@@ -5,7 +5,6 @@
// @dart = 2.8
import 'package:file/memory.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
......@@ -13,6 +12,7 @@ import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/ios/application_package.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/ios_deploy.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
......
......@@ -6,7 +6,6 @@
import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
......@@ -14,6 +13,7 @@ import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/application_package.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/ios_deploy.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
......
......@@ -7,7 +7,6 @@
import 'dart:async';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
......@@ -16,6 +15,7 @@ import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/device_port_forwader.dart';
import 'package:flutter_tools/src/ios/application_package.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/ios_deploy.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
......
......@@ -5,7 +5,6 @@
// @dart = 2.8
import 'package:file/memory.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
......@@ -15,6 +14,7 @@ import 'package:flutter_tools/src/devfs.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/device_port_forwader.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/ios/application_package.dart';
import 'package:flutter_tools/src/ios/plist_parser.dart';
import 'package:flutter_tools/src/ios/simulators.dart';
import 'package:flutter_tools/src/macos/xcode.dart';
......
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