20
20
defenc ,
21
21
force_text ,
22
22
with_metaclass ,
23
- PY3
23
+ PY3 ,
24
+ is_win ,
24
25
)
25
26
from git .util import LockFile
26
27
40
41
log = logging .getLogger ('git.config' )
41
42
log .addHandler (logging .NullHandler ())
42
43
44
+ # invariants
45
+ # represents the configuration level of a configuration file
46
+ CONFIG_LEVELS = ("system" , "user" , "global" , "repository" )
47
+
43
48
44
49
class MetaParserBuilder (abc .ABCMeta ):
45
50
@@ -191,6 +196,26 @@ def items_all(self):
191
196
return [(k , self .getall (k )) for k in self ]
192
197
193
198
199
+ def get_config_path (config_level ):
200
+
201
+ # we do not support an absolute path of the gitconfig on windows ,
202
+ # use the global config instead
203
+ if is_win and config_level == "system" :
204
+ config_level = "global"
205
+
206
+ if config_level == "system" :
207
+ return "/etc/gitconfig"
208
+ elif config_level == "user" :
209
+ config_home = os .environ .get ("XDG_CONFIG_HOME" ) or osp .join (os .environ .get ("HOME" , '~' ), ".config" )
210
+ return osp .normpath (osp .expanduser (osp .join (config_home , "git" , "config" )))
211
+ elif config_level == "global" :
212
+ return osp .normpath (osp .expanduser ("~/.gitconfig" ))
213
+ elif config_level == "repository" :
214
+ raise ValueError ("repository configuration level not allowed" )
215
+
216
+ ValueError ("Invalid configuration level: %r" % config_level )
217
+
218
+
194
219
class GitConfigParser (with_metaclass (MetaParserBuilder , cp .RawConfigParser , object )):
195
220
196
221
"""Implements specifics required to read git style configuration files.
@@ -229,7 +254,7 @@ class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser, obje
229
254
# list of RawConfigParser methods able to change the instance
230
255
_mutating_methods_ = ("add_section" , "remove_section" , "remove_option" , "set" )
231
256
232
- def __init__ (self , file_or_files , read_only = True , merge_includes = True ):
257
+ def __init__ (self , file_or_files = None , read_only = True , merge_includes = True , config_level = None ):
233
258
"""Initialize a configuration reader to read the given file_or_files and to
234
259
possibly allow changes to it by setting read_only False
235
260
@@ -251,7 +276,17 @@ def __init__(self, file_or_files, read_only=True, merge_includes=True):
251
276
if not hasattr (self , '_proxies' ):
252
277
self ._proxies = self ._dict ()
253
278
254
- self ._file_or_files = file_or_files
279
+ if file_or_files is not None :
280
+ self ._file_or_files = file_or_files
281
+ else :
282
+ if config_level is None :
283
+ if read_only :
284
+ self ._file_or_files = [get_config_path (f ) for f in CONFIG_LEVELS [:- 1 ]]
285
+ else :
286
+ raise ValueError ("No configuration level or configuration files specified" )
287
+ else :
288
+ self ._file_or_files = [get_config_path (config_level )]
289
+
255
290
self ._read_only = read_only
256
291
self ._dirty = False
257
292
self ._is_initialized = False
0 commit comments