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
()
55 self
._config
_files
= {}
56 self
._find
_config
_files
()
59 return copy
.deepcopy(self
._user
)
62 return copy
.deepcopy(self
._repo
)
65 return copy
.deepcopy(self
._all
)
67 def _find_config_files(self
):
69 Classify git config files into 'system', 'user', and 'repo'.
71 Populates self._configs with a list of the files in
72 reverse-precedence order. self._config_files is populated with
73 {category: path} where category is one of 'system', 'user', or 'repo'.
76 # Try the git config in git's installation prefix
77 statinfo
= _stat_info()
78 self
._configs
= map(lambda x
: x
[1], statinfo
)
79 self
._config
_files
= {}
80 for (cat
, path
, mtime
) in statinfo
:
81 self
._config
_files
[cat
] = path
84 """Read config values from git."""
91 Return True when the cache matches.
93 Updates the cache and returns False when the cache does not match.
96 cache_key
= _stat_info()
97 if not self
._cache
_key
or cache_key
!= self
._cache
_key
:
98 self
._cache
_key
= cache_key
102 def _read_configs(self
):
103 """Read git config value into the system, user and repo dicts."""
106 if 'system' in self
._config
_files
:
107 self
._system
= self
.read_config(self
._config
_files
['system'])
109 if 'user' in self
._config
_files
:
110 self
._user
= self
.read_config(self
._config
_files
['user'])
112 if 'repo' in self
._config
_files
:
113 self
._repo
= self
.read_config(self
._config
_files
['repo'])
116 for dct
in (self
._system
, self
._user
, self
._repo
):
117 self
._all
.update(dct
)
119 def read_config(self
, path
):
120 """Return git config data from a path as a dictionary."""
122 args
= ('--null', '--file', path
, '--list')
123 config_lines
= self
.git
.config(*args
).split('\0')
124 for line
in config_lines
:
126 k
, v
= line
.split('\n')
128 # the user has an invalid entry in their git config
135 if v
== 'true' or v
== 'false':
136 v
= bool(eval(v
.title()))
144 def get(self
, key
, default
=None):
145 """Return the string value for a config key."""
147 return self
._all
.get(key
, default
)
151 for key
, val
in self
._all
.items():
152 if fnmatch
.fnmatch(key
, pat
):
156 def get_encoding(self
, default
='utf-8'):
157 return self
.get('gui.encoding', default
=default
)
159 guitool_opts
= ('cmd', 'needsfile', 'noconsole', 'norescan', 'confirm',
160 'argprompt', 'revprompt', 'revunmerged', 'title', 'prompt')
162 def get_guitool_opts(self
, name
):
163 """Return the guitool.<name> namespace as a dict"""
164 keyprefix
= 'guitool.' + name
+ '.'
166 for cfg
in self
.guitool_opts
:
167 value
= self
.get(keyprefix
+ cfg
)
173 def get_guitool_names(self
):
175 guitools
= self
.find('guitool.*.cmd')
176 for name
, cmd
in guitools
.items():
177 name
= name
[len('guitool.'):-len('.cmd')]