Unverified Commit 28db5a0f authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Build iOS apps using Swift Packages (#72761)

parent 3082a280
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -39,7 +39,7 @@ target 'watch Extension' do ...@@ -39,7 +39,7 @@ target 'watch Extension' do
use_frameworks! use_frameworks!
use_modular_headers! use_modular_headers!
pod 'EFQRCode/watchOS', '5.1.6' pod 'EFQRCode', '6.0'
end end
post_install do |installer| post_install do |installer|
......
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,9 +2,6 @@ ...@@ -2,9 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,9 +2,6 @@ ...@@ -2,9 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -26,6 +26,13 @@ abstract class ProjectMigrator { ...@@ -26,6 +26,13 @@ abstract class ProjectMigrator {
} }
@protected @protected
String migrateFileContents(String fileContents) {
return fileContents;
}
@protected
/// Calls [migrateLine] per line, then [migrateFileContents]
/// including the line migrations.
void processFileLines(File file) { void processFileLines(File file) {
final List<String> lines = file.readAsLinesSync(); final List<String> lines = file.readAsLinesSync();
...@@ -51,9 +58,16 @@ abstract class ProjectMigrator { ...@@ -51,9 +58,16 @@ abstract class ProjectMigrator {
newProjectContents.writeln(newProjectLine); 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) { if (migrationRequired) {
logger.printStatus('Upgrading $basename'); logger.printStatus('Upgrading $basename');
file.writeAsStringSync(newProjectContents.toString()); file.writeAsStringSync(projectContentsWithMigratedContents);
} }
} }
} }
......
...@@ -25,6 +25,7 @@ import '../reporting/reporting.dart'; ...@@ -25,6 +25,7 @@ import '../reporting/reporting.dart';
import 'code_signing.dart'; import 'code_signing.dart';
import 'devices.dart'; import 'devices.dart';
import 'migrations/project_base_configuration_migration.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/remove_framework_link_and_embedding_migration.dart';
import 'migrations/xcode_build_system_migration.dart'; import 'migrations/xcode_build_system_migration.dart';
import 'xcodeproj.dart'; import 'xcodeproj.dart';
...@@ -106,6 +107,7 @@ Future<XcodeBuildResult> buildXcodeProject({ ...@@ -106,6 +107,7 @@ Future<XcodeBuildResult> buildXcodeProject({
RemoveFrameworkLinkAndEmbeddingMigration(app.project, globals.logger, globals.xcode, globals.flutterUsage), RemoveFrameworkLinkAndEmbeddingMigration(app.project, globals.logger, globals.xcode, globals.flutterUsage),
XcodeBuildSystemMigration(app.project, globals.logger), XcodeBuildSystemMigration(app.project, globals.logger),
ProjectBaseConfigurationMigration(app.project, globals.logger), ProjectBaseConfigurationMigration(app.project, globals.logger),
ProjectBuildLocationMigration(app.project, globals.logger),
]; ];
final ProjectMigration migration = ProjectMigration(migrators); final ProjectMigration migration = ProjectMigration(migrators);
......
// 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 '../../base/project_migrator.dart';
import '../../project.dart';
// Update the xcodeproj build location. Legacy build location does not work with Swift Packages.
class ProjectBuildLocationMigration extends ProjectMigrator {
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, '');
}
}
...@@ -446,6 +446,11 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject { ...@@ -446,6 +446,11 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
@override @override
File get xcodeProjectInfoFile => xcodeProject.childFile('project.pbxproj'); File get xcodeProjectInfoFile => xcodeProject.childFile('project.pbxproj');
File get xcodeProjectWorkspaceData =>
xcodeProject
.childDirectory('project.xcworkspace')
.childFile('contents.xcworkspacedata');
@override @override
Directory get xcodeWorkspace => hostAppRoot.childDirectory('$_hostAppProjectName.xcworkspace'); Directory get xcodeWorkspace => hostAppRoot.childDirectory('$_hostAppProjectName.xcworkspace');
......
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -2,6 +2,6 @@ ...@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>
...@@ -5,10 +5,9 @@ ...@@ -5,10 +5,9 @@
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/logger.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/base/project_migrator.dart'; import 'package:flutter_tools/src/base/project_migrator.dart';
import 'package:flutter_tools/src/ios/migrations/project_base_configuration_migration.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/remove_framework_link_and_embedding_migration.dart';
import 'package:flutter_tools/src/ios/migrations/xcode_build_system_migration.dart'; import 'package:flutter_tools/src/ios/migrations/xcode_build_system_migration.dart';
import 'package:flutter_tools/src/macos/xcode.dart'; import 'package:flutter_tools/src/macos/xcode.dart';
...@@ -49,15 +48,7 @@ void main () { ...@@ -49,15 +48,7 @@ void main () {
memoryFileSystem = MemoryFileSystem.test(); memoryFileSystem = MemoryFileSystem.test();
mockXcode = MockXcode(); mockXcode = MockXcode();
xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj'); xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj');
testLogger = BufferLogger.test();
testLogger = BufferLogger(
terminal: AnsiTerminal(
stdio: null,
platform: const LocalPlatform(),
),
outputPreferences: OutputPreferences.test(),
);
mockIosProject = MockIosProject(); mockIosProject = MockIosProject();
when(mockIosProject.xcodeProjectInfoFile).thenReturn(xcodeProjectInfoFile); when(mockIosProject.xcodeProjectInfoFile).thenReturn(xcodeProjectInfoFile);
}); });
...@@ -267,15 +258,7 @@ keep this 2 ...@@ -267,15 +258,7 @@ keep this 2
setUp(() { setUp(() {
memoryFileSystem = MemoryFileSystem.test(); memoryFileSystem = MemoryFileSystem.test();
xcodeWorkspaceSharedSettings = memoryFileSystem.file('WorkspaceSettings.xcsettings'); xcodeWorkspaceSharedSettings = memoryFileSystem.file('WorkspaceSettings.xcsettings');
testLogger = BufferLogger.test();
testLogger = BufferLogger(
terminal: AnsiTerminal(
stdio: null,
platform: const LocalPlatform(),
),
outputPreferences: OutputPreferences.test(),
);
mockIosProject = MockIosProject(); mockIosProject = MockIosProject();
when(mockIosProject.xcodeWorkspaceSharedSettings).thenReturn(xcodeWorkspaceSharedSettings); when(mockIosProject.xcodeWorkspaceSharedSettings).thenReturn(xcodeWorkspaceSharedSettings);
}); });
...@@ -338,24 +321,95 @@ keep this 2 ...@@ -338,24 +321,95 @@ keep this 2
}); });
}); });
group('remove Runner project base configuration', () { group('Xcode default build location', () {
MemoryFileSystem memoryFileSystem; MemoryFileSystem memoryFileSystem;
BufferLogger testLogger; BufferLogger testLogger;
MockIosProject mockIosProject; MockIosProject mockIosProject;
File xcodeProjectInfoFile; File xcodeProjectWorkspaceData;
setUp(() { setUp(() {
memoryFileSystem = MemoryFileSystem.test(); memoryFileSystem = MemoryFileSystem();
xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj'); 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( testWithoutContext('Xcode project is migrated', () {
terminal: AnsiTerminal( const String contents = '''
stdio: null, <?xml version="1.0" encoding="UTF-8"?>
platform: const LocalPlatform(), <Workspace
), version = "1.0">
outputPreferences: OutputPreferences.test(), <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(); mockIosProject = MockIosProject();
when(mockIosProject.xcodeProjectInfoFile).thenReturn(xcodeProjectInfoFile); 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