git_spawn/command/
describe.rs1use crate::command::{CommandExecutor, GitCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone, Default)]
9pub struct DescribeCommand {
10 pub executor: CommandExecutor,
12 pub commits: Vec<String>,
14 pub tags: bool,
16 pub all: bool,
18 pub always: bool,
20 pub long: bool,
22 pub dirty: Option<Option<String>>,
24 pub abbrev: Option<u32>,
26 pub match_pattern: Option<String>,
28 pub exclude: Option<String>,
30 pub first_parent: bool,
32}
33
34impl DescribeCommand {
35 #[must_use]
37 pub fn new() -> Self {
38 Self::default()
39 }
40
41 pub fn commit(&mut self, c: impl Into<String>) -> &mut Self {
43 self.commits.push(c.into());
44 self
45 }
46
47 pub fn tags(&mut self) -> &mut Self {
49 self.tags = true;
50 self
51 }
52
53 pub fn all(&mut self) -> &mut Self {
55 self.all = true;
56 self
57 }
58
59 pub fn always(&mut self) -> &mut Self {
61 self.always = true;
62 self
63 }
64
65 pub fn long(&mut self) -> &mut Self {
67 self.long = true;
68 self
69 }
70
71 pub fn dirty(&mut self) -> &mut Self {
73 self.dirty = Some(None);
74 self
75 }
76
77 pub fn dirty_mark(&mut self, mark: impl Into<String>) -> &mut Self {
79 self.dirty = Some(Some(mark.into()));
80 self
81 }
82
83 pub fn abbrev(&mut self, n: u32) -> &mut Self {
85 self.abbrev = Some(n);
86 self
87 }
88
89 pub fn match_pattern(&mut self, p: impl Into<String>) -> &mut Self {
91 self.match_pattern = Some(p.into());
92 self
93 }
94
95 pub fn exclude(&mut self, p: impl Into<String>) -> &mut Self {
97 self.exclude = Some(p.into());
98 self
99 }
100
101 pub fn first_parent(&mut self) -> &mut Self {
103 self.first_parent = true;
104 self
105 }
106}
107
108#[async_trait]
109impl GitCommand for DescribeCommand {
110 type Output = String;
112
113 fn get_executor(&self) -> &CommandExecutor {
114 &self.executor
115 }
116
117 fn get_executor_mut(&mut self) -> &mut CommandExecutor {
118 &mut self.executor
119 }
120
121 fn build_command_args(&self) -> Vec<String> {
122 let mut args = vec!["describe".to_string()];
123 if self.tags {
124 args.push("--tags".into());
125 }
126 if self.all {
127 args.push("--all".into());
128 }
129 if self.always {
130 args.push("--always".into());
131 }
132 if self.long {
133 args.push("--long".into());
134 }
135 if self.first_parent {
136 args.push("--first-parent".into());
137 }
138 match &self.dirty {
139 Some(None) => args.push("--dirty".into()),
140 Some(Some(mark)) => args.push(format!("--dirty={mark}")),
141 None => {}
142 }
143 if let Some(n) = self.abbrev {
144 args.push(format!("--abbrev={n}"));
145 }
146 if let Some(p) = &self.match_pattern {
147 args.push(format!("--match={p}"));
148 }
149 if let Some(p) = &self.exclude {
150 args.push(format!("--exclude={p}"));
151 }
152 args.extend(self.commits.iter().cloned());
153 args
154 }
155
156 async fn execute(&self) -> Result<String> {
157 let out = self.execute_raw().await?;
158 Ok(out.stdout_trimmed().to_string())
159 }
160}