Unverified Commit 9f5c6553 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Revert "Check for watch companion in build settings (#113956)" (#114035)

This reverts commit e1337218.
parent e1337218
......@@ -727,7 +727,6 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
IBSC_MODULE = watch_Extension;
INFOPLIST_FILE = watch/Info.plist;
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.flutter.extensionTest;
MARKETING_VERSION = 1.0.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
......@@ -758,7 +757,6 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
IBSC_MODULE = watch_Extension;
INFOPLIST_FILE = watch/Info.plist;
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.flutter.extensionTest;
MARKETING_VERSION = 1.0.0;
MTL_FAST_MATH = YES;
OTHER_LDFLAGS = "";
......@@ -787,7 +785,6 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
IBSC_MODULE = watch_Extension;
INFOPLIST_FILE = watch/Info.plist;
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.flutter.extensionTest;
MARKETING_VERSION = 1.0.0;
MTL_FAST_MATH = YES;
OTHER_LDFLAGS = "";
......
......@@ -25,6 +25,8 @@
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>WKCompanionAppBundleIdentifier</key>
<string>$(APP_BUNDLE_IDENTIFIER)</string>
<key>WKWatchKitApp</key>
<true/>
</dict>
......
......@@ -265,10 +265,9 @@ Future<XcodeBuildResult> buildXcodeProject({
// Check if the project contains a watchOS companion app.
final bool hasWatchCompanion = await app.project.containsWatchCompanion(
targets: projectInfo.targets,
schemes: projectInfo.schemes,
buildInfo: buildInfo,
deviceId: deviceID,
projectInfo.targets,
buildInfo,
deviceID,
);
if (hasWatchCompanion) {
// The -sdk argument has to be omitted if a watchOS companion app exists.
......
......@@ -198,11 +198,7 @@ class XcodeProjectInterpreter {
if (buildContext.environmentType == EnvironmentType.simulator)
...<String>['-sdk', 'iphonesimulator'],
'-destination',
if (buildContext.isWatch == true && buildContext.environmentType == EnvironmentType.physical)
'generic/platform=watchOS'
else if (buildContext.isWatch == true)
'generic/platform=watchOS Simulator'
else if (deviceId != null)
if (deviceId != null)
'id=$deviceId'
else if (buildContext.environmentType == EnvironmentType.physical)
'generic/platform=iOS'
......@@ -380,14 +376,12 @@ class XcodeProjectBuildContext {
this.configuration,
this.environmentType = EnvironmentType.physical,
this.deviceId,
this.isWatch = false,
});
final String? scheme;
final String? configuration;
final EnvironmentType environmentType;
final String? deviceId;
final bool isWatch;
@override
int get hashCode => Object.hash(scheme, configuration, environmentType, deviceId);
......@@ -401,8 +395,7 @@ class XcodeProjectBuildContext {
other.scheme == scheme &&
other.configuration == configuration &&
other.deviceId == deviceId &&
other.environmentType == environmentType &&
other.isWatch == isWatch;
other.environmentType == environmentType;
}
}
......
......@@ -256,8 +256,6 @@ class IosProject extends XcodeBasedProject {
BuildInfo? buildInfo, {
EnvironmentType environmentType = EnvironmentType.physical,
String? deviceId,
String? scheme,
bool isWatch = false,
}) async {
if (!existsSync()) {
return null;
......@@ -267,11 +265,9 @@ class IosProject extends XcodeBasedProject {
return null;
}
final String? scheme = info.schemeFor(buildInfo);
if (scheme == null) {
scheme = info.schemeFor(buildInfo);
if (scheme == null) {
info.reportFlavorNotFoundAndExit();
}
info.reportFlavorNotFoundAndExit();
}
final String? configuration = (await projectInfo())?.buildConfigurationFor(
......@@ -283,7 +279,6 @@ class IosProject extends XcodeBasedProject {
scheme: scheme,
configuration: configuration,
deviceId: deviceId,
isWatch: isWatch,
);
final Map<String, String>? currentBuildSettings = _buildSettingsByBuildContext[buildContext];
if (currentBuildSettings == null) {
......@@ -332,12 +327,7 @@ class IosProject extends XcodeBasedProject {
}
/// Check if one the [targets] of the project is a watchOS companion app target.
Future<bool> containsWatchCompanion({
required List<String> targets,
required List<String> schemes,
required BuildInfo buildInfo,
String? deviceId,
}) async {
Future<bool> containsWatchCompanion(List<String> targets, BuildInfo buildInfo, String? deviceId) async {
final String? bundleIdentifier = await productBundleIdentifier(buildInfo);
// A bundle identifier is required for a companion app.
if (bundleIdentifier == null) {
......@@ -346,8 +336,8 @@ class IosProject extends XcodeBasedProject {
for (final String target in targets) {
// Create Info.plist file of the target.
final File infoFile = hostAppRoot.childDirectory(target).childFile('Info.plist');
// In older versions of Xcode, if the target was a watchOS companion app,
// the Info.plist file of the target contained the key WKCompanionAppBundleIdentifier.
// The Info.plist file of a target contains the key WKCompanionAppBundleIdentifier,
// if it is a watchOS companion app.
if (infoFile.existsSync()) {
final String? fromPlist = globals.plistParser.getStringValueFromFile(infoFile.path, 'WKCompanionAppBundleIdentifier');
if (bundleIdentifier == fromPlist) {
......@@ -367,34 +357,6 @@ class IosProject extends XcodeBasedProject {
}
}
}
// If key not found in Info.plist above, do more expensive check of build settings.
// In newer versions of Xcode, the build settings of the watchOS companion
// app's scheme should contain the key INFOPLIST_KEY_WKCompanionAppBundleIdentifier.
final bool watchIdentifierFound = xcodeProjectInfoFile.readAsStringSync().contains('WKCompanionAppBundleIdentifier');
if (watchIdentifierFound == false) {
return false;
}
for (final String scheme in schemes) {
final Map<String, String>? allBuildSettings = await buildSettingsForBuildInfo(
buildInfo,
deviceId: deviceId,
scheme: scheme,
isWatch: true,
);
if (allBuildSettings != null) {
final String? fromBuild = allBuildSettings['INFOPLIST_KEY_WKCompanionAppBundleIdentifier'];
if (bundleIdentifier == fromBuild) {
return true;
}
if (fromBuild != null && fromBuild.contains(r'$')) {
final String substitutedVariable = substituteXcodeVariables(fromBuild, allBuildSettings);
if (substitutedVariable == bundleIdentifier) {
return true;
}
}
}
}
return false;
}
......
......@@ -395,76 +395,6 @@ void main() {
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('build settings uses watch destination if isWatch is true', () async {
platform.environment = const <String, String>{};
fakeProcessManager.addCommands(<FakeCommand>[
kWhichSysctlCommand,
kx64CheckCommand,
FakeCommand(
command: <String>[
'xcrun',
'xcodebuild',
'-project',
'/',
'-destination',
'generic/platform=watchOS',
'-showBuildSettings',
'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}',
],
exitCode: 1,
),
]);
expect(
await xcodeProjectInterpreter.getBuildSettings(
'',
buildContext: const XcodeProjectBuildContext(isWatch: true),
),
const <String, String>{},
);
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('build settings uses watch simulator destination if isWatch is true and environment type is simulator', () async {
platform.environment = const <String, String>{};
fakeProcessManager.addCommands(<FakeCommand>[
kWhichSysctlCommand,
kx64CheckCommand,
FakeCommand(
command: <String>[
'xcrun',
'xcodebuild',
'-project',
'/',
'-sdk',
'iphonesimulator',
'-destination',
'generic/platform=watchOS Simulator',
'-showBuildSettings',
'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}',
],
exitCode: 1,
),
]);
expect(
await xcodeProjectInterpreter.getBuildSettings(
'',
buildContext: const XcodeProjectBuildContext(environmentType: EnvironmentType.simulator, isWatch: true),
),
const <String, String>{},
);
expect(fakeProcessManager, hasNoRemainingExpectations);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
testWithoutContext('xcodebuild clean contains Flutter Xcode environment variables', () async {
platform.environment = const <String, String>{
'FLUTTER_XCODE_CODE_SIGN_STYLE': 'Manual',
......
......@@ -458,8 +458,7 @@ apply plugin: 'kotlin-android'
testWithMocks('from build settings, if no plist', () async {
final FlutterProject project = await someProject();
project.ios.xcodeProject.createSync();
const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Runner');
xcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = <String, String>{
xcodeProjectInterpreter.buildSettings = <String, String>{
'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject',
};
xcodeProjectInterpreter.xcodeProjectInfo = XcodeProjectInfo(<String>[], <String>[], <String>['Runner'], logger);
......@@ -487,8 +486,7 @@ apply plugin: 'kotlin-android'
testWithMocks('from build settings and plist, if default variable', () async {
final FlutterProject project = await someProject();
project.ios.xcodeProject.createSync();
const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Runner');
xcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = <String, String>{
xcodeProjectInterpreter.buildSettings = <String, String>{
'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject',
};
xcodeProjectInterpreter.xcodeProjectInfo = XcodeProjectInfo(<String>[], <String>[], <String>['Runner'], logger);
......@@ -501,8 +499,7 @@ apply plugin: 'kotlin-android'
final FlutterProject project = await someProject();
project.ios.xcodeProject.createSync();
project.ios.defaultHostInfoPlist.createSync(recursive: true);
const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Runner');
xcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = <String, String>{
xcodeProjectInterpreter.buildSettings = <String, String>{
'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject',
'SUFFIX': 'suffix',
};
......@@ -537,8 +534,7 @@ apply plugin: 'kotlin-android'
testWithMocks('handles case insensitive flavor', () async {
final FlutterProject project = await someProject();
project.ios.xcodeProject.createSync();
const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Free');
xcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = <String, String>{
xcodeProjectInterpreter.buildSettings = <String, String>{
'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject',
};
xcodeProjectInterpreter.xcodeProjectInfo =XcodeProjectInfo(<String>[], <String>[], <String>['Free'], logger);
......@@ -607,8 +603,7 @@ apply plugin: 'kotlin-android'
testUsingContext('app product name xcodebuild settings', () async {
final FlutterProject project = await someProject();
project.ios.xcodeProject.createSync();
const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Runner');
mockXcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = <String, String>{
mockXcodeProjectInterpreter.buildSettings = <String, String>{
'FULL_PRODUCT_NAME': 'My App.app',
};
mockXcodeProjectInterpreter.xcodeProjectInfo = XcodeProjectInfo(<String>[], <String>[], <String>['Runner'], logger);
......@@ -710,15 +705,7 @@ apply plugin: 'kotlin-android'
testUsingContext('cannot find bundle identifier', () async {
final FlutterProject project = await someProject();
expect(
await project.ios.containsWatchCompanion(
targets: <String>['WatchTarget'],
schemes: <String>[],
buildInfo: BuildInfo.debug,
deviceId: '123',
),
isFalse,
);
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], BuildInfo.debug, '123'), isFalse);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
......@@ -729,8 +716,7 @@ apply plugin: 'kotlin-android'
group('with bundle identifier', () {
setUp(() {
const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(scheme: 'Runner');
mockXcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = <String, String>{
mockXcodeProjectInterpreter.buildSettings = <String, String>{
'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject',
};
mockXcodeProjectInterpreter.xcodeProjectInfo = XcodeProjectInfo(<String>[], <String>[], <String>['Runner'], logger);
......@@ -738,15 +724,7 @@ apply plugin: 'kotlin-android'
testUsingContext('no Info.plist in target', () async {
final FlutterProject project = await someProject();
expect(
await project.ios.containsWatchCompanion(
targets: <String>['WatchTarget'],
schemes: <String>[],
buildInfo: BuildInfo.debug,
deviceId: '123',
),
isFalse,
);
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], BuildInfo.debug, '123'), isFalse);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
......@@ -759,15 +737,7 @@ apply plugin: 'kotlin-android'
final FlutterProject project = await someProject();
project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true);
expect(
await project.ios.containsWatchCompanion(
targets: <String>['WatchTarget'],
schemes: <String>[],
buildInfo: BuildInfo.debug,
deviceId: '123',
),
isFalse,
);
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], BuildInfo.debug, '123'), isFalse);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
......@@ -781,15 +751,7 @@ apply plugin: 'kotlin-android'
project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true);
testPlistParser.setProperty('WKCompanionAppBundleIdentifier', 'io.flutter.someOTHERproject');
expect(
await project.ios.containsWatchCompanion(
targets: <String>['WatchTarget'],
schemes: <String>[],
buildInfo: BuildInfo.debug,
deviceId: '123',
),
isFalse,
);
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], BuildInfo.debug, '123'), isFalse);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
......@@ -798,21 +760,13 @@ apply plugin: 'kotlin-android'
FlutterProjectFactory: () => flutterProjectFactory,
});
testUsingContext('has watch companion in plist', () async {
testUsingContext('has watch companion', () async {
final FlutterProject project = await someProject();
project.ios.xcodeProject.createSync();
project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true);
testPlistParser.setProperty('WKCompanionAppBundleIdentifier', 'io.flutter.someProject');
expect(
await project.ios.containsWatchCompanion(
targets: <String>['WatchTarget'],
schemes: <String>[],
buildInfo: BuildInfo.debug,
deviceId: '123',
),
isTrue,
);
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], BuildInfo.debug, '123'), isTrue);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
......@@ -821,112 +775,16 @@ apply plugin: 'kotlin-android'
FlutterProjectFactory: () => flutterProjectFactory,
});
testUsingContext('has watch companion in plist with xcode variable', () async {
testUsingContext('has watch companion with build settings', () async {
final FlutterProject project = await someProject();
project.ios.xcodeProject.createSync();
const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(
scheme: 'Runner',
deviceId: '123',
);
mockXcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = <String, String>{
mockXcodeProjectInterpreter.buildSettings = <String, String>{
'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject',
};
project.ios.hostAppRoot.childDirectory('WatchTarget').childFile('Info.plist').createSync(recursive: true);
testPlistParser.setProperty('WKCompanionAppBundleIdentifier', r'$(PRODUCT_BUNDLE_IDENTIFIER)');
expect(
await project.ios.containsWatchCompanion(
targets: <String>['WatchTarget'],
schemes: <String>[],
buildInfo: BuildInfo.debug,
deviceId: '123',
),
isTrue,
);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
PlistParser: () => testPlistParser,
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
FlutterProjectFactory: () => flutterProjectFactory,
});
testUsingContext('has watch companion in other scheme build settings', () async {
final FlutterProject project = await someProject();
project.ios.xcodeProject.createSync();
project.ios.xcodeProjectInfoFile.writeAsStringSync('''
Build settings for action build and target "WatchTarget":
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = io.flutter.someProject
''');
const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(
scheme: 'Runner',
deviceId: '123',
);
mockXcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = <String, String>{
'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject',
};
const XcodeProjectBuildContext watchBuildContext = XcodeProjectBuildContext(
scheme: 'WatchScheme',
deviceId: '123',
isWatch: true,
);
mockXcodeProjectInterpreter.buildSettingsByBuildContext[watchBuildContext] = <String, String>{
'INFOPLIST_KEY_WKCompanionAppBundleIdentifier': 'io.flutter.someProject',
};
expect(
await project.ios.containsWatchCompanion(
targets: <String>['Runner', 'WatchTarget'],
schemes: <String>['Runner', 'WatchScheme'],
buildInfo: BuildInfo.debug,
deviceId: '123',
),
isTrue,
);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
PlistParser: () => testPlistParser,
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
FlutterProjectFactory: () => flutterProjectFactory,
});
testUsingContext('has watch companion in other scheme build settings with xcode variable', () async {
final FlutterProject project = await someProject();
project.ios.xcodeProject.createSync();
project.ios.xcodeProjectInfoFile.writeAsStringSync(r'''
Build settings for action build and target "WatchTarget":
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = $(PRODUCT_BUNDLE_IDENTIFIER)
''');
const XcodeProjectBuildContext buildContext = XcodeProjectBuildContext(
scheme: 'Runner',
deviceId: '123'
);
mockXcodeProjectInterpreter.buildSettingsByBuildContext[buildContext] = <String, String>{
'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject',
};
const XcodeProjectBuildContext watchBuildContext = XcodeProjectBuildContext(
scheme: 'WatchScheme',
deviceId: '123',
isWatch: true,
);
mockXcodeProjectInterpreter.buildSettingsByBuildContext[watchBuildContext] = <String, String>{
'PRODUCT_BUNDLE_IDENTIFIER': 'io.flutter.someProject',
'INFOPLIST_KEY_WKCompanionAppBundleIdentifier': r'$(PRODUCT_BUNDLE_IDENTIFIER)',
};
expect(
await project.ios.containsWatchCompanion(
targets: <String>['Runner', 'WatchTarget'],
schemes: <String>['Runner', 'WatchScheme'],
buildInfo: BuildInfo.debug,
deviceId: '123',
),
isTrue,
);
expect(await project.ios.containsWatchCompanion(<String>['WatchTarget'], BuildInfo.debug, '123'), isTrue);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
......@@ -1217,7 +1075,7 @@ File androidPluginRegistrant(Directory parent) {
}
class FakeXcodeProjectInterpreter extends Fake implements XcodeProjectInterpreter {
final Map<XcodeProjectBuildContext, Map<String, String>> buildSettingsByBuildContext = <XcodeProjectBuildContext, Map<String, String>>{};
Map<String, String> buildSettings = <String, String>{};
late XcodeProjectInfo xcodeProjectInfo;
@override
......@@ -1225,10 +1083,7 @@ class FakeXcodeProjectInterpreter extends Fake implements XcodeProjectInterprete
XcodeProjectBuildContext? buildContext,
Duration timeout = const Duration(minutes: 1),
}) async {
if (buildSettingsByBuildContext[buildContext] == null) {
return <String, String>{};
}
return buildSettingsByBuildContext[buildContext]!;
return buildSettings;
}
@override
......
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