Unverified Commit dd9323bd authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Build iOS apps using Swift Packages (#68361)

parent 4a3e2a1a
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,9 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,9 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -25,6 +25,7 @@ import 'code_signing.dart';
import 'devices.dart';
import 'migrations/ios_migrator.dart';
import 'migrations/project_base_configuration_migration.dart';
import 'migrations/project_build_location_migration.dart';
import 'migrations/remove_framework_link_and_embedding_migration.dart';
import 'migrations/xcode_build_system_migration.dart';
import 'xcodeproj.dart';
......@@ -106,6 +107,7 @@ Future<XcodeBuildResult> buildXcodeProject({
RemoveFrameworkLinkAndEmbeddingMigration(app.project, globals.logger, globals.xcode, globals.flutterUsage),
XcodeBuildSystemMigration(app.project, globals.logger),
ProjectBaseConfigurationMigration(app.project, globals.logger),
ProjectBuildLocationMigration(app.project, globals.logger),
];
final IOSMigration migration = IOSMigration(migrators);
......
......@@ -26,6 +26,13 @@ abstract class IOSMigrator {
}
@protected
String migrateFileContents(String fileContents) {
return fileContents;
}
@protected
/// Calls [migrateLine] per line, then [migrateFileContents]
/// including the line migrations.
void processFileLines(File file) {
final List<String> lines = file.readAsLinesSync();
......@@ -51,9 +58,16 @@ abstract class IOSMigrator {
newProjectContents.writeln(newProjectLine);
}
final String projectContentsWithMigratedLines = newProjectContents.toString();
final String projectContentsWithMigratedContents = migrateFileContents(projectContentsWithMigratedLines);
if (projectContentsWithMigratedLines != projectContentsWithMigratedContents) {
logger.printTrace('Migrating $basename contents');
migrationRequired = true;
}
if (migrationRequired) {
logger.printStatus('Upgrading $basename');
file.writeAsStringSync(newProjectContents.toString());
file.writeAsStringSync(projectContentsWithMigratedContents);
}
}
}
......
// 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.
import '../../base/file_system.dart';
import '../../base/logger.dart';
import '../../project.dart';
import 'ios_migrator.dart';
// Update the xcodeproj build location. Legacy build location does not work with Swift Packages.
class ProjectBuildLocationMigration extends IOSMigrator {
ProjectBuildLocationMigration(
IosProject project,
Logger logger,
) : _xcodeProjectWorkspaceData = project.xcodeProjectWorkspaceData,
super(logger);
final File _xcodeProjectWorkspaceData;
@override
bool migrate() {
if (!_xcodeProjectWorkspaceData.existsSync()) {
logger.printTrace('Xcode project workspace data not found, skipping build location migration.');
return true;
}
processFileLines(_xcodeProjectWorkspaceData);
return true;
}
@override
String migrateLine(String line) {
const String legacyBuildLocation = 'location = "group:Runner.xcodeproj"';
const String defaultBuildLocation = 'location = "self:"';
return line.replaceAll(legacyBuildLocation, defaultBuildLocation);
}
@override
String migrateFileContents(String fileContents) {
const String podLocation = '''
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
''';
return fileContents.replaceAll(podLocation, '');
}
}
......@@ -444,6 +444,11 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
@override
File get xcodeProjectInfoFile => xcodeProject.childFile('project.pbxproj');
File get xcodeProjectWorkspaceData =>
xcodeProject
.childDirectory('project.xcworkspace')
.childFile('contents.xcworkspacedata');
@override
Directory get xcodeWorkspace => hostAppRoot.childDirectory('$_hostAppProjectName.xcworkspace');
......
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
......@@ -5,10 +5,9 @@
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/ios/migrations/ios_migrator.dart';
import 'package:flutter_tools/src/ios/migrations/project_base_configuration_migration.dart';
import 'package:flutter_tools/src/ios/migrations/project_build_location_migration.dart';
import 'package:flutter_tools/src/ios/migrations/remove_framework_link_and_embedding_migration.dart';
import 'package:flutter_tools/src/ios/migrations/xcode_build_system_migration.dart';
import 'package:flutter_tools/src/macos/xcode.dart';
......@@ -49,15 +48,7 @@ void main () {
memoryFileSystem = MemoryFileSystem.test();
mockXcode = MockXcode();
xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj');
testLogger = BufferLogger(
terminal: AnsiTerminal(
stdio: null,
platform: const LocalPlatform(),
),
outputPreferences: OutputPreferences.test(),
);
testLogger = BufferLogger.test();
mockIosProject = MockIosProject();
when(mockIosProject.xcodeProjectInfoFile).thenReturn(xcodeProjectInfoFile);
});
......@@ -267,15 +258,7 @@ keep this 2
setUp(() {
memoryFileSystem = MemoryFileSystem.test();
xcodeWorkspaceSharedSettings = memoryFileSystem.file('WorkspaceSettings.xcsettings');
testLogger = BufferLogger(
terminal: AnsiTerminal(
stdio: null,
platform: const LocalPlatform(),
),
outputPreferences: OutputPreferences.test(),
);
testLogger = BufferLogger.test();
mockIosProject = MockIosProject();
when(mockIosProject.xcodeWorkspaceSharedSettings).thenReturn(xcodeWorkspaceSharedSettings);
});
......@@ -338,24 +321,95 @@ keep this 2
});
});
group('remove Runner project base configuration', () {
group('Xcode default build location', () {
MemoryFileSystem memoryFileSystem;
BufferLogger testLogger;
MockIosProject mockIosProject;
File xcodeProjectInfoFile;
File xcodeProjectWorkspaceData;
setUp(() {
memoryFileSystem = MemoryFileSystem.test();
xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj');
memoryFileSystem = MemoryFileSystem();
xcodeProjectWorkspaceData = memoryFileSystem.file('contents.xcworkspacedata');
testLogger = BufferLogger.test();
mockIosProject = MockIosProject();
when(mockIosProject.xcodeProjectWorkspaceData).thenReturn(xcodeProjectWorkspaceData);
});
testWithoutContext('skipped if files are missing', () {
final ProjectBuildLocationMigration iosProjectMigration = ProjectBuildLocationMigration(
mockIosProject,
testLogger,
);
expect(iosProjectMigration.migrate(), isTrue);
expect(xcodeProjectWorkspaceData.existsSync(), isFalse);
expect(testLogger.traceText, contains('Xcode project workspace data not found, skipping build location migration.'));
expect(testLogger.statusText, isEmpty);
});
testWithoutContext('skipped if nothing to upgrade', () {
const String contents = '''
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>''';
xcodeProjectWorkspaceData.writeAsStringSync(contents);
final ProjectBuildLocationMigration iosProjectMigration = ProjectBuildLocationMigration(
mockIosProject,
testLogger,
);
expect(iosProjectMigration.migrate(), isTrue);
expect(xcodeProjectWorkspaceData.existsSync(), isTrue);
expect(testLogger.statusText, isEmpty);
});
testLogger = BufferLogger(
terminal: AnsiTerminal(
stdio: null,
platform: const LocalPlatform(),
),
outputPreferences: OutputPreferences.test(),
testWithoutContext('Xcode project is migrated', () {
const String contents = '''
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
''';
xcodeProjectWorkspaceData.writeAsStringSync(contents);
final ProjectBuildLocationMigration iosProjectMigration = ProjectBuildLocationMigration(
mockIosProject,
testLogger,
);
expect(iosProjectMigration.migrate(), isTrue);
expect(xcodeProjectWorkspaceData.readAsStringSync(), '''
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
''');
expect(testLogger.statusText, contains('Upgrading contents.xcworkspacedata'));
});
});
group('remove Runner project base configuration', () {
MemoryFileSystem memoryFileSystem;
BufferLogger testLogger;
MockIosProject mockIosProject;
File xcodeProjectInfoFile;
setUp(() {
memoryFileSystem = MemoryFileSystem();
xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj');
testLogger = BufferLogger.test();
mockIosProject = MockIosProject();
when(mockIosProject.xcodeProjectInfoFile).thenReturn(xcodeProjectInfoFile);
});
......
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