8 from cola
.decorators
import memoize
13 """Return a static GitConfig instance."""
17 def _appendifexists(category
, path
, result
):
19 mtime
= os
.stat(path
).st_mtime
20 result
.append((category
, path
, mtime
))
27 # Try /etc/gitconfig as a fallback for the system config
28 userconfig
= os
.path
.expanduser(os
.path
.join('~', '.gitconfig'))
29 _appendifexists('system', '/etc/gitconfig', data
)
30 _appendifexists('user', userconfig
, data
)
31 _appendifexists('repo', git
.instance().git_path('config'), data
)
35 class GitConfig(object):
36 """Encapsulate access to git-config values."""
39 self
.git
= git
.instance()
44 self
._cache
_key
= None
46 self
._config
_files
= {}
47 self
._find
_config
_files
()
54 self
._cache
_key
= None
56 self
._config
_files
= {}
57 self
._find
_config
_files
()
60 return copy
.deepcopy(self
._user
)
63 return copy
.deepcopy(self
._repo
)
66 return copy
.deepcopy(self
._all
)
68 def _find_config_files(self
):
70 Classify git config files into 'system', 'user', and 'repo'.
72 Populates self._configs with a list of the files in
73 reverse-precedence order. self._config_files is populated with
74 {category: path} where category is one of 'system', 'user', or 'repo'.
77 # Try the git config in git's installation prefix
78 statinfo
= _stat_info()
79 self
._configs
= map(lambda x
: x
[1], statinfo
)
80 self
._config
_files
= {}
81 for (cat
, path
, mtime
) in statinfo
:
82 self
._config
_files
[cat
] = path
85 """Read config values from git."""
92 Return True when the cache matches.
94 Updates the cache and returns False when the cache does not match.
97 cache_key
= _stat_info()
98 if not self
._cache
_key
or cache_key
!= self
._cache
_key
:
99 self
._cache
_key
= cache_key
103 def _read_configs(self
):
104 """Read git config value into the system, user and repo dicts."""
107 if 'system' in self
._config
_files
:
108 self
._system
= self
.read_config(self
._config
_files
['system'])
110 if 'user' in self
._config
_files
:
111 self
._user
= self
.read_config(self
._config
_files
['user'])
113 if 'repo' in self
._config
_files
:
114 self
._repo
= self
.read_config(self
._config
_files
['repo'])
117 for dct
in (self
._system
, self
._user
, self
._repo
):
118 self
._all
.update(dct
)
120 def read_config(self
, path
):
121 """Return git config data from a path as a dictionary."""
123 args
= ('--null', '--file', path
, '--list')
124 config_lines
= self
.git
.config(*args
).split('\0')
125 for line
in config_lines
:
127 k
, v
= line
.split('\n')
129 # the user has an invalid entry in their git config
136 if v
== 'true' or v
== 'false':
137 v
= bool(eval(v
.title()))
145 def get(self
, key
, default
=None):
146 """Return the string value for a config key."""
148 return self
._all
.get(key
, default
)
152 for key
, val
in self
._all
.items():
153 if fnmatch
.fnmatch(key
, pat
):
157 def get_encoding(self
, default
='utf-8'):
158 return self
.get('gui.encoding', default
=default
)
160 guitool_opts
= ('cmd', 'needsfile', 'noconsole', 'norescan', 'confirm',
161 'argprompt', 'revprompt', 'revunmerged', 'title', 'prompt')
163 def get_guitool_opts(self
, name
):
164 """Return the guitool.<name> namespace as a dict"""
165 keyprefix
= 'guitool.' + name
+ '.'
167 for cfg
in self
.guitool_opts
:
168 value
= self
.get(keyprefix
+ cfg
)
174 def get_guitool_names(self
):
176 guitools
= self
.find('guitool.*.cmd')
177 for name
, cmd
in guitools
.items():
178 name
= name
[len('guitool.'):-len('.cmd')]