@@ -4,6 +4,9 @@ use crate::{
4
4
config:: { cache:: util:: ApplyLeniency , Cache } ,
5
5
repository,
6
6
} ;
7
+ use git_config:: File ;
8
+ use git_sec:: Permission ;
9
+ use std:: borrow:: Cow ;
7
10
8
11
/// Initialization
9
12
impl Cache {
@@ -27,7 +30,7 @@ impl Cache {
27
30
home : home_env,
28
31
xdg_config_home : xdg_config_home_env,
29
32
ssh_prefix : _,
30
- http_transport : _ ,
33
+ http_transport,
31
34
} : repository:: permissions:: Environment ,
32
35
repository:: permissions:: Config {
33
36
git_binary : use_installation,
@@ -56,82 +59,82 @@ impl Cache {
56
59
..util:: base_options ( lossy)
57
60
} ;
58
61
59
- let config =
60
- {
61
- let home_env = & home_env;
62
- let xdg_config_home_env = & xdg_config_home_env;
63
- let git_prefix = & git_prefix;
64
- let metas = [
65
- git_config:: source:: Kind :: GitInstallation ,
66
- git_config:: source:: Kind :: System ,
67
- git_config:: source:: Kind :: Global ,
68
- ]
69
- . iter ( )
70
- . flat_map ( |kind| kind. sources ( ) )
71
- . filter_map ( |source| {
72
- match source {
73
- git_config:: Source :: GitInstallation if !use_installation => return None ,
74
- git_config:: Source :: System if !use_system => return None ,
75
- git_config:: Source :: Git if !use_git => return None ,
76
- git_config:: Source :: User if !use_user => return None ,
77
- _ => { }
78
- }
79
- source
80
- . storage_location ( & mut |name| {
81
- match name {
82
- git_ if git_. starts_with ( "GIT_" ) => Some ( git_prefix) ,
83
- "XDG_CONFIG_HOME" => Some ( xdg_config_home_env) ,
84
- "HOME" => Some ( home_env) ,
85
- _ => None ,
86
- }
87
- . and_then ( |perm| std:: env:: var_os ( name) . and_then ( |val| perm. check_opt ( val) ) )
88
- } )
89
- . map ( |p| ( source, p. into_owned ( ) ) )
90
- } )
91
- . map ( |( source, path) | git_config:: file:: Metadata {
92
- path : Some ( path) ,
93
- source : * source,
94
- level : 0 ,
95
- trust : git_sec:: Trust :: Full ,
96
- } ) ;
97
-
98
- let err_on_nonexisting_paths = false ;
99
- let mut globals = git_config:: File :: from_paths_metadata_buf (
100
- metas,
101
- & mut buf,
102
- err_on_nonexisting_paths,
103
- git_config:: file:: init:: Options {
104
- includes : git_config:: file:: includes:: Options :: no_follow ( ) ,
105
- ..options
106
- } ,
107
- )
108
- . map_err ( |err| match err {
109
- git_config:: file:: init:: from_paths:: Error :: Init ( err) => Error :: from ( err) ,
110
- git_config:: file:: init:: from_paths:: Error :: Io ( err) => err. into ( ) ,
111
- } ) ?
112
- . unwrap_or_default ( ) ;
113
-
114
- globals. append ( git_dir_config) ;
115
- globals. resolve_includes ( options) ?;
116
- if use_env {
117
- globals. append ( git_config:: File :: from_env ( options) ?. unwrap_or_default ( ) ) ;
118
- }
119
- if !cli_config_overrides. is_empty ( ) {
120
- crate :: config:: overrides:: append ( & mut globals, cli_config_overrides, git_config:: Source :: Cli )
121
- . map_err ( |err| Error :: ConfigOverrides {
122
- err,
123
- source : git_config:: Source :: Cli ,
124
- } ) ?;
62
+ let config = {
63
+ let home_env = & home_env;
64
+ let xdg_config_home_env = & xdg_config_home_env;
65
+ let git_prefix = & git_prefix;
66
+ let metas = [
67
+ git_config:: source:: Kind :: GitInstallation ,
68
+ git_config:: source:: Kind :: System ,
69
+ git_config:: source:: Kind :: Global ,
70
+ ]
71
+ . iter ( )
72
+ . flat_map ( |kind| kind. sources ( ) )
73
+ . filter_map ( |source| {
74
+ match source {
75
+ git_config:: Source :: GitInstallation if !use_installation => return None ,
76
+ git_config:: Source :: System if !use_system => return None ,
77
+ git_config:: Source :: Git if !use_git => return None ,
78
+ git_config:: Source :: User if !use_user => return None ,
79
+ _ => { }
125
80
}
126
- if !api_config_overrides. is_empty ( ) {
127
- crate :: config:: overrides:: append ( & mut globals, api_config_overrides, git_config:: Source :: Api )
128
- . map_err ( |err| Error :: ConfigOverrides {
129
- err,
130
- source : git_config:: Source :: Api ,
131
- } ) ?;
132
- }
133
- globals
134
- } ;
81
+ source
82
+ . storage_location ( & mut |name| {
83
+ match name {
84
+ git_ if git_. starts_with ( "GIT_" ) => Some ( git_prefix) ,
85
+ "XDG_CONFIG_HOME" => Some ( xdg_config_home_env) ,
86
+ "HOME" => Some ( home_env) ,
87
+ _ => None ,
88
+ }
89
+ . and_then ( |perm| std:: env:: var_os ( name) . and_then ( |val| perm. check_opt ( val) ) )
90
+ } )
91
+ . map ( |p| ( source, p. into_owned ( ) ) )
92
+ } )
93
+ . map ( |( source, path) | git_config:: file:: Metadata {
94
+ path : Some ( path) ,
95
+ source : * source,
96
+ level : 0 ,
97
+ trust : git_sec:: Trust :: Full ,
98
+ } ) ;
99
+
100
+ let err_on_nonexisting_paths = false ;
101
+ let mut globals = git_config:: File :: from_paths_metadata_buf (
102
+ metas,
103
+ & mut buf,
104
+ err_on_nonexisting_paths,
105
+ git_config:: file:: init:: Options {
106
+ includes : git_config:: file:: includes:: Options :: no_follow ( ) ,
107
+ ..options
108
+ } ,
109
+ )
110
+ . map_err ( |err| match err {
111
+ git_config:: file:: init:: from_paths:: Error :: Init ( err) => Error :: from ( err) ,
112
+ git_config:: file:: init:: from_paths:: Error :: Io ( err) => err. into ( ) ,
113
+ } ) ?
114
+ . unwrap_or_default ( ) ;
115
+
116
+ globals. append ( git_dir_config) ;
117
+ globals. resolve_includes ( options) ?;
118
+ if use_env {
119
+ globals. append ( git_config:: File :: from_env ( options) ?. unwrap_or_default ( ) ) ;
120
+ }
121
+ if !cli_config_overrides. is_empty ( ) {
122
+ crate :: config:: overrides:: append ( & mut globals, cli_config_overrides, git_config:: Source :: Cli , |_| None )
123
+ . map_err ( |err| Error :: ConfigOverrides {
124
+ err,
125
+ source : git_config:: Source :: Cli ,
126
+ } ) ?;
127
+ }
128
+ if !api_config_overrides. is_empty ( ) {
129
+ crate :: config:: overrides:: append ( & mut globals, api_config_overrides, git_config:: Source :: Api , |_| None )
130
+ . map_err ( |err| Error :: ConfigOverrides {
131
+ err,
132
+ source : git_config:: Source :: Api ,
133
+ } ) ?;
134
+ }
135
+ apply_environment_overrides ( & mut globals, * git_prefix, http_transport) ?;
136
+ globals
137
+ } ;
135
138
136
139
let hex_len = util:: parse_core_abbrev ( & config, object_hash) . with_leniency ( lenient_config) ?;
137
140
@@ -208,3 +211,96 @@ impl Cache {
208
211
Ok ( ( ) )
209
212
}
210
213
}
214
+
215
+ fn apply_environment_overrides (
216
+ config : & mut File < ' static > ,
217
+ git_prefix : Permission ,
218
+ http_transport : Permission ,
219
+ ) -> Result < ( ) , Error > {
220
+ fn var_as_bstring ( var : & str , perm : Permission ) -> Option < BString > {
221
+ perm. check_opt ( var)
222
+ . and_then ( std:: env:: var_os)
223
+ . and_then ( |val| git_path:: os_string_into_bstring ( val) . ok ( ) )
224
+ }
225
+
226
+ let mut env_override = git_config:: File :: new ( git_config:: file:: Metadata :: from ( git_config:: Source :: EnvOverride ) ) ;
227
+ {
228
+ let mut section = env_override
229
+ . new_section ( "http" , None )
230
+ . expect ( "statically known valid section name" ) ;
231
+ for ( var, key, permission) in [
232
+ ( "GIT_HTTP_LOW_SPEED_LIMIT" , "lowSpeedLimit" , git_prefix) ,
233
+ ( "GIT_HTTP_LOW_SPEED_TIME" , "lowSpeedTime" , git_prefix) ,
234
+ ( "GIT_HTTP_USER_AGENT" , "userAgent" , git_prefix) ,
235
+ ( "GIT_HTTP_PROXY_AUTHMETHOD" , "proxyAuthMethod" , git_prefix) ,
236
+ ( "all_proxy" , "all-proxy-lower" , http_transport) ,
237
+ ( "ALL_PROXY" , "all-proxy" , http_transport) ,
238
+ ] {
239
+ if let Some ( value) = var_as_bstring ( var, permission) {
240
+ section. push_with_comment (
241
+ key. try_into ( ) . expect ( "statically known to be valid" ) ,
242
+ Some ( value. as_ref ( ) ) ,
243
+ format ! ( "from {var}" ) . as_str ( ) ,
244
+ ) ;
245
+ }
246
+ }
247
+ if section. num_values ( ) == 0 {
248
+ let id = section. id ( ) ;
249
+ env_override. remove_section_by_id ( id) ;
250
+ }
251
+ }
252
+
253
+ {
254
+ let mut section = env_override
255
+ . new_section ( "gitoxide" , Some ( Cow :: Borrowed ( "https" . into ( ) ) ) )
256
+ . expect ( "statically known valid section name" ) ;
257
+
258
+ for ( var, key) in [ ( "HTTPS_PROXY" , "proxy" ) , ( "https_proxy" , "proxy" ) ] {
259
+ if let Some ( value) = var_as_bstring ( var, http_transport) {
260
+ section. push_with_comment (
261
+ key. try_into ( ) . expect ( "statically known to be valid" ) ,
262
+ Some ( value. as_ref ( ) ) ,
263
+ format ! ( "from {var}" ) . as_str ( ) ,
264
+ ) ;
265
+ }
266
+ }
267
+
268
+ if section. num_values ( ) == 0 {
269
+ let id = section. id ( ) ;
270
+ env_override. remove_section_by_id ( id) ;
271
+ }
272
+ }
273
+
274
+ {
275
+ let mut section = env_override
276
+ . new_section ( "gitoxide" , Some ( Cow :: Borrowed ( "http" . into ( ) ) ) )
277
+ . expect ( "statically known valid section name" ) ;
278
+
279
+ for ( var, key, permission) in [
280
+ ( "ALL_PROXY" , "allProxy" , http_transport) ,
281
+ ( "all_proxy" , "allProxy" , http_transport) ,
282
+ ( "NO_PROXY" , "noProxy" , http_transport) ,
283
+ ( "no_proxy" , "noProxy" , http_transport) ,
284
+ ( "http_proxy" , "proxy" , http_transport) ,
285
+ ( "GIT_CURL_VERBOSE" , "verbose" , git_prefix) ,
286
+ ] {
287
+ if let Some ( value) = var_as_bstring ( var, permission) {
288
+ section. push_with_comment (
289
+ key. try_into ( ) . expect ( "statically known to be valid" ) ,
290
+ Some ( value. as_ref ( ) ) ,
291
+ format ! ( "from {var}" ) . as_str ( ) ,
292
+ ) ;
293
+ }
294
+ }
295
+
296
+ if section. num_values ( ) == 0 {
297
+ let id = section. id ( ) ;
298
+ env_override. remove_section_by_id ( id) ;
299
+ }
300
+ }
301
+
302
+ if !env_override. is_void ( ) {
303
+ config. append ( env_override) ;
304
+ }
305
+ Ok ( ( ) )
306
+ }
0 commit comments