os_checker_plugin_cargo/repo/
git_info.rs

1use plugin::prelude::{cmd, duct, Result, Timestamp, Utf8Path};
2use serde::{Deserialize, Serialize};
3
4#[derive(Clone, Debug, Serialize, Deserialize)]
5pub struct GitInfo {
6    pub last_commit: Timestamp,
7    pub sha: String,
8    pub branch: String,
9}
10
11impl GitInfo {
12    pub fn new(root: &Utf8Path) -> Result<Self> {
13        let last_commit = last_commit_time(root)?;
14        let sha = head_sha(root)?;
15        let branch = current_branch(root)?;
16        Ok(Self {
17            last_commit,
18            sha,
19            branch,
20        })
21    }
22}
23
24fn run(expr: duct::Expression, root: &Utf8Path) -> Result<String> {
25    Ok(expr.dir(root).read()?.trim().to_owned())
26}
27
28fn last_commit_time(root: &Utf8Path) -> Result<Timestamp> {
29    let cmd = cmd!("git", "log", "-1", "--pretty=format:%ct");
30    // git log -1 --format="%ct"
31    let unix_timestamp = run(cmd, root)?.parse()?;
32    Ok(Timestamp::from_second(unix_timestamp)?)
33}
34
35fn head_sha(root: &Utf8Path) -> Result<String> {
36    // git rev-parse HEAD
37    run(cmd!("git", "rev-parse", "HEAD"), root)
38}
39
40fn current_branch(root: &Utf8Path) -> Result<String> {
41    // git branch --show-current
42    run(cmd!("git", "branch", "--show-current"), root)
43}
44
45#[test]
46fn git_info() -> Result<()> {
47    let root = ".".into();
48    dbg!(GitInfo::new(root)?);
49    Ok(())
50}