5 from cola
import gitcmd
10 """Return a static GitConfig instance."""
17 def _find_in_path(app
):
18 """Find a program in $PATH."""
19 is_win32
= sys
.platform
== 'win32'
20 for path
in os
.environ
.get('PATH', '').split(os
.pathsep
):
21 candidate
= os
.path
.join(path
, app
)
22 if os
.path
.exists(candidate
):
25 candidate
= os
.path
.join(path
, app
+ '.exe')
26 if os
.path
.exists(candidate
):
31 class GitConfig(object):
32 """Encapsulate access to git-config values."""
35 self
.git
= gitcmd
.instance()
39 self
._cache
_key
= None
42 self
._config
_files
= {}
43 self
._find
_config
_files
()
50 self
._config
_files
= {}
51 self
._find
_config
_files
()
53 def _find_config_files(self
):
55 Classify git config files into 'system', 'user', and 'repo'.
57 Populates self._configs with a list of the files in
58 reverse-precedence order. self._config_files is populated with
59 {category: path} where category is one of 'system', 'user', or 'repo'.
62 # Try the git config in git's installation prefix
63 git_path
= _find_in_path('git')
65 bin_dir
= os
.path
.dirname(git_path
)
66 prefix
= os
.path
.dirname(bin_dir
)
67 system_config
= os
.path
.join(prefix
, 'etc')
68 if os
.path
.exists(system_config
):
69 self
._config
_files
['system'] = system_config
70 self
._configs
.append(system_config
)
72 # Try /etc/gitconfig as a fallback for the system config
73 if 'system' not in self
._config
_files
:
74 system_config
= '/etc/gitconfig'
75 if os
.path
.exists(system_config
):
76 self
._config
_files
['system'] = system_config
77 self
._configs
.append(system_config
)
79 # Check for the user config
80 user_config
= os
.path
.expanduser('~/.gitconfig')
81 if os
.path
.exists(user_config
):
82 self
._config
_files
['user'] = user_config
83 self
._configs
.append(user_config
)
85 # Check for the repo config
86 repo_config
= self
.git
.git_path('config')
87 if os
.path
.exists(repo_config
):
88 self
._config
_files
['repo'] = repo_config
89 self
._configs
.append(repo_config
)
92 """Read config values from git."""
93 cache_key
= self
._get
_cache
_key
()
94 if cache_key
== self
._cache
_key
:
97 self
._cache
_key
= cache_key
99 def _get_cache_key(self
):
100 """Return a cache key used to avoiding re-reading git-config."""
101 return map(lambda x
: os
.stat(x
).st_mtime
, self
._configs
)
103 def _read_configs(self
):
108 if 'system' in self
._config
_files
:
109 self
._system
= self
.read_config(self
._config
_files
['system'])
111 if 'user' in self
._config
_files
:
112 self
._user
= self
.read_config(self
._config
_files
['user'])
114 if 'repo' in self
._config
_files
:
115 self
._repo
= self
.read_config(self
._config
_files
['repo'])
117 def read_config(self
, path
):
118 """Return git config data from a path as a dictionary."""
120 opts
= {'f': path
, 'z': True, 'list': True}
121 config_lines
= self
.git
.config(**opts
).split('\0')
122 for line
in config_lines
:
124 k
, v
= line
.split('\n')
126 # the user has an invalid entry in their git config
129 if v
== 'true' or v
== 'false':
130 v
= bool(eval(v
.title()))
138 def get(self
, key
, default
=None):
139 """Return the string value for a config key."""
141 for dct
in (self
._repo
, self
._user
, self
._system
):