1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package ports
4
5import (
6 "time"
7
8 "bnema.dev/ermite/internal/domain"
9)
10
11// The parameters and results of the use case interfaces (services.go). They
12// live here so that the adapters that call the use cases and the use cases
13// themselves share them without importing each other.
14
15// RepoPage is a page of repositories ordered by name.
16type RepoPage struct {
17 Repos []domain.Repo
18 // NextPageToken is empty on the last page.
19 NextPageToken string
20}
21
22// RepoView is a repository with the Git state that belongs in its summary.
23type RepoView struct {
24 domain.Repo
25 // DefaultBranch is the branch HEAD points to, even when it does not exist
26 // yet; empty when HEAD is detached or the directory is missing.
27 DefaultBranch string
28}
29
30// CreateRepoParams are the settings of a new repository.
31type CreateRepoParams struct {
32 Name domain.RepoName
33 Description string
34 // Topics are normalized by Create (see domain.NormalizeTopics).
35 Topics []string
36 // Visibility defaults to private when empty.
37 Visibility domain.Visibility
38}
39
40// UpdateRepoParams are the changes of Update; a nil field is left alone.
41type UpdateRepoParams struct {
42 Description *string
43 // Topics replaces the topics; an empty list clears them.
44 Topics *[]string
45 Visibility *domain.Visibility
46 DefaultBranch *string
47 // AllowedMergeModes replaces the allowed merge modes; it must hold at
48 // least one known mode.
49 AllowedMergeModes *[]domain.MergeMode
50 // FailingChecksBlock replaces the setting of that name.
51 FailingChecksBlock *bool
52}
53
54// TokenPage is a page of stored tokens, newest first.
55type TokenPage struct {
56 Tokens []domain.Token
57 // NextPageToken is empty on the last page.
58 NextPageToken string
59}
60
61// CreateTokenParams are the settings of a new token.
62type CreateTokenParams struct {
63 Label string
64 // Scopes must not be empty.
65 Scopes []domain.Scope
66 // Repos limits the token to these repositories; empty means every one.
67 Repos []domain.RepoName
68 // BranchPrefixes limits the token to the branches under these prefixes
69 // (see domain.ParseBranchPrefix); empty means every branch.
70 BranchPrefixes []string
71 // ExpiresAt is the zero time for a token that never expires.
72 ExpiresAt time.Time
73}
74
75// CreatedToken is a new token with its secret, which is shown once and never
76// stored.
77type CreatedToken struct {
78 Token domain.Token
79 Secret string
80}
81
82// ListRefsParams selects the refs to list.
83type ListRefsParams struct {
84 // Kinds restricts the result; empty means every kind.
85 Kinds []domain.RefKind
86 // PageSize is 0 for the default, and lowered to MaxRefPageSize.
87 PageSize int
88 // PageToken is the NextPageToken of the previous page, or empty.
89 PageToken string
90}
91
92// RefPage is a page of refs.
93type RefPage struct {
94 Refs []domain.Ref
95 // NextPageToken is empty on the last page.
96 NextPageToken string
97}
98
99// ListCommitsParams selects a page of history.
100type ListCommitsParams struct {
101 // Revision is where the history starts; the zero value is HEAD. Ignored
102 // when PageToken is set: the token pins the commit the first page started
103 // from, so every page walks the same history even if a branch moves.
104 Revision domain.Revision
105 // Path limits the history to the commits that changed it. It must be the
106 // same on every page of a listing.
107 Path domain.TreePath
108 // PageSize is 0 for the default, and lowered to MaxPageSize.
109 PageSize int
110 // PageToken is the NextPageToken of the previous page, or empty.
111 PageToken string
112}
113
114// HistoryPage is a page of history, newest first.
115type HistoryPage struct {
116 Commits []domain.Commit
117 // NextPageToken is empty on the last page.
118 NextPageToken string
119}
120
121// RepoStats are the figures of a repository the home page shows.
122type RepoStats struct {
123 // Commits is the number of commits of the default branch; Recent of them
124 // were committed in the last RecentDays days.
125 Commits, Recent int
126 // LatestTag is the most recently created tag; nil without tags.
127 LatestTag *domain.TagInfo
128 // Activity is the number of commits of each of the last ActivityDays
129 // days, oldest first; the last day ends now. A day is 24 hours.
130 Activity []int
131 // Partial tells that the recent commits were more than MaxCommitTimes:
132 // Recent and Activity count only some of them.
133 Partial bool
134}
135
136// RecentDays is the window of RepoStats.Recent.
137const RecentDays = 30
138
139// ActivityDays is the span of RepoStats.Activity.
140const ActivityDays = 90
141
142// WatchParams select the events of a watch.
143type WatchParams struct {
144 // Topics are TopicHome or "repo:<name>"; empty means TopicHome.
145 Topics []string
146 // ResumeAfter is the id of the last event the caller saw; empty to
147 // receive only new events.
148 ResumeAfter string
149 // Client identifies where the watch comes from, for the limit per client
150 // (MaxWatchersPerClient): an opaque key such as a normalized address; the
151 // web passes its visitor's. Empty only for callers with no client, which
152 // count against MaxWatchers alone.
153 Client string
154 // Ready, when not nil, is called once the topics are valid and the watch
155 // is registered: events published from then on are not missed. Nothing is
156 // sent before it returns.
157 Ready func()
158}
159
160// WatchEvent is one item of a watch.
161type WatchEvent struct {
162 // ID identifies the event, for resuming. Empty on a gap.
163 ID string
164 // Gap tells that events were lost: the caller must reload what it shows.
165 // Event is nil then.
166 Gap bool
167 // Event is a domain.RepoCreated, RepoUpdated, RepoDeleted, PushEvent,
168 // MergeRequestOpened, MergeRequestMerged, MergeRequestClosed,
169 // MergeRequestReady, CommentAdded, RunUpdated or JobUpdated.
170 Event domain.Event
171 // Repo is the state of the repository at delivery, for RepoCreated and
172 // RepoUpdated.
173 Repo *RepoView
174}
175
176// CreateMergeRequestParams describes the merge request to open.
177type CreateMergeRequestParams struct {
178 Title string
179 Description string
180 // Source is required; Target defaults to the default branch.
181 Source, Target string
182}
183
184// ListMergeRequestsParams selects a page of merge requests.
185type ListMergeRequestsParams struct {
186 // State restricts the result; empty means every state.
187 State domain.MRState
188 // PageSize is 0 for the default, and lowered to MaxPageSize.
189 PageSize int
190 // PageToken is the NextPageToken of the previous page, or empty.
191 PageToken string
192}
193
194// MergeRequestPage is a page of merge requests, highest number first.
195type MergeRequestPage struct {
196 MergeRequests []domain.MergeRequest
197 // NextPageToken is empty on the last page.
198 NextPageToken string
199}
200
201// MergeRequestDetail is a merge request with its review data.
202type MergeRequestDetail struct {
203 MergeRequest domain.MergeRequest
204 // Commits are the commits of the head that the target lacks, newest
205 // first, at most MaxMergeRequestCommits.
206 Commits []domain.Commit
207 CommitsTruncated bool
208 // DiffBaseID is the commit the diff compares from; zero when the source
209 // branch is gone, then the diff is empty.
210 DiffBaseID domain.ObjectID
211 Stats domain.DiffStats
212 Diff domain.Diff
213 // Comments are the comments, oldest first.
214 Comments []domain.Comment
215 // LastReadID is the head recorded by MarkRead; zero when none.
216 LastReadID domain.ObjectID
217 // LastReadLost tells that since-last-read was asked for, a head was
218 // recorded, but that commit is gone: the diff is against the target.
219 LastReadLost bool
220}
221
222// GetMergeRequestOptions say which diff MergeRequestService.Get reads.
223type GetMergeRequestOptions struct {
224 // SinceLastRead compares the head recorded by MarkRead with the head (see Get).
225 SinceLastRead bool
226 // Files, when set, lists every changed file, without the file-count
227 // limit, and reads the hunks of the files in the window only, each within
228 // the per-file and the total limits of domain.DefaultDiffLimits. Unset,
229 // the diff is bounded by domain.DefaultDiffLimits (the API contract).
230 Files *FileWindow
231 // Base and Head, when not zero, are the diff the caller shows: Get
232 // returns domain.ErrConflict when the request's diff base or head differ
233 // (the branch moved, a read was marked).
234 Base, Head domain.ObjectID
235 // DiffOnly skips the commits of the request (Commits stays empty).
236 DiffOnly bool
237}
238
239// FileWindow is the range [From, To) of files whose hunks are read.
240type FileWindow struct{ From, To int }
241
242// AddCommentParams describes the comment to add.
243type AddCommentParams struct {
244 // Path, Line and Side designate a line of the diff; all empty for a
245 // general comment.
246 Path string
247 Line int
248 Side domain.DiffSide
249 Text string
250}
251
252// MergeParams describes the merge to perform.
253type MergeParams struct {
254 // Mode defaults to fast-forward.
255 Mode domain.MergeMode
256 // HeadID is the commit the caller reviewed; the source branch must still
257 // point to it.
258 HeadID domain.ObjectID
259 // DeleteSource deletes the source branch after the merge.
260 DeleteSource bool
261}
262
263// MergeResult is a merged request and what happened to its source branch.
264type MergeResult struct {
265 domain.MergeRequest
266 // SourceDeleted is true when DeleteSource was asked and the branch is
267 // gone.
268 SourceDeleted bool
269}
270
271// LoginLink is a login link as the owner receives it.
272type LoginLink struct {
273 // URL holds the secret: show it once, never log it.
274 URL string
275 ExpiresAt time.Time
276}