use crate::command::{CommandExecutor, GitCommand};
use crate::error::Result;
use async_trait::async_trait;
#[derive(Debug, Clone, Default)]
pub struct DescribeCommand {
pub executor: CommandExecutor,
pub commits: Vec<String>,
pub tags: bool,
pub all: bool,
pub always: bool,
pub long: bool,
pub dirty: Option<Option<String>>,
pub abbrev: Option<u32>,
pub match_pattern: Option<String>,
pub exclude: Option<String>,
pub first_parent: bool,
}
impl DescribeCommand {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn commit(&mut self, c: impl Into<String>) -> &mut Self {
self.commits.push(c.into());
self
}
pub fn tags(&mut self) -> &mut Self {
self.tags = true;
self
}
pub fn all(&mut self) -> &mut Self {
self.all = true;
self
}
pub fn always(&mut self) -> &mut Self {
self.always = true;
self
}
pub fn long(&mut self) -> &mut Self {
self.long = true;
self
}
pub fn dirty(&mut self) -> &mut Self {
self.dirty = Some(None);
self
}
pub fn dirty_mark(&mut self, mark: impl Into<String>) -> &mut Self {
self.dirty = Some(Some(mark.into()));
self
}
pub fn abbrev(&mut self, n: u32) -> &mut Self {
self.abbrev = Some(n);
self
}
pub fn match_pattern(&mut self, p: impl Into<String>) -> &mut Self {
self.match_pattern = Some(p.into());
self
}
pub fn exclude(&mut self, p: impl Into<String>) -> &mut Self {
self.exclude = Some(p.into());
self
}
pub fn first_parent(&mut self) -> &mut Self {
self.first_parent = true;
self
}
}
#[async_trait]
impl GitCommand for DescribeCommand {
type Output = String;
fn get_executor(&self) -> &CommandExecutor {
&self.executor
}
fn get_executor_mut(&mut self) -> &mut CommandExecutor {
&mut self.executor
}
fn build_command_args(&self) -> Vec<String> {
let mut args = vec!["describe".to_string()];
if self.tags {
args.push("--tags".into());
}
if self.all {
args.push("--all".into());
}
if self.always {
args.push("--always".into());
}
if self.long {
args.push("--long".into());
}
if self.first_parent {
args.push("--first-parent".into());
}
match &self.dirty {
Some(None) => args.push("--dirty".into()),
Some(Some(mark)) => args.push(format!("--dirty={mark}")),
None => {}
}
if let Some(n) = self.abbrev {
args.push(format!("--abbrev={n}"));
}
if let Some(p) = &self.match_pattern {
args.push(format!("--match={p}"));
}
if let Some(p) = &self.exclude {
args.push(format!("--exclude={p}"));
}
args.extend(self.commits.iter().cloned());
args
}
async fn execute(&self) -> Result<String> {
let out = self.execute_raw().await?;
Ok(out.stdout_trimmed().to_string())
}
}