Files
xcodesApp-mirror/com.xcodesorg.xcodesapp.Helper/XPCDelegate.swift
2024-01-19 14:28:12 -06:00

103 lines
3.3 KiB
Swift

import Foundation
import os.log
class XPCDelegate: NSObject, NSXPCListenerDelegate, HelperXPCProtocol {
// MARK: - NSXPCListenerDelegate
func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
guard ConnectionVerifier.isValid(connection: newConnection) else { return false }
newConnection.exportedInterface = NSXPCInterface(with: HelperXPCProtocol.self)
newConnection.exportedObject = self
newConnection.resume()
return true
}
// MARK: - HelperXPCProtocol
func getVersion(completion: @escaping (String) -> Void) {
Logger.xpcDelegate.info("\(#function)")
completion(Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String)
}
func xcodeSelect(absolutePath: String, completion: @escaping (Error?) -> Void) {
Logger.xpcDelegate.info("\(#function)")
guard URL(fileURLWithPath: absolutePath).hasDirectoryPath else {
completion(XPCDelegateError(.invalidXcodePath))
return
}
run(
url: URL(fileURLWithPath: "/usr/bin/xcode-select"),
arguments: ["-s", absolutePath],
completion: completion
)
}
func devToolsSecurityEnable(completion: @escaping (Error?) -> Void) {
run(url: URL(fileURLWithPath: "/usr/sbin/DevToolsSecurity"), arguments: ["-enable"], completion: completion)
}
func addStaffToDevelopersGroup(completion: @escaping (Error?) -> Void) {
run(url: URL(fileURLWithPath: "/usr/sbin/dseditgroup"), arguments: ["-o", "edit", "-t", "group", "-a", "staff", "_developer"], completion: completion)
}
func acceptXcodeLicense(absoluteXcodePath: String, completion: @escaping (Error?) -> Void) {
run(url: URL(fileURLWithPath: absoluteXcodePath + "/Contents/Developer/usr/bin/xcodebuild"), arguments: ["-license", "accept"], completion: completion)
}
func runFirstLaunch(absoluteXcodePath: String, completion: @escaping (Error?) -> Void) {
run(url: URL(fileURLWithPath: absoluteXcodePath + "/Contents/Developer/usr/bin/xcodebuild"), arguments: ["-runFirstLaunch"], completion: completion)
}
}
// MARK: - Run
private func run(url: URL, arguments: [String], completion: @escaping (Error?) -> Void) {
Logger.xpcDelegate.info("Run executable: \(url), arguments: \(arguments.joined(separator: ", "))")
let process = Process()
process.executableURL = url
process.arguments = arguments
do {
try process.run()
process.waitUntilExit()
completion(nil)
} catch {
completion(error)
}
}
// MARK: - Errors
struct XPCDelegateError: CustomNSError {
enum Code: Int {
case invalidXcodePath
}
let code: Code
init(_ code: Code) {
self.code = code
}
// MARK: - CustomNSError
static var errorDomain: String { "XPCDelegateError" }
var errorCode: Int { code.rawValue }
var errorUserInfo: [String : Any] {
switch code {
case .invalidXcodePath:
return [
NSLocalizedDescriptionKey: "Invalid Xcode path.",
NSLocalizedFailureReasonErrorKey: "Xcode path must be absolute."
]
}
}
}