import Foundation import Observation /// `mr create --source --target --title --file -`. /// /// Branch names are typed, not picked: no command lists branches yet /// (krz/gitbay#45). The target prefills with the default branch from /// `repo show`. @Observable @MainActor final class MRCreateViewModel { private(set) var working = false private(set) var errorMessage: String? private(set) var defaultBranch: String? private let client: GitbayClient let repoPath: String init(client: GitbayClient, repoPath: String) { self.client = client self.repoPath = repoPath } func loadDefaultBranch() async { guard defaultBranch == nil else { return } defaultBranch = (try? await client.read( ["repo", "show", repoPath], as: RepoDetail.self ))?.defaultBranch } nonisolated private struct Created: Decodable, Sendable { let number: Int64 } func create(source: String, target: String, title: String, body: String) async -> Int64? { working = true errorMessage = nil defer { working = false } do { var argv = ["mr", "create", repoPath, "--source", source, "--target", target, "--title", title] var stdin: String? if !body.isEmpty { argv.append(contentsOf: ["--file", "-"]) stdin = body } let created = try await client.run(argv, stdin: stdin, as: Created.self) return created?.number } catch let error as GitbayError { errorMessage = error.userFacingMessage } catch { errorMessage = GitbayError.transport(error).userFacingMessage } return nil } }