Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Update PathRunnable so that it subclasses Runnable #883

Merged
merged 8 commits into from
Dec 3, 2024
115 changes: 102 additions & 13 deletions Sources/XcodeProj/Scheme/XCScheme+LaunchAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pepicrft Looks like this was supposed to be self.runnable = newValue. Xcode is warning about infinite recursion since it is essentially calling it's own setter.

}
}

public var customWorkingDirectory: String?
public var useCustomWorkingDirectory: Bool
public var ignoresPersistentStateOnLaunch: Bool
Expand Down Expand Up @@ -78,6 +87,7 @@ public extension XCScheme {

// MARK: - Init

@available(*, deprecated, message: "Use the init() that consolidates pathRunnable and runnable into a single parameter.")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pepicrft I think this deprecation warning was attached to the wrong init since the other convenience init now only accepts a PathRunnable

public init(runnable: Runnable?,
buildConfiguration: String,
preActions: [ExecutionAction] = [],
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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"]
Expand Down Expand Up @@ -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())
}
Expand Down Expand Up @@ -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 &&
Expand Down
34 changes: 20 additions & 14 deletions Sources/XcodeProj/Scheme/XCScheme+PathRunnable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,47 @@ import Foundation
import PathKit

public extension XCScheme {
class PathRunnable: Equatable {
class PathRunnable: Runnable {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making PathRunnable subclass Runnable means we'll also need to update ProfileAction to support it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I overlooked this one. I'll try to add this as well.

// MARK: - Attributes

public var runnableDebuggingMode: String
public var filePath: String

// MARK: - Init

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)
}
}
}
3 changes: 3 additions & 0 deletions Sources/XcodeProj/Scheme/XCScheme+ProfileAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
2 changes: 1 addition & 1 deletion Sources/XcodeProj/Scheme/XCScheme+Runnable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Tests/XcodeProjTests/Scheme/XCSchemeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Loading