Skip to main content

tagit_diff/
lib.rs

1//! Implementation for the `tagit diff` command.
2
3use std::{io::Write, process::Command};
4
5use owo_colors::OwoColorize;
6use tagit_core::{Tagit, out};
7use tagit_workspace::{WorkspaceEntry, with_workspace_entries};
8
9/// List workspace members whose sources differ from the tag they declare.
10pub fn diff() -> anyhow::Result<()> {
11    with_workspace_entries(
12        false,
13        false,
14        |WorkspaceEntry {
15             version,
16             tag_prefix,
17             paths,
18             name,
19             ..
20         }| {
21            let tag = &*format!("{tag_prefix}{version}");
22            let no_diff = paths.is_empty()
23                || !Tagit::exists(tag)?
24                || Command::new("git")
25                    .arg("diff-index")
26                    .arg("--quiet")
27                    .arg(tag)
28                    .args(paths)
29                    .status()?
30                    .success();
31            if !no_diff {
32                out!("differs", "{}", name.purple());
33                let stdout = Command::new("git")
34                    .arg("--no-pager")
35                    .arg("diff")
36                    .arg("-U0")
37                    .arg(tag)
38                    .arg("--")
39                    .args(paths)
40                    .output()?
41                    .stdout;
42                std::io::stdout().write_all(&stdout)?;
43            }
44            Ok(())
45        },
46    )
47}