Skip to main content

git_spawn/command/
tag.rs

1//! `git tag` — create, list, delete, or verify tags.
2
3use crate::command::{CommandExecutor, CommandOutput, GitCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7/// Builder for `git tag`.
8#[derive(Debug, Clone, Default)]
9pub struct TagCommand {
10    /// Shared executor.
11    pub executor: CommandExecutor,
12    /// Tag name.
13    pub name: Option<String>,
14    /// Commit-ish to tag.
15    pub commit: Option<String>,
16    /// `-a` annotated.
17    pub annotated: bool,
18    /// `-m` message.
19    pub message: Option<String>,
20    /// `-s` signed.
21    pub signed: bool,
22    /// `-f` force.
23    pub force: bool,
24    /// `-d` delete.
25    pub delete: bool,
26    /// `-l` list mode.
27    pub list: bool,
28    /// Pattern filter (for list).
29    pub pattern: Option<String>,
30}
31
32impl TagCommand {
33    /// New `tag` command.
34    #[must_use]
35    pub fn new() -> Self {
36        Self::default()
37    }
38
39    /// Name.
40    pub fn name(&mut self, n: impl Into<String>) -> &mut Self {
41        self.name = Some(n.into());
42        self
43    }
44
45    /// Commit to tag.
46    pub fn commit(&mut self, c: impl Into<String>) -> &mut Self {
47        self.commit = Some(c.into());
48        self
49    }
50
51    /// Annotated.
52    pub fn annotated(&mut self) -> &mut Self {
53        self.annotated = true;
54        self
55    }
56
57    /// Tag message.
58    pub fn message(&mut self, m: impl Into<String>) -> &mut Self {
59        self.message = Some(m.into());
60        self.annotated = true;
61        self
62    }
63
64    /// GPG-sign.
65    pub fn signed(&mut self) -> &mut Self {
66        self.signed = true;
67        self
68    }
69
70    /// Force.
71    pub fn force(&mut self) -> &mut Self {
72        self.force = true;
73        self
74    }
75
76    /// Delete.
77    pub fn delete(&mut self) -> &mut Self {
78        self.delete = true;
79        self
80    }
81
82    /// List mode.
83    pub fn list(&mut self) -> &mut Self {
84        self.list = true;
85        self
86    }
87
88    /// List pattern.
89    pub fn pattern(&mut self, p: impl Into<String>) -> &mut Self {
90        self.pattern = Some(p.into());
91        self.list = true;
92        self
93    }
94}
95
96#[async_trait]
97impl GitCommand for TagCommand {
98    type Output = CommandOutput;
99    fn get_executor(&self) -> &CommandExecutor {
100        &self.executor
101    }
102    fn get_executor_mut(&mut self) -> &mut CommandExecutor {
103        &mut self.executor
104    }
105    fn build_command_args(&self) -> Vec<String> {
106        let mut args = vec!["tag".to_string()];
107        if self.delete {
108            args.push("-d".into());
109            if let Some(n) = &self.name {
110                args.push(n.clone());
111            }
112            return args;
113        }
114        if self.list {
115            args.push("-l".into());
116            if let Some(p) = &self.pattern {
117                args.push(p.clone());
118            }
119            return args;
120        }
121        if self.annotated {
122            args.push("-a".into());
123        }
124        if self.signed {
125            args.push("-s".into());
126        }
127        if self.force {
128            args.push("-f".into());
129        }
130        if let Some(m) = &self.message {
131            args.push("-m".into());
132            args.push(m.clone());
133        }
134        if let Some(n) = &self.name {
135            args.push(n.clone());
136        }
137        if let Some(c) = &self.commit {
138            args.push(c.clone());
139        }
140        args
141    }
142    async fn execute(&self) -> Result<CommandOutput> {
143        self.execute_raw().await
144    }
145}