diff --git a/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift b/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift index 4edd89770..53d529153 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift @@ -42,7 +42,16 @@ public extension XCScheme { public var buildConfiguration: String public var launchStyle: Style public var askForAppToLaunch: Bool? - public var pathRunnable: PathRunnable? + public var pathRunnable: PathRunnable? { + // For backwards compatibility + get { + runnable as? PathRunnable + } + set { + self.pathRunnable = newValue + } + } + public var customWorkingDirectory: String? public var useCustomWorkingDirectory: Bool public var ignoresPersistentStateOnLaunch: Bool @@ -78,6 +87,7 @@ public extension XCScheme { // MARK: - Init + @available(*, deprecated, message: "Use the init() that consolidates pathRunnable and runnable into a single parameter.") public init(runnable: Runnable?, buildConfiguration: String, preActions: [ExecutionAction] = [], @@ -87,7 +97,7 @@ public extension XCScheme { selectedLauncherIdentifier: String = XCScheme.defaultLauncher, launchStyle: Style = .auto, askForAppToLaunch: Bool? = nil, - pathRunnable: PathRunnable? = nil, + pathRunnable _: PathRunnable? = nil, customWorkingDirectory: String? = nil, useCustomWorkingDirectory: Bool = false, ignoresPersistentStateOnLaunch: Bool = false, @@ -126,7 +136,6 @@ public extension XCScheme { self.selectedDebuggerIdentifier = selectedDebuggerIdentifier self.selectedLauncherIdentifier = selectedLauncherIdentifier self.askForAppToLaunch = askForAppToLaunch - self.pathRunnable = pathRunnable self.customWorkingDirectory = customWorkingDirectory self.useCustomWorkingDirectory = useCustomWorkingDirectory self.ignoresPersistentStateOnLaunch = ignoresPersistentStateOnLaunch @@ -161,6 +170,93 @@ public extension XCScheme { super.init(preActions, postActions) } + public convenience init( + pathRunnable: PathRunnable?, + buildConfiguration: String, + preActions: [ExecutionAction] = [], + postActions: [ExecutionAction] = [], + macroExpansion: BuildableReference? = nil, + selectedDebuggerIdentifier: String = XCScheme.defaultDebugger, + selectedLauncherIdentifier: String = XCScheme.defaultLauncher, + launchStyle: Style = .auto, + askForAppToLaunch: Bool? = nil, + customWorkingDirectory: String? = nil, + useCustomWorkingDirectory: Bool = false, + ignoresPersistentStateOnLaunch: Bool = false, + debugDocumentVersioning: Bool = true, + debugServiceExtension: String = LaunchAction.defaultDebugServiceExtension, + allowLocationSimulation: Bool = true, + locationScenarioReference: LocationScenarioReference? = nil, + enableGPUFrameCaptureMode: GPUFrameCaptureMode = LaunchAction.defaultGPUFrameCaptureMode, + disableGPUValidationMode: Bool = false, + enableGPUShaderValidationMode: Bool = false, + showGraphicsOverview: Bool = false, + logGraphicsOverview: Bool = false, + enableAddressSanitizer: Bool = false, + enableASanStackUseAfterReturn: Bool = false, + enableThreadSanitizer: Bool = false, + stopOnEveryThreadSanitizerIssue: Bool = false, + enableUBSanitizer: Bool = false, + stopOnEveryUBSanitizerIssue: Bool = false, + disableMainThreadChecker: Bool = false, + disablePerformanceAntipatternChecker: Bool = false, + stopOnEveryMainThreadCheckerIssue: Bool = false, + additionalOptions: [AdditionalOption] = [], + commandlineArguments: CommandLineArguments? = nil, + environmentVariables: [EnvironmentVariable]? = nil, + language: String? = nil, + region: String? = nil, + showNonLocalizedStrings: Bool = false, + launchAutomaticallySubstyle: String? = nil, + storeKitConfigurationFileReference: StoreKitConfigurationFileReference? = nil, + customLaunchCommand: String? = nil, + customLLDBInitFile: String? = nil + ) { + self.init( + runnable: pathRunnable, + buildConfiguration: buildConfiguration, + preActions: preActions, + postActions: postActions, + macroExpansion: macroExpansion, + selectedDebuggerIdentifier: selectedDebuggerIdentifier, + selectedLauncherIdentifier: selectedLauncherIdentifier, + launchStyle: launchStyle, + askForAppToLaunch: askForAppToLaunch, + pathRunnable: pathRunnable, + customWorkingDirectory: customWorkingDirectory, + useCustomWorkingDirectory: useCustomWorkingDirectory, + ignoresPersistentStateOnLaunch: ignoresPersistentStateOnLaunch, + debugDocumentVersioning: debugDocumentVersioning, + debugServiceExtension: debugServiceExtension, + allowLocationSimulation: allowLocationSimulation, + locationScenarioReference: locationScenarioReference, + enableGPUFrameCaptureMode: enableGPUFrameCaptureMode, + disableGPUValidationMode: disableGPUValidationMode, + enableGPUShaderValidationMode: enableGPUShaderValidationMode, + showGraphicsOverview: showGraphicsOverview, + logGraphicsOverview: logGraphicsOverview, + enableAddressSanitizer: enableAddressSanitizer, + enableASanStackUseAfterReturn: enableASanStackUseAfterReturn, + enableThreadSanitizer: enableThreadSanitizer, + stopOnEveryThreadSanitizerIssue: stopOnEveryThreadSanitizerIssue, + enableUBSanitizer: enableUBSanitizer, + stopOnEveryUBSanitizerIssue: stopOnEveryUBSanitizerIssue, + disableMainThreadChecker: disableMainThreadChecker, + disablePerformanceAntipatternChecker: disablePerformanceAntipatternChecker, + stopOnEveryMainThreadCheckerIssue: stopOnEveryMainThreadCheckerIssue, + additionalOptions: additionalOptions, + commandlineArguments: commandlineArguments, + environmentVariables: environmentVariables, + language: language, + region: region, + showNonLocalizedStrings: showNonLocalizedStrings, + launchAutomaticallySubstyle: launchAutomaticallySubstyle, + storeKitConfigurationFileReference: storeKitConfigurationFileReference, + customLaunchCommand: customLaunchCommand, + customLLDBInitFile: customLLDBInitFile + ) + } + // swiftlint:disable:next function_body_length override init(element: AEXMLElement) throws { buildConfiguration = element.attributes["buildConfiguration"] ?? LaunchAction.defaultBuildConfiguration @@ -177,15 +273,13 @@ public extension XCScheme { // Runnable let buildableProductRunnableElement = element["BuildableProductRunnable"] let remoteRunnableElement = element["RemoteRunnable"] + let pathRunnable = element["PathRunnable"] if buildableProductRunnableElement.error == nil { runnable = try BuildableProductRunnable(element: buildableProductRunnableElement) } else if remoteRunnableElement.error == nil { runnable = try RemoteRunnable(element: remoteRunnableElement) - } - - let pathRunnable = element["PathRunnable"] - if pathRunnable.error == nil { - self.pathRunnable = try PathRunnable(element: pathRunnable) + } else if pathRunnable.error == nil { + runnable = try PathRunnable(element: pathRunnable) } let buildableReferenceElement = element["MacroExpansion"]["BuildableReference"] @@ -324,10 +418,6 @@ public extension XCScheme { element.addChild(runnable.xmlElement()) } - if let pathRunnable { - element.addChild(pathRunnable.xmlElement()) - } - if let locationScenarioReference { element.addChild(locationScenarioReference.xmlElement()) } @@ -395,7 +485,6 @@ public extension XCScheme { buildConfiguration == rhs.buildConfiguration && launchStyle == rhs.launchStyle && askForAppToLaunch == rhs.askForAppToLaunch && - pathRunnable == rhs.pathRunnable && customWorkingDirectory == rhs.customWorkingDirectory && useCustomWorkingDirectory == rhs.useCustomWorkingDirectory && ignoresPersistentStateOnLaunch == rhs.ignoresPersistentStateOnLaunch && diff --git a/Sources/XcodeProj/Scheme/XCScheme+PathRunnable.swift b/Sources/XcodeProj/Scheme/XCScheme+PathRunnable.swift index 220de342d..44296ea24 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+PathRunnable.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+PathRunnable.swift @@ -3,10 +3,9 @@ import Foundation import PathKit public extension XCScheme { - class PathRunnable: Equatable { + class PathRunnable: Runnable { // MARK: - Attributes - public var runnableDebuggingMode: String public var filePath: String // MARK: - Init @@ -14,30 +13,37 @@ public extension XCScheme { public init(filePath: String, runnableDebuggingMode: String = "0") { self.filePath = filePath - self.runnableDebuggingMode = runnableDebuggingMode + super.init(buildableReference: nil, + runnableDebuggingMode: runnableDebuggingMode) } - init(element: AEXMLElement) throws { - runnableDebuggingMode = element.attributes["runnableDebuggingMode"] ?? "0" + override init(element: AEXMLElement) throws { filePath = element.attributes["FilePath"] ?? "" + try super.init(element: element) } // MARK: - XML - func xmlElement() -> AEXMLElement { - AEXMLElement(name: "PathRunnable", - value: nil, - attributes: [ - "runnableDebuggingMode": runnableDebuggingMode, - "FilePath": filePath, - ]) + override func xmlElement() -> AEXMLElement { + let element = super.xmlElement() + element.name = "PathRunnable" + element.attributes["FilePath"] = filePath + return element } // MARK: - Equatable + override func isEqual(other: XCScheme.Runnable) -> Bool { + guard let other = other as? PathRunnable else { + return false + } + + return super.isEqual(other: other) && + filePath == other.filePath + } + public static func == (lhs: PathRunnable, rhs: PathRunnable) -> Bool { - lhs.runnableDebuggingMode == rhs.runnableDebuggingMode && - lhs.filePath == rhs.filePath + lhs.isEqual(other: rhs) } } } diff --git a/Sources/XcodeProj/Scheme/XCScheme+ProfileAction.swift b/Sources/XcodeProj/Scheme/XCScheme+ProfileAction.swift index 6c4864996..f972cf76a 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+ProfileAction.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+ProfileAction.swift @@ -115,10 +115,13 @@ public extension XCScheme { // Runnable let buildableProductRunnableElement = element["BuildableProductRunnable"] let remoteRunnableElement = element["RemoteRunnable"] + let pathRunnableElement = element["PathRunnable"] if buildableProductRunnableElement.error == nil { runnable = try BuildableProductRunnable(element: buildableProductRunnableElement) } else if remoteRunnableElement.error == nil { runnable = try RemoteRunnable(element: remoteRunnableElement) + } else if pathRunnableElement.error == nil { + runnable = try PathRunnable(element: pathRunnableElement) } let buildableReferenceElement = element["MacroExpansion"]["BuildableReference"] diff --git a/Sources/XcodeProj/Scheme/XCScheme+Runnable.swift b/Sources/XcodeProj/Scheme/XCScheme+Runnable.swift index 27471e9f3..4ada2d38c 100644 --- a/Sources/XcodeProj/Scheme/XCScheme+Runnable.swift +++ b/Sources/XcodeProj/Scheme/XCScheme+Runnable.swift @@ -10,7 +10,7 @@ public extension XCScheme { // MARK: - Init - public init(buildableReference: BuildableReference, + public init(buildableReference: BuildableReference?, runnableDebuggingMode: String = "0") { self.buildableReference = buildableReference self.runnableDebuggingMode = runnableDebuggingMode diff --git a/Tests/XcodeProjTests/Scheme/XCSchemeTests.swift b/Tests/XcodeProjTests/Scheme/XCSchemeTests.swift index d4ed343c2..44ed24fc4 100644 --- a/Tests/XcodeProjTests/Scheme/XCSchemeTests.swift +++ b/Tests/XcodeProjTests/Scheme/XCSchemeTests.swift @@ -159,7 +159,7 @@ final class XCSchemeIntegrationTests: XCTestCase { // Given let filePath = "/usr/bin/foo" let pathRunnable = XCScheme.PathRunnable(filePath: filePath, runnableDebuggingMode: "0") - let subject = XCScheme.LaunchAction(runnable: nil, buildConfiguration: "Debug", pathRunnable: pathRunnable) + let subject = XCScheme.LaunchAction(runnable: pathRunnable, buildConfiguration: "Debug") // When let element = subject.xmlElement()