Commit | Line | Data |
---|---|---|
41a6d859 CM |
1 | """Handles the Stacked GIT configuration files |
2 | """ | |
3 | ||
4 | __copyright__ = """ | |
5 | Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com> | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License version 2 as | |
9 | published by the Free Software Foundation. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program; if not, write to the Free Software | |
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | """ | |
20 | ||
c73e63b7 | 21 | import os, re |
170f576b | 22 | from stgit import basedir |
87c93eab | 23 | from stgit.exception import * |
f0de3f92 | 24 | from stgit.run import * |
41a6d859 | 25 | |
87c93eab | 26 | class GitConfigException(StgException): |
c73e63b7 YD |
27 | pass |
28 | ||
29 | class GitConfig: | |
30 | __defaults={ | |
d0329a77 CM |
31 | 'stgit.smtpserver': ['localhost:25'], |
32 | 'stgit.smtpdelay': ['5'], | |
33 | 'stgit.pullcmd': ['git pull'], | |
34 | 'stgit.fetchcmd': ['git fetch'], | |
35 | 'stgit.pull-policy': ['pull'], | |
36 | 'stgit.autoimerge': ['no'], | |
37 | 'stgit.keepoptimized': ['no'], | |
38 | 'stgit.shortnr': ['5'], | |
3ecc9c01 CM |
39 | 'stgit.pager': ['less'], |
40 | 'stgit.alias.add': ['git add'], | |
41 | 'stgit.alias.rm': ['git rm'], | |
42 | 'stgit.alias.mv': ['git mv'], | |
43 | 'stgit.alias.resolved': ['git add'] | |
c73e63b7 YD |
44 | } |
45 | ||
a264e49b ST |
46 | __cache = None |
47 | ||
48 | def load(self): | |
49 | """Load the whole configuration in __cache unless it has been | |
50 | done already.""" | |
51 | if self.__cache is not None: | |
52 | return | |
d0329a77 | 53 | self.__cache = self.__defaults |
a1c48461 CM |
54 | lines = Run('git', 'config', '--null', '--list' |
55 | ).discard_exitcode().raw_output() | |
a264e49b ST |
56 | for line in filter(None, lines.split('\0')): |
57 | key, value = line.split('\n', 1) | |
58 | self.__cache.setdefault(key, []).append(value) | |
9a4bf454 | 59 | |
c73e63b7 | 60 | def get(self, name): |
a264e49b | 61 | self.load() |
d0329a77 CM |
62 | try: |
63 | return self.__cache[name][-1] | |
64 | except KeyError: | |
65 | return None | |
c73e63b7 YD |
66 | |
67 | def getall(self, name): | |
a264e49b ST |
68 | self.load() |
69 | try: | |
9a4bf454 | 70 | return self.__cache[name] |
a264e49b ST |
71 | except KeyError: |
72 | return [] | |
c73e63b7 YD |
73 | |
74 | def getint(self, name): | |
75 | value = self.get(name) | |
e928a3ec KH |
76 | if value == None: |
77 | return None | |
78 | elif value.isdigit(): | |
c73e63b7 YD |
79 | return int(value) |
80 | else: | |
81 | raise GitConfigException, 'Value for "%s" is not an integer: "%s"' % (name, value) | |
82 | ||
3ecc9c01 CM |
83 | def getstartswith(self, name): |
84 | self.load() | |
85 | return ((n, v[-1]) for (n, v) in self.__cache.iteritems() | |
86 | if n.startswith(name)) | |
87 | ||
cb5be4c3 | 88 | def rename_section(self, from_name, to_name): |
f0de3f92 KH |
89 | """Rename a section in the config file. Silently do nothing if |
90 | the section doesn't exist.""" | |
cd885e08 | 91 | Run('git', 'config', '--rename-section', from_name, to_name |
a66b9072 | 92 | ).returns([0, 1, 128]).run() |
8591add9 | 93 | self.__cache.clear() |
cb5be4c3 | 94 | |
9a6bcbe2 KH |
95 | def remove_section(self, name): |
96 | """Remove a section in the config file. Silently do nothing if | |
97 | the section doesn't exist.""" | |
cd885e08 | 98 | Run('git', 'config', '--remove-section', name |
a66b9072 | 99 | ).returns([0, 1, 128]).discard_stderr().discard_output() |
9a6bcbe2 KH |
100 | self.__cache.clear() |
101 | ||
c73e63b7 | 102 | def set(self, name, value): |
cd885e08 | 103 | Run('git', 'config', name, value).run() |
8591add9 | 104 | self.__cache[name] = value |
c73e63b7 | 105 | |
0aee23c2 | 106 | def unset(self, name): |
641ec552 CP |
107 | Run('git', 'config', '--unset', name).run() |
108 | self.__cache[name] = [None] | |
0aee23c2 | 109 | |
c73e63b7 YD |
110 | def sections_matching(self, regexp): |
111 | """Takes a regexp with a single group, matches it against all | |
112 | config variables, and returns a list whose members are the | |
113 | group contents, for all variable names matching the regexp. | |
114 | """ | |
115 | result = [] | |
cd885e08 | 116 | for line in Run('git', 'config', '--get-regexp', '"^%s$"' % regexp |
f0de3f92 | 117 | ).returns([0, 1]).output_lines(): |
c73e63b7 YD |
118 | m = re.match('^%s ' % regexp, line) |
119 | if m: | |
120 | result.append(m.group(1)) | |
c73e63b7 | 121 | return result |
afddd62b CM |
122 | |
123 | def get_colorbool(self, name, stdout_is_tty): | |
124 | """Invoke 'git config --get-colorbool' and return the result.""" | |
125 | return Run('git', 'config', '--get-colorbool', name, | |
126 | stdout_is_tty).output_one_line() | |
c73e63b7 YD |
127 | |
128 | config=GitConfig() | |
abcc2620 | 129 | |
eee7283e CM |
130 | def config_setup(): |
131 | global config | |
132 | ||
afddd62b | 133 | os.environ.setdefault('PAGER', config.get('stgit.pager')) |
e6bca570 | 134 | os.environ.setdefault('LESS', '-FRSX') |
c73e63b7 | 135 | # FIXME: handle EDITOR the same way ? |
eee7283e CM |
136 | |
137 | class ConfigOption: | |
138 | """Delayed cached reading of a configuration option. | |
139 | """ | |
140 | def __init__(self, section, option): | |
141 | self.__section = section | |
142 | self.__option = option | |
143 | self.__value = None | |
144 | ||
145 | def __str__(self): | |
146 | if not self.__value: | |
c73e63b7 | 147 | self.__value = config.get(self.__section + '.' + self.__option) |
eee7283e | 148 | return self.__value |
d7fade4b CM |
149 | |
150 | ||
151 | # cached extensions | |
152 | __extensions = None | |
153 | ||
154 | def file_extensions(): | |
155 | """Returns a dictionary with the conflict file extensions | |
156 | """ | |
157 | global __extensions | |
158 | ||
159 | if not __extensions: | |
c73e63b7 | 160 | cfg_ext = config.get('stgit.extensions').split() |
d7fade4b CM |
161 | if len(cfg_ext) != 3: |
162 | raise CmdException, '"extensions" configuration error' | |
163 | ||
164 | __extensions = { 'ancestor': cfg_ext[0], | |
165 | 'current': cfg_ext[1], | |
166 | 'patched': cfg_ext[2] } | |
167 | ||
168 | return __extensions |