diff --git a/Sources/XcodesKit/XcodeSelect.swift b/Sources/XcodesKit/XcodeSelect.swift index 7a4c193..2f387a0 100644 --- a/Sources/XcodesKit/XcodeSelect.swift +++ b/Sources/XcodesKit/XcodeSelect.swift @@ -24,6 +24,13 @@ public func selectXcode(shouldPrint: Bool, pathOrVersion: String, directory: Pat let versionToSelect = pathOrVersion.isEmpty ? Version.fromXcodeVersionFile() : Version(xcodeVersion: pathOrVersion) let installedXcodes = Current.files.installedXcodes(directory) + + if installedXcodes.isEmpty { + Current.logging.log("No Xcode version installed. Please run 'xcodes install' and try again.".red) + Current.shell.exit(1) + return Promise(error: XcodeSelectError.noInstalledXcodes) + } + if let version = versionToSelect, let installedXcode = installedXcodes.first(withVersion: version) { let selectedInstalledXcodeVersion = installedXcodes.first { output.out.hasPrefix($0.path.string) }.map { $0.version } @@ -153,6 +160,7 @@ public func selectXcodeAtPath(_ pathString: String) -> Promise { public enum XcodeSelectError: LocalizedError { case invalidPath(String) case invalidIndex(min: Int, max: Int, given: String?) + case noInstalledXcodes public var errorDescription: String? { switch self { @@ -160,6 +168,8 @@ public enum XcodeSelectError: LocalizedError { return "Not a valid Xcode path: \(pathString)" case .invalidIndex(let min, let max, let given): return "Not a valid number. Expecting a whole number between \(min)-\(max), but given \(given ?? "nothing")." + case .noInstalledXcodes: + return "No Xcode version installed. Please run 'xcodes install' and try again." } } } diff --git a/Tests/XcodesKitTests/XcodesKitTests.swift b/Tests/XcodesKitTests/XcodesKitTests.swift index 1282d92..aa06725 100644 --- a/Tests/XcodesKitTests/XcodesKitTests.swift +++ b/Tests/XcodesKitTests/XcodesKitTests.swift @@ -954,6 +954,22 @@ final class XcodesKitTests: XCTestCase { """) } + func test_SelectXcode_WithNoInstalledVersions_LogsError() { + var log = "" + Current.files.installedXcodes = { _ in [] } // Simulate no installed Xcodes + XcodesKit.Current.logging.log = { log = $0 } + + let expectation = XCTestExpectation(description: "Select Xcode") + selectXcode(shouldPrint: false, pathOrVersion: "", directory: Path.root.join("Applications")) + .ensure { + XCTAssertEqual(log, "No Xcode version installed. Please run 'xcodes install' and try again.") + expectation.fulfill() + } + .cauterize() + + wait(for: [expectation], timeout: 0.5) + } + func test_SelectPath() { var log = "" XcodesKit.Current.logging.log = { log.append($0 + "\n") }