7 from cola
import gitcmd
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 _appendifexists('system', '/etc/gitconfig', data
)
29 _appendifexists('user', os
.path
.expanduser('~/.gitconfig'), data
)
30 _appendifexists('repo', gitcmd
.instance().git_path('config'), data
)
34 class GitConfig(object):
35 """Encapsulate access to git-config values."""
38 self
.git
= gitcmd
.instance()
43 self
._cache
_key
= None
45 self
._config
_files
= {}
46 self
._find
_config
_files
()
54 self
._config
_files
= {}
55 self
._find
_config
_files
()
58 return copy
.deepcopy(self
._user
)
61 return copy
.deepcopy(self
._repo
)
64 return copy
.deepcopy(self
._all
)
66 def _find_config_files(self
):
68 Classify git config files into 'system', 'user', and 'repo'.
70 Populates self._configs with a list of the files in
71 reverse-precedence order. self._config_files is populated with
72 {category: path} where category is one of 'system', 'user', or 'repo'.
75 # Try the git config in git's installation prefix
76 statinfo
= _stat_info()
77 self
._configs
= map(lambda x
: x
[1], statinfo
)
78 self
._config
_files
= {}
79 for (cat
, path
, mtime
) in statinfo
:
80 self
._config
_files
[cat
] = path
83 """Read config values from git."""
90 Return True when the cache matches.
92 Updates the cache and returns False when the cache does not match.
95 cache_key
= _stat_info()
96 if not self
._cache
_key
or cache_key
!= self
._cache
_key
:
97 self
._cache
_key
= cache_key
101 def _read_configs(self
):
102 """Read git config value into the system, user and repo dicts."""
105 if 'system' in self
._config
_files
:
106 self
._system
= self
.read_config(self
._config
_files
['system'])
108 if 'user' in self
._config
_files
:
109 self
._user
= self
.read_config(self
._config
_files
['user'])
111 if 'repo' in self
._config
_files
:
112 self
._repo
= self
.read_config(self
._config
_files
['repo'])
115 for dct
in (self
._system
, self
._user
, self
._repo
):
116 self
._all
.update(dct
)
118 def read_config(self
, path
):
119 """Return git config data from a path as a dictionary."""
121 args
= ('--null', '--file', path
, '--list')
122 config_lines
= self
.git
.config(*args
).split('\0')
123 for line
in config_lines
:
125 k
, v
= line
.split('\n')
127 # the user has an invalid entry in their git config
134 if v
== 'true' or v
== 'false':
135 v
= bool(eval(v
.title()))
143 def get(self
, key
, default
=None):
144 """Return the string value for a config key."""
146 return self
._all
.get(key
, default
)
150 for key
, val
in self
._all
.items():
151 if fnmatch
.fnmatch(key
, pat
):
155 def get_encoding(self
, default
='utf-8'):
156 return self
.get('gui.encoding', default
=default
)
158 guitool_opts
= ('cmd', 'needsfile', 'noconsole', 'norescan', 'confirm',
159 'argprompt', 'revprompt', 'revunmerged', 'title', 'prompt')
161 def get_guitool_opts(self
, name
):
162 """Return the guitool.<name> namespace as a dict"""
163 keyprefix
= 'guitool.' + name
+ '.'
165 for cfg
in self
.guitool_opts
:
166 value
= self
.get(keyprefix
+ cfg
)
172 def get_guitool_names(self
):
174 guitools
= self
.find('guitool.*.cmd')
175 for name
, cmd
in guitools
.items():
176 name
= name
[len('guitool.'):-len('.cmd')]