Add basic gitlog

This commit is contained in:
2022-11-06 16:08:01 +01:00
parent a449640ed5
commit 738f4a9add
6 changed files with 355 additions and 17 deletions

2
crates/gitlog_core/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/target
/Cargo.lock

View File

@@ -0,0 +1,12 @@
[package]
name = "gitlog_core"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
eyre = { workspace = true }
git2 = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }

View File

@@ -0,0 +1,78 @@
use git2::Repository;
use serde::Serialize;
#[allow(dead_code)]
#[derive(Debug, Serialize)]
struct CommitAuthor {
email: String,
name: String,
}
#[allow(dead_code)]
#[derive(Debug, Serialize)]
struct Commit {
title: String,
#[serde(skip_serializing_if = "Option::is_none")]
message: Option<String>,
author: CommitAuthor,
time: i64,
}
pub fn get_git_log(path: String) -> eyre::Result<String> {
let repo = Repository::open(path)?;
let mut revwalk = repo.revwalk()?;
revwalk.set_sorting(git2::Sort::TIME)?;
let revspec = repo.revparse("HEAD")?;
let from = revspec.from().ok_or(eyre::anyhow!("could not get HEAD"))?;
revwalk.push(from.id())?;
let mut commits: Vec<Commit> = Vec::new();
for rev in revwalk.enumerate() {
let oid = rev.1?;
let commit = repo.find_commit(oid)?;
let message = commit
.message()
.ok_or(eyre::anyhow!("could not find message from commit"))?;
let timestamp = commit.time();
let author = commit.author();
let message_content = message.split("\n");
let message_heading = message_content
.clone()
.take(1)
.collect::<Vec<&str>>()
.join("\n");
let message_content = message_content
.clone()
.skip(1)
.collect::<Vec<&str>>()
.join("\n");
let commit = Commit {
title: message_heading,
message: if message_content == "" {
None
} else {
Some(message_content)
},
author: CommitAuthor {
email: author
.email()
.ok_or(eyre::anyhow!("could not get authors email"))?
.to_string(),
name: author
.name()
.ok_or(eyre::anyhow!("could not get authors name"))?
.to_string(),
},
time: timestamp.seconds(),
};
commits.push(commit);
}
let commits_str = serde_json::to_string(&commits)?;
Ok(commits_str)
}