JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

Add info to RepositoryBranch, fix unwrap and reduce duplicate code

erremilia - ⁨2⁩ years ago

parent: tbd commit: ⁨b285b99

Showing ⁨⁨2⁩ changed files⁩ with ⁨⁨87⁩ insertions⁩ and ⁨⁨121⁩ deletions⁩

giterated-daemon/src/backend/git.rs

View file
@@ -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

View file
@@ -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)]