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 |
41a6d859 | 23 | |
c73e63b7 YD |
24 | class GitConfigException(Exception): |
25 | pass | |
26 | ||
27 | class GitConfig: | |
28 | __defaults={ | |
29 | 'stgit.autoresolved': 'no', | |
30 | 'stgit.smtpserver': 'localhost:25', | |
31 | 'stgit.smtpdelay': '5', | |
7441f961 CM |
32 | 'stgit.pullcmd': 'git-pull', |
33 | 'stgit.pull-does-rebase': 'no', | |
c73e63b7 YD |
34 | 'stgit.merger': 'diff3 -L current -L ancestor -L patched -m -E ' \ |
35 | '"%(branch1)s" "%(ancestor)s" "%(branch2)s" > "%(output)s"', | |
36 | 'stgit.autoimerge': 'no', | |
37 | 'stgit.keeporig': 'yes', | |
38 | 'stgit.keepoptimized': 'no', | |
39 | 'stgit.extensions': '.ancestor .current .patched', | |
40 | 'stgit.shortnr': '5' | |
41 | } | |
42 | ||
9a4bf454 YD |
43 | __cache={} |
44 | ||
c73e63b7 YD |
45 | def __run(self, cmd, args=None): |
46 | """__run: runs cmd using spawnvp. | |
47 | ||
48 | Runs cmd using spawnvp. The shell is avoided so it won't mess up | |
49 | our arguments. If args is very large, the command is run multiple | |
50 | times; args is split xargs style: cmd is passed on each | |
51 | invocation. Unlike xargs, returns immediately if any non-zero | |
52 | return code is received. | |
53 | """ | |
54 | ||
55 | args_l=cmd.split() | |
56 | if args is None: | |
57 | args = [] | |
58 | for i in range(0, len(args)+1, 100): | |
59 | r=os.spawnvp(os.P_WAIT, args_l[0], args_l + args[i:min(i+100, len(args))]) | |
60 | if r: | |
61 | return r | |
62 | return 0 | |
63 | ||
64 | def get(self, name): | |
9a4bf454 YD |
65 | if self.__cache.has_key(name): |
66 | return self.__cache[name] | |
67 | ||
c73e63b7 YD |
68 | stream = os.popen('git repo-config --get %s' % name, 'r') |
69 | value = stream.readline().strip() | |
70 | stream.close() | |
71 | if len(value) > 0: | |
9a4bf454 | 72 | pass |
c73e63b7 | 73 | elif (self.__defaults.has_key(name)): |
9a4bf454 | 74 | value = self.__defaults[name] |
c73e63b7 | 75 | else: |
9a4bf454 YD |
76 | value = None |
77 | ||
78 | self.__cache[name] = value | |
79 | return value | |
c73e63b7 YD |
80 | |
81 | def getall(self, name): | |
9a4bf454 YD |
82 | if self.__cache.has_key(name): |
83 | return self.__cache[name] | |
84 | ||
c73e63b7 YD |
85 | stream = os.popen('git repo-config --get-all %s' % name, 'r') |
86 | values = [line.strip() for line in stream] | |
87 | stream.close() | |
9a4bf454 YD |
88 | |
89 | self.__cache[name] = values | |
c73e63b7 YD |
90 | return values |
91 | ||
92 | def getint(self, name): | |
93 | value = self.get(name) | |
94 | if value.isdigit(): | |
95 | return int(value) | |
96 | else: | |
97 | raise GitConfigException, 'Value for "%s" is not an integer: "%s"' % (name, value) | |
98 | ||
cb5be4c3 PR |
99 | def rename_section(self, from_name, to_name): |
100 | self.__run('git-repo-config --rename-section', [from_name, to_name]) | |
101 | ||
c73e63b7 YD |
102 | def set(self, name, value): |
103 | self.__run('git-repo-config', [name, value]) | |
104 | ||
105 | def sections_matching(self, regexp): | |
106 | """Takes a regexp with a single group, matches it against all | |
107 | config variables, and returns a list whose members are the | |
108 | group contents, for all variable names matching the regexp. | |
109 | """ | |
110 | result = [] | |
111 | stream = os.popen('git repo-config --get-regexp "^%s$"' % regexp, 'r') | |
112 | for line in stream: | |
113 | m = re.match('^%s ' % regexp, line) | |
114 | if m: | |
115 | result.append(m.group(1)) | |
116 | stream.close() | |
117 | return result | |
118 | ||
119 | config=GitConfig() | |
abcc2620 | 120 | |
eee7283e CM |
121 | def config_setup(): |
122 | global config | |
123 | ||
eee7283e | 124 | # Set the PAGER environment to the config value (if any) |
c73e63b7 YD |
125 | pager = config.get('stgit.pager') |
126 | if pager: | |
127 | os.environ['PAGER'] = pager | |
128 | # FIXME: handle EDITOR the same way ? | |
eee7283e CM |
129 | |
130 | class ConfigOption: | |
131 | """Delayed cached reading of a configuration option. | |
132 | """ | |
133 | def __init__(self, section, option): | |
134 | self.__section = section | |
135 | self.__option = option | |
136 | self.__value = None | |
137 | ||
138 | def __str__(self): | |
139 | if not self.__value: | |
c73e63b7 | 140 | self.__value = config.get(self.__section + '.' + self.__option) |
eee7283e | 141 | return self.__value |
d7fade4b CM |
142 | |
143 | ||
144 | # cached extensions | |
145 | __extensions = None | |
146 | ||
147 | def file_extensions(): | |
148 | """Returns a dictionary with the conflict file extensions | |
149 | """ | |
150 | global __extensions | |
151 | ||
152 | if not __extensions: | |
c73e63b7 | 153 | cfg_ext = config.get('stgit.extensions').split() |
d7fade4b CM |
154 | if len(cfg_ext) != 3: |
155 | raise CmdException, '"extensions" configuration error' | |
156 | ||
157 | __extensions = { 'ancestor': cfg_ext[0], | |
158 | 'current': cfg_ext[1], | |
159 | 'patched': cfg_ext[2] } | |
160 | ||
161 | return __extensions |