yonaskolb / XcodeGen

A Swift command line tool for generating your Xcode project
MIT License
6.9k stars 810 forks source link

Is it possible to conditionally exclude platforms from a target spec? #844

Open daltonclaybrook opened 4 years ago

daltonclaybrook commented 4 years ago

I have a framework target that is compiled for iOS, tvOS, and watchOS. I would like to create a unit test bundle for this framework and specify it in the target scheme definition. Here are the two targets in the spec:

PlatformDemoKit:
    type: framework
    platform: [iOS, tvOS, watchOS]
    sources:
        - PlatformDemoKit
    scheme:
        testTargets:
            - PlatformDemoKitTests_${platform}

PlatformDemoKitTests:
    type: bundle.unit-test
    platform: [iOS, tvOS]
    sources:
        - PlatformDemoKitTests
    dependencies:
        - target: PlatformDemoKit_${platform}

As you may have already guessed, this spec results in an error in XcodeGen:

Spec validation error: Target "PlatformDemoKit_watchOS" scheme has invalid test "PlatformDemoKitTests_watchOS"

Unfortunately, as of this writing, Xcode does not allow us to make test bundles with watchOS as the base SDK. Ideally, I would like to simply exclude the PlatformDemoKitTests_watchOS target from the testTargets list for watchOS given that it does not exist. Is what I'm trying to do possible in XcodeGen? Is there a more "idiomatic XcodeGen" way of solving this problem?

yonaskolb commented 4 years ago

There's no way to exclude a test target per platform like that but you could create seperate targets instead of using a single one with multiple platforms. This will have the same affect but you can customize each one (like not including tests for watchOS). You can leverage target templates to reduce any duplication.

daltonclaybrook commented 4 years ago

Thanks for the response. In your opinion, would something like this make sense as a feature request? Not sure what syntax would be most appropriate, but something like this comes to mind:

scheme:
    testTargets:
        - PlatformDemoKitTests_${platform?}
        # or
        - PlatformDemoKitTests_$?{platform}

The effect would be to mark the platform variable as optional and omit this test target from the list it is missing.