Skip to main content

git_proc/
commit.rs

1use std::ffi::OsStr;
2use std::path::Path;
3
4use crate::CommandError;
5
6/// Create a new `git commit` command builder.
7#[must_use]
8pub fn new() -> Commit<'static> {
9    Commit::new()
10}
11
12/// Builder for `git commit` command.
13///
14/// See `git commit --help` for full documentation.
15#[derive(Debug)]
16pub struct Commit<'a> {
17    repo_path: Option<&'a Path>,
18    message: Option<&'a str>,
19    author: Option<&'a str>,
20    date: Option<&'a str>,
21    allow_empty: bool,
22    allow_empty_message: bool,
23    porcelain: bool,
24    env_vars: Vec<(cmd_proc::EnvVariableName<'a>, &'a OsStr)>,
25}
26
27crate::impl_repo_path!(Commit);
28crate::impl_porcelain!(Commit);
29
30impl<'a> Commit<'a> {
31    #[must_use]
32    fn new() -> Self {
33        Self {
34            repo_path: None,
35            message: None,
36            author: None,
37            date: None,
38            allow_empty: false,
39            allow_empty_message: false,
40            porcelain: false,
41            env_vars: Vec::new(),
42        }
43    }
44
45    /// Set the commit message.
46    ///
47    /// Corresponds to `--message` or `-m`.
48    #[must_use]
49    pub fn message(mut self, message: &'a str) -> Self {
50        self.message = Some(message);
51        self
52    }
53
54    /// Set the commit author.
55    ///
56    /// Corresponds to `--author`. Format: `Name <email>`.
57    #[must_use]
58    pub fn author(mut self, author: &'a str) -> Self {
59        self.author = Some(author);
60        self
61    }
62
63    /// Set the author date.
64    ///
65    /// Corresponds to `--date`.
66    #[must_use]
67    pub fn date(mut self, date: &'a str) -> Self {
68        self.date = Some(date);
69        self
70    }
71
72    crate::flag_methods! {
73        /// Allow creating a commit with no changes.
74        ///
75        /// Corresponds to `--allow-empty`.
76        pub fn allow_empty / allow_empty_if, allow_empty, "Conditionally allow creating a commit with no changes."
77    }
78
79    crate::flag_methods! {
80        /// Allow creating a commit with an empty message.
81        ///
82        /// Corresponds to `--allow-empty-message`.
83        pub fn allow_empty_message / allow_empty_message_if, allow_empty_message, "Conditionally allow creating a commit with an empty message."
84    }
85
86    /// Set an environment variable for the command.
87    #[must_use]
88    pub fn env(mut self, key: cmd_proc::EnvVariableName<'a>, value: &'a OsStr) -> Self {
89        self.env_vars.push((key, value));
90        self
91    }
92
93    /// Execute the command and return the exit status.
94    pub async fn status(self) -> Result<(), CommandError> {
95        crate::Build::build(self).status().await
96    }
97}
98
99impl Default for Commit<'_> {
100    fn default() -> Self {
101        Self::new()
102    }
103}
104
105impl crate::Build for Commit<'_> {
106    fn build(self) -> cmd_proc::Command {
107        crate::base_command(self.repo_path)
108            .argument("commit")
109            .optional_option("--message", self.message)
110            .optional_option("--author", self.author)
111            .optional_option("--date", self.date)
112            .optional_flag(self.allow_empty, "--allow-empty")
113            .optional_flag(self.allow_empty_message, "--allow-empty-message")
114            .optional_flag(self.porcelain, "--porcelain")
115            .envs(self.env_vars)
116    }
117}
118
119#[cfg(feature = "test-utils")]
120impl Commit<'_> {
121    /// Compare the built command with another command using debug representation.
122    pub fn test_eq(&self, other: &cmd_proc::Command) {
123        let command = crate::Build::build(Self {
124            repo_path: self.repo_path,
125            message: self.message,
126            author: self.author,
127            date: self.date,
128            allow_empty: self.allow_empty,
129            allow_empty_message: self.allow_empty_message,
130            porcelain: self.porcelain,
131            env_vars: self.env_vars.clone(),
132        });
133        command.test_eq(other);
134    }
135}