pr_01m47d15m3e54sn21z27rpy5n9/crates/contracts/src/repos.rs

333 lines9,341 bytesCodeBlame
1//! The repos service: repository metadata, contents, forks and git access.
2//!
3//! Each `*Args` struct is the argument of the method of the same name,
4//! served at `POST /rpc/<method>`.
5
6use serde::{Deserialize, Serialize};
7
8use crate::{User, Viewer};
9
10#[derive(Clone, Debug, Serialize, Deserialize)]
11#[serde(rename_all = "camelCase")]
12pub struct Repo {
13 pub id: String,
14 /// The slug of the workspace that owns it: the first URL segment.
15 pub namespace: String,
16 pub name: String,
17 pub description: Option<String>,
18 pub is_private: bool,
19 pub owner_id: String,
20 pub default_branch: String,
21 /// Set when this repo is a pull request's working copy of another repo.
22 pub fork_of: Option<String>,
23 /// RFC 3339.
24 pub created_at: String,
25}
26
27#[derive(Clone, Debug, Serialize, Deserialize)]
28pub struct RepoPath {
29 pub namespace: String,
30 pub name: String,
31}
32
33#[derive(Clone, Debug, Serialize, Deserialize)]
34pub struct Signature {
35 pub name: String,
36 pub email: String,
37}
38
39#[derive(Clone, Debug, Serialize, Deserialize)]
40#[serde(rename_all = "camelCase")]
41pub struct Commit {
42 pub hash: String,
43 pub tree_hash: String,
44 pub message: String,
45 pub author: Signature,
46 pub parents: Vec<String>,
47 /// RFC 3339.
48 pub authored_at: String,
49}
50
51#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
52#[serde(rename_all = "lowercase")]
53pub enum EntryKind {
54 Tree,
55 Blob,
56 Symlink,
57 Gitlink,
58 Exec,
59}
60
61#[derive(Clone, Debug, Serialize, Deserialize)]
62pub struct TreeEntry {
63 pub name: String,
64 pub hash: String,
65 pub kind: EntryKind,
66}
67
68#[derive(Clone, Debug, Serialize, Deserialize)]
69pub struct Readme {
70 pub name: String,
71 /// Null when the file is binary or too large to show.
72 pub text: Option<String>,
73}
74
75#[derive(Clone, Debug, Serialize, Deserialize)]
76pub struct TreeView {
77 pub repo: Repo,
78 #[serde(rename = "ref")]
79 pub git_ref: String,
80 pub path: String,
81 /// Null when the repo has no commits yet.
82 pub head: Option<Commit>,
83 pub entries: Vec<TreeEntry>,
84 pub readme: Option<Readme>,
85}
86
87#[derive(Clone, Debug, Serialize, Deserialize)]
88pub struct BlobView {
89 pub repo: Repo,
90 #[serde(rename = "ref")]
91 pub git_ref: String,
92 pub path: String,
93 pub size: u64,
94 /// Null when the file is binary or too large to show.
95 pub text: Option<String>,
96}
97
98/// A git remote and a short-lived credential for it.
99#[derive(Clone, Debug, Serialize, Deserialize)]
100pub struct GitAccess {
101 pub remote: String,
102 pub token: String,
103}
104
105#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
106pub enum GitService {
107 #[serde(rename = "git-upload-pack")]
108 UploadPack,
109 #[serde(rename = "git-receive-pack")]
110 ReceivePack,
111}
112
113/// The result of landing a pull request.
114#[derive(Clone, Debug, Serialize, Deserialize)]
115pub struct Landed {
116 /// The commit the branch points to now.
117 pub commit: String,
118 /// The commit it pointed to before, if it had one. Comparing against
119 /// this shows what the pull request changed.
120 pub previous: Option<String>,
121}
122
123/// `get`. Returns `Outcome<Repo>`.
124#[derive(Debug, Serialize, Deserialize)]
125pub struct GetArgs {
126 pub path: RepoPath,
127 pub viewer: Viewer,
128}
129
130/// `get_by_id`. Returns `Outcome<Repo>`.
131#[derive(Debug, Serialize, Deserialize)]
132pub struct GetByIdArgs {
133 pub id: String,
134 pub viewer: Viewer,
135}
136
137/// `list`: repos the viewer may see, newest first. Returns `Vec<Repo>`.
138#[derive(Debug, Default, Serialize, Deserialize)]
139#[serde(rename_all = "camelCase")]
140pub struct ListArgs {
141 pub viewer: Viewer,
142 #[serde(default)]
143 pub query: Option<String>,
144 /// Only repos in this workspace.
145 #[serde(default)]
146 pub namespace: Option<String>,
147 /// Only repos in workspaces the viewer belongs to.
148 #[serde(default)]
149 pub member_only: bool,
150}
151
152/// `create`. Returns `Outcome<Repo>`.
153#[derive(Debug, Serialize, Deserialize)]
154#[serde(rename_all = "camelCase")]
155pub struct CreateArgs {
156 /// Who is creating it; they must belong to the workspace.
157 pub owner: User,
158 /// The workspace it is created in.
159 pub namespace: String,
160 pub name: String,
161 #[serde(default)]
162 pub description: Option<String>,
163 #[serde(default)]
164 pub is_private: bool,
165}
166
167/// `tree`. Returns `Outcome<TreeView>`.
168#[derive(Debug, Serialize, Deserialize)]
169#[serde(rename_all = "camelCase")]
170pub struct TreeArgs {
171 pub path: RepoPath,
172 pub viewer: Viewer,
173 /// The default branch when absent.
174 #[serde(default, rename = "ref")]
175 pub git_ref: Option<String>,
176 #[serde(default)]
177 pub tree_path: String,
178}
179
180/// `blob`. Returns `Outcome<BlobView>`.
181#[derive(Debug, Serialize, Deserialize)]
182#[serde(rename_all = "camelCase")]
183pub struct BlobArgs {
184 pub path: RepoPath,
185 pub viewer: Viewer,
186 #[serde(rename = "ref")]
187 pub git_ref: String,
188 pub file_path: String,
189}
190
191/// `log`. Returns `Outcome<Vec<Commit>>`.
192#[derive(Debug, Serialize, Deserialize)]
193pub struct LogArgs {
194 pub path: RepoPath,
195 pub viewer: Viewer,
196 #[serde(default, rename = "ref")]
197 pub git_ref: Option<String>,
198 pub limit: u32,
199}
200
201/// `fork_for_pull`: a copy-on-write copy of the source repo, hidden from
202/// listings, for one pull request to be made in. Returns `Outcome<Repo>`.
203#[derive(Debug, Serialize, Deserialize)]
204#[serde(rename_all = "camelCase")]
205pub struct ForkArgs {
206 pub source_id: String,
207 pub pull_id: String,
208 pub actor: User,
209}
210
211/// `git_access`: authorizes a git operation and says where to send it.
212/// Pushing to a repo that does not exist creates it in the pusher's own
213/// namespace. Returns `Outcome<GitAccess>`.
214#[derive(Debug, Serialize, Deserialize)]
215pub struct GitAccessArgs {
216 pub path: RepoPath,
217 pub viewer: Viewer,
218 pub service: GitService,
219}
220
221/// `land`: moves a repository's default branch to the head of a pull
222/// request's source. Refused with `conflict` when the source is behind,
223/// since that would discard commits. Returns `Outcome<Landed>`.
224#[derive(Debug, Serialize, Deserialize)]
225#[serde(rename_all = "camelCase")]
226pub struct LandArgs {
227 /// The repository holding the commits: a pull request's fork, or the
228 /// target itself when landing one of its own branches.
229 pub source_id: String,
230 /// The branch of the source to land. Required when the source is the
231 /// target; a fork lands its default branch.
232 #[serde(default)]
233 pub branch: Option<String>,
234 pub actor: User,
235}
236
237#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
238#[serde(rename_all = "lowercase")]
239pub enum FileStatus {
240 Added,
241 Modified,
242 Deleted,
243}
244
245#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
246#[serde(rename_all = "lowercase")]
247pub enum LineKind {
248 /// Unchanged, shown for context.
249 Context,
250 Add,
251 Delete,
252}
253
254#[derive(Clone, Debug, Serialize, Deserialize)]
255pub struct DiffLine {
256 pub kind: LineKind,
257 /// Line number in the old file; absent for added lines.
258 pub old: Option<u32>,
259 /// Line number in the new file; absent for deleted lines.
260 pub new: Option<u32>,
261 pub text: String,
262}
263
264/// A run of changed lines with their surrounding context.
265#[derive(Clone, Debug, Serialize, Deserialize)]
266pub struct Hunk {
267 pub lines: Vec<DiffLine>,
268}
269
270#[derive(Clone, Debug, Serialize, Deserialize)]
271pub struct FileDiff {
272 pub path: String,
273 pub status: FileStatus,
274 pub additions: u32,
275 pub deletions: u32,
276 /// True when the file is binary or too large, so no lines are shown.
277 pub binary: bool,
278 pub hunks: Vec<Hunk>,
279}
280
281/// What changed between two commits.
282#[derive(Clone, Debug, Serialize, Deserialize)]
283pub struct Comparison {
284 /// Null when the head has no earlier commit to compare against.
285 pub base: Option<String>,
286 pub head: String,
287 pub files: Vec<FileDiff>,
288 /// True when the change was too large to return in full.
289 pub truncated: bool,
290}
291
292/// `compare`: what `head` changes relative to `base`.
293///
294/// `head` is a branch or a commit, and defaults to the default branch.
295/// With no `base`, a fork is compared against the point where it and the
296/// repository it came from last agreed; a branch against the point where it
297/// left the default branch; and the default branch against its head's
298/// parent. Returns `Outcome<Comparison>`.
299#[derive(Debug, Serialize, Deserialize)]
300#[serde(rename_all = "camelCase")]
301pub struct CompareArgs {
302 pub repo_id: String,
303 pub viewer: Viewer,
304 #[serde(default)]
305 pub base: Option<String>,
306 #[serde(default)]
307 pub head: Option<String>,
308}
309
310/// A branch and the commit it points to.
311#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
312pub struct Branch {
313 pub name: String,
314 pub hash: String,
315}
316
317/// `branches`: the repository's branches, default branch first.
318/// Returns `Outcome<Vec<Branch>>`.
319#[derive(Debug, Serialize, Deserialize)]
320pub struct BranchesArgs {
321 pub path: RepoPath,
322 pub viewer: Viewer,
323}
324
325/// `head`: the commit a branch points to, or null. For services reacting
326/// to a push, which have no viewer; it reveals nothing but a commit hash.
327/// Returns `Option<String>`.
328#[derive(Debug, Serialize, Deserialize)]
329#[serde(rename_all = "camelCase")]
330pub struct HeadArgs {
331 pub repo_id: String,
332 pub branch: String,
333}