Re-expose Operation State in generics.
This is the worst code I have ever written. I hate the way this changes everything. ugh.
parent: tbd commit: 90db3e2
1 | use Error; |
2 | use async_trait; |
3 | |
4 | use BranchType; |
5 | use ; |
6 | |
7 | use |
8 | AccessList, Commit, DefaultBranch, Description, IssueLabel, Repository, RepositoryBranch, |
9 | RepositoryBranchesRequest, RepositoryChunkLine, RepositoryCommitBeforeRequest, |
10 | RepositoryCommitFromIdRequest, RepositoryDiff, RepositoryDiffFile, RepositoryDiffFileChunk, |
11 | RepositoryDiffFileInfo, RepositoryDiffFileStatus, RepositoryDiffPatchRequest, |
12 | RepositoryDiffRequest, RepositoryFile, RepositoryFileFromIdRequest, |
13 | RepositoryFileFromPathRequest, RepositoryFileInspectRequest, RepositoryIssue, |
14 | RepositoryIssueLabelsRequest, RepositoryIssuesCountRequest, RepositoryIssuesRequest, |
15 | RepositoryLastCommitOfFileRequest, RepositoryObjectType, RepositoryStatistics, |
16 | RepositoryStatisticsRequest, RepositoryTreeEntry, RepositoryVisibility, Visibility, |
17 | ; |
18 | |
19 | use User; |
20 | |
21 | use ; |
22 | |
23 | use PgPool; |
24 | use Deref; |
25 | use |
26 | , |
27 | , | Arc
28 | ; |
29 | use Error; |
30 | use OnceCell; |
31 | |
32 | use ; |
33 | |
34 | // TODO: Handle this |
35 | //region database structures |
36 | |
37 | /// Repository in the database |
38 | |
39 | |
40 | #[sqlx(try_from = "String")] |
41 | pub owner_user: User, |
42 | pub name: String, |
43 | pub description: , |
44 | pub visibility: RepositoryVisibility, |
45 | pub default_branch: String, |
46 | |
47 | |
48 | |
49 | // Separate function because "Private" will be expanded later |
50 | /// Checks if the user is allowed to view this repository |
51 | pub async |
52 | &self, |
53 | our_instance: &Instance, |
54 | user: & , |
55 | stack: &GiteratedStack, |
56 | |
57 | if matches! |
58 | return true; |
59 | |
60 | |
61 | // User must exist for any further checks to pass |
62 | let user = match user |
63 | Some => user, |
64 | None => return false, |
65 | ; |
66 | |
67 | if *user.deref == self.owner_user |
68 | // owner can always view |
69 | return true; |
70 | |
71 | |
72 | if matches! |
73 | // Check if the user can view\ |
74 | let access_list = stack |
75 | . |
76 | owner: self.owner_user.clone, |
77 | name: self.name.clone, |
78 | instance: our_instance.clone, |
79 | |
80 | .await |
81 | .unwrap; |
82 | |
83 | access_list |
84 | .0 |
85 | .iter |
86 | .any |
87 | else |
88 | false |
89 | |
90 | |
91 | |
92 | // This is in it's own function because I assume I'll have to add logic to this later |
93 | |
94 | &self, |
95 | repository_directory: &str, |
96 | |
97 | match open |
98 | "{}/{}/{}/{}" |
99 | repository_directory, self.owner_user.instance, self.owner_user.username, self.name |
100 | ) |
101 | Ok => Ok, |
102 | Err => |
103 | let err = FailedOpeningFromDisk; |
104 | error!; |
105 | |
106 | Err |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | //endregion |
113 | |
114 | |
115 | |
116 | |
117 | FailedCreatingRepository, |
118 | |
119 | FailedInsertingIntoDatabase, |
120 | |
121 | RepositoryNotFound , |
122 | |
123 | RepositoryAlreadyExists , |
124 | |
125 | CouldNotDeleteFromDisk, |
126 | |
127 | FailedDeletingFromDatabase, |
128 | |
129 | FailedOpeningFromDisk, |
130 | |
131 | RefNotFound, |
132 | |
133 | HeadNotFound, |
134 | |
135 | PathNotFound, |
136 | |
137 | LastCommitNotFound, |
138 | |
139 | InvalidObjectId, |
140 | |
141 | BlobNotFound, |
142 | |
143 | TreeNotFound, |
144 | |
145 | CommitNotFound, |
146 | |
147 | CommitParentNotFound, |
148 | |
149 | FailedDiffing, |
150 | |
151 | |
152 | |
153 | pub pg_pool: PgPool, |
154 | pub repository_folder: String, |
155 | pub instance: Instance, |
156 | pub stack: , |
157 | |
158 | |
159 | |
160 | |
161 | pg_pool: &PgPool, |
162 | repository_folder: &str, |
163 | instance: impl , |
164 | stack: , |
165 | |
166 | let instance = instance.to_owned; |
167 | |
168 | Self |
169 | pg_pool: pg_pool.clone, |
170 | repository_folder: repository_folder.to_string, |
171 | instance, |
172 | stack, |
173 | |
174 | |
175 | |
176 | pub async |
177 | &self, |
178 | user: &User, |
179 | repository_name: &str, |
180 | |
181 | if let Ok = query_as! |
182 | r#"SELECT owner_user, name, description, visibility as "visibility: _", default_branch FROM repositories WHERE owner_user = $1 AND name = $2"#, |
183 | user.to_string, repository_name |
184 | .fetch_one |
185 | .await |
186 | Ok |
187 | else |
188 | Err |
189 | owner_user: user.to_string, |
190 | name: repository_name.to_string, |
191 | |
192 | |
193 | |
194 | |
195 | pub async |
196 | &self, |
197 | user: &User, |
198 | repository_name: &str, |
199 | |
200 | if let Err = remove_dir_all |
201 | "{}/{}/{}/{}" |
202 | self.repository_folder, user.instance, user.username, repository_name |
203 | ) |
204 | let err = CouldNotDeleteFromDisk; |
205 | error! |
206 | "Couldn't delete repository from disk, this is bad! {:?}", |
207 | err |
208 | ; |
209 | |
210 | return Err; |
211 | |
212 | |
213 | // Delete the repository from the database |
214 | match query! |
215 | "DELETE FROM repositories WHERE owner_user = $1 AND name = $2", |
216 | user.to_string, |
217 | repository_name |
218 | |
219 | .execute |
220 | .await |
221 | |
222 | Ok => Ok, |
223 | Err => Err, |
224 | |
225 | |
226 | |
227 | pub async |
228 | &self, |
229 | owner: &User, |
230 | name: &str, |
231 | requester: & , |
232 | |
233 | let repository = match self |
234 | .find_by_owner_user_name |
235 | // &request.owner.instance.url, |
236 | owner, name, |
237 | |
238 | .await |
239 | |
240 | Ok => repository, |
241 | Err => return Err, |
242 | ; |
243 | |
244 | if let Some = requester |
245 | if !repository |
246 | .can_user_view_repository |
247 | &self.instance, |
248 | &Some, |
249 | self.stack.get .unwrap, |
250 | |
251 | .await |
252 | |
253 | return Err |
254 | owner_user: repository.owner_user.to_string, |
255 | name: repository.name.clone, |
256 | ; |
257 | |
258 | else if matches! |
259 | // Unauthenticated users can never view private repositories |
260 | |
261 | return Err |
262 | owner_user: repository.owner_user.to_string, |
263 | name: repository.name.clone, |
264 | ; |
265 | |
266 | |
267 | match repository.open_git2_repository |
268 | Ok => Ok, |
269 | Err => Err, |
270 | |
271 | |
272 | |
273 | // TODO: Find where this fits |
274 | // TODO: Cache this and general repository tree and invalidate select files on push |
275 | // TODO: Find better and faster technique for this |
276 | |
277 | path: &str, |
278 | git: & Repository, |
279 | start_commit: & Commit, |
280 | |
281 | trace!; |
282 | |
283 | let mut revwalk = git.revwalk?; |
284 | revwalk.set_sorting?; |
285 | revwalk.push?; |
286 | |
287 | for oid in revwalk |
288 | let oid = oid?; |
289 | let commit = git.find_commit?; |
290 | |
291 | // Merge commits have 2 or more parents |
292 | // Commits with 0 parents are handled different because we can't diff against them |
293 | if commit.parent_count == 0 |
294 | return Ok; |
295 | else if commit.parent_count == 1 |
296 | let tree = commit.tree?; |
297 | let last_tree = commit.parent?.tree?; |
298 | |
299 | // Get the diff between the current tree and the last one |
300 | let diff = git.diff_tree_to_tree?; |
301 | |
302 | for dd in diff.deltas |
303 | // Get the path of the current file we're diffing against |
304 | let current_path = dd.new_file .path .unwrap; |
305 | |
306 | // Path or directory |
307 | if current_path.eq || current_path.starts_with |
308 | return Ok; |
309 | |
310 | |
311 | |
312 | |
313 | |
314 | Err? |
315 | |
316 | |
317 | /// Gets the total amount of commits using revwalk |
318 | |
319 | git: & Repository, |
320 | start_commit: & Commit, |
321 | |
322 | // TODO: There must be a better way |
323 | let mut revwalk = git.revwalk?; |
324 | revwalk.set_sorting?; |
325 | revwalk.push?; |
326 | |
327 | Ok |
328 | |
329 | |
330 | |
331 | git: & Repository, |
332 | rev: , |
333 | |
334 | // Try and parse the input as a reference and get the object ID |
335 | let mut tree_id = match rev |
336 | None => |
337 | if let Ok = git.head |
338 | // TODO: Fix for symbolic references |
339 | head.target |
340 | else |
341 | // Nothing in database, render empty tree. |
342 | return Err; |
343 | |
344 | |
345 | Some => |
346 | // Find the reference, otherwise return GitBackendError |
347 | git.refname_to_id .ok |
348 | |
349 | ; |
350 | |
351 | // If the reference wasn't found, try parsing it as a commit ID |
352 | if tree_id.is_none |
353 | if let Ok = from_str |
354 | tree_id = Some |
355 | |
356 | |
357 | |
358 | // If the commit ID wasn't found, try parsing it as a branch and otherwise return error |
359 | if tree_id.is_none |
360 | match git.find_branch |
361 | Ok => tree_id = branch.get .target, |
362 | Err => |
363 | return Err |
364 | Box new .into, |
365 | |
366 | |
367 | |
368 | |
369 | |
370 | // Should be safe? |
371 | Ok |
372 | |
373 | |
374 | /// Gets the last commit in a rev |
375 | |
376 | let oid = Self get_oid_from_reference?; |
377 | |
378 | // Walk through the repository commit graph starting at our rev |
379 | let mut revwalk = git.revwalk?; |
380 | revwalk.set_sorting?; |
381 | revwalk.push?; |
382 | |
383 | if let Some = revwalk.next |
384 | if let Ok = git |
385 | .find_commit |
386 | .map_err |
387 | |
388 | return Ok; |
389 | |
390 | |
391 | |
392 | Err |
393 | |
394 | |
395 | |
396 | |
397 | |
398 | async |
399 | &mut self, |
400 | requester: & , |
401 | repository: &Repository, |
402 | |
403 | if let Ok = self |
404 | .find_by_owner_user_name |
405 | .await |
406 | |
407 | Ok |
408 | .can_user_view_repository |
409 | .await |
410 | else |
411 | Ok |
412 | |
413 | |
414 | |
415 | async |
416 | &mut self, |
417 | _user: &AuthenticatedUser, |
418 | request: &RepositoryCreateRequest, |
419 | |
420 | // Check if repository already exists in the database |
421 | if let Ok = self |
422 | .find_by_owner_user_name |
423 | .await |
424 | |
425 | let err = RepositoryAlreadyExists |
426 | owner_user: repository.owner_user.to_string, |
427 | name: repository.name, |
428 | ; |
429 | error!; |
430 | |
431 | return Err; |
432 | |
433 | |
434 | // Insert the repository into the database |
435 | let _ = match query_as! |
436 | r#"INSERT INTO repositories VALUES ($1, $2, $3, $4, $5) RETURNING owner_user, name, description, visibility as "visibility: _", default_branch"#, |
437 | request.owner.to_string, request.name, request.description, request.visibility as _, "master" |
438 | .fetch_one |
439 | .await |
440 | Ok => repository, |
441 | Err => |
442 | let err = FailedInsertingIntoDatabase; |
443 | error!; |
444 | |
445 | return Err; |
446 | |
447 | ; |
448 | |
449 | // Create bare (server side) repository on disk |
450 | match init_bare |
451 | "{}/{}/{}/{}" |
452 | self.repository_folder, request.owner.instance, request.owner.username, request.name |
453 | ) |
454 | Ok => |
455 | debug! |
456 | "Created new repository with the name {}/{}/{}", |
457 | request.owner.instance, request.owner.username, request.name |
458 | ; |
459 | |
460 | let stack = self.stack.get .unwrap; |
461 | |
462 | let repository = Repository |
463 | owner: request.owner.clone, |
464 | name: request.name.clone, |
465 | instance: request.instance.as_ref .unwrap_or .clone, |
466 | ; |
467 | |
468 | stack |
469 | .write_setting |
470 | &repository, |
471 | Description, |
472 | |
473 | .await |
474 | .unwrap; |
475 | |
476 | stack |
477 | .write_setting |
478 | .await |
479 | .unwrap; |
480 | |
481 | stack |
482 | .write_setting |
483 | .await |
484 | .unwrap; |
485 | |
486 | Ok |
487 | |
488 | Err => |
489 | let err = FailedCreatingRepository; |
490 | error!; |
491 | |
492 | // Delete repository from database |
493 | self.delete_by_owner_user_name |
494 | .await?; |
495 | |
496 | // ??? |
497 | Err |
498 | |
499 | |
500 | |
501 | |
502 | async |
503 | &mut self, |
504 | requester: & , |
505 | repository: &Repository, |
506 | request: &RepositoryFileInspectRequest, |
507 | |
508 | let git = self |
509 | .open_repository_and_check_permissions |
510 | .await?; |
511 | |
512 | let tree_id = Self get_oid_from_reference?; |
513 | |
514 | // unwrap might be dangerous? |
515 | // Get the commit from the oid |
516 | let commit = git.find_commit .unwrap; |
517 | |
518 | // this is stupid |
519 | let rev = request.rev.clone .unwrap_or_else; |
520 | let mut current_path = rev.clone; |
521 | |
522 | // Get the commit tree |
523 | let git_tree = if let Some = &request.path |
524 | // Add it to our full path string |
525 | current_path.push_str; |
526 | // Get the specified path, return an error if it wasn't found. |
527 | let entry = match commit |
528 | .tree |
529 | .unwrap |
530 | .get_path |
531 | .map_err |
532 | |
533 | Ok => entry, |
534 | Err => return Err, |
535 | ; |
536 | // Turn the entry into a git tree |
537 | entry.to_object .unwrap .as_tree .unwrap .clone |
538 | else |
539 | commit.tree .unwrap |
540 | ; |
541 | |
542 | // Iterate over the git tree and collect it into our own tree types |
543 | let mut tree = git_tree |
544 | .iter |
545 | .map |
546 | let object_type = match entry.kind .unwrap |
547 | => Tree, | Tree
548 | => Blob, | Blob
549 | _ => unreachable!, |
550 | ; |
551 | let mut tree_entry = new |
552 | entry.id .to_string .as_str, |
553 | entry.name .unwrap, |
554 | object_type, |
555 | entry.filemode, |
556 | ; |
557 | |
558 | if request.extra_metadata |
559 | // Get the file size if It's a blob |
560 | let object = entry.to_object .unwrap; |
561 | if let Some = object.as_blob |
562 | tree_entry.size = Some; |
563 | |
564 | |
565 | // Get the path to the folder the file is in by removing the rev from current_path |
566 | let mut path = current_path.replace; |
567 | if path.starts_with |
568 | path.remove; |
569 | |
570 | |
571 | // Format it as the path + file name |
572 | let full_path = if path.is_empty |
573 | entry.name .unwrap .to_string |
574 | else |
575 | format! |
576 | ; |
577 | |
578 | // Get the last commit made to the entry |
579 | if let Ok = |
580 | get_last_commit_of_file |
581 | |
582 | tree_entry.last_commit = Some; |
583 | |
584 | |
585 | |
586 | tree_entry |
587 | |
588 | .; |
589 | |
590 | // Sort the tree alphabetically and with tree first |
591 | tree.sort_unstable_by_key; |
592 | tree.sort_unstable_by_key |
593 | Reverse |
594 | ; |
595 | |
596 | Ok |
597 | |
598 | |
599 | async |
600 | &mut self, |
601 | requester: & , |
602 | repository: &Repository, |
603 | request: &RepositoryFileFromIdRequest, |
604 | |
605 | let git = self |
606 | .open_repository_and_check_permissions |
607 | .await?; |
608 | |
609 | // Parse the passed object id |
610 | let oid = match from_str |
611 | Ok => oid, |
612 | Err => |
613 | return Err |
614 | |
615 | ; |
616 | |
617 | // Find the file and turn it into our own struct |
618 | let file = match git.find_blob |
619 | Ok => RepositoryFile |
620 | id: blob.id .to_string, |
621 | content: blob.content .to_vec, |
622 | binary: blob.is_binary, |
623 | size: blob.size, |
624 | , |
625 | Err => return Err, |
626 | ; |
627 | |
628 | Ok |
629 | |
630 | |
631 | async |
632 | &mut self, |
633 | requester: & , |
634 | repository: &Repository, |
635 | request: &RepositoryFileFromPathRequest, |
636 | |
637 | let git = self |
638 | .open_repository_and_check_permissions |
639 | .await?; |
640 | |
641 | let tree_id = Self get_oid_from_reference?; |
642 | |
643 | // unwrap might be dangerous? |
644 | // Get the commit from the oid |
645 | let commit = git.find_commit .unwrap; |
646 | |
647 | // this is stupid |
648 | let mut current_path = request.rev.clone .unwrap_or_else; |
649 | |
650 | // Add it to our full path string |
651 | current_path.push_str; |
652 | // Get the specified path, return an error if it wasn't found. |
653 | let entry = match commit |
654 | .tree |
655 | .unwrap |
656 | .get_path |
657 | .map_err |
658 | |
659 | Ok => entry, |
660 | Err => return Err, |
661 | ; |
662 | |
663 | // Find the file and turn it into our own struct |
664 | let file = match git.find_blob |
665 | Ok => RepositoryFile |
666 | id: blob.id .to_string, |
667 | content: blob.content .to_vec, |
668 | binary: blob.is_binary, |
669 | size: blob.size, |
670 | , |
671 | Err => |
672 | return Err |
673 | |
674 | ; |
675 | |
676 | Ok |
677 | |
678 | |
679 | async |
680 | &mut self, |
681 | requester: & , |
682 | repository: &Repository, |
683 | request: &RepositoryCommitFromIdRequest, |
684 | |
685 | let git = self |
686 | .open_repository_and_check_permissions |
687 | .await?; |
688 | |
689 | // Parse the passed object ids |
690 | let oid = from_str |
691 | .map_err?; |
692 | |
693 | // Get the commit from the oid |
694 | let commit = git |
695 | .find_commit |
696 | .map_err?; |
697 | |
698 | Ok |
699 | |
700 | |
701 | async |
702 | &mut self, |
703 | requester: & , |
704 | repository: &Repository, |
705 | request: &RepositoryLastCommitOfFileRequest, |
706 | |
707 | let git = self |
708 | .open_repository_and_check_permissions |
709 | .await?; |
710 | |
711 | // Parse the passed object ids |
712 | let oid = from_str |
713 | .map_err?; |
714 | |
715 | // Get the commit from the oid |
716 | let commit = git |
717 | .find_commit |
718 | .map_err?; |
719 | |
720 | // Find the last commit of the file |
721 | let commit = get_last_commit_of_file?; |
722 | |
723 | Ok |
724 | |
725 | |
726 | async |
727 | &mut self, |
728 | requester: & , |
729 | repository: &Repository, |
730 | request: &RepositoryStatisticsRequest, |
731 | |
732 | let git = self |
733 | .open_repository_and_check_permissions |
734 | .await?; |
735 | |
736 | let tree_id = Self get_oid_from_reference?; |
737 | |
738 | // unwrap might be dangerous? |
739 | // Get the commit from the oid |
740 | let commit = git.find_commit .unwrap; |
741 | |
742 | // Count the amount of branches and tags |
743 | let mut branches = 0; |
744 | let mut tags = 0; |
745 | if let Ok = git.references |
746 | for reference in references.flatten |
747 | if reference.is_branch |
748 | branches += 1; |
749 | else if reference.is_tag |
750 | tags += 1; |
751 | |
752 | |
753 | |
754 | |
755 | Ok |
756 | commits: get_total_commit_count?, |
757 | branches, |
758 | tags, |
759 | |
760 | |
761 | |
762 | async |
763 | &mut self, |
764 | requester: & , |
765 | repository: &Repository, |
766 | _request: &RepositoryBranchesRequest, |
767 | |
768 | let git = self |
769 | .open_repository_and_check_permissions |
770 | .await?; |
771 | |
772 | let mut branches = vec!; |
773 | |
774 | for branch in git.branches? |
775 | let branch = branch?; |
776 | |
777 | let Some = branch.0.name .ok .flatten else |
778 | continue; |
779 | ; |
780 | |
781 | // TODO: Non UTF-8? |
782 | let commit = |
783 | ok; | get_last_commit_in_rev .
784 | |
785 | // TODO: Implement stale with configurable age |
786 | let stale = false; |
787 | |
788 | branches.push |
789 | name: name.to_string, |
790 | stale, |
791 | last_commit: commit, |
792 | |
793 | |
794 | |
795 | Ok |
796 | |
797 | |
798 | async |
799 | &mut self, |
800 | requester: & , |
801 | repository: &Repository, |
802 | request: &RepositoryDiffRequest, |
803 | |
804 | let git = self |
805 | .open_repository_and_check_permissions |
806 | .await?; |
807 | |
808 | // Parse the passed object ids |
809 | let oid_old = from_str |
810 | .map_err?; |
811 | let oid_new = from_str |
812 | .map_err?; |
813 | |
814 | // Get the ids associates commits |
815 | let commit_old = git |
816 | .find_commit |
817 | .map_err?; |
818 | let commit_new = git |
819 | .find_commit |
820 | .map_err?; |
821 | |
822 | // Get the commit trees |
823 | let tree_old = commit_old |
824 | .tree |
825 | .map_err?; |
826 | let tree_new = commit_new |
827 | .tree |
828 | .map_err?; |
829 | |
830 | // Diff the two trees against each other |
831 | let diff = git |
832 | .diff_tree_to_tree |
833 | .map_err |
834 | FailedDiffing |
835 | ?; |
836 | |
837 | // Should be safe to unwrap? |
838 | let stats = diff.stats .unwrap; |
839 | let mut files: = vec!; |
840 | |
841 | diff.deltas .enumerate .for_each |
842 | // Parse the old file info from the delta |
843 | let old_file_info = match delta.old_file .exists |
844 | true => Some |
845 | id: delta.old_file .id .to_string, |
846 | path: delta |
847 | .old_file |
848 | .path |
849 | .unwrap |
850 | .to_str |
851 | .unwrap |
852 | .to_string, |
853 | size: delta.old_file .size, |
854 | binary: delta.old_file .is_binary, |
855 | , |
856 | false => None, |
857 | ; |
858 | // Parse the new file info from the delta |
859 | let new_file_info = match delta.new_file .exists |
860 | true => Some |
861 | id: delta.new_file .id .to_string, |
862 | path: delta |
863 | .new_file |
864 | .path |
865 | .unwrap |
866 | .to_str |
867 | .unwrap |
868 | .to_string, |
869 | size: delta.new_file .size, |
870 | binary: delta.new_file .is_binary, |
871 | , |
872 | false => None, |
873 | ; |
874 | |
875 | let mut chunks: = vec!; |
876 | if let Some = from_diff .ok .flatten |
877 | for chunk_num in 0..patch.num_hunks |
878 | if let Ok = patch.hunk |
879 | let mut lines: = vec!; |
880 | |
881 | for line_num in 0..chunk_num_lines |
882 | if let Ok = patch.line_in_hunk |
883 | if let Ok = String from_utf8 |
884 | lines.push |
885 | change_type: line.origin_value .into, |
886 | content: line_utf8, |
887 | old_line_num: line.old_lineno, |
888 | new_line_num: line.new_lineno, |
889 | ; |
890 | |
891 | |
892 | continue; |
893 | |
894 | |
895 | |
896 | chunks.push |
897 | header: String from_utf8 .ok, |
898 | old_start: chunk.old_start, |
899 | old_lines: chunk.old_lines, |
900 | new_start: chunk.new_start, |
901 | new_lines: chunk.new_lines, |
902 | lines, |
903 | ; |
904 | |
905 | |
906 | ; |
907 | |
908 | let file = RepositoryDiffFile |
909 | status: from, |
910 | old_file_info, |
911 | new_file_info, |
912 | chunks, |
913 | ; |
914 | |
915 | files.push; |
916 | ; |
917 | |
918 | Ok |
919 | new_commit: from, |
920 | files_changed: stats.files_changed, |
921 | insertions: stats.insertions, |
922 | deletions: stats.deletions, |
923 | files, |
924 | |
925 | |
926 | |
927 | async |
928 | &mut self, |
929 | requester: & , |
930 | repository: &Repository, |
931 | request: &RepositoryDiffPatchRequest, |
932 | |
933 | let git = self |
934 | .open_repository_and_check_permissions |
935 | .await?; |
936 | |
937 | // Parse the passed object ids |
938 | let oid_old = from_str |
939 | .map_err?; |
940 | let oid_new = from_str |
941 | .map_err?; |
942 | |
943 | // Get the ids associates commits |
944 | let commit_old = git |
945 | .find_commit |
946 | .map_err?; |
947 | let commit_new = git |
948 | .find_commit |
949 | .map_err?; |
950 | |
951 | // Get the commit trees |
952 | let tree_old = commit_old |
953 | .tree |
954 | .map_err?; |
955 | let tree_new = commit_new |
956 | .tree |
957 | .map_err?; |
958 | |
959 | // Diff the two trees against each other |
960 | let diff = git |
961 | .diff_tree_to_tree |
962 | .map_err |
963 | FailedDiffing |
964 | ?; |
965 | |
966 | // Print the entire patch |
967 | let mut patch = String new; |
968 | |
969 | diff.print |
970 | match line.origin |
971 | '+' | '-' | ' ' => patch.push, |
972 | _ => |
973 | |
974 | patch.push_str; |
975 | true |
976 | |
977 | .unwrap; |
978 | |
979 | Ok |
980 | |
981 | |
982 | async |
983 | &mut self, |
984 | requester: & , |
985 | repository: &Repository, |
986 | request: &RepositoryCommitBeforeRequest, |
987 | |
988 | let git = self |
989 | .open_repository_and_check_permissions |
990 | .await?; |
991 | |
992 | // Parse the passed object id |
993 | let oid = match from_str |
994 | Ok => oid, |
995 | Err => |
996 | return Err |
997 | |
998 | ; |
999 | |
1000 | // Find the commit using the parsed oid |
1001 | let commit = match git.find_commit |
1002 | Ok => commit, |
1003 | Err => return Err, |
1004 | ; |
1005 | |
1006 | // Get the first parent it has |
1007 | let parent = commit.parent; |
1008 | if let Ok = parent |
1009 | return Ok; |
1010 | else |
1011 | // TODO: See if can be done better |
1012 | // Walk through the repository commit graph starting at our current commit |
1013 | let mut revwalk = git.revwalk?; |
1014 | revwalk.set_sorting?; |
1015 | revwalk.push?; |
1016 | |
1017 | if let Some = revwalk.next |
1018 | // Find the commit using the parsed oid |
1019 | if let Ok = git.find_commit |
1020 | return Ok; |
1021 | |
1022 | |
1023 | |
1024 | Err |
1025 | |
1026 | |
1027 | |
1028 | |
1029 | |
1030 | |
1031 | &mut self, |
1032 | _requester: & , |
1033 | _request: &RepositoryIssuesCountRequest, |
1034 | |
1035 | todo! |
1036 | |
1037 | |
1038 | |
1039 | &mut self, |
1040 | _requester: & , |
1041 | _request: &RepositoryIssueLabelsRequest, |
1042 | |
1043 | todo! |
1044 | |
1045 | |
1046 | |
1047 | &mut self, |
1048 | _requester: & , |
1049 | _request: &RepositoryIssuesRequest, |
1050 | |
1051 | todo! |
1052 | |
1053 | |
1054 | |
1055 | |
1056 | |
1057 | |
1058 | pub repository: String, |
1059 | pub name: String, |
1060 | pub value: String, |
1061 | |
1062 |