Add caching to the new config class.
[stgit] / stgit / config.py
CommitLineData
41a6d859
CM
1"""Handles the Stacked GIT configuration files
2"""
3
4__copyright__ = """
5Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License version 2 as
9published by the Free Software Foundation.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19"""
20
c73e63b7 21import os, re
170f576b 22from stgit import basedir
41a6d859 23
c73e63b7
YD
24class GitConfigException(Exception):
25 pass
26
27class GitConfig:
28 __defaults={
29 'stgit.autoresolved': 'no',
30 'stgit.smtpserver': 'localhost:25',
31 'stgit.smtpdelay': '5',
32 'stgit.pullcmd': 'git-pull',
33 'stgit.merger': 'diff3 -L current -L ancestor -L patched -m -E ' \
34 '"%(branch1)s" "%(ancestor)s" "%(branch2)s" > "%(output)s"',
35 'stgit.autoimerge': 'no',
36 'stgit.keeporig': 'yes',
37 'stgit.keepoptimized': 'no',
38 'stgit.extensions': '.ancestor .current .patched',
39 'stgit.shortnr': '5'
40 }
41
9a4bf454
YD
42 __cache={}
43
c73e63b7
YD
44 def __run(self, cmd, args=None):
45 """__run: runs cmd using spawnvp.
46
47 Runs cmd using spawnvp. The shell is avoided so it won't mess up
48 our arguments. If args is very large, the command is run multiple
49 times; args is split xargs style: cmd is passed on each
50 invocation. Unlike xargs, returns immediately if any non-zero
51 return code is received.
52 """
53
54 args_l=cmd.split()
55 if args is None:
56 args = []
57 for i in range(0, len(args)+1, 100):
58 r=os.spawnvp(os.P_WAIT, args_l[0], args_l + args[i:min(i+100, len(args))])
59 if r:
60 return r
61 return 0
62
63 def get(self, name):
9a4bf454
YD
64 if self.__cache.has_key(name):
65 return self.__cache[name]
66
c73e63b7
YD
67 stream = os.popen('git repo-config --get %s' % name, 'r')
68 value = stream.readline().strip()
69 stream.close()
70 if len(value) > 0:
9a4bf454 71 pass
c73e63b7 72 elif (self.__defaults.has_key(name)):
9a4bf454 73 value = self.__defaults[name]
c73e63b7 74 else:
9a4bf454
YD
75 value = None
76
77 self.__cache[name] = value
78 return value
c73e63b7
YD
79
80 def getall(self, name):
9a4bf454
YD
81 if self.__cache.has_key(name):
82 return self.__cache[name]
83
c73e63b7
YD
84 stream = os.popen('git repo-config --get-all %s' % name, 'r')
85 values = [line.strip() for line in stream]
86 stream.close()
9a4bf454
YD
87
88 self.__cache[name] = values
c73e63b7
YD
89 return values
90
91 def getint(self, name):
92 value = self.get(name)
93 if value.isdigit():
94 return int(value)
95 else:
96 raise GitConfigException, 'Value for "%s" is not an integer: "%s"' % (name, value)
97
98 def set(self, name, value):
99 self.__run('git-repo-config', [name, value])
100
101 def sections_matching(self, regexp):
102 """Takes a regexp with a single group, matches it against all
103 config variables, and returns a list whose members are the
104 group contents, for all variable names matching the regexp.
105 """
106 result = []
107 stream = os.popen('git repo-config --get-regexp "^%s$"' % regexp, 'r')
108 for line in stream:
109 m = re.match('^%s ' % regexp, line)
110 if m:
111 result.append(m.group(1))
112 stream.close()
113 return result
114
115config=GitConfig()
abcc2620 116
eee7283e
CM
117def config_setup():
118 global config
119
eee7283e 120 # Set the PAGER environment to the config value (if any)
c73e63b7
YD
121 pager = config.get('stgit.pager')
122 if pager:
123 os.environ['PAGER'] = pager
124 # FIXME: handle EDITOR the same way ?
eee7283e
CM
125
126class ConfigOption:
127 """Delayed cached reading of a configuration option.
128 """
129 def __init__(self, section, option):
130 self.__section = section
131 self.__option = option
132 self.__value = None
133
134 def __str__(self):
135 if not self.__value:
c73e63b7 136 self.__value = config.get(self.__section + '.' + self.__option)
eee7283e 137 return self.__value
d7fade4b
CM
138
139
140# cached extensions
141__extensions = None
142
143def file_extensions():
144 """Returns a dictionary with the conflict file extensions
145 """
146 global __extensions
147
148 if not __extensions:
c73e63b7 149 cfg_ext = config.get('stgit.extensions').split()
d7fade4b
CM
150 if len(cfg_ext) != 3:
151 raise CmdException, '"extensions" configuration error'
152
153 __extensions = { 'ancestor': cfg_ext[0],
154 'current': cfg_ext[1],
155 'patched': cfg_ext[2] }
156
157 return __extensions