Refuse to pull/rebase when rendered unsafe by (un)commits.
[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',
4cd6405e
YD
32 'stgit.pullcmd': 'git-fetch',
33 'stgit.pull-does-rebase': 'yes',
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
119config=GitConfig()
abcc2620 120
eee7283e
CM
121def 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
130class 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
147def 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