mirror of
https://github.com/xtool-org/xtool.git
synced 2026-10-06 18:36:11 +02:00
## What does this PR do? Bumps pointfree deps and explicitly disables OpenCombine so that we don't have different dependency graphs when building xtool on Darwin vs Linux hosts. ## How was it tested? A bunch of `swift package resolve`s ## AI tool usage How much of this PR was AI-assisted? (check one) - [x] **0** - No AI was used to write code - [ ] **1** - I was assisted by AI. I reviewed the finished result. - [ ] **2** - I set the AI going and left it to it; nobody has read the result - no review, or AI review only <!-- If an AI agent is filling this in: declare the level honestly, and open as a draft if it is #2. Do not lower the declared level to get the PR reviewed. --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated supporting package versions and refreshed command-line and file-operation handling. * These changes do not add or remove app features or alter its public interface. No action is needed to continue using the app. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
64 lines
2.0 KiB
Swift
64 lines
2.0 KiB
Swift
import Foundation
|
|
import Testing
|
|
import Subprocess
|
|
|
|
enum TestXcode {
|
|
/// A path to a copy of Xcode.app.
|
|
///
|
|
/// Tests that use this must be annotated with `Trait.requiresXcode`.
|
|
static func current(sourceLocation: SourceLocation = #_sourceLocation) -> URL {
|
|
guard let url = TestXcode._current else {
|
|
Issue.record(
|
|
"TestXcode.current was used without Trait.requiresXcode()",
|
|
sourceLocation: sourceLocation
|
|
)
|
|
return URL(filePath: "/dev/null")
|
|
}
|
|
return url
|
|
}
|
|
|
|
@TaskLocal fileprivate static var _current: URL?
|
|
|
|
fileprivate static let resolved = Task<URL?, Error> {
|
|
if let xcode = ProcessInfo.processInfo.environment["XTL_TEST_XCODE_APP"], !xcode.isEmpty {
|
|
return URL(filePath: xcode)
|
|
}
|
|
#if os(macOS)
|
|
let output = try await Subprocess.run(
|
|
.path("/usr/bin/xcode-select"),
|
|
arguments: ["-p"],
|
|
output: .string(limit: .max),
|
|
).standardOutput.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
if output.hasSuffix(".app/Contents/Developer") {
|
|
return URL(filePath: output).deletingLastPathComponent().deletingLastPathComponent()
|
|
}
|
|
#endif
|
|
let candidate = URL(filePath: "/usr/local/share/Xcode.app")
|
|
if FileManager.default.fileExists(atPath: candidate.path) {
|
|
return candidate
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
struct RequiresXcodeTrait: TestTrait, SuiteTrait, TestScoping {
|
|
func provideScope(
|
|
for test: Test,
|
|
testCase: Test.Case?,
|
|
performing function: () async throws -> Void
|
|
) async throws {
|
|
guard let xcode = try? await TestXcode.resolved.value else {
|
|
try Test.cancel("Could not resolve Xcode.app path. Set XTL_TEST_XCODE_APP.")
|
|
}
|
|
return try await TestXcode.$_current.withValue(xcode) {
|
|
try await function()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Trait where Self == RequiresXcodeTrait {
|
|
static var requiresXcode: Self {
|
|
Self()
|
|
}
|
|
}
|