Migrate older Xcode projects off the legacy build system (#52288)

This commit is contained in:
Jenn Magder 2020-03-10 10:11:16 -07:00 committed by GitHub
parent 60d0fef17a
commit fdd023fa59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 137 additions and 10 deletions

View file

@ -24,6 +24,7 @@ import '../reporting/reporting.dart';
import 'code_signing.dart';
import 'migrations/ios_migrator.dart';
import 'migrations/remove_framework_link_and_embedding_migration.dart';
import 'migrations/xcode_build_system_migration.dart';
import 'xcodeproj.dart';
class IMobileDevice {
@ -90,7 +91,8 @@ Future<XcodeBuildResult> buildXcodeProject({
}
final List<IOSMigrator> migrators = <IOSMigrator>[
RemoveFrameworkLinkAndEmbeddingMigration(app.project, globals.logger, globals.xcode, globals.flutterUsage)
RemoveFrameworkLinkAndEmbeddingMigration(app.project, globals.logger, globals.xcode, globals.flutterUsage),
XcodeBuildSystemMigration(app.project, globals.logger),
];
final IOSMigration migration = IOSMigration(migrators);

View file

@ -20,7 +20,10 @@ abstract class IOSMigrator {
bool migrate();
/// Return null if the line should be deleted.
String migrateLine(String line);
@protected
String migrateLine(String line) {
return line;
}
@protected
void processFileLines(File file) {

View file

@ -10,9 +10,9 @@ import '../../project.dart';
import '../../reporting/reporting.dart';
import 'ios_migrator.dart';
/// Xcode 11.4 requires linked and embedded frameworks to contain all targeted architectures before build phases are run.
/// This caused issues switching between a real device and simulator due to architecture mismatch.
/// Remove the linking and embedding logic from the Xcode project to give the tool more control over these.
// Xcode 11.4 requires linked and embedded frameworks to contain all targeted architectures before build phases are run.
// This caused issues switching between a real device and simulator due to architecture mismatch.
// Remove the linking and embedding logic from the Xcode project to give the tool more control over these.
class RemoveFrameworkLinkAndEmbeddingMigration extends IOSMigrator {
RemoveFrameworkLinkAndEmbeddingMigration(
IosProject project,
@ -28,13 +28,8 @@ class RemoveFrameworkLinkAndEmbeddingMigration extends IOSMigrator {
final Xcode _xcode;
final Usage _usage;
/// Inspect [project] for necessary migrations and rewrite files as needed.
@override
bool migrate() {
return _migrateXcodeProjectInfoFile();
}
bool _migrateXcodeProjectInfoFile() {
if (!_xcodeProjectInfoFile.existsSync()) {
logger.printTrace('Xcode project not found, skipping migration');
return true;

View file

@ -0,0 +1,48 @@
// 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';
// Xcode legacy build system no longer supported by Xcode.
// Set in https://github.com/flutter/flutter/pull/21901/.
// Removed in https://github.com/flutter/flutter/pull/33684.
class XcodeBuildSystemMigration extends IOSMigrator {
XcodeBuildSystemMigration(
IosProject project,
Logger logger,
) : _xcodeWorkspaceSharedSettings = project.xcodeWorkspaceSharedSettings,
super(logger);
final File _xcodeWorkspaceSharedSettings;
@override
bool migrate() {
if (!_xcodeWorkspaceSharedSettings.existsSync()) {
logger.printTrace('Xcode workspace settings not found, skipping migration');
return true;
}
final String contents = _xcodeWorkspaceSharedSettings.readAsStringSync();
// Only delete this file when it matches the original Flutter template.
const String legacyBuildSettingsWorkspace = '''
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
</dict>
</plist>''';
// contains instead of equals to ignore newline file ending variance.
if (contents.contains(legacyBuildSettingsWorkspace)) {
logger.printStatus('Legacy build system detected, removing ${_xcodeWorkspaceSharedSettings.path}');
_xcodeWorkspaceSharedSettings.deleteSync();
}
return true;
}
}

View file

@ -12,6 +12,7 @@ import 'package:platform/platform.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/terminal.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';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
@ -257,6 +258,84 @@ keep this 2
verify(mockUsage.sendEvent('ios-migration', 'remove-frameworks', label: 'failure', value: null));
});
});
group('new Xcode build system', () {
MemoryFileSystem memoryFileSystem;
BufferLogger testLogger;
MockIosProject mockIosProject;
File xcodeWorkspaceSharedSettings;
setUp(() {
memoryFileSystem = MemoryFileSystem();
xcodeWorkspaceSharedSettings = memoryFileSystem.file('WorkspaceSettings.xcsettings');
testLogger = BufferLogger(
terminal: AnsiTerminal(
stdio: null,
platform: const LocalPlatform(),
),
outputPreferences: OutputPreferences.test(),
);
mockIosProject = MockIosProject();
when(mockIosProject.xcodeWorkspaceSharedSettings).thenReturn(xcodeWorkspaceSharedSettings);
});
testWithoutContext('skipped if files are missing', () {
final XcodeBuildSystemMigration iosProjectMigration = XcodeBuildSystemMigration(
mockIosProject,
testLogger,
);
expect(iosProjectMigration.migrate(), isTrue);
expect(xcodeWorkspaceSharedSettings.existsSync(), isFalse);
expect(testLogger.traceText, contains('Xcode workspace settings not found, skipping migration'));
expect(testLogger.statusText, isEmpty);
});
testWithoutContext('skipped if nothing to upgrade', () {
const String contents = '''
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string></string>
</dict>
</plist>''';
xcodeWorkspaceSharedSettings.writeAsStringSync(contents);
final XcodeBuildSystemMigration iosProjectMigration = XcodeBuildSystemMigration(
mockIosProject,
testLogger,
);
expect(iosProjectMigration.migrate(), isTrue);
expect(xcodeWorkspaceSharedSettings.existsSync(), isTrue);
expect(testLogger.statusText, isEmpty);
});
testWithoutContext('Xcode project is migrated', () {
const String contents = '''
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
</dict>
</plist>''';
xcodeWorkspaceSharedSettings.writeAsStringSync(contents);
final XcodeBuildSystemMigration iosProjectMigration = XcodeBuildSystemMigration(
mockIosProject,
testLogger,
);
expect(iosProjectMigration.migrate(), isTrue);
expect(xcodeWorkspaceSharedSettings.existsSync(), isFalse);
expect(testLogger.statusText, contains('Legacy build system detected, removing'));
});
});
});
}