v0.33.0 cf26365

dto.go RawHistoryFolder

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 // includes ActiveAt, the latest repository activity
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	// Issues replaces the issues mode.
51	Issues *domain.IssuesMode
52	// AllowAutoMerge replaces the setting of that name.
53	AllowAutoMerge *bool
54}
55
56// EnableAutoMergeParams are the settings of EnableAutoMerge.
57type EnableAutoMergeParams struct {
58	// Mode is the merge mode to use; empty means fast-forward.
59	Mode domain.MergeMode
60	// HeadID is the head the caller saw; required. Auto-merge is enabled only
61	// if the source branch still points to it.
62	HeadID domain.ObjectID
63}
64
65// TokenPage is a page of stored tokens, newest first.
66type TokenPage struct {
67	Tokens []domain.Token
68	// NextPageToken is empty on the last page.
69	NextPageToken string
70}
71
72// CreateTokenParams are the settings of a new token.
73type CreateTokenParams struct {
74	Label string
75	// Scopes must not be empty.
76	Scopes []domain.Scope
77	// Repos limits the token to these repositories; empty means every one.
78	Repos []domain.RepoName
79	// BranchPrefixes limits the token to the branches under these prefixes
80	// (see domain.ParseBranchPrefix); empty means every branch.
81	BranchPrefixes []string
82	// ExpiresAt is the zero time for a token that never expires.
83	ExpiresAt time.Time
84}
85
86// CreatedToken is a new token with its secret, which is shown once and never
87// stored.
88type CreatedToken struct {
89	Token  domain.Token
90	Secret string
91}
92
93// ListRefsParams selects the refs to list.
94type ListRefsParams struct {
95	// Kinds restricts the result; empty means every kind.
96	Kinds []domain.RefKind
97	// PageSize is 0 for the default, and lowered to MaxRefPageSize.
98	PageSize int
99	// PageToken is the NextPageToken of the previous page, or empty.
100	PageToken string
101}
102
103// RefPage is a page of refs.
104type RefPage struct {
105	Refs []domain.Ref
106	// NextPageToken is empty on the last page.
107	NextPageToken string
108}
109
110// ListCommitsParams selects a page of history.
111type ListCommitsParams struct {
112	// Revision is where the history starts; the zero value is HEAD. Ignored
113	// when PageToken is set: the token pins the commit the first page started
114	// from, so every page walks the same history even if a branch moves.
115	Revision domain.Revision
116	// Path limits the history to the commits that changed it. It must be the
117	// same on every page of a listing.
118	Path domain.TreePath
119	// PageSize is 0 for the default, and lowered to MaxPageSize.
120	PageSize int
121	// PageToken is the NextPageToken of the previous page, or empty.
122	PageToken string
123}
124
125// HistoryPage is a page of history, newest first.
126type HistoryPage struct {
127	Commits []domain.Commit
128	// NextPageToken is empty on the last page.
129	NextPageToken string
130}
131
132// RepoStats are the figures of a repository the home page shows.
133type RepoStats struct {
134	// Commits is the number of commits of the default branch; Recent of them
135	// were committed in the last RecentDays days.
136	Commits, Recent int
137	// LatestTag is the most recently created tag; nil without tags.
138	LatestTag *domain.TagInfo
139	// Activity is the number of commits of each of the last ActivityDays
140	// days, oldest first; the last day ends now. A day is 24 hours.
141	Activity []int
142	// Partial tells that the recent commits were more than MaxCommitTimes:
143	// Recent and Activity count only some of them.
144	Partial bool
145}
146
147// RecentDays is the window of RepoStats.Recent.
148const RecentDays = 30
149
150// ActivityDays is the span of RepoStats.Activity.
151const ActivityDays = 90
152
153// WatchParams select the events of a watch.
154type WatchParams struct {
155	// Topics are TopicHome or "repo:<name>"; empty means TopicHome.
156	Topics []string
157	// ResumeAfter is the id of the last event the caller saw; empty to
158	// receive only new events.
159	ResumeAfter string
160	// Client identifies where the watch comes from, for the limit per client
161	// (MaxWatchersPerClient): an opaque key such as a normalized address; the
162	// web passes its visitor's. Empty only for callers with no client, which
163	// count against MaxWatchers alone.
164	Client string
165	// Ready, when not nil, is called once the topics are valid and the watch
166	// is registered: events published from then on are not missed. Nothing is
167	// sent before it returns.
168	Ready func()
169}
170
171// WatchEvent is one item of a watch.
172type WatchEvent struct {
173	// ID identifies the event, for resuming. Empty on a gap.
174	ID string
175	// Gap tells that events were lost: the caller must reload what it shows.
176	// Event is nil then.
177	Gap bool
178	// Event is a domain.RepoCreated, RepoUpdated, RepoDeleted, PushEvent,
179	// MergeRequestOpened, MergeRequestMerged, MergeRequestClosed,
180	// MergeRequestReady, CommentAdded, RunUpdated or JobUpdated.
181	Event domain.Event
182	// Repo is the state of the repository at delivery, for RepoCreated and
183	// RepoUpdated.
184	Repo *RepoView
185}
186
187// CreateMergeRequestParams describes the merge request to open.
188type CreateMergeRequestParams struct {
189	Title       string
190	Description string
191	// Source is required; Target defaults to the default branch.
192	Source, Target string
193}
194
195// ListMergeRequestsParams selects a page of merge requests.
196type ListMergeRequestsParams struct {
197	// State restricts the result; empty means every state.
198	State domain.MRState
199	// PageSize is 0 for the default, and lowered to MaxPageSize.
200	PageSize int
201	// PageToken is the NextPageToken of the previous page, or empty.
202	PageToken string
203}
204
205// MergeRequestPage is a page of merge requests, highest number first.
206type MergeRequestPage struct {
207	MergeRequests []domain.MergeRequest
208	// NextPageToken is empty on the last page.
209	NextPageToken string
210	// Mergeability holds, by number, the mergeability of the open requests of
211	// the page (nil when the server does not compute it).
212	Mergeability map[int64]domain.Mergeability
213}
214
215// ListIssuesParams selects a page of issues from an IssueStore.
216type ListIssuesParams struct {
217	// State restricts the result; empty means every state.
218	State domain.IssueState
219	// PageSize is the most issues returned; 0 or less means no limit. The
220	// use case chooses it.
221	PageSize int
222	// PageToken is the NextPageToken of the previous page, or empty.
223	PageToken string
224}
225
226// IssuePage is a page of issues, highest number first.
227type IssuePage struct {
228	Issues []domain.Issue
229	// NextPageToken is empty on the last page.
230	NextPageToken string
231}
232
233// ListPendingParams selects a page of pending issues.
234type ListPendingParams struct {
235	// PageSize is the page size; the use case applies the default and the
236	// maximum, a store takes it as is (0: every one).
237	PageSize int
238	// PageToken is the NextPageToken of the previous page.
239	PageToken string
240}
241
242// PendingIssuePage is a page of pending issues, oldest first.
243type PendingIssuePage struct {
244	Issues        []domain.PendingIssue
245	NextPageToken string
246}
247
248// CreateIssueParams describes the issue to open.
249type CreateIssueParams struct {
250	Title string
251	Body  string
252}
253
254// IssueReference is a merge request of the same repository naming an issue.
255type IssueReference struct {
256	Number int64
257	Title  domain.MRTitle
258	State  domain.MRState
259	Closes bool
260}
261
262// IssueDetail is an issue with its comments and referencing merge requests.
263type IssueDetail struct {
264	// References are ascending by number, at most 100.
265	References []IssueReference
266	Issue      domain.Issue
267	// Comments are oldest first.
268	Comments []domain.IssueComment
269}
270
271// CompareResult describes source commits absent from target, newest first.
272type CompareResult struct {
273	Ahead  []domain.Commit
274	Behind bool
275	Exact  bool
276}
277
278// PushSummary counts a bounded range; More means additional commits exist.
279type PushSummary struct {
280	Count     int
281	More      bool
282	Rewritten bool
283}
284
285// MergeRequestDetail is a merge request with its review data.
286type MergeRequestDetail struct {
287	MergeRequest domain.MergeRequest
288	// NewCommits is the unread prefix of Commits; zero if the read head is absent.
289	NewCommits int
290	// HeadUnread reports whether the nonzero head differs from the shared read position.
291	HeadUnread bool
292	// Commits are the commits of the head that the target lacks, newest
293	// first, at most MaxMergeRequestCommits.
294	Commits          []domain.Commit
295	CommitsTruncated bool
296	// DiffBaseID is the commit the diff compares from; zero when the source
297	// branch is gone, then the diff is empty.
298	DiffBaseID domain.ObjectID
299	Stats      domain.DiffStats
300	Diff       domain.Diff
301	// Comments are the comments, oldest first.
302	Comments []domain.Comment
303	// Verdicts are the latest verdict per author in note ID order.
304	Verdicts []domain.AuthorVerdict
305	// Mergeability is zero unless the request is open.
306	Mergeability domain.Mergeability
307	// LastReadID is the head recorded by MarkRead; zero when none.
308	LastReadID domain.ObjectID
309	// LastReadLost tells that since-last-read was asked for, a head was
310	// recorded, but that commit is gone: the diff is against the target.
311	LastReadLost bool
312}
313
314// GetMergeRequestOptions say which diff MergeRequestService.Get reads.
315type GetMergeRequestOptions struct {
316	// SinceLastRead compares the head recorded by MarkRead with the head (see Get).
317	SinceLastRead bool
318	// Files, when set, lists every changed file, without the file-count
319	// limit, and reads the hunks of the files in the window only, each within
320	// the per-file and the total limits of domain.DefaultDiffLimits; generated
321	// files are listed collapsed (domain.OmitGenerated). With Full, the single
322	// file is read without the line limits. Unset, the diff is bounded by
323	// domain.DefaultDiffLimits and generated files are read (the API contract).
324	Files *FileWindow
325	// Base and Head, when not zero, are the diff the caller shows: Get
326	// returns domain.ErrConflict when the request's diff base or head differ
327	// (the branch moved, a read was marked).
328	Base, Head domain.ObjectID
329	// DiffOnly skips the commits of the request (Commits stays empty).
330	DiffOnly bool
331	// Load, when set with Files, is the index of a collapsed file Get reads in
332	// full and splices into the diff in place of its collapsed entry (the page
333	// of a client without scripts). Ignored when the index is out of range,
334	// the file is not collapsed, or there is no diff.
335	Load *int
336}
337
338// FileWindow is the range [From, To) of files whose hunks are read.
339//
340// Full asks for the one file From read in full: no line limit applies, only
341// the byte guard (domain.OneFileDiffLimits). It requires To == From+1; a
342// window with Full and any other To is domain.ErrInvalid.
343type FileWindow struct {
344	From, To int
345	Full     bool
346}
347
348// GetCommitOptions say which diff BrowseService.GetCommit reads.
349type GetCommitOptions struct {
350	// Files, when set, reads the hunks of a window of the files, as
351	// GetMergeRequestOptions.Files does. Unset (the zero value), the diff is
352	// bounded by domain.DefaultDiffLimits.
353	Files *FileWindow
354	// Page, without Files, reads the diff for a page: every file listed, the
355	// hunks of the first domain.CommitPageFiles files read, generated files
356	// collapsed, and the files past the window collapsed too
357	// (domain.OmitBudget). Combined with Files it is domain.ErrInvalid.
358	Page bool
359	// Load is the index of a collapsed file read in full and spliced into the
360	// diff, as GetMergeRequestOptions.Load. It requires Page.
361	Load *int
362}
363
364// AddCommentParams describes the comment to add.
365type AddCommentParams struct {
366	// ReplyTo names a non-deleted root; replies cannot specify an anchor or verdict.
367	ReplyTo int64
368	// StartLine starts an inclusive range, requiring a path and 1 <= StartLine < Line.
369	StartLine int
370	// Verdict requires mr:review and is only permitted on roots.
371	Verdict domain.Verdict
372	// Path, Line and Side designate a line of the diff; all empty for a
373	// general comment.
374	Path string
375	Line int
376	Side domain.DiffSide
377	Text string
378}
379
380// MergeParams describes the merge to perform.
381type MergeParams struct {
382	// IgnoreChecks bypasses checks and requires mr:force-merge.
383	IgnoreChecks bool
384	// Mode defaults to fast-forward.
385	Mode domain.MergeMode
386	// HeadID is the commit the caller reviewed; the source branch must still
387	// point to it.
388	HeadID domain.ObjectID
389	// DeleteSource deletes the source branch after the merge.
390	DeleteSource bool
391}
392
393// MergeResult is a merged request and what happened to its source branch.
394type MergeResult struct {
395	domain.MergeRequest
396	// SourceDeleted is true when DeleteSource was asked: the deletion is
397	// requested, and done asynchronously after the merge returned (it is
398	// skipped if the branch moved meanwhile).
399	SourceDeleted bool
400}
401
402// LoginLink is a login link as the owner receives it.
403type LoginLink struct {
404	// URL holds the secret: show it once, never log it.
405	URL       string
406	ExpiresAt time.Time
407}
408
409// InboxCounts are the numbers of open items across every repository, whatever
410// the filter.
411type InboxCounts struct{ MergeRequests, Issues, Pending, Running int }
412
413// InboxOverview is what the owner has to look at across every repository: the
414// open merge requests and issues, ongoing CI runs, and issues awaiting moderation.
415type InboxOverview struct {
416	Counts InboxCounts
417	// Runs are queued or in progress, newest first, respecting the filter.
418	Runs []domain.CIRun
419	// RunsEnabled distinguishes disabled CI from an empty queue.
420	RunsEnabled bool
421	// MergeRequests and Issues are those of the filtered repository, or of
422	// every repository when there is no filter. Counts always counts all.
423	MergeRequests []domain.MergeRequest
424	Issues        []domain.Issue
425	// Pending are the issues awaiting moderation, in every repository
426	// whatever the filter, oldest first. At most domain.MaxPendingIssues.
427	Pending []domain.PendingIssue
428	// Repos are the repositories that have at least one open item, by name,
429	// whatever the filter: they feed the filter itself.
430	Repos []domain.RepoName
431}
432
433// History query limits.
434const (
435	// MaxMergeRequestCommits bounds the commits returned with a merge request.
436	MaxMergeRequestCommits = 100
437	// MaxCompareCommits bounds a repository comparison.
438	MaxCompareCommits = 500
439	// MaxPushSummaryCommits bounds the commits counted in a push summary.
440	MaxPushSummaryCommits = 100
441)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 44

↑↓ moveenter openesc close