Files
start-os/core/src/s9pk/git_hash.rs
2026-01-05 11:20:24 -07:00

94 lines
2.2 KiB
Rust

use std::ops::Deref;
use std::path::Path;
use tokio::process::Command;
use ts_rs::TS;
use crate::prelude::*;
use crate::util::Invoke;
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, TS, PartialEq, Eq)]
#[ts(type = "string")]
pub struct GitHash(String);
impl GitHash {
pub async fn from_path(path: impl AsRef<Path>) -> Result<GitHash, Error> {
let mut hash = String::from_utf8(
Command::new("git")
.arg("rev-parse")
.arg("HEAD")
.current_dir(&path)
.invoke(ErrorKind::Git)
.await?,
)?;
while hash.ends_with(|c: char| c.is_whitespace()) {
hash.pop();
}
if Command::new("git")
.arg("diff-index")
.arg("--quiet")
.arg("HEAD")
.arg("--")
.invoke(ErrorKind::Git)
.await
.is_err()
{
hash += "-modified";
}
Ok(GitHash(hash))
}
pub fn load_sync() -> Option<GitHash> {
let mut hash = String::from_utf8(
std::process::Command::new("git")
.arg("rev-parse")
.arg("HEAD")
.output()
.ok()?
.stdout,
)
.ok()?;
while hash.ends_with(|c: char| c.is_whitespace()) {
hash.pop();
}
if !std::process::Command::new("git")
.arg("diff-index")
.arg("--quiet")
.arg("HEAD")
.arg("--")
.output()
.ok()?
.status
.success()
{
hash += "-modified";
}
Some(GitHash(hash))
}
}
impl AsRef<str> for GitHash {
fn as_ref(&self) -> &str {
&self.0
}
}
impl Deref for GitHash {
type Target = str;
fn deref(&self) -> &Self::Target {
self.as_ref()
}
}
// #[tokio::test]
// async fn test_githash_for_current() {
// let answer: GitHash = GitHash::from_path(std::env::current_dir().unwrap())
// .await
// .unwrap();
// let answer_str: &str = answer.as_ref();
// assert!(
// !answer_str.is_empty(),
// "Should have a hash for this current working"
// );
// }