mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Update minimum macOS version as needed in Swift package (#152347)
If Swift Package Manager is enabled, the tool generates a Swift package at `<ios/macos>/Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage/`. This Swift package is how the tool adds plugins to the Flutter project. SwiftPM is strictly enforces platform versions: you cannot depend on a Swift package if its supported version is higher than your own. On iOS, we use the project's minimum deployment version for the generated Swift package. If a plugin has a higher requirement, you'll need to update your project's minimum deployment version. The generated Swift package is automatically updated the next time you run the tool. This updates macOS to do the same thing. Fixes https://github.com/flutter/flutter/issues/146204
This commit is contained in:
parent
0632b904d9
commit
40843e3e61
@ -195,6 +195,11 @@ class XcodeProjectInterpreter {
|
||||
final String? configuration = buildContext.configuration;
|
||||
final String? target = buildContext.target;
|
||||
final String? deviceId = buildContext.deviceId;
|
||||
final String buildDir = switch (buildContext.sdk) {
|
||||
XcodeSdk.MacOSX => getMacOSBuildDirectory(),
|
||||
XcodeSdk.IPhoneOS || XcodeSdk.IPhoneSimulator => getIosBuildDirectory(),
|
||||
XcodeSdk.WatchOS || XcodeSdk.WatchSimulator => getIosBuildDirectory(),
|
||||
};
|
||||
final List<String> showBuildSettingsCommand = <String>[
|
||||
...xcrunCommand(),
|
||||
'xcodebuild',
|
||||
@ -206,21 +211,20 @@ class XcodeProjectInterpreter {
|
||||
...<String>['-configuration', configuration],
|
||||
if (target != null)
|
||||
...<String>['-target', target],
|
||||
if (buildContext.environmentType == EnvironmentType.simulator)
|
||||
if (buildContext.sdk == XcodeSdk.IPhoneSimulator || buildContext.sdk == XcodeSdk.WatchSimulator)
|
||||
...<String>['-sdk', 'iphonesimulator'],
|
||||
'-destination',
|
||||
if (buildContext.isWatch && buildContext.environmentType == EnvironmentType.physical)
|
||||
'generic/platform=watchOS'
|
||||
else if (buildContext.isWatch)
|
||||
'generic/platform=watchOS Simulator'
|
||||
else if (deviceId != null)
|
||||
if (deviceId != null)
|
||||
'id=$deviceId'
|
||||
else if (buildContext.environmentType == EnvironmentType.physical)
|
||||
'generic/platform=iOS'
|
||||
else
|
||||
'generic/platform=iOS Simulator',
|
||||
else switch (buildContext.sdk) {
|
||||
XcodeSdk.IPhoneOS => 'generic/platform=iOS',
|
||||
XcodeSdk.IPhoneSimulator => 'generic/platform=iOS Simulator',
|
||||
XcodeSdk.MacOSX => 'generic/platform=macOS',
|
||||
XcodeSdk.WatchOS => 'generic/platform=watchOS',
|
||||
XcodeSdk.WatchSimulator => 'generic/platform=watchOS Simulator',
|
||||
},
|
||||
'-showBuildSettings',
|
||||
'BUILD_DIR=${_fileSystem.path.absolute(getIosBuildDirectory())}',
|
||||
'BUILD_DIR=${_fileSystem.path.absolute(buildDir)}',
|
||||
...environmentVariablesAsXcodeBuildSettings(_platform),
|
||||
];
|
||||
try {
|
||||
@ -238,14 +242,19 @@ class XcodeProjectInterpreter {
|
||||
return parseXcodeBuildSettings(out);
|
||||
} on Exception catch (error) {
|
||||
if (error is ProcessException && error.toString().contains('timed out')) {
|
||||
final String eventType = switch (buildContext.sdk) {
|
||||
XcodeSdk.MacOSX => 'macos',
|
||||
XcodeSdk.IPhoneOS || XcodeSdk.IPhoneSimulator => 'ios',
|
||||
XcodeSdk.WatchOS || XcodeSdk.WatchSimulator => 'watchos',
|
||||
};
|
||||
BuildEvent('xcode-show-build-settings-timeout',
|
||||
type: 'ios',
|
||||
type: eventType,
|
||||
command: showBuildSettingsCommand.join(' '),
|
||||
flutterUsage: _usage,
|
||||
).send();
|
||||
_analytics.send(Event.flutterBuildInfo(
|
||||
label: 'xcode-show-build-settings-timeout',
|
||||
buildType: 'ios',
|
||||
buildType: eventType,
|
||||
command: showBuildSettingsCommand.join(' '),
|
||||
));
|
||||
}
|
||||
@ -394,26 +403,40 @@ String substituteXcodeVariables(String str, Map<String, String> xcodeBuildSettin
|
||||
return str.replaceAllMapped(_varExpr, (Match m) => xcodeBuildSettings[m[1]!] ?? m[0]!);
|
||||
}
|
||||
|
||||
/// Xcode SDKs. Corresponds to undocumented Xcode SUPPORTED_PLATFORMS values.
|
||||
/// Use `xcodebuild -showsdks` to get a list of SDKs installed on your machine.
|
||||
enum XcodeSdk {
|
||||
IPhoneOS,
|
||||
IPhoneSimulator,
|
||||
MacOSX,
|
||||
WatchOS,
|
||||
WatchSimulator,
|
||||
}
|
||||
|
||||
@immutable
|
||||
class XcodeProjectBuildContext {
|
||||
const XcodeProjectBuildContext({
|
||||
this.scheme,
|
||||
this.configuration,
|
||||
this.environmentType = EnvironmentType.physical,
|
||||
this.sdk = XcodeSdk.IPhoneOS,
|
||||
this.deviceId,
|
||||
this.target,
|
||||
this.isWatch = false,
|
||||
});
|
||||
|
||||
final String? scheme;
|
||||
final String? configuration;
|
||||
final EnvironmentType environmentType;
|
||||
final XcodeSdk sdk;
|
||||
final String? deviceId;
|
||||
final String? target;
|
||||
final bool isWatch;
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(scheme, configuration, environmentType, deviceId, target);
|
||||
int get hashCode => Object.hash(
|
||||
scheme,
|
||||
configuration,
|
||||
sdk,
|
||||
deviceId,
|
||||
target,
|
||||
);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
@ -424,8 +447,7 @@ class XcodeProjectBuildContext {
|
||||
other.scheme == scheme &&
|
||||
other.configuration == configuration &&
|
||||
other.deviceId == deviceId &&
|
||||
other.environmentType == environmentType &&
|
||||
other.isWatch == isWatch &&
|
||||
other.sdk == sdk &&
|
||||
other.target == target;
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import 'migrations/macos_deployment_target_migration.dart';
|
||||
import 'migrations/nsapplicationmain_deprecation_migration.dart';
|
||||
import 'migrations/remove_macos_framework_link_and_embedding_migration.dart';
|
||||
import 'migrations/secure_restorable_state_migration.dart';
|
||||
import 'swift_package_manager.dart';
|
||||
|
||||
/// When run in -quiet mode, Xcode should only print from the underlying tasks to stdout.
|
||||
/// Passing this regexp to trace moves the stdout output to stderr.
|
||||
@ -108,29 +109,6 @@ Future<void> buildMacOS({
|
||||
if (!flutterBuildDir.existsSync()) {
|
||||
flutterBuildDir.createSync(recursive: true);
|
||||
}
|
||||
// Write configuration to an xconfig file in a standard location.
|
||||
await updateGeneratedXcodeProperties(
|
||||
project: flutterProject,
|
||||
buildInfo: buildInfo,
|
||||
targetOverride: targetOverride,
|
||||
useMacOSConfig: true,
|
||||
);
|
||||
|
||||
// TODO(vashworth): Call `SwiftPackageManager.updateMinimumDeployment`
|
||||
// using MACOSX_DEPLOYMENT_TARGET once https://github.com/flutter/flutter/issues/146204
|
||||
// is fixed.
|
||||
|
||||
await processPodsIfNeeded(flutterProject.macos, getMacOSBuildDirectory(), buildInfo.mode);
|
||||
// If the xcfilelists do not exist, create empty version.
|
||||
if (!flutterProject.macos.inputFileList.existsSync()) {
|
||||
flutterProject.macos.inputFileList.createSync(recursive: true);
|
||||
}
|
||||
if (!flutterProject.macos.outputFileList.existsSync()) {
|
||||
flutterProject.macos.outputFileList.createSync(recursive: true);
|
||||
}
|
||||
if (configOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Directory xcodeProject = flutterProject.macos.xcodeProject;
|
||||
|
||||
@ -150,6 +128,44 @@ Future<void> buildMacOS({
|
||||
if (configuration == null) {
|
||||
throwToolExit('Unable to find expected configuration in Xcode project.');
|
||||
}
|
||||
|
||||
final Map<String, String> buildSettings = await flutterProject.macos.buildSettingsForBuildInfo(
|
||||
buildInfo,
|
||||
scheme: scheme,
|
||||
configuration: configuration,
|
||||
) ?? <String, String>{};
|
||||
|
||||
// Write configuration to an xconfig file in a standard location.
|
||||
await updateGeneratedXcodeProperties(
|
||||
project: flutterProject,
|
||||
buildInfo: buildInfo,
|
||||
targetOverride: targetOverride,
|
||||
useMacOSConfig: true,
|
||||
);
|
||||
|
||||
if (flutterProject.usesSwiftPackageManager) {
|
||||
final String? macOSDeploymentTarget = buildSettings['MACOSX_DEPLOYMENT_TARGET'];
|
||||
if (macOSDeploymentTarget != null) {
|
||||
SwiftPackageManager.updateMinimumDeployment(
|
||||
platform: SupportedPlatform.macos,
|
||||
project: flutterProject.macos,
|
||||
deploymentTarget: macOSDeploymentTarget,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await processPodsIfNeeded(flutterProject.macos, getMacOSBuildDirectory(), buildInfo.mode);
|
||||
// If the xcfilelists do not exist, create empty version.
|
||||
if (!flutterProject.macos.inputFileList.existsSync()) {
|
||||
flutterProject.macos.inputFileList.createSync(recursive: true);
|
||||
}
|
||||
if (!flutterProject.macos.outputFileList.existsSync()) {
|
||||
flutterProject.macos.outputFileList.createSync(recursive: true);
|
||||
}
|
||||
if (configOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Run the Xcode build.
|
||||
final Stopwatch sw = Stopwatch()..start();
|
||||
final Status status = globals.logger.startProgress(
|
||||
|
@ -155,6 +155,89 @@ abstract class XcodeBasedProject extends FlutterProjectPlatform {
|
||||
return _projectInfo ??= await xcodeProjectInterpreter.getInfo(hostAppRoot.path);
|
||||
}
|
||||
XcodeProjectInfo? _projectInfo;
|
||||
|
||||
/// The build settings for the host app of this project, as a detached map.
|
||||
///
|
||||
/// Returns null, if Xcode tooling is unavailable.
|
||||
Future<Map<String, String>?> buildSettingsForBuildInfo(
|
||||
BuildInfo? buildInfo, {
|
||||
String? scheme,
|
||||
String? configuration,
|
||||
String? target,
|
||||
EnvironmentType environmentType = EnvironmentType.physical,
|
||||
String? deviceId,
|
||||
bool isWatch = false,
|
||||
}) async {
|
||||
if (!existsSync()) {
|
||||
return null;
|
||||
}
|
||||
final XcodeProjectInfo? info = await projectInfo();
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
scheme ??= info.schemeFor(buildInfo);
|
||||
if (scheme == null) {
|
||||
info.reportFlavorNotFoundAndExit();
|
||||
}
|
||||
|
||||
configuration ??= (await projectInfo())?.buildConfigurationFor(
|
||||
buildInfo,
|
||||
scheme,
|
||||
);
|
||||
|
||||
final XcodeSdk sdk = switch ((environmentType, this)) {
|
||||
(EnvironmentType.physical, _) when isWatch => XcodeSdk.WatchOS,
|
||||
(EnvironmentType.simulator, _) when isWatch => XcodeSdk.WatchSimulator,
|
||||
(EnvironmentType.physical, IosProject _) => XcodeSdk.IPhoneOS,
|
||||
(EnvironmentType.simulator, IosProject _) => XcodeSdk.WatchSimulator,
|
||||
(EnvironmentType.physical, MacOSProject _) => XcodeSdk.MacOSX,
|
||||
(_, _) => throw ArgumentError('Unsupported SDK')
|
||||
};
|
||||
|
||||
return _buildSettingsForXcodeProjectBuildContext(
|
||||
XcodeProjectBuildContext(
|
||||
scheme: scheme,
|
||||
configuration: configuration,
|
||||
sdk: sdk,
|
||||
target: target,
|
||||
deviceId: deviceId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<Map<String, String>?> _buildSettingsForXcodeProjectBuildContext(XcodeProjectBuildContext buildContext) async {
|
||||
if (!existsSync()) {
|
||||
return null;
|
||||
}
|
||||
final Map<String, String>? currentBuildSettings = _buildSettingsByBuildContext[buildContext];
|
||||
if (currentBuildSettings == null) {
|
||||
final Map<String, String>? calculatedBuildSettings = await _xcodeProjectBuildSettings(buildContext);
|
||||
if (calculatedBuildSettings != null) {
|
||||
_buildSettingsByBuildContext[buildContext] = calculatedBuildSettings;
|
||||
}
|
||||
}
|
||||
return _buildSettingsByBuildContext[buildContext];
|
||||
}
|
||||
|
||||
final Map<XcodeProjectBuildContext, Map<String, String>> _buildSettingsByBuildContext = <XcodeProjectBuildContext, Map<String, String>>{};
|
||||
|
||||
Future<Map<String, String>?> _xcodeProjectBuildSettings(XcodeProjectBuildContext buildContext) async {
|
||||
final XcodeProjectInterpreter? xcodeProjectInterpreter = globals.xcodeProjectInterpreter;
|
||||
if (xcodeProjectInterpreter == null || !xcodeProjectInterpreter.isInstalled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Map<String, String> buildSettings = await xcodeProjectInterpreter.getBuildSettings(
|
||||
xcodeProject.path,
|
||||
buildContext: buildContext,
|
||||
);
|
||||
if (buildSettings.isNotEmpty) {
|
||||
// No timeouts, flakes, or errors.
|
||||
return buildSettings;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the iOS sub-project of a Flutter project.
|
||||
@ -424,80 +507,6 @@ class IosProject extends XcodeBasedProject {
|
||||
return productName ?? XcodeBasedProject._defaultHostAppName;
|
||||
}
|
||||
|
||||
/// The build settings for the host app of this project, as a detached map.
|
||||
///
|
||||
/// Returns null, if iOS tooling is unavailable.
|
||||
Future<Map<String, String>?> buildSettingsForBuildInfo(
|
||||
BuildInfo? buildInfo, {
|
||||
String? scheme,
|
||||
String? configuration,
|
||||
String? target,
|
||||
EnvironmentType environmentType = EnvironmentType.physical,
|
||||
String? deviceId,
|
||||
bool isWatch = false,
|
||||
}) async {
|
||||
if (!existsSync()) {
|
||||
return null;
|
||||
}
|
||||
final XcodeProjectInfo? info = await projectInfo();
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
scheme ??= info.schemeFor(buildInfo);
|
||||
if (scheme == null) {
|
||||
info.reportFlavorNotFoundAndExit();
|
||||
}
|
||||
|
||||
configuration ??= (await projectInfo())?.buildConfigurationFor(
|
||||
buildInfo,
|
||||
scheme,
|
||||
);
|
||||
return _buildSettingsForXcodeProjectBuildContext(
|
||||
XcodeProjectBuildContext(
|
||||
environmentType: environmentType,
|
||||
scheme: scheme,
|
||||
configuration: configuration,
|
||||
target: target,
|
||||
deviceId: deviceId,
|
||||
isWatch: isWatch,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<Map<String, String>?> _buildSettingsForXcodeProjectBuildContext(XcodeProjectBuildContext buildContext) async {
|
||||
if (!existsSync()) {
|
||||
return null;
|
||||
}
|
||||
final Map<String, String>? currentBuildSettings = _buildSettingsByBuildContext[buildContext];
|
||||
if (currentBuildSettings == null) {
|
||||
final Map<String, String>? calculatedBuildSettings = await _xcodeProjectBuildSettings(buildContext);
|
||||
if (calculatedBuildSettings != null) {
|
||||
_buildSettingsByBuildContext[buildContext] = calculatedBuildSettings;
|
||||
}
|
||||
}
|
||||
return _buildSettingsByBuildContext[buildContext];
|
||||
}
|
||||
|
||||
final Map<XcodeProjectBuildContext, Map<String, String>> _buildSettingsByBuildContext = <XcodeProjectBuildContext, Map<String, String>>{};
|
||||
|
||||
Future<Map<String, String>?> _xcodeProjectBuildSettings(XcodeProjectBuildContext buildContext) async {
|
||||
final XcodeProjectInterpreter? xcodeProjectInterpreter = globals.xcodeProjectInterpreter;
|
||||
if (xcodeProjectInterpreter == null || !xcodeProjectInterpreter.isInstalled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Map<String, String> buildSettings = await xcodeProjectInterpreter.getBuildSettings(
|
||||
xcodeProject.path,
|
||||
buildContext: buildContext,
|
||||
);
|
||||
if (buildSettings.isNotEmpty) {
|
||||
// No timeouts, flakes, or errors.
|
||||
return buildSettings;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> ensureReadyForPlatformSpecificTooling() async {
|
||||
await _regenerateFromTemplateIfNeeded();
|
||||
if (!_flutterLibRoot.existsSync()) {
|
||||
|
@ -325,7 +325,9 @@ void main() {
|
||||
expect(
|
||||
await xcodeProjectInterpreter.getBuildSettings(
|
||||
'',
|
||||
buildContext: const XcodeProjectBuildContext(environmentType: EnvironmentType.simulator),
|
||||
buildContext: const XcodeProjectBuildContext(
|
||||
sdk: XcodeSdk.IPhoneSimulator,
|
||||
),
|
||||
),
|
||||
const <String, String>{},
|
||||
);
|
||||
@ -398,7 +400,7 @@ void main() {
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testUsingContext('build settings uses watch destination if isWatch is true', () async {
|
||||
testUsingContext('build settings uses watch destination', () async {
|
||||
platform.environment = const <String, String>{};
|
||||
|
||||
fakeProcessManager.addCommands(<FakeCommand>[
|
||||
@ -422,7 +424,9 @@ void main() {
|
||||
expect(
|
||||
await xcodeProjectInterpreter.getBuildSettings(
|
||||
'',
|
||||
buildContext: const XcodeProjectBuildContext(isWatch: true),
|
||||
buildContext: const XcodeProjectBuildContext(
|
||||
sdk: XcodeSdk.WatchOS,
|
||||
),
|
||||
),
|
||||
const <String, String>{},
|
||||
);
|
||||
@ -432,7 +436,7 @@ void main() {
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testUsingContext('build settings uses watch simulator destination if isWatch is true and environment type is simulator', () async {
|
||||
testUsingContext('build settings uses watch simulator destination', () async {
|
||||
platform.environment = const <String, String>{};
|
||||
|
||||
fakeProcessManager.addCommands(<FakeCommand>[
|
||||
@ -458,7 +462,45 @@ void main() {
|
||||
expect(
|
||||
await xcodeProjectInterpreter.getBuildSettings(
|
||||
'',
|
||||
buildContext: const XcodeProjectBuildContext(environmentType: EnvironmentType.simulator, isWatch: true),
|
||||
buildContext: const XcodeProjectBuildContext(
|
||||
sdk: XcodeSdk.WatchSimulator,
|
||||
),
|
||||
),
|
||||
const <String, String>{},
|
||||
);
|
||||
expect(fakeProcessManager, hasNoRemainingExpectations);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testUsingContext('build settings uses macosx destination', () async {
|
||||
platform.environment = const <String, String>{};
|
||||
|
||||
fakeProcessManager.addCommands(<FakeCommand>[
|
||||
kWhichSysctlCommand,
|
||||
kx64CheckCommand,
|
||||
FakeCommand(
|
||||
command: <String>[
|
||||
'xcrun',
|
||||
'xcodebuild',
|
||||
'-project',
|
||||
'/',
|
||||
'-destination',
|
||||
'generic/platform=macOS',
|
||||
'-showBuildSettings',
|
||||
'BUILD_DIR=${fileSystem.path.absolute('build', 'macos')}',
|
||||
],
|
||||
exitCode: 1,
|
||||
),
|
||||
]);
|
||||
|
||||
expect(
|
||||
await xcodeProjectInterpreter.getBuildSettings(
|
||||
'',
|
||||
buildContext: const XcodeProjectBuildContext(
|
||||
sdk: XcodeSdk.MacOSX,
|
||||
),
|
||||
),
|
||||
const <String, String>{},
|
||||
);
|
||||
|
@ -1458,7 +1458,7 @@ plugins {
|
||||
const XcodeProjectBuildContext watchBuildContext = XcodeProjectBuildContext(
|
||||
scheme: 'WatchScheme',
|
||||
deviceId: '123',
|
||||
isWatch: true,
|
||||
sdk: XcodeSdk.WatchOS,
|
||||
);
|
||||
mockXcodeProjectInterpreter.buildSettingsByBuildContext[watchBuildContext] = <String, String>{
|
||||
'INFOPLIST_KEY_WKCompanionAppBundleIdentifier': 'io.flutter.someProject',
|
||||
@ -1498,7 +1498,7 @@ plugins {
|
||||
const XcodeProjectBuildContext watchBuildContext = XcodeProjectBuildContext(
|
||||
scheme: 'WatchScheme',
|
||||
deviceId: '123',
|
||||
isWatch: true,
|
||||
sdk: XcodeSdk.WatchOS,
|
||||
);
|
||||
mockXcodeProjectInterpreter.buildSettingsByBuildContext[watchBuildContext] = <String, String>{
|
||||
IosProject.kProductBundleIdKey: 'io.flutter.someProject',
|
||||
|
@ -475,4 +475,136 @@ void main() {
|
||||
);
|
||||
}
|
||||
}, skip: !platform.isMacOS); // [intended] Swift Package Manager only works on macos.
|
||||
|
||||
test("Generated Swift package uses iOS's project minimum deployment", () async {
|
||||
final Directory workingDirectory = fileSystem.systemTempDirectory
|
||||
.createTempSync('swift_package_manager_minimum_deployment_ios.');
|
||||
final String workingDirectoryPath = workingDirectory.path;
|
||||
try {
|
||||
await SwiftPackageManagerUtils.enableSwiftPackageManager(flutterBin, workingDirectoryPath);
|
||||
final String appDirectoryPath = await SwiftPackageManagerUtils.createApp(
|
||||
flutterBin,
|
||||
workingDirectoryPath,
|
||||
iosLanguage: 'swift',
|
||||
platform: 'ios',
|
||||
usesSwiftPackageManager: true,
|
||||
options: <String>['--platforms=ios'],
|
||||
);
|
||||
|
||||
// Modify the project to raise the deployment version.
|
||||
final File projectFile = fileSystem
|
||||
.directory(appDirectoryPath)
|
||||
.childDirectory('ios')
|
||||
.childDirectory('Runner.xcodeproj')
|
||||
.childFile('project.pbxproj');
|
||||
|
||||
final String oldProject = projectFile.readAsStringSync();
|
||||
final String newProject = oldProject.replaceAll(
|
||||
RegExp(r'IPHONEOS_DEPLOYMENT_TARGET = \d+\.\d+;'),
|
||||
'IPHONEOS_DEPLOYMENT_TARGET = 15.1;',
|
||||
);
|
||||
|
||||
projectFile.writeAsStringSync(newProject);
|
||||
|
||||
// Build the app. This generates Flutter's Swift package.
|
||||
await SwiftPackageManagerUtils.buildApp(
|
||||
flutterBin,
|
||||
appDirectoryPath,
|
||||
options: <String>['ios', '--debug', '-v'],
|
||||
);
|
||||
|
||||
// Verify the generated Swift package uses the project's minimum deployment.
|
||||
final File generatedManifestFile = fileSystem
|
||||
.directory(appDirectoryPath)
|
||||
.childDirectory('ios')
|
||||
.childDirectory('Flutter')
|
||||
.childDirectory('ephemeral')
|
||||
.childDirectory('Packages')
|
||||
.childDirectory('FlutterGeneratedPluginSwiftPackage')
|
||||
.childFile('Package.swift');
|
||||
|
||||
expect(generatedManifestFile.existsSync(), isTrue);
|
||||
|
||||
final String generatedManifest = generatedManifestFile.readAsStringSync();
|
||||
const String expected = '''
|
||||
platforms: [
|
||||
.iOS("15.1")
|
||||
],
|
||||
''';
|
||||
|
||||
expect(generatedManifest.contains(expected), isTrue);
|
||||
} finally {
|
||||
await SwiftPackageManagerUtils.disableSwiftPackageManager(flutterBin, workingDirectoryPath);
|
||||
ErrorHandlingFileSystem.deleteIfExists(
|
||||
workingDirectory,
|
||||
recursive: true,
|
||||
);
|
||||
}
|
||||
}, skip: !platform.isMacOS); // [intended] Swift Package Manager only works on macos.
|
||||
|
||||
test("Generated Swift package uses macOS's project minimum deployment", () async {
|
||||
final Directory workingDirectory = fileSystem.systemTempDirectory
|
||||
.createTempSync('swift_package_manager_minimum_deployment_macos.');
|
||||
final String workingDirectoryPath = workingDirectory.path;
|
||||
try {
|
||||
await SwiftPackageManagerUtils.enableSwiftPackageManager(flutterBin, workingDirectoryPath);
|
||||
final String appDirectoryPath = await SwiftPackageManagerUtils.createApp(
|
||||
flutterBin,
|
||||
workingDirectoryPath,
|
||||
iosLanguage: 'swift',
|
||||
platform: 'macos',
|
||||
usesSwiftPackageManager: true,
|
||||
options: <String>['--platforms=macos'],
|
||||
);
|
||||
|
||||
// Modify the project to raise the deployment version.
|
||||
final File projectFile = fileSystem
|
||||
.directory(appDirectoryPath)
|
||||
.childDirectory('macos')
|
||||
.childDirectory('Runner.xcodeproj')
|
||||
.childFile('project.pbxproj');
|
||||
|
||||
final String oldProject = projectFile.readAsStringSync();
|
||||
final String newProject = oldProject.replaceAll(
|
||||
RegExp(r'MACOSX_DEPLOYMENT_TARGET = \d+\.\d+;'),
|
||||
'MACOSX_DEPLOYMENT_TARGET = 15.1;',
|
||||
);
|
||||
|
||||
projectFile.writeAsStringSync(newProject);
|
||||
|
||||
// Build the app. This generates Flutter's Swift package.
|
||||
await SwiftPackageManagerUtils.buildApp(
|
||||
flutterBin,
|
||||
appDirectoryPath,
|
||||
options: <String>['macos', '--debug', '-v'],
|
||||
);
|
||||
|
||||
// Verify the generated Swift package uses the project's minimum deployment.
|
||||
final File generatedManifestFile = fileSystem
|
||||
.directory(appDirectoryPath)
|
||||
.childDirectory('macos')
|
||||
.childDirectory('Flutter')
|
||||
.childDirectory('ephemeral')
|
||||
.childDirectory('Packages')
|
||||
.childDirectory('FlutterGeneratedPluginSwiftPackage')
|
||||
.childFile('Package.swift');
|
||||
|
||||
expect(generatedManifestFile.existsSync(), isTrue);
|
||||
|
||||
final String generatedManifest = generatedManifestFile.readAsStringSync();
|
||||
const String expected = '''
|
||||
platforms: [
|
||||
.macOS("15.1")
|
||||
],
|
||||
''';
|
||||
|
||||
expect(generatedManifest.contains(expected), isTrue);
|
||||
} finally {
|
||||
await SwiftPackageManagerUtils.disableSwiftPackageManager(flutterBin, workingDirectoryPath);
|
||||
ErrorHandlingFileSystem.deleteIfExists(
|
||||
workingDirectory,
|
||||
recursive: true,
|
||||
);
|
||||
}
|
||||
}, skip: !platform.isMacOS); // [intended] Swift Package Manager only works on macos.
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user