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

ambee/giterated

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

Simple branch staleness implementation

Emilia - ⁨1⁩ year ago

parent: tbd commit: ⁨efc3f02

Showing ⁨⁨5⁩ changed files⁩ with ⁨⁨63⁩ insertions⁩ and ⁨⁨14⁩ deletions⁩

giterated-daemon/src/backend/git.rs

View file
@@ -4,9 +4,10 @@ use async_trait::async_trait;
4 4 use git2::BranchType;
5 5 use giterated_models::instance::{Instance, RepositoryCreateRequest};
6 6
7 use giterated_models::object::Object;
7 8 use giterated_models::repository::{
8 AccessList, Commit, DefaultBranch, Description, IssueLabel, Repository, RepositoryBranch,
9 RepositoryBranchFilter, RepositoryBranchesRequest, RepositoryChunkLine,
9 AccessList, BranchStaleAfter, Commit, DefaultBranch, Description, IssueLabel, Repository,
10 RepositoryBranch, RepositoryBranchFilter, RepositoryBranchesRequest, RepositoryChunkLine,
10 11 RepositoryCommitBeforeRequest, RepositoryCommitFromIdRequest, RepositoryDiff,
11 12 RepositoryDiffFile, RepositoryDiffFileChunk, RepositoryDiffFileInfo, RepositoryDiffFileStatus,
12 13 RepositoryDiffPatchRequest, RepositoryDiffRequest, RepositoryFile, RepositoryFileFromIdRequest,
@@ -18,7 +19,7 @@ use giterated_models::repository::{
18 19
19 20 use giterated_models::user::User;
20 21
21 use giterated_stack::{AuthenticatedUser, GiteratedStack};
22 use giterated_stack::{AuthenticatedUser, GiteratedStack, OperationState, StackOperationState};
22 23
23 24 use sqlx::PgPool;
24 25 use std::ops::Deref;
@@ -397,7 +398,7 @@ impl GitBackend {
397 398 }
398 399 }
399 400
400 #[async_trait]
401 #[async_trait(?Send)]
401 402 impl RepositoryBackend for GitBackend {
402 403 async fn exists(
403 404 &mut self,
@@ -785,13 +786,22 @@ impl RepositoryBackend for GitBackend {
785 786 async fn repository_get_branches(
786 787 &mut self,
787 788 requester: &Option<AuthenticatedUser>,
788 repository: &Repository,
789 repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>,
790 OperationState(operation_state): OperationState<StackOperationState>,
789 791 request: &RepositoryBranchesRequest,
790 792 ) -> Result<(Vec<RepositoryBranch>, usize), Error> {
793 let repository: &Repository = repository_object.object();
791 794 let git = self
792 795 .open_repository_and_check_permissions(&repository.owner, &repository.name, requester)
793 796 .await?;
794 797
798 // Get the stale(after X seconds) setting
799 let stale_after = repository_object
800 .get::<BranchStaleAfter>(&operation_state)
801 .await
802 .unwrap_or_default()
803 .0;
804
795 805 // Could be done better with the RepositoryBranchFilter::None check done beforehand.
796 806 let mut filtered_branches = git
797 807 .branches(None)?
@@ -809,8 +819,12 @@ impl RepositoryBackend for GitBackend {
809 819 return None;
810 820 };
811 821
812 // TODO: Implement stale with configurable age
813 let stale = false;
822 let stale = !branch.is_head()
823 && chrono::Utc::now()
824 .naive_utc()
825 .signed_duration_since(commit.time)
826 .num_seconds()
827 > stale_after.into();
814 828
815 829 // Filter based on if the branch is stale or not
816 830 if request.filter != RepositoryBranchFilter::None {

giterated-daemon/src/backend/mod.rs

View file
@@ -6,7 +6,8 @@ pub mod user;
6 6
7 7 use anyhow::Error;
8 8 use async_trait::async_trait;
9 use giterated_stack::AuthenticatedUser;
9 use giterated_models::object::Object;
10 use giterated_stack::{AuthenticatedUser, GiteratedStack, OperationState, StackOperationState};
10 11 use serde_json::Value;
11 12
12 13 use crate::backend::git::GitBackendError;
@@ -28,7 +29,7 @@ use giterated_models::repository::{
28 29
29 30 use giterated_models::user::User;
30 31
31 #[async_trait]
32 #[async_trait(?Send)]
32 33 pub trait RepositoryBackend {
33 34 async fn create_repository(
34 35 &mut self,
@@ -92,7 +93,8 @@ pub trait RepositoryBackend {
92 93 async fn repository_get_branches(
93 94 &mut self,
94 95 requester: &Option<AuthenticatedUser>,
95 repository: &Repository,
96 repository_object: &mut Object<'_, StackOperationState, Repository, GiteratedStack>,
97 OperationState(operation_state): OperationState<StackOperationState>,
96 98 request: &RepositoryBranchesRequest,
97 99 ) -> Result<(Vec<RepositoryBranch>, usize), Error>;
98 100 async fn exists(

giterated-daemon/src/database_backend/handler.rs

View file
@@ -149,14 +149,19 @@ pub async fn repository_get_branches(
149 149 backend: GiteratedStack,
150 150 requester: Option<AuthenticatedUser>,
151 151 ) -> Result<(Vec<RepositoryBranch>, usize), OperationError<RepositoryError>> {
152 let object = backend
152 let mut object = backend
153 153 .get_object::<Repository>(&object.to_string(), &operation_state)
154 154 .await
155 155 .unwrap();
156 156
157 157 let mut repository_backend = state.repository_backend.lock().await;
158 158 let branches = repository_backend
159 .repository_get_branches(&requester, object.object(), &operation)
159 .repository_get_branches(
160 &requester,
161 &mut object,
162 OperationState(operation_state),
163 &operation,
164 )
160 165 .await
161 166 .as_internal_error()?;
162 167 drop(repository_backend);

giterated-daemon/src/database_backend/mod.rs

View file
@@ -8,7 +8,7 @@ use anyhow::Context;
8 8
9 9 use giterated_models::instance::Instance;
10 10 use giterated_models::repository::{
11 CommitBodyType, DefaultBranch, Description, Repository, Visibility,
11 BranchStaleAfter, CommitBodyType, DefaultBranch, Description, Repository, Visibility,
12 12 };
13 13 use giterated_models::user::{Bio, DisplayName, User};
14 14 use giterated_stack::provider::MetadataProvider;
@@ -76,7 +76,8 @@ impl DatabaseBackend {
76 76 .value_setting::<Repository, Description>()
77 77 .value_setting::<Repository, Visibility>()
78 78 .value_setting::<Repository, DefaultBranch>()
79 .value_setting::<Repository, CommitBodyType>();
79 .value_setting::<Repository, CommitBodyType>()
80 .value_setting::<Repository, BranchStaleAfter>();
80 81
81 82 // builder.value(repository_latest_commit);
82 83

giterated-models/src/repository/values.rs

View file
@@ -97,3 +97,30 @@ impl GiteratedObjectValue for CommitBodyType {
97 97 "commit_body_type"
98 98 }
99 99 }
100
101 /// This value determines after how long of a period of inactivity a branch is marked stale in seconds.
102 /// The default (as we have not implemented it via config) is about 3 months.
103 #[derive(Debug, Hash, Clone, PartialEq, Eq, Serialize, Deserialize)]
104 pub struct BranchStaleAfter(pub u32);
105
106 impl Default for BranchStaleAfter {
107 fn default() -> Self {
108 // TODO: Make default configurable using config
109 // This is about 3 months in seconds
110 Self(7889238)
111 }
112 }
113
114 impl GiteratedObjectValue for BranchStaleAfter {
115 type Object = Repository;
116
117 fn value_name() -> &'static str {
118 "branch_stale_after"
119 }
120 }
121
122 impl Setting for BranchStaleAfter {
123 fn name() -> &'static str {
124 "branch_stale_after"
125 }
126 }