Add ahead_behind comparison, filter and range to branches request.
parent: tbd commit: 3aca035
Showing 3 changed files with 67 insertions and 18 deletions
giterated-daemon/src/backend/git.rs
@@ -13,7 +13,7 @@ use giterated_models::repository::{ | ||
13 | 13 | RepositoryFileFromPathRequest, RepositoryFileInspectRequest, RepositoryIssue, |
14 | 14 | RepositoryIssueLabelsRequest, RepositoryIssuesCountRequest, RepositoryIssuesRequest, |
15 | 15 | RepositoryLastCommitOfFileRequest, RepositoryObjectType, RepositoryStatistics, |
16 | RepositoryStatisticsRequest, RepositoryTreeEntry, RepositoryVisibility, Visibility, | |
16 | RepositoryStatisticsRequest, RepositoryTreeEntry, RepositoryVisibility, Visibility, RepositoryBranchFilter, | |
17 | 17 | }; |
18 | 18 | |
19 | 19 | use giterated_models::user::User; |
@@ -771,33 +771,63 @@ impl RepositoryBackend for GitBackend { | ||
771 | 771 | &mut self, |
772 | 772 | requester: &Option<AuthenticatedUser>, |
773 | 773 | repository: &Repository, |
774 | _request: &RepositoryBranchesRequest, | |
774 | request: &RepositoryBranchesRequest, | |
775 | 775 | ) -> Result<Vec<RepositoryBranch>, Error> { |
776 | 776 | let git = self |
777 | 777 | .open_repository_and_check_permissions(&repository.owner, &repository.name, requester) |
778 | 778 | .await?; |
779 | 779 | |
780 | let mut branches = vec![]; | |
781 | ||
782 | for branch in git.branches(None)? { | |
783 | let branch = branch?; | |
780 | // Could be done better with the RepositoryBranchFilter::None check done beforehand. | |
781 | let mut filtered_branches = git.branches(None)?.filter_map(|branch| { | |
782 | let branch = branch.ok()?.0; | |
784 | 783 | |
785 | let Some(name) = branch.0.name().ok().flatten() else { | |
786 | continue; | |
784 | let Some(name) = branch.name().ok().flatten() else { | |
785 | return None; | |
787 | 786 | }; |
788 | 787 | |
789 | 788 | // TODO: Non UTF-8? |
790 | let commit = | |
791 | GitBackend::get_last_commit_in_rev(&git, branch.0.get().name().unwrap()).ok(); | |
789 | let Some(commit) = GitBackend::get_last_commit_in_rev(&git, branch.get().name().unwrap()).ok() else { | |
790 | return None; | |
791 | }; | |
792 | 792 | |
793 | 793 | // TODO: Implement stale with configurable age |
794 | 794 | let stale = false; |
795 | 795 | |
796 | branches.push(RepositoryBranch { | |
797 | name: name.to_string(), | |
798 | stale, | |
799 | last_commit: commit, | |
800 | }) | |
796 | // Filter based on if the branch is stale or not | |
797 | if request.filter != RepositoryBranchFilter::None { | |
798 | #[allow(clippy::if_same_then_else)] | |
799 | if stale && request.filter == RepositoryBranchFilter::Active { | |
800 | return None; | |
801 | } else if !stale && request.filter == RepositoryBranchFilter::Stale { | |
802 | return None; | |
803 | } | |
804 | } | |
805 | ||
806 | Some((name.to_string(), branch, stale, commit)) | |
807 | }).collect::<Vec<_>>(); | |
808 | ||
809 | // Sort the branches by commit date | |
810 | filtered_branches.sort_by(|(_, _, _, c1), (_, _, _, c2)| c2.time.cmp(&c1.time)); | |
811 | // Go to the requested position | |
812 | let mut filtered_branches = filtered_branches.iter().skip(request.range.0); | |
813 | ||
814 | let head = git.head()?; | |
815 | let mut branches = vec![]; | |
816 | ||
817 | // Iterate through the filtered branches using the passed range | |
818 | for _ in request.range.0..request.range.1 { | |
819 | let Some((name, branch, stale, commit)) = filtered_branches.next() else { | |
820 | break; | |
821 | }; | |
822 | ||
823 | // Get how many commits are ahead of and behind of the head | |
824 | let ahead_behind_head = if head.target().is_some() && branch.get().target().is_some() { | |
825 | git.graph_ahead_behind(branch.get().target().unwrap(), head.target().unwrap()).ok() | |
826 | } else { | |
827 | None | |
828 | }; | |
829 | ||
830 | branches.push(RepositoryBranch { name: name.to_string(), stale: *stale, last_commit: Some(commit.clone()), ahead_behind_head }) | |
801 | 831 | } |
802 | 832 | |
803 | 833 | Ok(branches) |
giterated-models/src/repository/mod.rs
@@ -163,6 +163,16 @@ pub struct RepositoryBranch { | ||
163 | 163 | pub stale: bool, |
164 | 164 | /// The last commit made to the branch |
165 | 165 | pub last_commit: Option<Commit>, |
166 | /// How many commits this branch is ahead or behind from the main branch | |
167 | pub ahead_behind_head: Option<(usize, usize)>, | |
168 | } | |
169 | ||
170 | /// Filter primarily used for branch requests | |
171 | #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] | |
172 | pub enum RepositoryBranchFilter { | |
173 | None, | |
174 | Active, | |
175 | Stale, | |
166 | 176 | } |
167 | 177 | |
168 | 178 | #[derive(Clone, Debug, Serialize, Deserialize)] |
giterated-models/src/repository/operations.rs
@@ -9,7 +9,7 @@ use crate::{ | ||
9 | 9 | |
10 | 10 | use super::{ |
11 | 11 | Commit, IssueLabel, Repository, RepositoryBranch, RepositoryDiff, RepositoryFile, |
12 | RepositoryIssue, RepositoryStatistics, RepositoryTreeEntry, RepositoryView, | |
12 | RepositoryIssue, RepositoryStatistics, RepositoryTreeEntry, RepositoryView, RepositoryBranchFilter, | |
13 | 13 | }; |
14 | 14 | |
15 | 15 | /// A request to get a repository's information. |
@@ -264,7 +264,10 @@ impl GiteratedOperation<Repository> for RepositoryStatisticsRequest { | ||
264 | 264 | /// - User Authorization |
265 | 265 | /// - Potential User permissions checks |
266 | 266 | #[derive(Clone, Debug, Serialize, Deserialize)] |
267 | pub struct RepositoryBranchesRequest; | |
267 | pub struct RepositoryBranchesRequest { | |
268 | pub filter: RepositoryBranchFilter, | |
269 | pub range: (usize, usize), | |
270 | } | |
268 | 271 | |
269 | 272 | impl GiteratedOperation<Repository> for RepositoryBranchesRequest { |
270 | 273 | type Success = Vec<RepositoryBranch>; |
@@ -392,9 +395,15 @@ impl<S: Clone + Send + Sync, B: ObjectBackend<S> + std::fmt::Debug> Object<'_, S | ||
392 | 395 | |
393 | 396 | pub async fn branches( |
394 | 397 | &mut self, |
398 | filter: RepositoryBranchFilter, | |
399 | range_start: usize, | |
400 | range_end: usize, | |
395 | 401 | operation_state: &S, |
396 | 402 | ) -> Result<Vec<RepositoryBranch>, OperationError<RepositoryError>> { |
397 | self.request::<RepositoryBranchesRequest>(RepositoryBranchesRequest, operation_state) | |
403 | self.request::<RepositoryBranchesRequest>(RepositoryBranchesRequest { | |
404 | filter, | |
405 | range: (range_start, range_end), | |
406 | }, operation_state) | |
398 | 407 | .await |
399 | 408 | } |
400 | 409 |