From f5d559158b0ce6e102f9a992f05dcb79d538c413 Mon Sep 17 00:00:00 2001 From: Sebastian Martinez Date: Wed, 27 Nov 2024 16:40:57 +0100 Subject: [PATCH] Add `list_commits` tauri command Returns all commits for a specific repo. Takes a `parent` argument as starting point for the git history. Uses the `head` field of the project payload if not provided. Instead of since and until timestamps uses cursor and take params to paginate the commit history. --- crates/radicle-tauri/src/commands/repo.rs | 11 ++++++ crates/radicle-tauri/src/lib.rs | 1 + crates/radicle-types/bindings/repo/Commit.ts | 10 ++++++ crates/radicle-types/src/repo.rs | 31 +++++++++++++++++ crates/radicle-types/src/traits/repo.rs | 35 ++++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 crates/radicle-types/bindings/repo/Commit.ts diff --git a/crates/radicle-tauri/src/commands/repo.rs b/crates/radicle-tauri/src/commands/repo.rs index c0312d838..9f4a56d1b 100644 --- a/crates/radicle-tauri/src/commands/repo.rs +++ b/crates/radicle-tauri/src/commands/repo.rs @@ -32,3 +32,14 @@ pub async fn diff_stats( ) -> Result { ctx.diff_stats(rid, base, head) } + +#[tauri::command] +pub async fn list_commits( + ctx: tauri::State<'_, AppState>, + rid: RepoId, + parent: Option, + skip: Option, + take: Option, +) -> Result>, Error> { + ctx.list_commits(rid, parent, skip, take) +} diff --git a/crates/radicle-tauri/src/lib.rs b/crates/radicle-tauri/src/lib.rs index 4427c3981..0eba2dba2 100644 --- a/crates/radicle-tauri/src/lib.rs +++ b/crates/radicle-tauri/src/lib.rs @@ -96,6 +96,7 @@ pub fn run() { repo::list_repos, repo::repo_by_id, repo::diff_stats, + repo::list_commits, diff::get_diff, cob::get_file_by_oid, cob::activity_by_id, diff --git a/crates/radicle-types/bindings/repo/Commit.ts b/crates/radicle-types/bindings/repo/Commit.ts new file mode 100644 index 000000000..f12788770 --- /dev/null +++ b/crates/radicle-types/bindings/repo/Commit.ts @@ -0,0 +1,10 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type Commit = { + id: string; + author: { name: string; email: string; time: number }; + committer: { name: string; email: string; time: number }; + message: string; + summary: string; + parents: Array; +}; diff --git a/crates/radicle-types/src/repo.rs b/crates/radicle-types/src/repo.rs index b65309a75..0df2eda26 100644 --- a/crates/radicle-types/src/repo.rs +++ b/crates/radicle-types/src/repo.rs @@ -1,5 +1,6 @@ use std::collections::BTreeSet; +use radicle_surf as surf; use serde::{Deserialize, Serialize}; use ts_rs::TS; @@ -112,3 +113,33 @@ pub struct ProjectPayloadMeta { #[ts(type = "number")] pub last_commit_timestamp: i64, } + +#[derive(Clone, Serialize, TS)] +#[serde(rename_all = "camelCase")] +#[ts(export)] +#[ts(export_to = "repo/")] +pub struct Commit { + #[ts(as = "String")] + pub id: git::Oid, + #[ts(type = "{ name: string; email: string; time: number; }")] + pub author: surf::Author, + #[ts(type = "{ name: string; email: string; time: number; }")] + pub committer: surf::Author, + pub message: String, + pub summary: String, + #[ts(as = "Vec")] + pub parents: Vec, +} + +impl From for Commit { + fn from(value: surf::Commit) -> Self { + Self { + id: value.id, + author: value.author, + committer: value.committer, + message: value.message, + summary: value.summary, + parents: value.parents, + } + } +} diff --git a/crates/radicle-types/src/traits/repo.rs b/crates/radicle-types/src/traits/repo.rs index 1128eb56e..350ef4177 100644 --- a/crates/radicle-types/src/traits/repo.rs +++ b/crates/radicle-types/src/traits/repo.rs @@ -157,4 +157,39 @@ pub trait Repo: Profile { Ok::<_, Error>(diff) } + + fn list_commits( + &self, + rid: identity::RepoId, + parent: Option, + skip: Option, + take: Option, + ) -> Result>, Error> { + let profile = self.profile(); + let cursor = skip.unwrap_or(0); + let take = take.unwrap_or(20); + let repo = profile.storage.repository(rid)?; + + let sha = match parent { + Some(commit) => commit, + None => repo.head()?.1.to_string(), + }; + + let repo = surf::Repository::open(repo.path())?; + let history = repo.history(&sha)?; + + let mut commits = history + .filter_map(|c| c.map(Into::into).ok()) + .skip(cursor) + .take(take + 1); // Take one extra item to check if there's more. + + let paginated_commits: Vec<_> = commits.by_ref().take(take).collect(); + let more = commits.next().is_some(); + + Ok::<_, Error>(cobs::PaginatedQuery { + cursor, + more, + content: paginated_commits.to_vec(), + }) + } }