From d218ada92fbcd68127c240418968c3893f70714e Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Wed, 9 Feb 2022 11:30:23 +1100 Subject: [PATCH 01/11] fix archive if repo path has spaces --- Makefile | 2 +- scripts/archive.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f3dd42b2..aa515b3d 100644 --- a/Makefile +++ b/Makefile @@ -46,4 +46,4 @@ brew: brew bump-formula-pr --url=$(RELEASE_TAR) XcodeGen archive: build - ./scripts/archive.sh $(EXECUTABLE_PATH) + ./scripts/archive.sh "$(EXECUTABLE_PATH)" diff --git a/scripts/archive.sh b/scripts/archive.sh index ad335507..0a9ebb58 100755 --- a/scripts/archive.sh +++ b/scripts/archive.sh @@ -10,7 +10,7 @@ LICENSE=LICENSE # copy mkdir -p $BINDIR -cp -f $1 $BINDIR +cp -f "$1" $BINDIR mkdir -p $SHAREDIR cp -R SettingPresets $SHAREDIR/SettingPresets From a10c7c4c24f6f5b6acccafb7a5bb57a33068a8a7 Mon Sep 17 00:00:00 2001 From: Vladislav Lisyanskiy Date: Sun, 6 Mar 2022 10:32:35 +0300 Subject: [PATCH 02/11] Fixed Glob crash (#1181) --- CHANGELOG.md | 4 ++++ Sources/XcodeGenCore/Atomic.swift | 27 +++++++++++++++++++++++++++ Sources/XcodeGenCore/Glob.swift | 2 +- 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 Sources/XcodeGenCore/Atomic.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index ab73aaf2..c5394630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +### Fixed + +- Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x + ## 2.26.0 ### Added diff --git a/Sources/XcodeGenCore/Atomic.swift b/Sources/XcodeGenCore/Atomic.swift new file mode 100644 index 00000000..c7911ca4 --- /dev/null +++ b/Sources/XcodeGenCore/Atomic.swift @@ -0,0 +1,27 @@ +// +// Atomic.swift +// +// +// Created by Vladislav Lisianskii on 23.02.2022. +// + +import Foundation + +@propertyWrapper +struct Atomic { + private let queue = DispatchQueue(label: "com.xcodegencore.atomic") + private var value: Value + + init(wrappedValue: Value) { + self.value = wrappedValue + } + + var wrappedValue: Value { + get { + return queue.sync { value } + } + set { + queue.sync { value = newValue } + } + } +} diff --git a/Sources/XcodeGenCore/Glob.swift b/Sources/XcodeGenCore/Glob.swift index 596e986c..e3025eab 100644 --- a/Sources/XcodeGenCore/Glob.swift +++ b/Sources/XcodeGenCore/Glob.swift @@ -57,7 +57,7 @@ public class Glob: Collection { public static let defaultBlacklistedDirectories = ["node_modules", "Pods"] - private var isDirectoryCache = [String: Bool]() + @Atomic private var isDirectoryCache = [String: Bool]() public let behavior: Behavior public let blacklistedDirectories: [String] From 3b5ca91b76bbd482e602ffd902872d14a8e11074 Mon Sep 17 00:00:00 2001 From: Gabriel Lanata Date: Wed, 16 Mar 2022 21:56:03 -0700 Subject: [PATCH 03/11] Add coverage targets for target schemes (#1189) * Changes * Tests and docs * Update fixtures * Update CHANGELOG.md Co-authored-by: Yonas Kolb Co-authored-by: Yonas Kolb --- CHANGELOG.md | 1 + Docs/ProjectSpec.md | 4 ++++ Sources/ProjectSpec/TargetScheme.swift | 17 +++++++++++++++++ Sources/XcodeGenKit/SchemeGenerator.swift | 1 + .../xcschemes/App_iOS Production.xcscheme | 11 ++++++++++- .../xcschemes/App_iOS Staging.xcscheme | 11 ++++++++++- .../xcschemes/App_iOS Test.xcscheme | 11 ++++++++++- Tests/Fixtures/TestProject/project.yml | 2 ++ Tests/ProjectSpecTests/ProjectSpecTests.swift | 1 + Tests/ProjectSpecTests/SpecLoadingTests.swift | 2 ++ .../SchemeGeneratorTests.swift | 19 +++++++++++++++++++ 11 files changed, 77 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5394630..0093bf6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Added - Added the option to specify a `location` in a test target [#1150](https://github.com/yonaskolb/XcodeGen/issues/1150) @KrisRJack +- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata ### Changed diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 1874c94d..700fb800 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -653,6 +653,7 @@ This is a convenience used to automatically generate schemes for a target based - [x] **configVariants**: **[String]** - This generates a scheme for each entry, using configs that contain the name with debug and release variants. This is useful for having different environment schemes. - [ ] **testTargets**: **[[Test Target](#test-target)]** - a list of test targets that should be included in the scheme. These will be added to the build targets and the test entries. Each entry can either be a simple string, or a [Test Target](#test-target) - [ ] **gatherCoverageData**: **Bool** - a boolean that indicates if this scheme should gather coverage data. This defaults to false +- [ ] **coverageTargets**: **[String]** - a list of targets to gather code coverage. Each entry can either be a simple string, or a string using [Project Reference](#project-reference) - [ ] **disableMainThreadChecker**: **Bool** - a boolean that indicates if this scheme should disable the Main Thread Checker. This defaults to false - [ ] **stopOnEveryMainThreadCheckerIssue**: **Bool** - a boolean that indicates if this scheme should stop at every Main Thread Checker issue. This defaults to false - [ ] **buildImplicitDependencies**: **Bool** - Flag to determine if Xcode should build implicit dependencies of this scheme. By default this is `true` if not set. @@ -691,6 +692,9 @@ targets: - Staging - Production gatherCoverageData: true + coverageTargets: + - MyTarget1 + - ExternalTarget/OtherTarget1 commandLineArguments: "-MyEnabledArg": true "-MyDisabledArg": false diff --git a/Sources/ProjectSpec/TargetScheme.swift b/Sources/ProjectSpec/TargetScheme.swift index 1beedb6a..289bf5e3 100644 --- a/Sources/ProjectSpec/TargetScheme.swift +++ b/Sources/ProjectSpec/TargetScheme.swift @@ -11,6 +11,7 @@ public struct TargetScheme: Equatable { public var testTargets: [Scheme.Test.TestTarget] public var configVariants: [String] public var gatherCoverageData: Bool + public var coverageTargets: [TargetReference] public var storeKitConfiguration: String? public var language: String? public var region: String? @@ -26,6 +27,7 @@ public struct TargetScheme: Equatable { testTargets: [Scheme.Test.TestTarget] = [], configVariants: [String] = [], gatherCoverageData: Bool = gatherCoverageDataDefault, + coverageTargets: [TargetReference] = [], storeKitConfiguration: String? = nil, language: String? = nil, region: String? = nil, @@ -40,6 +42,7 @@ public struct TargetScheme: Equatable { self.testTargets = testTargets self.configVariants = configVariants self.gatherCoverageData = gatherCoverageData + self.coverageTargets = coverageTargets self.storeKitConfiguration = storeKitConfiguration self.language = language self.region = region @@ -69,6 +72,19 @@ extension TargetScheme: JSONObjectConvertible { } else { testTargets = [] } + + if let targets = jsonDictionary["coverageTargets"] as? [Any] { + coverageTargets = try targets.compactMap { target in + if let string = target as? String { + return try TargetReference(string) + } else { + return nil + } + } + } else { + coverageTargets = [] + } + configVariants = jsonDictionary.json(atKeyPath: "configVariants") ?? [] gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? TargetScheme.gatherCoverageDataDefault storeKitConfiguration = jsonDictionary.json(atKeyPath: "storeKitConfiguration") @@ -88,6 +104,7 @@ extension TargetScheme: JSONEncodable { public func toJSONValue() -> Any { var dict: [String: Any] = [ "configVariants": configVariants, + "coverageTargets": coverageTargets.map { $0.reference }, "commandLineArguments": commandLineArguments, "testTargets": testTargets.map { $0.toJSONValue() }, "environmentVariables": environmentVariables.map { $0.toJSONValue() }, diff --git a/Sources/XcodeGenKit/SchemeGenerator.swift b/Sources/XcodeGenKit/SchemeGenerator.swift index e5fa2d54..fa008bb7 100644 --- a/Sources/XcodeGenKit/SchemeGenerator.swift +++ b/Sources/XcodeGenKit/SchemeGenerator.swift @@ -413,6 +413,7 @@ extension Scheme { test: .init( config: debugConfig, gatherCoverageData: targetScheme.gatherCoverageData, + coverageTargets: targetScheme.coverageTargets, disableMainThreadChecker: targetScheme.disableMainThreadChecker, commandLineArguments: targetScheme.commandLineArguments, targets: targetScheme.testTargets, diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme index d06a2910..47969050 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/xcshareddata/xcschemes/App_iOS Production.xcscheme @@ -28,7 +28,7 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" codeCoverageEnabled = "YES" - onlyGenerateCoverageForSpecifiedTargets = "NO" + onlyGenerateCoverageForSpecifiedTargets = "YES" shouldUseLaunchSchemeArgsEnv = "NO" disableMainThreadChecker = "YES"> @@ -72,6 +72,15 @@ isEnabled = "YES"> + + + + @@ -72,6 +72,15 @@ isEnabled = "YES"> + + + + @@ -72,6 +72,15 @@ isEnabled = "YES"> + + + + Date: Thu, 17 Mar 2022 15:57:22 +1100 Subject: [PATCH 04/11] Update CHANGELOG.md --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0093bf6b..2f6917e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Next Version +### Added + +- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata + ### Fixed - Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x @@ -11,7 +15,6 @@ ### Added - Added the option to specify a `location` in a test target [#1150](https://github.com/yonaskolb/XcodeGen/issues/1150) @KrisRJack -- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata ### Changed From 7b9d95ab4cb73b1fc206914fbeed7ee75e2f4f73 Mon Sep 17 00:00:00 2001 From: Evan Coleman Date: Sat, 19 Mar 2022 23:19:23 -0400 Subject: [PATCH 05/11] Skip compile sources for watch apps (#1185) * Skip compile sources build phase for watch2 apps if empty * add changelog entry * Fix tests Co-authored-by: Yonas Kolb --- CHANGELOG.md | 9 +++++---- Sources/ProjectSpec/XCProjExtensions.swift | 4 ++-- .../TestProject/Project.xcodeproj/project.pbxproj | 8 -------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f6917e6..21de2b77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,14 @@ ## Next Version -### Added - -- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata - ### Fixed - Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x +- Skip generating empty compile sources build phases for watch apps [#1185](https://github.com/yonaskolb/XcodeGen/issues/1185) @evandcoleman + +### Added + +- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata ## 2.26.0 diff --git a/Sources/ProjectSpec/XCProjExtensions.swift b/Sources/ProjectSpec/XCProjExtensions.swift index bf3d36d2..9bee91be 100644 --- a/Sources/ProjectSpec/XCProjExtensions.swift +++ b/Sources/ProjectSpec/XCProjExtensions.swift @@ -48,8 +48,8 @@ extension PBXProductType { public var canSkipCompileSourcesBuildPhase: Bool { switch self { - case .bundle, .stickerPack, .messagesApplication: - // Bundles, sticker packs and simple messages applications without sources should not include a + case .bundle, .watch2App, .stickerPack, .messagesApplication: + // Bundles, watch apps, sticker packs and simple messages applications without sources should not include a // compile sources build phase. Doing so can cause Xcode to produce an error on build. return true default: diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index c0344eb3..2f440618 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -1697,7 +1697,6 @@ isa = PBXNativeTarget; buildConfigurationList = 6B5C5F08C0EF06457756E379 /* Build configuration list for PBXNativeTarget "App_watchOS" */; buildPhases = ( - 91C895DE8170C96A75D29426 /* Sources */, B7B71FA7D279029BF7A7FC7C /* Resources */, C765431E5FF4B02F59DE79B0 /* Embed App Extensions */, ); @@ -2706,13 +2705,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 91C895DE8170C96A75D29426 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 96BB43F4706B031DA45166E8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; From e77caa8a4052b394d09948801dc5883f0a325e16 Mon Sep 17 00:00:00 2001 From: Christian Huck Date: Sun, 20 Mar 2022 04:20:37 +0100 Subject: [PATCH 06/11] add .gyb as an accepted source file (#1191) * add .gyb to source files * Update CHANGELOG.md Co-authored-by: Christian Huck --- CHANGELOG.md | 2 ++ Sources/ProjectSpec/FileType.swift | 1 + 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21de2b77..3672aee2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ - Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata +- Fixed issue where .gyb files could not be added to source file list [#1191]((https://github.com/yonaskolb/XcodeGen/issues/1191) @hakkurishian + ## 2.26.0 ### Added diff --git a/Sources/ProjectSpec/FileType.swift b/Sources/ProjectSpec/FileType.swift index 372bc79d..d106b285 100644 --- a/Sources/ProjectSpec/FileType.swift +++ b/Sources/ProjectSpec/FileType.swift @@ -75,6 +75,7 @@ extension FileType { // sources "swift": FileType(buildPhase: .sources), + "gyb": FileType(buildPhase: .sources), "m": FileType(buildPhase: .sources), "mm": FileType(buildPhase: .sources), "cpp": FileType(buildPhase: .sources), From 146eaadaf3aed2242d71c8531a38c153520d7fa9 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Sun, 20 Mar 2022 14:20:53 +1100 Subject: [PATCH 07/11] Update CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3672aee2..d9af32ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,6 @@ ### Added - Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata - - Fixed issue where .gyb files could not be added to source file list [#1191]((https://github.com/yonaskolb/XcodeGen/issues/1191) @hakkurishian ## 2.26.0 From 245f17117abe10a4d823c917fbed7dceaff1a851 Mon Sep 17 00:00:00 2001 From: "freddi(Yuki Aki)" Date: Sun, 20 Mar 2022 12:27:29 +0900 Subject: [PATCH 08/11] Support test target for local Swift Package (#1169) * support local Swift Package test case into test scheme * update test * add test * update CHABGELOG.md * Update CHANGELOG.md * revert resolved package test * Update Sources/XcodeGenKit/SchemeGenerator.swift Co-authored-by: Kohki Miki * make TargetReference convert from new JSON format * add .package for location of target reference * receive target reference format at target of scheme * update test * update XcodeProj * add test and fix small bugs * update docs * support multiple style of coverageTargets * add edge case of parsing test targets * fix docs * Update Docs/ProjectSpec.md Co-authored-by: Yonas Kolb * create TestableTargetReference for not making API complex * fix code format * fix parameter name to Testable Target Reference * support directly writing key of Testable Target Reference * fix compile error in build Co-authored-by: Kohki Miki Co-authored-by: Yonas Kolb --- CHANGELOG.md | 2 + Docs/ProjectSpec.md | 22 +++- Sources/ProjectSpec/Project.swift | 4 + Sources/ProjectSpec/Scheme.swift | 47 ++++++-- Sources/ProjectSpec/SpecValidation.swift | 18 +++ Sources/ProjectSpec/SpecValidationError.swift | 3 + Sources/ProjectSpec/TargetReference.swift | 4 +- Sources/ProjectSpec/TargetScheme.swift | 7 +- Sources/ProjectSpec/TestTargeReference.swift | 112 ++++++++++++++++++ Sources/XcodeGenKit/SchemeGenerator.swift | 29 ++++- .../xcshareddata/xcschemes/App.xcscheme | 20 ++++ Tests/Fixtures/SPM/project.yml | 7 +- .../SchemeGeneratorTests.swift | 37 +++++- 13 files changed, 284 insertions(+), 28 deletions(-) create mode 100644 Sources/ProjectSpec/TestTargeReference.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index d9af32ed..eca47f8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Change Log ## Next Version +#### Added +- Support test target for local Swift Package [#1074](https://github.com/yonaskolb/XcodeGen/pull/1074) @freddi-kit ### Fixed diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 700fb800..70562385 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -828,14 +828,22 @@ A multiline script can be written using the various YAML multiline methods, for ### Test Action - [ ] **gatherCoverageData**: **Bool** - a boolean that indicates if this scheme should gather coverage data. This defaults to false -- [ ] **coverageTargets**: **[String]** - a list of targets to gather code coverage. Each entry can either be a simple string, or a string using [Project Reference](#project-reference) +- [ ] **coverageTargets**: **[[Testable Target Reference](#testable-target-reference)]** - a list of targets to gather code coverage. Each entry can also either be a simple string, a string using [Project Reference](#project-reference) or [Testable Target Reference](#testable-target-reference) - [ ] **targets**: **[[Test Target](#test-target)]** - a list of targets to test. Each entry can either be a simple string, or a [Test Target](#test-target) - [ ] **customLLDBInit**: **String** - the absolute path to the custom `.lldbinit` file - [ ] **captureScreenshotsAutomatically**: **Bool** - indicates whether screenshots should be captured automatically while UI Testing. This defaults to true. - [ ] **deleteScreenshotsWhenEachTestSucceeds**: **Bool** - whether successful UI tests should cause automatically-captured screenshots to be deleted. If `captureScreenshotsAutomatically` is false, this value is ignored. This defaults to true. #### Test Target -- [x] **name**: **String** - The name of the target +A target can be one of a 2 types: + +- **name**: **String** - The name of the target. +- **target**: **[Testable Target Reference](#testable-target-reference)** - The information of the target. You can specify more detailed information than `name:`. + +As syntax suger, you can also specify **[Testable Target Reference](#testable-target-reference)** without `target`. + +#### Other Parameters + - [ ] **parallelizable**: **Bool** - Whether to run tests in parallel. Defaults to false - [ ] **randomExecutionOrder**: **Bool** - Whether to run tests in a random order. Defaults to false - [ ] **location**: **String** - GPX file or predefined value for simulating location. See [Simulate Location](#simulate-location) for location examples. @@ -843,6 +851,12 @@ A multiline script can be written using the various YAML multiline methods, for - [ ] **skippedTests**: **[String]** - List of tests in the test target to skip. Defaults to empty - [ ] **selectedTests**: **[String]** - List of tests in the test target to whitelist and select. Defaults to empty. This will override `skippedTests` if provided +#### Testable Target Reference +A Testable Target Reference can be one of 3 types: +- `package: {local-swift-package-name}/{target-name}`: Name of local swift package and its target. +- `local: {target-name}`: Name of local target. +- `project: {project-reference-name}/{target-name}`: Name of local swift package and its target. + ### Archive Action - [ ] **customArchiveName**: **String** - the custom name to give to the archive @@ -902,12 +916,16 @@ schemes: coverageTargets: - MyTarget1 - ExternalTarget/OtherTarget1 + - package: LocalPackage/TestTarget targets: - Tester1 - name: Tester2 parallelizable: true randomExecutionOrder: true skippedTests: [Test/testExample()] + - package: APIClient/APIClientTests + parallelizable: true + randomExecutionOrder: true environmentVariables: - variable: TEST_ENV_VAR value: VALUE diff --git a/Sources/ProjectSpec/Project.swift b/Sources/ProjectSpec/Project.swift index 2d6842dc..972daa01 100644 --- a/Sources/ProjectSpec/Project.swift +++ b/Sources/ProjectSpec/Project.swift @@ -83,6 +83,10 @@ public struct Project: BuildSettingsContainer { targetsMap[targetName] } + public func getPackage(_ packageName: String) -> SwiftPackage? { + packages[packageName] + } + public func getAggregateTarget(_ targetName: String) -> AggregateTarget? { aggregateTargetsMap[targetName] } diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index 25ce697c..73c762d6 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -169,7 +169,7 @@ public struct Scheme: Equatable { public var config: String? public var gatherCoverageData: Bool - public var coverageTargets: [TargetReference] + public var coverageTargets: [TestableTargetReference] public var disableMainThreadChecker: Bool public var commandLineArguments: [String: Bool] public var targets: [TestTarget] @@ -189,7 +189,7 @@ public struct Scheme: Equatable { public static let parallelizableDefault = false public var name: String { targetReference.name } - public let targetReference: TargetReference + public let targetReference: TestableTargetReference public var randomExecutionOrder: Bool public var parallelizable: Bool public var location: String? @@ -198,7 +198,7 @@ public struct Scheme: Equatable { public var selectedTests: [String] public init( - targetReference: TargetReference, + targetReference: TestableTargetReference, randomExecutionOrder: Bool = randomExecutionOrderDefault, parallelizable: Bool = parallelizableDefault, location: String? = nil, @@ -217,7 +217,7 @@ public struct Scheme: Equatable { public init(stringLiteral value: String) { do { - targetReference = try TargetReference(value) + targetReference = try TestableTargetReference(value) randomExecutionOrder = false parallelizable = false location = nil @@ -233,7 +233,7 @@ public struct Scheme: Equatable { public init( config: String, gatherCoverageData: Bool = gatherCoverageDataDefault, - coverageTargets: [TargetReference] = [], + coverageTargets: [TestableTargetReference] = [], disableMainThreadChecker: Bool = disableMainThreadCheckerDefault, randomExecutionOrder: Bool = false, parallelizable: Bool = false, @@ -331,10 +331,10 @@ public struct Scheme: Equatable { } public struct BuildTarget: Equatable, Hashable { - public var target: TargetReference + public var target: TestableTargetReference public var buildTypes: [BuildType] - public init(target: TargetReference, buildTypes: [BuildType] = BuildType.all) { + public init(target: TestableTargetReference, buildTypes: [BuildType] = BuildType.all) { self.target = target self.buildTypes = buildTypes } @@ -465,13 +465,28 @@ extension Scheme.Test: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { config = jsonDictionary.json(atKeyPath: "config") gatherCoverageData = jsonDictionary.json(atKeyPath: "gatherCoverageData") ?? Scheme.Test.gatherCoverageDataDefault - coverageTargets = try (jsonDictionary.json(atKeyPath: "coverageTargets") ?? []).map { try TargetReference($0) } + + if let coverages = jsonDictionary["coverageTargets"] as? [Any] { + coverageTargets = try coverages.compactMap { target in + if let string = target as? String { + return try TestableTargetReference(string) + } else if let dictionary = target as? JSONDictionary, + let target: TestableTargetReference = try? .init(jsonDictionary: dictionary) { + return target + } else { + return nil + } + } + } else { + coverageTargets = [] + } + disableMainThreadChecker = jsonDictionary.json(atKeyPath: "disableMainThreadChecker") ?? Scheme.Test.disableMainThreadCheckerDefault commandLineArguments = jsonDictionary.json(atKeyPath: "commandLineArguments") ?? [:] if let targets = jsonDictionary["targets"] as? [Any] { self.targets = try targets.compactMap { target in if let string = target as? String { - return try TestTarget(targetReference: TargetReference(string)) + return try TestTarget(targetReference: TestableTargetReference(string)) } else if let dictionary = target as? JSONDictionary { return try TestTarget(jsonDictionary: dictionary) } else { @@ -538,7 +553,17 @@ extension Scheme.Test: JSONEncodable { extension Scheme.Test.TestTarget: JSONObjectConvertible { public init(jsonDictionary: JSONDictionary) throws { - targetReference = try TargetReference(jsonDictionary.json(atKeyPath: "name")) + if let name: String = jsonDictionary.json(atKeyPath: "name") { + targetReference = try TestableTargetReference(name) + } else if let local: String = jsonDictionary.json(atKeyPath: "local") { + self.targetReference = TestableTargetReference.local(local) + } else if let project: String = jsonDictionary.json(atKeyPath: "project") { + self.targetReference = TestableTargetReference.project(project) + } else if let package: String = jsonDictionary.json(atKeyPath: "package") { + self.targetReference = TestableTargetReference.package(package) + } else { + self.targetReference = try jsonDictionary.json(atKeyPath: "target") + } randomExecutionOrder = jsonDictionary.json(atKeyPath: "randomExecutionOrder") ?? Scheme.Test.TestTarget.randomExecutionOrderDefault parallelizable = jsonDictionary.json(atKeyPath: "parallelizable") ?? Scheme.Test.TestTarget.parallelizableDefault location = jsonDictionary.json(atKeyPath: "location") ?? nil @@ -694,7 +719,7 @@ extension Scheme.Build: JSONObjectConvertible { } else { buildTypes = BuildType.all } - let target = try TargetReference(targetRepr) + let target = try TestableTargetReference(targetRepr) targets.append(Scheme.BuildTarget(target: target, buildTypes: buildTypes)) } self.targets = targets.sorted { $0.target.name < $1.target.name } diff --git a/Sources/ProjectSpec/SpecValidation.swift b/Sources/ProjectSpec/SpecValidation.swift index fd1049c6..01caca58 100644 --- a/Sources/ProjectSpec/SpecValidation.swift +++ b/Sources/ProjectSpec/SpecValidation.swift @@ -119,6 +119,10 @@ extension Project { for testTarget in scheme.testTargets { if getTarget(testTarget.name) == nil { + // For test case of local Swift Package + if case .package(let name) = testTarget.targetReference.location, getPackage(name) != nil { + continue + } errors.append(.invalidTargetSchemeTest(target: target.name, testTarget: testTarget.name)) } } @@ -243,4 +247,18 @@ extension Project { return nil } } + + /// Returns a descriptive error if the given target reference was invalid otherwise `nil`. + private func validationError(for testableTargetReference: TestableTargetReference, in scheme: Scheme, action: String) -> SpecValidationError.ValidationError? { + switch testableTargetReference.location { + case .local where getProjectTarget(testableTargetReference.name) == nil: + return .invalidSchemeTarget(scheme: scheme.name, target: testableTargetReference.name, action: action) + case .project(let project) where getProjectReference(project) == nil: + return .invalidProjectReference(scheme: scheme.name, reference: project) + case .package(let package) where getPackage(package) == nil: + return .invalidLocalPackage(package) + case .local, .project, .package: + return nil + } + } } diff --git a/Sources/ProjectSpec/SpecValidationError.swift b/Sources/ProjectSpec/SpecValidationError.swift index c1948652..f4025bbf 100644 --- a/Sources/ProjectSpec/SpecValidationError.swift +++ b/Sources/ProjectSpec/SpecValidationError.swift @@ -20,6 +20,7 @@ public struct SpecValidationError: Error, CustomStringConvertible { case invalidSchemeTarget(scheme: String, target: String, action: String) case invalidSchemeConfig(scheme: String, config: String) case invalidSwiftPackage(name: String, target: String) + case invalidPackageDependencyReference(name: String) case invalidLocalPackage(String) case invalidConfigFile(configFile: String, config: String) case invalidBuildSettingConfig(String) @@ -69,6 +70,8 @@ public struct SpecValidationError: Error, CustomStringConvertible { return "Target \(target.quoted) has an invalid package dependency \(name.quoted)" case let .invalidLocalPackage(path): return "Invalid local package \(path.quoted)" + case let .invalidPackageDependencyReference(name): + return "Package reference \(name) must be specified as package dependency, not target" case let .missingConfigForTargetScheme(target, configType): return "Target \(target.quoted) is missing a config of type \(configType.rawValue) to generate its scheme" case let .missingDefaultConfig(name): diff --git a/Sources/ProjectSpec/TargetReference.swift b/Sources/ProjectSpec/TargetReference.swift index 1a64e258..22da0a2e 100644 --- a/Sources/ProjectSpec/TargetReference.swift +++ b/Sources/ProjectSpec/TargetReference.swift @@ -46,8 +46,8 @@ extension TargetReference: CustomStringConvertible { public var reference: String { switch location { case .local: return name - case .project(let projectPath): - return "\(projectPath)/\(name)" + case .project(let root): + return "\(root)/\(name)" } } diff --git a/Sources/ProjectSpec/TargetScheme.swift b/Sources/ProjectSpec/TargetScheme.swift index 289bf5e3..136fd796 100644 --- a/Sources/ProjectSpec/TargetScheme.swift +++ b/Sources/ProjectSpec/TargetScheme.swift @@ -62,9 +62,10 @@ extension TargetScheme: JSONObjectConvertible { if let targets = jsonDictionary["testTargets"] as? [Any] { testTargets = try targets.compactMap { target in if let string = target as? String { - return .init(targetReference: try TargetReference(string)) - } else if let dictionary = target as? JSONDictionary { - return try .init(jsonDictionary: dictionary) + return .init(targetReference: try TestableTargetReference(string)) + } else if let dictionary = target as? JSONDictionary, + let target: Scheme.Test.TestTarget = try? .init(jsonDictionary: dictionary) { + return target } else { return nil } diff --git a/Sources/ProjectSpec/TestTargeReference.swift b/Sources/ProjectSpec/TestTargeReference.swift new file mode 100644 index 00000000..17ea557b --- /dev/null +++ b/Sources/ProjectSpec/TestTargeReference.swift @@ -0,0 +1,112 @@ +import Foundation +import JSONUtilities + +public struct TestableTargetReference: Hashable { + public var name: String + public var location: Location + + public var targetReference: TargetReference { + switch location { + case .local: + return TargetReference(name: name, location: .local) + case .project(let projectName): + return TargetReference(name: name, location: .project(projectName)) + case .package: + fatalError("Package target is only available for testable") + } + } + + public enum Location: Hashable { + case local + case project(String) + case package(String) + } + + public init(name: String, location: Location) { + self.name = name + self.location = location + } +} + +extension TestableTargetReference { + public init(_ string: String) throws { + let paths = string.split(separator: "/") + switch paths.count { + case 2: + location = .project(String(paths[0])) + name = String(paths[1]) + case 1: + location = .local + name = String(paths[0]) + default: + throw SpecParsingError.invalidTargetReference(string) + } + } + + public static func local(_ name: String) -> TestableTargetReference { + TestableTargetReference(name: name, location: .local) + } + + public static func project(_ name: String) -> TestableTargetReference { + let paths = name.split(separator: "/") + return TestableTargetReference(name: String(paths[1]), location: .project(String(paths[0]))) + } + + public static func package(_ name: String) -> TestableTargetReference { + let paths = name.split(separator: "/") + return TestableTargetReference(name: String(paths[1]), location: .package(String(paths[0]))) + } +} + +extension TestableTargetReference: ExpressibleByStringLiteral { + public init(stringLiteral value: String) { + try! self.init(value) + } +} + +extension TestableTargetReference: CustomStringConvertible { + public var reference: String { + switch location { + case .local: return name + case .project(let root), .package(let root): + return "\(root)/\(name)" + } + } + + public var description: String { + reference + } +} + +extension TestableTargetReference: JSONObjectConvertible { + + public init(jsonDictionary: JSONDictionary) throws { + if let project: String = jsonDictionary.json(atKeyPath: "project") { + let paths = project.split(separator: "/") + name = String(paths[1]) + location = .project(String(paths[0])) + } else if let project: String = jsonDictionary.json(atKeyPath: "package") { + let paths = project.split(separator: "/") + name = String(paths[1]) + location = .package(String(paths[0])) + } else { + name = try jsonDictionary.json(atKeyPath: "local") + location = .local + } + } +} + +extension TestableTargetReference: JSONEncodable { + public func toJSONValue() -> Any { + var dictionary: JSONDictionary = [:] + switch self.location { + case .package(let packageName): + dictionary["package"] = "\(packageName)/\(name)" + case .project(let projectName): + dictionary["project"] = "\(projectName)/\(name)" + case .local: + dictionary["local"] = name + } + return dictionary + } +} diff --git a/Sources/XcodeGenKit/SchemeGenerator.swift b/Sources/XcodeGenKit/SchemeGenerator.swift index fa008bb7..e980b994 100644 --- a/Sources/XcodeGenKit/SchemeGenerator.swift +++ b/Sources/XcodeGenKit/SchemeGenerator.swift @@ -136,9 +136,27 @@ public class SchemeGenerator { blueprintName: target.name ) } + + func getBuildableTestableReference(_ target: TestableTargetReference) throws -> XCScheme.BuildableReference { + switch target.location { + case .package(let packageName): + guard let package = self.project.getPackage(packageName), + case .local(let path) = package else { + throw SchemeGenerationError.missingPackage(packageName) + } + return XCScheme.BuildableReference( + referencedContainer: "container:\(path)", + blueprintIdentifier: target.name, + buildableName: target.name, + blueprintName: target.name + ) + default: + return try getBuildableReference(target.targetReference) + } + } func getBuildEntry(_ buildTarget: Scheme.BuildTarget) throws -> XCScheme.BuildAction.Entry { - let buildableReference = try getBuildableReference(buildTarget.target) + let buildableReference = try getBuildableTestableReference(buildTarget.target) return XCScheme.BuildAction.Entry(buildableReference: buildableReference, buildFor: buildTarget.buildTypes) } @@ -216,7 +234,7 @@ public class SchemeGenerator { } let coverageBuildableTargets = try scheme.test?.coverageTargets.map { - try getBuildableReference($0) + try getBuildableTestableReference($0) } ?? [] let testCommandLineArgs = scheme.test.map { XCScheme.CommandLineArguments($0.commandLineArguments) } @@ -375,6 +393,7 @@ public class SchemeGenerator { enum SchemeGenerationError: Error, CustomStringConvertible { case missingTarget(TargetReference, projectPath: String) + case missingPackage(String) case missingProject(String) case missingBuildTargets(String) @@ -386,6 +405,8 @@ enum SchemeGenerationError: Error, CustomStringConvertible { return "Unable to find project reference named \"\(project)\" in project.yml" case .missingBuildTargets(let name): return "Unable to find at least one build target in scheme \"\(name)\"" + case .missingPackage(let package): + return "Unable to find swift package named \"\(package)\" in project.yml" } } } @@ -436,14 +457,14 @@ extension Scheme { } private static func buildTargets(for target: Target, project: Project) -> [BuildTarget] { - let buildTarget = Scheme.BuildTarget(target: TargetReference.local(target.name)) + let buildTarget = Scheme.BuildTarget(target: TestableTargetReference.local(target.name)) switch target.type { case .watchApp, .watch2App: let hostTarget = project.targets .first { projectTarget in projectTarget.dependencies.contains { $0.reference == target.name } } - .map { BuildTarget(target: TargetReference.local($0.name)) } + .map { BuildTarget(target: TestableTargetReference.local($0.name)) } return hostTarget.map { [buildTarget, $0] } ?? [buildTarget] default: return [buildTarget] diff --git a/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme b/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme index ed6efd9a..ff4048c2 100644 --- a/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme +++ b/Tests/Fixtures/SPM/SPM.xcodeproj/xcshareddata/xcschemes/App.xcscheme @@ -30,6 +30,26 @@ onlyGenerateCoverageForSpecifiedTargets = "NO" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + + Date: Sun, 20 Mar 2022 14:28:41 +1100 Subject: [PATCH 09/11] Update CHANGELOG.md --- CHANGELOG.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eca47f8e..1ec079a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,19 +1,18 @@ # Change Log ## Next Version + #### Added + - Support test target for local Swift Package [#1074](https://github.com/yonaskolb/XcodeGen/pull/1074) @freddi-kit +- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata +- Fixed issue where .gyb files could not be added to source file list [#1191]((https://github.com/yonaskolb/XcodeGen/issues/1191) @hakkurishian ### Fixed - Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x - Skip generating empty compile sources build phases for watch apps [#1185](https://github.com/yonaskolb/XcodeGen/issues/1185) @evandcoleman -### Added - -- Added `coverageTargets` for target test schemes. This enables to gather code coverage for specific targets. [#1189](https://github.com/yonaskolb/XcodeGen/pull/1189) @gabriellanata -- Fixed issue where .gyb files could not be added to source file list [#1191]((https://github.com/yonaskolb/XcodeGen/issues/1191) @hakkurishian - ## 2.26.0 ### Added From d7accac686cbb6b271d118a0b743784a1d6b1ca8 Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Sun, 20 Mar 2022 14:30:49 +1100 Subject: [PATCH 10/11] Update to 2.27.0 --- CHANGELOG.md | 4 ++++ Makefile | 2 +- README.md | 2 +- Sources/XcodeGen/main.swift | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ec079a8..2d32e9bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Next Version +## 2.27.0 + #### Added - Support test target for local Swift Package [#1074](https://github.com/yonaskolb/XcodeGen/pull/1074) @freddi-kit @@ -13,6 +15,8 @@ - Fixed crash caused by a simultaneous write during a glob processing [#1177](https://github.com/yonaskolb/XcodeGen/issues/1177) @tr1ckyf0x - Skip generating empty compile sources build phases for watch apps [#1185](https://github.com/yonaskolb/XcodeGen/issues/1185) @evandcoleman +[Commits](https://github.com/yonaskolb/XcodeGen/compare/2.26.0...2.27.0) + ## 2.26.0 ### Added diff --git a/Makefile b/Makefile index aa515b3d..c03ff674 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TOOL_NAME = XcodeGen export EXECUTABLE_NAME = xcodegen -VERSION = 2.26.0 +VERSION = 2.27.0 PREFIX = /usr/local INSTALL_PATH = $(PREFIX)/bin/$(EXECUTABLE_NAME) diff --git a/README.md b/README.md index 6b036a52..f7ada854 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ swift run xcodegen Add the following to your Package.swift file's dependencies: ```swift -.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.26.0"), +.package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.27.0"), ``` And then import wherever needed: `import XcodeGenKit` diff --git a/Sources/XcodeGen/main.swift b/Sources/XcodeGen/main.swift index 8ba636bf..fee30977 100644 --- a/Sources/XcodeGen/main.swift +++ b/Sources/XcodeGen/main.swift @@ -3,6 +3,6 @@ import ProjectSpec import XcodeGenCLI import Version -let version = Version("2.26.0") +let version = Version("2.27.0") let cli = XcodeGenCLI(version: version) cli.execute() From f6cdd090c22622c3e2254da167099e3980e9bd89 Mon Sep 17 00:00:00 2001 From: yonaskolb Date: Sun, 20 Mar 2022 14:44:14 +1100 Subject: [PATCH 11/11] use new TestableTargetReference in TargetScheme.coverageTargets --- Docs/ProjectSpec.md | 4 ++-- Sources/ProjectSpec/TargetScheme.swift | 9 ++++++--- Tests/XcodeGenKitTests/SchemeGeneratorTests.swift | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index 70562385..b9e5b2e6 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -653,7 +653,7 @@ This is a convenience used to automatically generate schemes for a target based - [x] **configVariants**: **[String]** - This generates a scheme for each entry, using configs that contain the name with debug and release variants. This is useful for having different environment schemes. - [ ] **testTargets**: **[[Test Target](#test-target)]** - a list of test targets that should be included in the scheme. These will be added to the build targets and the test entries. Each entry can either be a simple string, or a [Test Target](#test-target) - [ ] **gatherCoverageData**: **Bool** - a boolean that indicates if this scheme should gather coverage data. This defaults to false -- [ ] **coverageTargets**: **[String]** - a list of targets to gather code coverage. Each entry can either be a simple string, or a string using [Project Reference](#project-reference) +- [ ] **coverageTargets**: **[[Testable Target Reference](#testable-target-reference) - a list of targets to gather code coverage. Each entry can either be a simple string, a string using [Project Reference](#project-reference) or [Testable Target Reference](#testable-target-reference) - [ ] **disableMainThreadChecker**: **Bool** - a boolean that indicates if this scheme should disable the Main Thread Checker. This defaults to false - [ ] **stopOnEveryMainThreadCheckerIssue**: **Bool** - a boolean that indicates if this scheme should stop at every Main Thread Checker issue. This defaults to false - [ ] **buildImplicitDependencies**: **Bool** - Flag to determine if Xcode should build implicit dependencies of this scheme. By default this is `true` if not set. @@ -828,7 +828,7 @@ A multiline script can be written using the various YAML multiline methods, for ### Test Action - [ ] **gatherCoverageData**: **Bool** - a boolean that indicates if this scheme should gather coverage data. This defaults to false -- [ ] **coverageTargets**: **[[Testable Target Reference](#testable-target-reference)]** - a list of targets to gather code coverage. Each entry can also either be a simple string, a string using [Project Reference](#project-reference) or [Testable Target Reference](#testable-target-reference) +- [ ] **coverageTargets**: **[[Testable Target Reference](#testable-target-reference)]** - a list of targets to gather code coverage. Each entry can either be a simple string, a string using [Project Reference](#project-reference) or [Testable Target Reference](#testable-target-reference) - [ ] **targets**: **[[Test Target](#test-target)]** - a list of targets to test. Each entry can either be a simple string, or a [Test Target](#test-target) - [ ] **customLLDBInit**: **String** - the absolute path to the custom `.lldbinit` file - [ ] **captureScreenshotsAutomatically**: **Bool** - indicates whether screenshots should be captured automatically while UI Testing. This defaults to true. diff --git a/Sources/ProjectSpec/TargetScheme.swift b/Sources/ProjectSpec/TargetScheme.swift index 136fd796..9eb7f279 100644 --- a/Sources/ProjectSpec/TargetScheme.swift +++ b/Sources/ProjectSpec/TargetScheme.swift @@ -11,7 +11,7 @@ public struct TargetScheme: Equatable { public var testTargets: [Scheme.Test.TestTarget] public var configVariants: [String] public var gatherCoverageData: Bool - public var coverageTargets: [TargetReference] + public var coverageTargets: [TestableTargetReference] public var storeKitConfiguration: String? public var language: String? public var region: String? @@ -27,7 +27,7 @@ public struct TargetScheme: Equatable { testTargets: [Scheme.Test.TestTarget] = [], configVariants: [String] = [], gatherCoverageData: Bool = gatherCoverageDataDefault, - coverageTargets: [TargetReference] = [], + coverageTargets: [TestableTargetReference] = [], storeKitConfiguration: String? = nil, language: String? = nil, region: String? = nil, @@ -77,7 +77,10 @@ extension TargetScheme: JSONObjectConvertible { if let targets = jsonDictionary["coverageTargets"] as? [Any] { coverageTargets = try targets.compactMap { target in if let string = target as? String { - return try TargetReference(string) + return try TestableTargetReference(string) + } else if let dictionary = target as? JSONDictionary, + let target: TestableTargetReference = try? .init(jsonDictionary: dictionary) { + return target } else { return nil } diff --git a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift index 3257f380..2d820209 100644 --- a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift @@ -331,7 +331,7 @@ class SchemeGeneratorTests: XCTestCase { target.scheme = try TargetScheme( gatherCoverageData: true, coverageTargets: [ - TargetReference(framework.name), + TestableTargetReference(framework.name), ] )