gitbay/Builds/BuildDetailViewModel.swift
39 lines · 1148 bytes
1import Foundation
2import Observation
3
4nonisolated struct BuildDetail: Sendable {
5 let build: Build
6 let log: String
7}
8
9/// One build: `build show` for what it was, `build log` for what it did.
10/// The web's build page shows both; the log alone leaves the screen
11/// unable to say whether the build passed.
12@Observable
13@MainActor
14final class BuildDetailViewModel {
15
16 private(set) var state: LoadState<BuildDetail> = .loading
17
18 private let client: GitbayClient
19 let repoPath: String
20 let number: Int64
21
22 init(client: GitbayClient, repoPath: String, number: Int64) {
23 self.client = client
24 self.repoPath = repoPath
25 self.number = number
26 }
27
28 func load() async {
29 let ref = [repoPath, String(number)]
30 do {
31 async let build = client.read(["build", "show"] + ref, as: Build.self)
32 // A queued build has no log yet; that is not a failure.
33 async let log = client.readText(["build", "log"] + ref)
34 state = .loaded(BuildDetail(build: try await build, log: (try? await log) ?? ""))
35 } catch {
36 state = .from(error)
37 }
38 }
39}