Add info to RepositoryBranch, fix unwrap and reduce duplicate code
parent: tbd commit: b285b99
Showing 2 changed files with 87 insertions and 121 deletions
giterated-daemon/src/backend/git.rs
@@ -148,6 +148,8 @@ pub enum GitBackendError { | ||
148 | 148 | FailedOpeningFromDisk(git2::Error), |
149 | 149 | #[error("Couldn't find ref with name `{0}`")] |
150 | 150 | RefNotFound(String), |
151 | #[error("Couldn't find repository head")] | |
152 | HeadNotFound, | |
151 | 153 | #[error("Couldn't find path in repository `{0}`")] |
152 | 154 | PathNotFound(String), |
153 | 155 | #[error("Couldn't find commit for path `{0}`")] |
@@ -344,6 +346,74 @@ impl GitBackend { | ||
344 | 346 | |
345 | 347 | Ok(revwalk.count()) |
346 | 348 | } |
349 | ||
350 | pub fn get_oid_from_reference( | |
351 | git: &git2::Repository, | |
352 | rev: Option<&str>, | |
353 | ) -> anyhow::Result<git2::Oid> { | |
354 | // Try and parse the input as a reference and get the object ID | |
355 | let mut tree_id = match rev { | |
356 | None => { | |
357 | if let Ok(head) = git.head() { | |
358 | // TODO: Fix for symbolic references | |
359 | head.target() | |
360 | } else { | |
361 | // Nothing in database, render empty tree. | |
362 | return Err(GitBackendError::HeadNotFound.into()); | |
363 | } | |
364 | } | |
365 | Some(rev_name) => { | |
366 | // Find the reference, otherwise return GitBackendError | |
367 | git.refname_to_id(rev_name).ok() | |
368 | } | |
369 | }; | |
370 | ||
371 | // If the reference wasn't found, try parsing it as a commit ID | |
372 | if tree_id.is_none() { | |
373 | if let Ok(oid) = git2::Oid::from_str(rev.as_ref().unwrap()) { | |
374 | tree_id = Some(oid) | |
375 | } | |
376 | } | |
377 | ||
378 | // If the commit ID wasn't found, try parsing it as a branch and otherwise return error | |
379 | if tree_id.is_none() { | |
380 | match git.find_branch(rev.as_ref().unwrap(), BranchType::Local) { | |
381 | Ok(branch) => tree_id = branch.get().target(), | |
382 | Err(_) => { | |
383 | return Err(Box::new(GitBackendError::RefNotFound( | |
384 | rev.unwrap().to_string(), | |
385 | )) | |
386 | .into()) | |
387 | } | |
388 | } | |
389 | } | |
390 | ||
391 | // Should be safe? | |
392 | Ok(tree_id.unwrap()) | |
393 | } | |
394 | ||
395 | /// Gets the last commit in a rev | |
396 | pub fn get_last_commit_in_rev( | |
397 | git: &git2::Repository, | |
398 | rev: &str, | |
399 | ) -> anyhow::Result<Commit> { | |
400 | let oid = Self::get_oid_from_reference(git, Some(rev))?; | |
401 | ||
402 | // Walk through the repository commit graph starting at our rev | |
403 | let mut revwalk = git.revwalk()?; | |
404 | revwalk.set_sorting(git2::Sort::TIME)?; | |
405 | revwalk.push(oid)?; | |
406 | ||
407 | if let Some(commit_oid) = revwalk.next() { | |
408 | if let Ok(commit_oid) = commit_oid { | |
409 | if let Ok(commit) = git.find_commit(commit_oid).map_err(|_| GitBackendError::CommitNotFound(commit_oid.to_string())) { | |
410 | return Ok(Commit::from(commit)); | |
411 | } | |
412 | } | |
413 | } | |
414 | ||
415 | Err(GitBackendError::RefNotFound(oid.to_string()).into()) | |
416 | } | |
347 | 417 | } |
348 | 418 | |
349 | 419 | #[async_trait] |
@@ -524,46 +594,11 @@ impl RepositoryBackend for GitBackend { | ||
524 | 594 | .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) |
525 | 595 | .await?; |
526 | 596 | |
527 | // Try and parse the input as a reference and get the object ID | |
528 | let mut tree_id = match &request.rev { | |
529 | None => { | |
530 | if let Ok(head) = git.head() { | |
531 | // TODO: Fix for symbolic references | |
532 | head.target() | |
533 | } else { | |
534 | // Nothing in database, render empty tree. | |
535 | return Ok(vec![]); | |
536 | } | |
537 | } | |
538 | Some(rev_name) => { | |
539 | // Find the reference, otherwise return GitBackendError | |
540 | git.refname_to_id(rev_name).ok() | |
541 | } | |
542 | }; | |
543 | ||
544 | // If the reference wasn't found, try parsing it as a commit ID | |
545 | if tree_id.is_none() { | |
546 | if let Ok(oid) = git2::Oid::from_str(request.rev.as_ref().unwrap()) { | |
547 | tree_id = Some(oid) | |
548 | } | |
549 | } | |
550 | ||
551 | // If the commit ID wasn't found, try parsing it as a branch and otherwise return error | |
552 | if tree_id.is_none() { | |
553 | match git.find_branch(request.rev.as_ref().unwrap(), BranchType::Local) { | |
554 | Ok(branch) => tree_id = branch.get().target(), | |
555 | Err(_) => { | |
556 | return Err(Box::new(GitBackendError::RefNotFound( | |
557 | request.rev.clone().unwrap(), | |
558 | )) | |
559 | .into()) | |
560 | } | |
561 | } | |
562 | } | |
597 | let tree_id = Self::get_oid_from_reference(&git, request.rev.as_ref().map(|s| s.as_str()))?; | |
563 | 598 | |
564 | 599 | // unwrap might be dangerous? |
565 | 600 | // Get the commit from the oid |
566 | let commit = git.find_commit(tree_id.unwrap()).unwrap(); | |
601 | let commit = git.find_commit(tree_id).unwrap(); | |
567 | 602 | |
568 | 603 | // this is stupid |
569 | 604 | let mut current_path = request.rev.clone().unwrap_or_else(|| "master".to_string()); |
@@ -681,50 +716,11 @@ impl RepositoryBackend for GitBackend { | ||
681 | 716 | .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) |
682 | 717 | .await?; |
683 | 718 | |
684 | // TODO: Remove duplicate code with repository_file_inspect, most of it is duplicate. | |
685 | // Try and parse the input as a reference and get the object ID | |
686 | let mut tree_id = match &request.rev { | |
687 | None => { | |
688 | if let Ok(head) = git.head() { | |
689 | // TODO: Fix for symbolic references | |
690 | head.target() | |
691 | } else { | |
692 | // Nothing in database, render empty tree. | |
693 | return Err(Box::new(GitBackendError::RefNotFound( | |
694 | request.rev.clone().unwrap(), | |
695 | )) | |
696 | .into()); | |
697 | } | |
698 | } | |
699 | Some(rev_name) => { | |
700 | // Find the reference, otherwise return GitBackendError | |
701 | git.refname_to_id(rev_name).ok() | |
702 | } | |
703 | }; | |
704 | ||
705 | // If the reference wasn't found, try parsing it as a commit ID | |
706 | if tree_id.is_none() { | |
707 | if let Ok(oid) = git2::Oid::from_str(request.rev.as_ref().unwrap()) { | |
708 | tree_id = Some(oid) | |
709 | } | |
710 | } | |
711 | ||
712 | // If the commit ID wasn't found, try parsing it as a branch and otherwise return error | |
713 | if tree_id.is_none() { | |
714 | match git.find_branch(request.rev.as_ref().unwrap(), BranchType::Local) { | |
715 | Ok(branch) => tree_id = branch.get().target(), | |
716 | Err(_) => { | |
717 | return Err(Box::new(GitBackendError::RefNotFound( | |
718 | request.rev.clone().unwrap(), | |
719 | )) | |
720 | .into()) | |
721 | } | |
722 | } | |
723 | } | |
719 | let tree_id = Self::get_oid_from_reference(&git, request.rev.as_ref().map(|s| s.as_str()))?; | |
724 | 720 | |
725 | 721 | // unwrap might be dangerous? |
726 | 722 | // Get the commit from the oid |
727 | let commit = git.find_commit(tree_id.unwrap()).unwrap(); | |
723 | let commit = git.find_commit(tree_id).unwrap(); | |
728 | 724 | |
729 | 725 | // this is stupid |
730 | 726 | let mut current_path = request.rev.clone().unwrap_or_else(|| "master".to_string()); |
@@ -811,50 +807,11 @@ impl RepositoryBackend for GitBackend { | ||
811 | 807 | .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) |
812 | 808 | .await?; |
813 | 809 | |
814 | // TODO: Remove duplicate code with repository_file_inspect, most of it is duplicate. | |
815 | // Try and parse the input as a reference and get the object ID | |
816 | let mut tree_id = match &request.rev { | |
817 | None => { | |
818 | if let Ok(head) = git.head() { | |
819 | // TODO: Fix for symbolic references | |
820 | head.target() | |
821 | } else { | |
822 | // Nothing in database, render empty tree. | |
823 | return Err(Box::new(GitBackendError::RefNotFound( | |
824 | request.rev.clone().unwrap(), | |
825 | )) | |
826 | .into()); | |
827 | } | |
828 | } | |
829 | Some(rev_name) => { | |
830 | // Find the reference, otherwise return GitBackendError | |
831 | git.refname_to_id(rev_name).ok() | |
832 | } | |
833 | }; | |
834 | ||
835 | // If the reference wasn't found, try parsing it as a commit ID | |
836 | if tree_id.is_none() { | |
837 | if let Ok(oid) = git2::Oid::from_str(request.rev.as_ref().unwrap()) { | |
838 | tree_id = Some(oid) | |
839 | } | |
840 | } | |
841 | ||
842 | // If the commit ID wasn't found, try parsing it as a branch and otherwise return error | |
843 | if tree_id.is_none() { | |
844 | match git.find_branch(request.rev.as_ref().unwrap(), BranchType::Local) { | |
845 | Ok(branch) => tree_id = branch.get().target(), | |
846 | Err(_) => { | |
847 | return Err(Box::new(GitBackendError::RefNotFound( | |
848 | request.rev.clone().unwrap(), | |
849 | )) | |
850 | .into()) | |
851 | } | |
852 | } | |
853 | } | |
810 | let tree_id = Self::get_oid_from_reference(&git, request.rev.as_ref().map(|s| s.as_str()))?; | |
854 | 811 | |
855 | 812 | // unwrap might be dangerous? |
856 | 813 | // Get the commit from the oid |
857 | let commit = git.find_commit(tree_id.unwrap()).unwrap(); | |
814 | let commit = git.find_commit(tree_id).unwrap(); | |
858 | 815 | |
859 | 816 | // Count the amount of branches and tags |
860 | 817 | let mut branches = 0; |
@@ -888,7 +845,6 @@ impl RepositoryBackend for GitBackend { | ||
888 | 845 | |
889 | 846 | let mut branches = vec![]; |
890 | 847 | |
891 | // TODO: Add details like stale and such | |
892 | 848 | for branch in git.branches(None)? { |
893 | 849 | let branch = branch?; |
894 | 850 | |
@@ -896,7 +852,13 @@ impl RepositoryBackend for GitBackend { | ||
896 | 852 | continue; |
897 | 853 | }; |
898 | 854 | |
899 | branches.push(RepositoryBranch { name: name.to_string() }) | |
855 | // TODO: Non UTF-8? | |
856 | let commit = GitBackend::get_last_commit_in_rev(&git, branch.0.get().name().unwrap()).ok(); | |
857 | ||
858 | // TODO: Implement stale with configurable age | |
859 | let mut stale = false; | |
860 | ||
861 | branches.push(RepositoryBranch {name:name.to_string(), stale, last_commit: commit }) | |
900 | 862 | } |
901 | 863 | |
902 | 864 | Ok(branches) |
giterated-models/src/repository/mod.rs
@@ -155,6 +155,10 @@ pub struct RepositoryStatistics { | ||
155 | 155 | pub struct RepositoryBranch { |
156 | 156 | /// Full reference name |
157 | 157 | pub name: String, |
158 | /// Whether the repository is stale or not | |
159 | pub stale: bool, | |
160 | /// The last commit made to the branch | |
161 | pub last_commit: Option<Commit>, | |
158 | 162 | } |
159 | 163 | |
160 | 164 | #[derive(Clone, Debug, Serialize, Deserialize)] |