From f417df59800b86b168d78a2be031fc06321b227b Mon Sep 17 00:00:00 2001 From: Tatsuki Otsuka Date: Thu, 11 Apr 2024 19:22:37 +0900 Subject: [PATCH 1/4] Reject multiplatform apps that support the watchOS destination This commit also fixes existing test cases. --- Sources/ProjectSpec/SpecValidation.swift | 6 ++++++ Sources/ProjectSpec/SpecValidationError.swift | 3 +++ Tests/XcodeGenKitTests/ProjectGeneratorTests.swift | 8 ++++---- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Sources/ProjectSpec/SpecValidation.swift b/Sources/ProjectSpec/SpecValidation.swift index 9bf43e1a5..a34fb3d4e 100644 --- a/Sources/ProjectSpec/SpecValidation.swift +++ b/Sources/ProjectSpec/SpecValidation.swift @@ -185,6 +185,12 @@ extension Project { errors.append(.unexpectedTargetPlatformForSupportedDestinations(target: target.name, platform: target.platform)) } + if let supportedDestinations = target.supportedDestinations, + target.type.isApp, + supportedDestinations.contains(.watchOS) { + errors.append(.containsWatchOSDestinationForMultiplatformApp(target: target.name)) + } + if target.supportedDestinations?.contains(.macOS) == true, target.supportedDestinations?.contains(.macCatalyst) == true { diff --git a/Sources/ProjectSpec/SpecValidationError.swift b/Sources/ProjectSpec/SpecValidationError.swift index 1840a9bd1..6e93de0ef 100644 --- a/Sources/ProjectSpec/SpecValidationError.swift +++ b/Sources/ProjectSpec/SpecValidationError.swift @@ -19,6 +19,7 @@ public struct SpecValidationError: Error, CustomStringConvertible { case invalidTargetSchemeTest(target: String, testTarget: String) case invalidTargetPlatformForSupportedDestinations(target: String) case unexpectedTargetPlatformForSupportedDestinations(target: String, platform: Platform) + case containsWatchOSDestinationForMultiplatformApp(target: String) case multipleMacPlatformsInSupportedDestinations(target: String) case missingTargetPlatformInSupportedDestinations(target: String, platform: Platform) case invalidSchemeTarget(scheme: String, target: String, action: String) @@ -66,6 +67,8 @@ public struct SpecValidationError: Error, CustomStringConvertible { return "Target \(target.quoted) has multiple definitions of mac platforms in supported destinations" case let .missingTargetPlatformInSupportedDestinations(target, platform): return "Target \(target.quoted) has platform \(platform.rawValue.quoted) that is missing in supported destinations" + case let .containsWatchOSDestinationForMultiplatformApp(target): + return "Multiplatform app \(target.quoted) cannot contain watchOS in \"supportedDestinations\". Create a separate target using \"platform\" for watchOS apps" case let .invalidConfigFile(configFile, config): return "Invalid config file \(configFile.quoted) for config \(config.quoted)" case let .invalidSchemeTarget(scheme, target, action): diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index 44046460f..f34d487c0 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -485,8 +485,8 @@ class ProjectGeneratorTests: XCTestCase { try expect(targetConfig1.buildSettings["CODE_SIGN_IDENTITY"] as? String) == "iPhone Developer" } - $0.it("supportedDestinations merges settings - iOS, watchOS") { - let target = Target(name: "Target", type: .application, platform: .auto, supportedDestinations: [.iOS, .watchOS]) + $0.it("supportedDestinations merges settings - iOS, watchOS (framework)") { + let target = Target(name: "Target", type: .framework, platform: .auto, supportedDestinations: [.iOS, .watchOS]) let project = Project(name: "", targets: [target]) let pbxProject = try project.generatePbxProj() @@ -499,8 +499,8 @@ class ProjectGeneratorTests: XCTestCase { try expect(targetConfig1.buildSettings["SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD"] as? Bool) == true } - $0.it("supportedDestinations merges settings - visionOS, watchOS") { - let target = Target(name: "Target", type: .application, platform: .auto, supportedDestinations: [.visionOS, .watchOS]) + $0.it("supportedDestinations merges settings - visionOS, watchOS (framework)") { + let target = Target(name: "Target", type: .framework, platform: .auto, supportedDestinations: [.visionOS, .watchOS]) let project = Project(name: "", targets: [target]) let pbxProject = try project.generatePbxProj() From b90fec13fc1f6f06c85b13f4c982306ed13a6735 Mon Sep 17 00:00:00 2001 From: Tatsuki Otsuka Date: Thu, 11 Apr 2024 19:22:57 +0900 Subject: [PATCH 2/4] Add test cases --- Tests/ProjectSpecTests/ProjectSpecTests.swift | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Tests/ProjectSpecTests/ProjectSpecTests.swift b/Tests/ProjectSpecTests/ProjectSpecTests.swift index 5f1f48546..b6d5f0174 100644 --- a/Tests/ProjectSpecTests/ProjectSpecTests.swift +++ b/Tests/ProjectSpecTests/ProjectSpecTests.swift @@ -203,6 +203,32 @@ class ProjectSpecTests: XCTestCase { try expectValidationError(project, .unexpectedTargetPlatformForSupportedDestinations(target: "target1", platform: .watchOS)) } + $0.it("watchOS in multiplatform app's supported destinations") { + var project = baseProject + project.targets = [ + Target( + name: "target1", + type: .application, + platform: .auto, + supportedDestinations: [.watchOS] + ) + ] + try expectValidationError(project, .containsWatchOSDestinationForMultiplatformApp(target: "target1")) + } + + $0.it("watchOS in non-app's supported destinations") { + var project = baseProject + project.targets = [ + Target( + name: "target1", + type: .framework, + platform: .auto, + supportedDestinations: [.watchOS] + ) + ] + try expectNoValidationError(project, .containsWatchOSDestinationForMultiplatformApp(target: "target1")) + } + $0.it("multiple definitions of mac platform in supported destinations") { var project = baseProject project.targets = [ From a379d11885db3b8088ce9b7ae0e525dbd4249cd2 Mon Sep 17 00:00:00 2001 From: Tatsuki Otsuka Date: Thu, 11 Apr 2024 19:23:03 +0900 Subject: [PATCH 3/4] Update docs --- Docs/ProjectSpec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index fd821a6ef..430e54e4e 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -500,7 +500,7 @@ targets: destinationFilters: [iOS] ``` -Note that the definition of supported destinations can be applied to every type of bundle making everything more easy to manage (app targets, unit tests, UI tests etc). +Note that the definition of supported destinations can be applied to almost every type of bundle making everything more easy to manage (app targets, unit tests, UI tests etc). App targets currently do not support the watchOS destination. Create a separate target using `platform` for watchOS apps. See Apple's [Configuring a multiplatform app](https://developer.apple.com/documentation/xcode/configuring-a-multiplatform-app-target) for details. ### Sources From df68c2c851fd0095f04311178dff664ebe7139cd Mon Sep 17 00:00:00 2001 From: Tatsuki Otsuka Date: Thu, 18 Apr 2024 15:55:43 +0900 Subject: [PATCH 4/4] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c62677ff2..257cd75cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +### Fixed + +- Fixed `supportedDestinations` validation when it contains watchOS for multiplatform apps. #1470 @tatsuky + ## 2.40.1 ### Fixed