chiark / gitweb /
901f60092abc715c0ee3b7fabb32660dec444cf7
[stgit] / stgit / config.py
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
21 import os, re
22 from stgit import basedir
23
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',
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
42     __cache={}
43
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):
64         if self.__cache.has_key(name):
65             return self.__cache[name]
66
67         stream = os.popen('git repo-config --get %s' % name, 'r')
68         value = stream.readline().strip()
69         stream.close()
70         if len(value) > 0:
71             pass
72         elif (self.__defaults.has_key(name)):
73             value = self.__defaults[name]
74         else:
75             value = None
76
77         self.__cache[name] = value
78         return value
79
80     def getall(self, name):
81         if self.__cache.has_key(name):
82             return self.__cache[name]
83
84         stream = os.popen('git repo-config --get-all %s' % name, 'r')
85         values = [line.strip() for line in stream]
86         stream.close()
87
88         self.__cache[name] = values
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         
115 config=GitConfig()
116
117 def config_setup():
118     global config
119
120     # Set the PAGER environment to the config value (if any)
121     pager = config.get('stgit.pager')
122     if pager:
123         os.environ['PAGER'] = pager
124     # FIXME: handle EDITOR the same way ?
125
126 class 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:
136             self.__value = config.get(self.__section + '.' + self.__option)
137         return self.__value
138
139
140 # cached extensions
141 __extensions = None
142
143 def file_extensions():
144     """Returns a dictionary with the conflict file extensions
145     """
146     global __extensions
147
148     if not __extensions:
149         cfg_ext = config.get('stgit.extensions').split()
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