gitbay/MRs/MRModels.swift
149 lines · 4490 bytes
1import Foundation
2
3/// One row of `mr list`, and the header half of `mr show`.
4nonisolated struct MergeRequest: Decodable, Sendable, Hashable, Identifiable {
5 let number: Int64
6 let title: String
7 let state: String
8 let author: String
9 /// "branch" for a same-repo MR, "owner/name:branch" cross-repo,
10 /// "" when the source is gone.
11 let source: String
12 let targetRef: String
13 let headSHA: String
14 let body: String?
15 let createdAt: Date
16
17 enum CodingKeys: String, CodingKey {
18 case number, title, state, author, source, body
19 case targetRef = "target_ref"
20 case headSHA = "head_sha"
21 case createdAt = "created_at"
22 }
23
24 var id: Int64 { number }
25 var isOpen: Bool { state == "open" }
26}
27
28/// The whole of `mr show`.
29nonisolated struct MRDetail: Decodable, Sendable, Hashable {
30 let number: Int64
31 let title: String
32 let state: String
33 let author: String
34 let source: String
35 let targetRef: String
36 let headSHA: String
37 let body: String?
38 let milestone: String?
39 let createdAt: Date
40 /// Set once the merge request is resolved. The actor is absent when
41 /// the account is gone, or the row was imported.
42 let mergedAt: Date?
43 let mergedBy: String?
44 let closedAt: Date?
45 let closedBy: String?
46 let checks: [Check]?
47 let checksCombined: String?
48 let unresolvedThreads: Int?
49 let commits: [MRCommit]?
50 let comments: [MRComment]?
51 let reviews: [Review]?
52
53 enum CodingKeys: String, CodingKey {
54 case number, title, state, author, source, body, milestone, checks, commits, comments, reviews
55 case targetRef = "target_ref"
56 case headSHA = "head_sha"
57 case createdAt = "created_at"
58 case mergedAt = "merged_at"
59 case mergedBy = "merged_by"
60 case closedAt = "closed_at"
61 case closedBy = "closed_by"
62 case checksCombined = "checks_combined"
63 case unresolvedThreads = "unresolved_threads"
64 }
65
66 var isOpen: Bool { state == "open" }
67
68 nonisolated struct Check: Decodable, Sendable, Hashable {
69 let context: String
70 let state: String
71 let url: String?
72 /// When the check last changed state.
73 let updatedAt: Date?
74 /// How long the build behind the check ran, as the server
75 /// formats it ("1m12s"). Only CI checks have a build to time.
76 let duration: String?
77
78 enum CodingKeys: String, CodingKey {
79 case context, state, url, duration
80 case updatedAt = "updated_at"
81 }
82 }
83
84 nonisolated struct MRCommit: Decodable, Sendable, Hashable, Identifiable {
85 let sha: String
86 let subject: String
87 var id: String { sha }
88 var shortSHA: String { String(sha.prefix(10)) }
89 }
90
91 nonisolated struct MRComment: Decodable, Sendable, Hashable, Identifiable {
92 let author: String
93 let body: String
94 let createdAt: Date
95
96 enum CodingKeys: String, CodingKey {
97 case author, body
98 case createdAt = "created_at"
99 }
100
101 var id: String { author + createdAt.timeIntervalSince1970.description + body }
102 }
103
104 nonisolated struct Review: Decodable, Sendable, Hashable, Identifiable {
105 let reviewer: String
106 let verdict: String
107 /// The review predates the current head — it approved older code.
108 let stale: Bool
109 let createdAt: Date?
110
111 enum CodingKeys: String, CodingKey {
112 case reviewer, verdict, stale
113 case createdAt = "created_at"
114 }
115
116 var id: String { reviewer }
117 }
118}
119
120/// One review thread of `mr threads`.
121nonisolated struct ReviewThread: Decodable, Sendable, Hashable, Identifiable {
122 let id: Int64
123 let path: String
124 let side: String // new | old
125 let line: Int64
126 /// Anchored to an older head; the diff has moved under it.
127 let stale: Bool
128 let resolvedBy: String?
129 let comments: [Comment]
130
131 enum CodingKeys: String, CodingKey {
132 case id, path, side, line, stale, comments
133 case resolvedBy = "resolved_by"
134 }
135
136 var isResolved: Bool { resolvedBy != nil }
137
138 nonisolated struct Comment: Decodable, Sendable, Hashable, Identifiable {
139 let id: Int64
140 let author: String
141 let body: String
142 let createdAt: Date
143
144 enum CodingKeys: String, CodingKey {
145 case id, author, body
146 case createdAt = "created_at"
147 }
148 }
149}