-
Notifications
You must be signed in to change notification settings - Fork 7
/
create_commit.rs
115 lines (109 loc) · 4.2 KB
/
create_commit.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use super::config::{config_get_bool, config_get_string, ConfigGetError};
use super::create_signed_commit::{create_signed_commit, CreateSignedCommitError};
use super::create_unsigned_commit::{create_unsigned_commit, CreateUnsignedCommitError};
use super::signers;
use git2;
use std::result::Result;
use std::str;
#[derive(Debug)]
pub enum CreateCommitError {
GetCommitGpgsignFailed(ConfigGetError),
GetGpgFormatFailed(ConfigGetError),
GetUserSigningKeyFailed(ConfigGetError),
CreateSignedCommitFailed(CreateSignedCommitError),
CreateUnsignedCommitFailed(CreateUnsignedCommitError),
UserSigningKeyNotFoundInGitConfig,
Unhandled(Box<dyn std::error::Error>),
}
pub fn create_commit(
repo: &'_ git2::Repository,
config: &'_ git2::Config,
dest_ref_name: &str,
author: &git2::Signature<'_>,
committer: &git2::Signature<'_>,
message: &str,
tree: &git2::Tree<'_>,
parents: &[&git2::Commit<'_>],
) -> Result<git2::Oid, CreateCommitError> {
let sign_commit_flag = config_get_bool(config, "commit.gpgsign")
.map_err(CreateCommitError::GetCommitGpgsignFailed)?
.unwrap_or(false);
if sign_commit_flag {
let gpg_format = config_get_string(config, "gpg.format")
.map_err(CreateCommitError::GetGpgFormatFailed)?
.unwrap_or(("openpgp").to_string());
// If program is specified for the desired format, use that program to sign the commit.
// Otherwise, fallback to the general program (legacy for opengpg).
let gpg_program_option = config_get_string(config, &format!("gpg.{}.program", gpg_format))
.and_then(|opt| {
opt.map_or_else(|| config_get_string(config, "gpg.program"), |v| Ok(Some(v)))
})
.map_err(|e| CreateCommitError::Unhandled(e.into()))?;
let signing_key_config = config_get_string(config, "user.signingkey")
.map_err(CreateCommitError::GetUserSigningKeyFailed)?
.ok_or(CreateCommitError::UserSigningKeyNotFoundInGitConfig)?;
match gpg_format.as_str() {
"openpgp" => create_signed_commit(
repo,
signers::gpg_signer(signing_key_config, gpg_program_option),
dest_ref_name,
author,
committer,
message,
tree,
parents,
)
.map_err(CreateCommitError::CreateSignedCommitFailed),
"ssh" => create_signed_commit(
repo,
signers::ssh_signer(signing_key_config, gpg_program_option),
dest_ref_name,
author,
committer,
message,
tree,
parents,
)
.map_err(CreateCommitError::CreateSignedCommitFailed),
"x509" => {
eprintln!("Warning: gps currently does NOT support x509 signatures. See issue #44 - https://github.com/uptech/git-ps-rs/issues");
eprintln!("The commit has been created unsigned!");
create_unsigned_commit(
repo,
dest_ref_name,
author,
committer,
message,
tree,
parents,
)
.map_err(CreateCommitError::CreateUnsignedCommitFailed)
}
_ => {
eprintln!("Warning: gps currently only supports GPG & SSH signatures. See issue #44 - https://github.com/uptech/git-ps-rs/issues");
eprintln!("The commit has been created unsigned!");
create_unsigned_commit(
repo,
dest_ref_name,
author,
committer,
message,
tree,
parents,
)
.map_err(CreateCommitError::CreateUnsignedCommitFailed)
}
}
} else {
create_unsigned_commit(
repo,
dest_ref_name,
author,
committer,
message,
tree,
parents,
)
.map_err(CreateCommitError::CreateUnsignedCommitFailed)
}
}