1use git2::{Config as GitConfig, Error as GitError};
6use std::fs::{metadata, write};
7use std::io::Error as IoError;
8use std::path::{Path, PathBuf};
9
10pub const DEFAULT_GIT_BRANCH: &str = "main";
13
14pub const DEFAULT_GIT_CONFIG_PATH: &str = "lorry.gitconfig";
17
18pub const GIT_CONFIG_GLOBAL: &str = "GIT_CONFIG_GLOBAL";
21
22pub const GITLAB_OAUTH_USER: &str = "oauth2";
24
25#[derive(thiserror::Error, Debug)]
27pub enum Error {
28 #[error("Git Configuration Invalid: {0}")]
30 Git(#[from] GitError),
31
32 #[error("IO Failure: {0}")]
34 Io(#[from] IoError),
35}
36
37pub struct Config(pub PathBuf);
41
42impl Config {
43 #[tracing::instrument(skip_all, fields(git_cfg_path = self.0.to_str()))]
47 pub fn setup(
48 &self,
49 git_identity: (&str, &str),
50 n_threads: i64,
51 no_ssl_verify: bool,
52 http_version: Option<&str>,
53 ask_pass_program: &Path,
54 git_credentials_file: Option<&Path>,
55 ) -> Result<(), Error> {
56 if metadata(&self.0).is_err() {
57 write(&self.0, [])?;
58 }
59 let mut cfg = GitConfig::open(&self.0)?;
60 cfg.set_str("user.name", git_identity.0)?;
61 cfg.set_str("user.email", git_identity.1)?;
62
63 cfg.set_bool("gc.autodetach", false)?;
65
66 cfg.set_i64("pack.threads", n_threads)?;
68
69 cfg.set_bool("http.sslVerify", !no_ssl_verify)?;
71
72 if let Some(version) = http_version {
74 cfg.set_str("http.version", version)?;
75 }
76
77 cfg.set_str("http.extraHeader", crate::LORRY_VERSION_HEADER)?;
79
80 cfg.set_str("init.defaultBranch", DEFAULT_GIT_BRANCH)?;
82
83 cfg.set_str("credential.username", GITLAB_OAUTH_USER)?;
86
87 cfg.set_str("core.askPass", &ask_pass_program.to_string_lossy())?;
89
90 if let Some(gitcredentials_path) = git_credentials_file {
92 cfg.set_str(
93 "credential.helper",
94 &format!("store --file {}", gitcredentials_path.display()),
95 )?;
96 }
97
98 tracing::debug!("Initialized git config");
99 Ok(())
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106 use crate::git_config::Config as GitConfig;
107 use tempfile::tempdir;
108
109 #[test]
110 pub fn test_rawfile_init() {
111 let test_dir = tempdir().unwrap();
112 let git_config_path = test_dir.path().join("gitconfig");
113 let git_config = GitConfig(git_config_path);
114 git_config
115 .setup(
116 ("Lorry", "hello@example.org"),
117 1,
118 false,
119 Some("HTTP/1.1"),
120 Path::new("/dev/null"),
121 None,
122 )
123 .unwrap();
124 }
125}