From a2835ef2992e08cebab37fba52b93fbf1a59f26d Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Mon, 16 Sep 2019 11:00:32 +0900 Subject: [PATCH 01/11] Add debugEnabled option for run and test --- Sources/ProjectSpec/Scheme.swift | 21 +++++++++++++++++++-- Sources/XcodeGenKit/SchemeGenerator.swift | 2 ++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Sources/ProjectSpec/Scheme.swift b/Sources/ProjectSpec/Scheme.swift index f60a26da..cc53b13a 100644 --- a/Sources/ProjectSpec/Scheme.swift +++ b/Sources/ProjectSpec/Scheme.swift @@ -69,6 +69,7 @@ public struct Scheme: Equatable { public struct Run: BuildAction { public static let disableMainThreadCheckerDefault = false + public static let debugEnabledDefault = true public var config: String? public var commandLineArguments: [String: Bool] @@ -78,6 +79,7 @@ public struct Scheme: Equatable { public var disableMainThreadChecker: Bool public var language: String? public var region: String? + public var debugEnabled: Bool public init( config: String, @@ -87,7 +89,8 @@ public struct Scheme: Equatable { environmentVariables: [XCScheme.EnvironmentVariable] = [], disableMainThreadChecker: Bool = disableMainThreadCheckerDefault, language: String? = nil, - region: String? = nil + region: String? = nil, + debugEnabled: Bool = debugEnabledDefault ) { self.config = config self.commandLineArguments = commandLineArguments @@ -97,12 +100,14 @@ public struct Scheme: Equatable { self.disableMainThreadChecker = disableMainThreadChecker self.language = language self.region = region + self.debugEnabled = debugEnabled } } public struct Test: BuildAction { public static let gatherCoverageDataDefault = false public static let disableMainThreadCheckerDefault = false + public static let debugEnabledDefault = true public var config: String? public var gatherCoverageData: Bool @@ -114,6 +119,7 @@ public struct Scheme: Equatable { public var environmentVariables: [XCScheme.EnvironmentVariable] public var language: String? public var region: String? + public var debugEnabled: Bool public struct TestTarget: Equatable, ExpressibleByStringLiteral { public static let randomExecutionOrderDefault = false @@ -156,7 +162,8 @@ public struct Scheme: Equatable { postActions: [ExecutionAction] = [], environmentVariables: [XCScheme.EnvironmentVariable] = [], language: String? = nil, - region: String? = nil + region: String? = nil, + debugEnabled: Bool = debugEnabledDefault ) { self.config = config self.gatherCoverageData = gatherCoverageData @@ -168,6 +175,7 @@ public struct Scheme: Equatable { self.environmentVariables = environmentVariables self.language = language self.region = region + self.debugEnabled = debugEnabled } public var shouldUseLaunchSchemeArgsEnv: Bool { @@ -275,6 +283,7 @@ extension Scheme.Run: JSONObjectConvertible { disableMainThreadChecker = jsonDictionary.json(atKeyPath: "disableMainThreadChecker") ?? Scheme.Run.disableMainThreadCheckerDefault language = jsonDictionary.json(atKeyPath: "language") region = jsonDictionary.json(atKeyPath: "region") + debugEnabled = jsonDictionary.json(atKeyPath: "debugEnabled") ?? Scheme.Run.debugEnabledDefault } } @@ -294,6 +303,9 @@ extension Scheme.Run: JSONEncodable { dict["disableMainThreadChecker"] = disableMainThreadChecker } + if debugEnabled != Scheme.Run.debugEnabledDefault { + dict["debugEnabled"] = debugEnabled + } return dict } } @@ -323,6 +335,7 @@ extension Scheme.Test: JSONObjectConvertible { environmentVariables = try XCScheme.EnvironmentVariable.parseAll(jsonDictionary: jsonDictionary) language = jsonDictionary.json(atKeyPath: "language") region = jsonDictionary.json(atKeyPath: "region") + debugEnabled = jsonDictionary.json(atKeyPath: "debugEnabled") ?? Scheme.Test.debugEnabledDefault } } @@ -347,6 +360,10 @@ extension Scheme.Test: JSONEncodable { dict["disableMainThreadChecker"] = disableMainThreadChecker } + if debugEnabled != Scheme.Run.debugEnabledDefault { + dict["debugEnabled"] = debugEnabled + } + return dict } } diff --git a/Sources/XcodeGenKit/SchemeGenerator.swift b/Sources/XcodeGenKit/SchemeGenerator.swift index 2af0b16e..e1076dae 100644 --- a/Sources/XcodeGenKit/SchemeGenerator.swift +++ b/Sources/XcodeGenKit/SchemeGenerator.swift @@ -152,6 +152,7 @@ public class SchemeGenerator { testables: testables, preActions: scheme.test?.preActions.map(getExecutionAction) ?? [], postActions: scheme.test?.postActions.map(getExecutionAction) ?? [], + selectedDebuggerIdentifier: (scheme.test?.debugEnabled ?? Scheme.Test.debugEnabledDefault) ? XCScheme.defaultDebugger : "", shouldUseLaunchSchemeArgsEnv: scheme.test?.shouldUseLaunchSchemeArgsEnv ?? true, codeCoverageEnabled: scheme.test?.gatherCoverageData ?? Scheme.Test.gatherCoverageDataDefault, disableMainThreadChecker: scheme.test?.disableMainThreadChecker ?? Scheme.Test.disableMainThreadCheckerDefault, @@ -167,6 +168,7 @@ public class SchemeGenerator { preActions: scheme.run?.preActions.map(getExecutionAction) ?? [], postActions: scheme.run?.postActions.map(getExecutionAction) ?? [], macroExpansion: shouldExecuteOnLaunch ? nil : buildableReference, + selectedDebuggerIdentifier: (scheme.run?.debugEnabled ?? Scheme.Run.debugEnabledDefault) ? XCScheme.defaultDebugger : "", disableMainThreadChecker: scheme.run?.disableMainThreadChecker ?? Scheme.Run.disableMainThreadCheckerDefault, commandlineArguments: launchCommandLineArgs, environmentVariables: launchVariables, From 6b2cd0a9167613012aa1066fe2edbf3f271f09b9 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Mon, 16 Sep 2019 11:05:30 +0900 Subject: [PATCH 02/11] Add test case for debugEnabled --- .../SchemeGeneratorTests.swift | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift index ac84c0c1..8bf0d7db 100644 --- a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift @@ -87,6 +87,9 @@ class SchemeGeneratorTests: XCTestCase { try expect(xcscheme.profileAction?.buildConfiguration) == "Release" try expect(xcscheme.analyzeAction?.buildConfiguration) == "Debug" try expect(xcscheme.archiveAction?.buildConfiguration) == "Release" + + try expect(xcscheme.launchAction?.selectedDebuggerIdentifier) == XCScheme.defaultDebugger + try expect(xcscheme.testAction?.selectedDebuggerIdentifier) == XCScheme.defaultDebugger } $0.it("sets environment variables for a scheme") { @@ -174,6 +177,26 @@ class SchemeGeneratorTests: XCTestCase { try expect(xcscheme.profileAction?.environmentVariables) == variables } + $0.it("generate scheme without debugger") { + let scheme = Scheme( + name: "TestScheme", + build: Scheme.Build(targets: [buildTarget]), + run: Scheme.Run(config: "Debug", debugEnabled: false) + ) + let project = Project( + name: "test", + targets: [app, framework], + schemes: [scheme] + ) + let xcodeProject = try project.generateXcodeProject() + + guard let xcscheme = xcodeProject.sharedData?.schemes.first else { + throw failure("Scheme not found") + } + + try expect(xcscheme.launchAction?.selectedDebuggerIdentifier) == "" + } + $0.it("generates pre and post actions for target schemes") { var target = app target.scheme = TargetScheme( From 758e807c612b68e5ba20512905abd864e235a2c5 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Mon, 16 Sep 2019 11:14:10 +0900 Subject: [PATCH 03/11] Update ProjectSpec.md --- Docs/ProjectSpec.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index c87cf910..a2801e01 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -687,6 +687,7 @@ The different actions share some properties: - [ ] **disableMainThreadChecker**: **Bool** - `run` and `test` actions can define a boolean that indicates that this scheme should disable the Main Thread Checker. This defaults to false - [ ] **language**: **String** - `run` and `test` actions can define a language that is used for Application Language - [ ] **region**: **String** - `run` and `test` actions can define a language that is used for Application Region +- [ ] **debugEnabled**: **Bool** - `run` and `test` actions can define a whether debugger should be used. ### Execution Action From a550dceb2140c76bd7fae670f462f50eac4938f8 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Mon, 16 Sep 2019 11:14:21 +0900 Subject: [PATCH 04/11] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9381cfc..825fd0a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Added `includes` to `sources` for a Target. This follows the same glob-style as `excludes` but functions as a way to only include files that match a specified pattern. Useful if you only want a certain file type, for example specifying `**/*.swift`. [#637](https://github.com/yonaskolb/XcodeGen/pull/637) @bclymer - Support `dylib` SDK. [#650](https://github.com/yonaskolb/XcodeGen/pull/650) - Added `language` and `region` options for `run` and `test` scheme [#654](https://github.com/yonaskolb/XcodeGen/pull/654) +- Added `debugEnabled` option for `run` and `test` scheme [#657](https://github.com/yonaskolb/XcodeGen/pull/657) #### Fixed From fa8c71569a0a34b8618734a535d9721f6fea78b8 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Mon, 16 Sep 2019 15:35:24 +0900 Subject: [PATCH 05/11] Check only path to avoid slow equability check --- Sources/XcodeGenKit/SourceGenerator.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/XcodeGenKit/SourceGenerator.swift b/Sources/XcodeGenKit/SourceGenerator.swift index 7d99f59b..548d4483 100644 --- a/Sources/XcodeGenKit/SourceGenerator.swift +++ b/Sources/XcodeGenKit/SourceGenerator.swift @@ -244,7 +244,7 @@ class SourceGenerator { if let cachedGroup = groupsByPath[path] { for child in children { // only add the children that aren't already in the cachedGroup - if !cachedGroup.children.contains(child) { + if !cachedGroup.children.contains(where: { $0.path == child.path }) { cachedGroup.children.append(child) } } From 0dc4a8de417084b08f800d63effc134da835f80a Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 21 Sep 2019 20:00:40 +0900 Subject: [PATCH 06/11] Copy cachedGroup.children and write back only once --- Sources/XcodeGenKit/SourceGenerator.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Sources/XcodeGenKit/SourceGenerator.swift b/Sources/XcodeGenKit/SourceGenerator.swift index 548d4483..4b96e9ea 100644 --- a/Sources/XcodeGenKit/SourceGenerator.swift +++ b/Sources/XcodeGenKit/SourceGenerator.swift @@ -242,12 +242,14 @@ class SourceGenerator { let groupReference: PBXGroup if let cachedGroup = groupsByPath[path] { + var cachedGroupChildren = cachedGroup.children for child in children { // only add the children that aren't already in the cachedGroup - if !cachedGroup.children.contains(where: { $0.path == child.path }) { - cachedGroup.children.append(child) + if !cachedGroupChildren.contains(where: { $0.path == child.path }) { + cachedGroupChildren.append(child) } } + cachedGroup.children = cachedGroupChildren groupReference = cachedGroup } else { From e278a706feb7e97f0d1e0c7235705319080d1368 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 21 Sep 2019 20:03:09 +0900 Subject: [PATCH 07/11] Add comment --- Sources/XcodeGenKit/SourceGenerator.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/XcodeGenKit/SourceGenerator.swift b/Sources/XcodeGenKit/SourceGenerator.swift index 4b96e9ea..21e9e980 100644 --- a/Sources/XcodeGenKit/SourceGenerator.swift +++ b/Sources/XcodeGenKit/SourceGenerator.swift @@ -245,6 +245,7 @@ class SourceGenerator { var cachedGroupChildren = cachedGroup.children for child in children { // only add the children that aren't already in the cachedGroup + // Check equality by path because XcodeProj.PBXObject.== is very slow. if !cachedGroupChildren.contains(where: { $0.path == child.path }) { cachedGroupChildren.append(child) } From 2def6138c434f0750d6ba3ba68a587bf4a7d7df3 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 21 Sep 2019 20:22:58 +0900 Subject: [PATCH 08/11] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9381cfc..acd35f3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ #### Fixed - Expand template variable in Array of Any [#651](https://github.com/yonaskolb/XcodeGen/pull/651) @kateinoigakukun +- Significantly improve performance when running with a large number files. [#658](https://github.com/yonaskolb/XcodeGen/pull/658) @kateinoigakukun ## 2.7.0 From d3bf42f2ca4ec3d2c1724f5a1cc9c9048e36c8c9 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 22 Sep 2019 19:30:22 +0900 Subject: [PATCH 09/11] Check sourceTree also to ensure they have same root --- Sources/XcodeGenKit/SourceGenerator.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/XcodeGenKit/SourceGenerator.swift b/Sources/XcodeGenKit/SourceGenerator.swift index 21e9e980..35e1ab3b 100644 --- a/Sources/XcodeGenKit/SourceGenerator.swift +++ b/Sources/XcodeGenKit/SourceGenerator.swift @@ -245,8 +245,8 @@ class SourceGenerator { var cachedGroupChildren = cachedGroup.children for child in children { // only add the children that aren't already in the cachedGroup - // Check equality by path because XcodeProj.PBXObject.== is very slow. - if !cachedGroupChildren.contains(where: { $0.path == child.path }) { + // Check equality by path and sourceTree because XcodeProj.PBXObject.== is very slow. + if !cachedGroupChildren.contains(where: { $0.path == child.path && $0.sourceTree == child.sourceTree }) { cachedGroupChildren.append(child) } } From 28466593137eb444820e68275527bd70161b749d Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 22 Sep 2019 21:14:15 +0900 Subject: [PATCH 10/11] Set selectedLauncherIdentifier when debug disabled --- Sources/XcodeGenKit/SchemeGenerator.swift | 1 + Tests/XcodeGenKitTests/SchemeGeneratorTests.swift | 1 + 2 files changed, 2 insertions(+) diff --git a/Sources/XcodeGenKit/SchemeGenerator.swift b/Sources/XcodeGenKit/SchemeGenerator.swift index e1076dae..0de02729 100644 --- a/Sources/XcodeGenKit/SchemeGenerator.swift +++ b/Sources/XcodeGenKit/SchemeGenerator.swift @@ -169,6 +169,7 @@ public class SchemeGenerator { postActions: scheme.run?.postActions.map(getExecutionAction) ?? [], macroExpansion: shouldExecuteOnLaunch ? nil : buildableReference, selectedDebuggerIdentifier: (scheme.run?.debugEnabled ?? Scheme.Run.debugEnabledDefault) ? XCScheme.defaultDebugger : "", + selectedLauncherIdentifier: (scheme.run?.debugEnabled ?? Scheme.Run.debugEnabledDefault) ? XCScheme.defaultLauncher : "Xcode.IDEFoundation.Launcher.PosixSpawn", disableMainThreadChecker: scheme.run?.disableMainThreadChecker ?? Scheme.Run.disableMainThreadCheckerDefault, commandlineArguments: launchCommandLineArgs, environmentVariables: launchVariables, diff --git a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift index 8bf0d7db..be00176f 100644 --- a/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/SchemeGeneratorTests.swift @@ -195,6 +195,7 @@ class SchemeGeneratorTests: XCTestCase { } try expect(xcscheme.launchAction?.selectedDebuggerIdentifier) == "" + try expect(xcscheme.launchAction?.selectedLauncherIdentifier) == "Xcode.IDEFoundation.Launcher.PosixSpawn" } $0.it("generates pre and post actions for target schemes") { From e3ca38a63575f174338d1643fd632ef3be374ddb Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 22 Sep 2019 21:37:31 +0900 Subject: [PATCH 11/11] Update ProjectSpec.md --- Docs/ProjectSpec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md index a2801e01..d9749612 100644 --- a/Docs/ProjectSpec.md +++ b/Docs/ProjectSpec.md @@ -687,7 +687,7 @@ The different actions share some properties: - [ ] **disableMainThreadChecker**: **Bool** - `run` and `test` actions can define a boolean that indicates that this scheme should disable the Main Thread Checker. This defaults to false - [ ] **language**: **String** - `run` and `test` actions can define a language that is used for Application Language - [ ] **region**: **String** - `run` and `test` actions can define a language that is used for Application Region -- [ ] **debugEnabled**: **Bool** - `run` and `test` actions can define a whether debugger should be used. +- [ ] **debugEnabled**: **Bool** - `run` and `test` actions can define a whether debugger should be used. This defaults to true. ### Execution Action