Unverified Commit 483f71ae authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Migrate application_package to null safety (#83956)

parent efe0c5eb
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:meta/meta.dart';
import '../application_package.dart'; import '../application_package.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../build_info.dart'; import '../build_info.dart';
...@@ -13,15 +9,14 @@ import '../globals_null_migrated.dart' as globals; ...@@ -13,15 +9,14 @@ import '../globals_null_migrated.dart' as globals;
import '../project.dart'; import '../project.dart';
import 'plist_parser.dart'; import 'plist_parser.dart';
/// Tests whether a [Directory] is an iOS bundle directory. /// Tests whether a [Directory] is an iOS bundle directory.
bool _isBundleDirectory(Directory dir) => dir.path.endsWith('.app'); bool _isBundleDirectory(Directory dir) => dir.path.endsWith('.app');
abstract class IOSApp extends ApplicationPackage { abstract class IOSApp extends ApplicationPackage {
IOSApp({@required String projectBundleId}) : super(id: projectBundleId); IOSApp({required String projectBundleId}) : super(id: projectBundleId);
/// Creates a new IOSApp from an existing app bundle or IPA. /// Creates a new IOSApp from an existing app bundle or IPA.
factory IOSApp.fromPrebuiltApp(FileSystemEntity applicationBinary) { static IOSApp? fromPrebuiltApp(FileSystemEntity applicationBinary) {
final FileSystemEntityType entityType = globals.fs.typeSync(applicationBinary.path); final FileSystemEntityType entityType = globals.fs.typeSync(applicationBinary.path);
if (entityType == FileSystemEntityType.notFound) { if (entityType == FileSystemEntityType.notFound) {
globals.printError( globals.printError(
...@@ -61,7 +56,7 @@ abstract class IOSApp extends ApplicationPackage { ...@@ -61,7 +56,7 @@ abstract class IOSApp extends ApplicationPackage {
globals.printError('Invalid prebuilt iOS app. Does not contain Info.plist.'); globals.printError('Invalid prebuilt iOS app. Does not contain Info.plist.');
return null; return null;
} }
final String id = globals.plistParser.getValueFromFile( final String? id = globals.plistParser.getValueFromFile(
plistPath, plistPath,
PlistParser.kCFBundleIdentifierKey, PlistParser.kCFBundleIdentifierKey,
); );
...@@ -77,7 +72,7 @@ abstract class IOSApp extends ApplicationPackage { ...@@ -77,7 +72,7 @@ abstract class IOSApp extends ApplicationPackage {
); );
} }
static Future<IOSApp> fromIosProject(IosProject project, BuildInfo buildInfo) { static Future<IOSApp?> fromIosProject(IosProject project, BuildInfo buildInfo) async {
if (!globals.platform.isMacOS) { if (!globals.platform.isMacOS) {
return null; return null;
} }
...@@ -106,26 +101,29 @@ abstract class IOSApp extends ApplicationPackage { ...@@ -106,26 +101,29 @@ abstract class IOSApp extends ApplicationPackage {
/// Directory used by ios-deploy to store incremental installation metadata for /// Directory used by ios-deploy to store incremental installation metadata for
/// faster second installs. /// faster second installs.
Directory get appDeltaDirectory; Directory? get appDeltaDirectory;
} }
class BuildableIOSApp extends IOSApp { class BuildableIOSApp extends IOSApp {
BuildableIOSApp(this.project, String projectBundleId, String hostAppBundleName) BuildableIOSApp(this.project, String projectBundleId, String? hostAppBundleName)
: _hostAppBundleName = hostAppBundleName, : _hostAppBundleName = hostAppBundleName,
super(projectBundleId: projectBundleId); super(projectBundleId: projectBundleId);
static Future<BuildableIOSApp> fromProject(IosProject project, BuildInfo buildInfo) async { static Future<BuildableIOSApp?> fromProject(IosProject project, BuildInfo buildInfo) async {
final String projectBundleId = await project.productBundleIdentifier(buildInfo); final String? hostAppBundleName = await project.hostAppBundleName(buildInfo);
final String hostAppBundleName = await project.hostAppBundleName(buildInfo); final String? projectBundleId = await project.productBundleIdentifier(buildInfo);
if (projectBundleId != null) {
return BuildableIOSApp(project, projectBundleId, hostAppBundleName); return BuildableIOSApp(project, projectBundleId, hostAppBundleName);
} }
return null;
}
final IosProject project; final IosProject project;
final String _hostAppBundleName; final String? _hostAppBundleName;
@override @override
String get name => _hostAppBundleName; String? get name => _hostAppBundleName;
@override @override
String get simulatorBundlePath => _buildAppPath('iphonesimulator'); String get simulatorBundlePath => _buildAppPath('iphonesimulator');
...@@ -139,8 +137,8 @@ class BuildableIOSApp extends IOSApp { ...@@ -139,8 +137,8 @@ class BuildableIOSApp extends IOSApp {
// Xcode uses this path for the final archive bundle location, // Xcode uses this path for the final archive bundle location,
// not a top-level output directory. // not a top-level output directory.
// Specifying `build/ios/archive/Runner` will result in `build/ios/archive/Runner.xcarchive`. // Specifying `build/ios/archive/Runner` will result in `build/ios/archive/Runner.xcarchive`.
String get archiveBundlePath String get archiveBundlePath => globals.fs.path.join(getIosBuildDirectory(), 'archive',
=> globals.fs.path.join(getIosBuildDirectory(), 'archive', globals.fs.path.withoutExtension(_hostAppBundleName)); _hostAppBundleName == null ? 'Runner' : globals.fs.path.withoutExtension(_hostAppBundleName!));
// The output xcarchive bundle path `build/ios/archive/Runner.xcarchive`. // The output xcarchive bundle path `build/ios/archive/Runner.xcarchive`.
String get archiveBundleOutputPath => String get archiveBundleOutputPath =>
...@@ -156,19 +154,19 @@ class BuildableIOSApp extends IOSApp { ...@@ -156,19 +154,19 @@ class BuildableIOSApp extends IOSApp {
class PrebuiltIOSApp extends IOSApp { class PrebuiltIOSApp extends IOSApp {
PrebuiltIOSApp({ PrebuiltIOSApp({
this.bundleDir, required this.bundleDir,
this.bundleName, this.bundleName,
@required String projectBundleId, required String projectBundleId,
}) : super(projectBundleId: projectBundleId); }) : super(projectBundleId: projectBundleId);
final Directory bundleDir; final Directory bundleDir;
final String bundleName; final String? bundleName;
@override @override
final Directory appDeltaDirectory = null; final Directory? appDeltaDirectory = null;
@override @override
String get name => bundleName; String? get name => bundleName;
@override @override
String get simulatorBundlePath => _bundlePath; String get simulatorBundlePath => _bundlePath;
......
...@@ -381,6 +381,17 @@ void main() { ...@@ -381,6 +381,17 @@ void main() {
expect(iosApp, null); expect(iosApp, null);
}, overrides: overrides); }, overrides: overrides);
testUsingContext('returns null when there with no product identifier', () async {
globals.fs.file('pubspec.yaml').createSync();
globals.fs.file('.packages').createSync();
final Directory project = globals.fs.directory('ios/Runner.xcodeproj')..createSync(recursive: true);
project.childFile('project.pbxproj').createSync();
final BuildableIOSApp iosApp = await IOSApp.fromIosProject(
FlutterProject.fromDirectory(globals.fs.currentDirectory).ios, null) as BuildableIOSApp;
expect(iosApp, null);
}, overrides: overrides);
}); });
group('FuchsiaApp', () { group('FuchsiaApp', () {
......
...@@ -30,14 +30,17 @@ const Map<String, String> kDyLdLibEntry = <String, String>{ ...@@ -30,14 +30,17 @@ const Map<String, String> kDyLdLibEntry = <String, String>{
void main() { void main() {
Artifacts artifacts; Artifacts artifacts;
String iosDeployPath; String iosDeployPath;
FileSystem fileSystem;
Directory bundleDirectory;
setUp(() { setUp(() {
artifacts = Artifacts.test(); artifacts = Artifacts.test();
fileSystem = MemoryFileSystem.test();
bundleDirectory = fileSystem.directory('bundle');
iosDeployPath = artifacts.getHostArtifact(HostArtifact.iosDeploy).path; iosDeployPath = artifacts.getHostArtifact(HostArtifact.iosDeploy).path;
}); });
testWithoutContext('IOSDevice.installApp calls ios-deploy correctly with USB', () async { testWithoutContext('IOSDevice.installApp calls ios-deploy correctly with USB', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
final IOSApp iosApp = PrebuiltIOSApp( final IOSApp iosApp = PrebuiltIOSApp(
projectBundleId: 'app', projectBundleId: 'app',
bundleDir: fileSystem.currentDirectory, bundleDir: fileSystem.currentDirectory,
...@@ -68,7 +71,6 @@ void main() { ...@@ -68,7 +71,6 @@ void main() {
}); });
testWithoutContext('IOSDevice.installApp calls ios-deploy correctly with network', () async { testWithoutContext('IOSDevice.installApp calls ios-deploy correctly with network', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
final IOSApp iosApp = PrebuiltIOSApp( final IOSApp iosApp = PrebuiltIOSApp(
projectBundleId: 'app', projectBundleId: 'app',
bundleDir: fileSystem.currentDirectory, bundleDir: fileSystem.currentDirectory,
...@@ -98,7 +100,7 @@ void main() { ...@@ -98,7 +100,7 @@ void main() {
}); });
testWithoutContext('IOSDevice.uninstallApp calls ios-deploy correctly', () async { testWithoutContext('IOSDevice.uninstallApp calls ios-deploy correctly', () async {
final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app'); final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app', bundleDir: bundleDirectory);
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: <String>[ FakeCommand(command: <String>[
iosDeployPath, iosDeployPath,
...@@ -121,7 +123,7 @@ void main() { ...@@ -121,7 +123,7 @@ void main() {
group('isAppInstalled', () { group('isAppInstalled', () {
testWithoutContext('catches ProcessException from ios-deploy', () async { testWithoutContext('catches ProcessException from ios-deploy', () async {
final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app'); final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app', bundleDir: bundleDirectory);
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: <String>[ FakeCommand(command: <String>[
iosDeployPath, iosDeployPath,
...@@ -145,7 +147,7 @@ void main() { ...@@ -145,7 +147,7 @@ void main() {
}); });
testWithoutContext('returns true when app is installed', () async { testWithoutContext('returns true when app is installed', () async {
final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app'); final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app', bundleDir: bundleDirectory);
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: <String>[ FakeCommand(command: <String>[
iosDeployPath, iosDeployPath,
...@@ -169,7 +171,7 @@ void main() { ...@@ -169,7 +171,7 @@ void main() {
}); });
testWithoutContext('returns false when app is not installed', () async { testWithoutContext('returns false when app is not installed', () async {
final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app'); final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app', bundleDir: bundleDirectory);
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: <String>[ FakeCommand(command: <String>[
iosDeployPath, iosDeployPath,
...@@ -195,7 +197,7 @@ void main() { ...@@ -195,7 +197,7 @@ void main() {
}); });
testWithoutContext('returns false on command timeout or other error', () async { testWithoutContext('returns false on command timeout or other error', () async {
final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app'); final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app', bundleDir: bundleDirectory);
const String stderr = '2020-03-26 17:48:43.484 ios-deploy[21518:5501783] [ !! ] Timed out waiting for device'; const String stderr = '2020-03-26 17:48:43.484 ios-deploy[21518:5501783] [ !! ] Timed out waiting for device';
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: <String>[ FakeCommand(command: <String>[
...@@ -224,7 +226,6 @@ void main() { ...@@ -224,7 +226,6 @@ void main() {
}); });
testWithoutContext('IOSDevice.installApp catches ProcessException from ios-deploy', () async { testWithoutContext('IOSDevice.installApp catches ProcessException from ios-deploy', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
final IOSApp iosApp = PrebuiltIOSApp( final IOSApp iosApp = PrebuiltIOSApp(
projectBundleId: 'app', projectBundleId: 'app',
bundleDir: fileSystem.currentDirectory, bundleDir: fileSystem.currentDirectory,
...@@ -249,7 +250,7 @@ void main() { ...@@ -249,7 +250,7 @@ void main() {
}); });
testWithoutContext('IOSDevice.uninstallApp catches ProcessException from ios-deploy', () async { testWithoutContext('IOSDevice.uninstallApp catches ProcessException from ios-deploy', () async {
final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app'); final IOSApp iosApp = PrebuiltIOSApp(projectBundleId: 'app', bundleDir: bundleDirectory);
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[ final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: <String>[ FakeCommand(command: <String>[
iosDeployPath, iosDeployPath,
......
...@@ -93,6 +93,7 @@ void main() { ...@@ -93,6 +93,7 @@ void main() {
final IOSApp iosApp = PrebuiltIOSApp( final IOSApp iosApp = PrebuiltIOSApp(
projectBundleId: 'app', projectBundleId: 'app',
bundleName: 'Runner', bundleName: 'Runner',
bundleDir: MemoryFileSystem.test().directory('bundle'),
); );
device.portForwarder = devicePortForwarder; device.portForwarder = devicePortForwarder;
......
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