mirror of
https://github.com/jnsahaj/lumen.git
synced 2025-12-23 05:36:48 +00:00
128 lines
3.5 KiB
Rust
128 lines
3.5 KiB
Rust
use crate::error::LumenError;
|
|
use std::process::Command;
|
|
use thiserror::Error;
|
|
|
|
#[derive(Error, Debug, Clone)]
|
|
pub enum CommitError {
|
|
#[error("Commit '{0}' not found")]
|
|
InvalidCommit(String),
|
|
|
|
#[error("Diff for commit '{0}' is empty")]
|
|
EmptyDiff(String),
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct Commit {
|
|
pub full_hash: String,
|
|
pub message: String,
|
|
pub diff: String,
|
|
pub author_name: String,
|
|
pub author_email: String,
|
|
pub date: String,
|
|
}
|
|
|
|
impl Commit {
|
|
pub fn new(sha: String) -> Result<Self, LumenError> {
|
|
Self::is_valid_commit(&sha)?;
|
|
|
|
Ok(Commit {
|
|
full_hash: Self::get_full_hash(&sha)?,
|
|
message: Self::get_message(&sha)?,
|
|
diff: Self::get_diff(&sha)?,
|
|
author_name: Self::get_author_name(&sha)?,
|
|
author_email: Self::get_author_email(&sha)?,
|
|
date: Self::get_date(&sha)?,
|
|
})
|
|
}
|
|
|
|
pub fn is_valid_commit(sha: &str) -> Result<(), LumenError> {
|
|
let output = Command::new("git").args(["cat-file", "-t", sha]).output()?;
|
|
let output_str = String::from_utf8(output.stdout)?;
|
|
|
|
if output_str.trim() == "commit" {
|
|
return Ok(());
|
|
}
|
|
|
|
Err(CommitError::InvalidCommit(sha.to_string()).into())
|
|
}
|
|
|
|
fn get_full_hash(sha: &str) -> Result<String, LumenError> {
|
|
let output = Command::new("git").args(["rev-parse", sha]).output()?;
|
|
|
|
let mut full_hash = String::from_utf8(output.stdout)?;
|
|
full_hash.pop(); // Remove trailing newline
|
|
Ok(full_hash)
|
|
}
|
|
|
|
fn get_diff(sha: &str) -> Result<String, LumenError> {
|
|
let output = Command::new("git")
|
|
.args([
|
|
"diff-tree",
|
|
"-p",
|
|
"--binary",
|
|
"--no-color",
|
|
"--compact-summary",
|
|
sha,
|
|
])
|
|
.output()?;
|
|
|
|
let diff = String::from_utf8(output.stdout)?;
|
|
if diff.is_empty() {
|
|
return Err(CommitError::EmptyDiff(sha.to_string()).into());
|
|
}
|
|
|
|
Ok(diff)
|
|
}
|
|
|
|
fn get_message(sha: &str) -> Result<String, LumenError> {
|
|
let output = Command::new("git")
|
|
.args(["log", "--format=%B", "-n", "1", sha])
|
|
.output()?;
|
|
|
|
let mut message = String::from_utf8(output.stdout)?;
|
|
message.pop(); // Remove trailing newline
|
|
message.pop();
|
|
Ok(message)
|
|
}
|
|
|
|
fn get_author_name(sha: &str) -> Result<String, LumenError> {
|
|
let output = Command::new("git")
|
|
.args(["log", "--format=%an", "-n", "1", sha])
|
|
.output()?;
|
|
|
|
let mut name = String::from_utf8(output.stdout)?;
|
|
name.pop(); // Remove trailing newline
|
|
Ok(name)
|
|
}
|
|
|
|
fn get_author_email(sha: &str) -> Result<String, LumenError> {
|
|
let output = Command::new("git")
|
|
.args(["log", "--format=%ae", "-n", "1", sha])
|
|
.output()?;
|
|
|
|
let mut email = String::from_utf8(output.stdout)?;
|
|
email.pop(); // Remove trailing newline
|
|
Ok(email)
|
|
}
|
|
|
|
fn get_date(sha: &str) -> Result<String, LumenError> {
|
|
let output = Command::new("git")
|
|
.args([
|
|
"log",
|
|
"--format=%cd",
|
|
"--date=format:%Y-%m-%d %H:%M:%S",
|
|
"-n",
|
|
"1",
|
|
sha,
|
|
])
|
|
.output()?;
|
|
|
|
let mut date = String::from_utf8(output.stdout)?;
|
|
date.pop(); // Remove trailing newline
|
|
Ok(date)
|
|
}
|
|
|
|
pub fn to_string(&self) -> String {
|
|
self.full_hash.clone()
|
|
}
|
|
}
|