@@ -4,14 +4,16 @@ use anyhow::{bail, Context};
44use log:: { debug, trace} ;
55use serde:: Deserialize ;
66
7- use crate :: model:: protofetch:: Protocol ;
7+ use crate :: { git :: backend :: GitBackendType , model:: protofetch:: Protocol } ;
88
99#[ derive( Debug ) ]
1010pub struct ProtofetchConfig {
1111 pub cache_dir : PathBuf ,
1212 pub default_protocol : Protocol ,
1313 pub jobs : Option < usize > ,
1414 pub copy_jobs : Option < usize > ,
15+ pub git_backend : GitBackendType ,
16+ pub git_executable : Option < String > ,
1517}
1618
1719impl ProtofetchConfig {
@@ -27,6 +29,8 @@ impl ProtofetchConfig {
2729 default_protocol : resolve_default_protocol ( raw_config. git . protocol ) ?,
2830 jobs : raw_config. jobs ,
2931 copy_jobs : raw_config. copy_jobs ,
32+ git_backend : raw_config. git . backend . unwrap_or_default ( ) ,
33+ git_executable : raw_config. git . executable_path ,
3034 } ;
3135 trace ! ( "Loaded configuration: {:?}" , config) ;
3236
@@ -54,13 +58,15 @@ struct CacheConfig {
5458#[ derive( Default , Debug , Deserialize , PartialEq , Eq ) ]
5559struct GitConfig {
5660 protocol : Option < Protocol > ,
61+ backend : Option < GitBackendType > ,
62+ executable_path : Option < String > ,
5763}
5864
5965impl RawConfig {
6066 fn load (
6167 config_dir : Option < PathBuf > ,
6268 config_override : Option < toml:: Table > ,
63- env_override : Option < HashMap < String , String > > ,
69+ env_override : Option < HashMap < & str , & str > > ,
6470 ) -> anyhow:: Result < Self > {
6571 // Base config: override table (tests) takes priority; otherwise read
6672 // the optional config.toml file; fall back to defaults.
@@ -87,18 +93,19 @@ impl RawConfig {
8793 // the source so tests inject a HashMap and prod reads std::env.
8894 fn get < T > (
8995 key : & str ,
90- env_override : & Option < HashMap < String , String > > ,
96+ env_override : & Option < HashMap < & str , & str > > ,
9197 ) -> anyhow:: Result < Option < T > >
9298 where
9399 T : FromStr ,
94- T :: Err : std :: error :: Error + Send + Sync + ' static ,
100+ T :: Err : Into < anyhow :: Error > + Send + Sync + ' static ,
95101 {
96102 let raw = match env_override {
97- Some ( map) => map. get ( key) . cloned ( ) ,
103+ Some ( map) => map. get ( key) . copied ( ) . map ( ToOwned :: to_owned ) ,
98104 None => std:: env:: var ( key) . ok ( ) ,
99105 } ;
100106 raw. map ( |v| {
101107 v. parse ( )
108+ . map_err ( Into :: into)
102109 . with_context ( || format ! ( "invalid value for {key}" ) )
103110 } )
104111 . transpose ( )
@@ -110,6 +117,14 @@ impl RawConfig {
110117 if let Some ( protocol) = get :: < Protocol > ( "PROTOFETCH_GIT_PROTOCOL" , & env_override) ? {
111118 config. git . protocol = Some ( protocol) ;
112119 }
120+ if let Some ( backend) = get :: < GitBackendType > ( "PROTOFETCH_GIT_BACKEND" , & env_override) ? {
121+ config. git . backend = Some ( backend) ;
122+ }
123+ if let Some ( executable_path) =
124+ get :: < String > ( "PROTOFETCH_GIT_EXECUTABLE_PATH" , & env_override) ?
125+ {
126+ config. git . executable_path = Some ( executable_path) ;
127+ }
113128 if let Some ( jobs) = get :: < usize > ( "PROTOFETCH_JOBS" , & env_override) ? {
114129 config. jobs = Some ( jobs) ;
115130 }
@@ -199,7 +214,11 @@ mod tests {
199214 config,
200215 RawConfig {
201216 cache: CacheConfig { dir: None } ,
202- git: GitConfig { protocol: None } ,
217+ git: GitConfig {
218+ protocol: None ,
219+ backend: None ,
220+ executable_path: None ,
221+ } ,
203222 jobs: None ,
204223 copy_jobs: None ,
205224 }
@@ -209,11 +228,15 @@ mod tests {
209228 #[ test]
210229 fn load_environment ( ) {
211230 let env = HashMap :: from ( [
212- ( "PROTOFETCH_CACHE_DIR" . to_owned ( ) , "/cache" . to_owned ( ) ) ,
213- ( "PROTOFETCH_GIT_PROTOCOL" . to_owned ( ) , "ssh" . to_owned ( ) ) ,
214- ( "PROTOFETCH_JOBS" . to_owned ( ) , "16" . to_owned ( ) ) ,
215- ( "PROTOFETCH_COPY_JOBS" . to_owned ( ) , "4" . to_owned ( ) ) ,
231+ ( "PROTOFETCH_CACHE_DIR" , "/cache" ) ,
232+ ( "PROTOFETCH_GIT_PROTOCOL" , "ssh" ) ,
233+ ( "PROTOFETCH_GIT_BACKEND" , "cli" ) ,
234+ ( "PROTOFETCH_GIT_EXECUTABLE_PATH" , "/usr/bin/git" ) ,
235+ ( "PROTOFETCH_JOBS" , "16" ) ,
236+ ( "PROTOFETCH_COPY_JOBS" , "4" ) ,
216237 ] ) ;
238+ // Note: `git.executable_path` is a config-file-only setting; the
239+ // `Environment` source's `_` separator would split a two-word key.
217240 let config = RawConfig :: load ( None , Some ( Default :: default ( ) ) , Some ( env) ) . unwrap ( ) ;
218241 assert_eq ! (
219242 config,
@@ -222,7 +245,9 @@ mod tests {
222245 dir: Some ( "/cache" . into( ) )
223246 } ,
224247 git: GitConfig {
225- protocol: Some ( Protocol :: Ssh )
248+ protocol: Some ( Protocol :: Ssh ) ,
249+ backend: Some ( GitBackendType :: Cli ) ,
250+ executable_path: Some ( "/usr/bin/git" . to_owned( ) ) ,
226251 } ,
227252 jobs: Some ( 16 ) ,
228253 copy_jobs: Some ( 4 ) ,
@@ -241,6 +266,8 @@ mod tests {
241266
242267 [ git]
243268 protocol = "ssh"
269+ backend = "cli"
270+ executable_path = "/usr/bin/git"
244271 } ) ,
245272 Some ( env) ,
246273 )
@@ -252,7 +279,9 @@ mod tests {
252279 dir: Some ( "/cache" . into( ) )
253280 } ,
254281 git: GitConfig {
255- protocol: Some ( Protocol :: Ssh )
282+ protocol: Some ( Protocol :: Ssh ) ,
283+ backend: Some ( GitBackendType :: Cli ) ,
284+ executable_path: Some ( "/usr/bin/git" . to_owned( ) ) ,
256285 } ,
257286 jobs: None ,
258287 copy_jobs: None ,
0 commit comments