chiark / gitweb /
Use FETCH_HEAD to know where to rebase to after pull.
[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-fetch',
33         'stgit.pull-does-rebase': 'yes',
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
43     __cache={}
44
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):
65         if self.__cache.has_key(name):
66             return self.__cache[name]
67
68         stream = os.popen('git repo-config --get %s' % name, 'r')
69         value = stream.readline().strip()
70         stream.close()
71         if len(value) > 0:
72             pass
73         elif (self.__defaults.has_key(name)):
74             value = self.__defaults[name]
75         else:
76             value = None
77
78         self.__cache[name] = value
79         return value
80
81     def getall(self, name):
82         if self.__cache.has_key(name):
83             return self.__cache[name]
84
85         stream = os.popen('git repo-config --get-all %s' % name, 'r')
86         values = [line.strip() for line in stream]
87         stream.close()
88
89         self.__cache[name] = values
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
99     def set(self, name, value):
100         self.__run('git-repo-config', [name, value])
101
102     def sections_matching(self, regexp):
103         """Takes a regexp with a single group, matches it against all
104         config variables, and returns a list whose members are the
105         group contents, for all variable names matching the regexp.
106         """
107         result = []
108         stream = os.popen('git repo-config --get-regexp "^%s$"' % regexp, 'r')
109         for line in stream:
110             m = re.match('^%s ' % regexp, line)
111             if m:
112                 result.append(m.group(1))
113         stream.close()
114         return result
115         
116 config=GitConfig()
117
118 def config_setup():
119     global config
120
121     # Set the PAGER environment to the config value (if any)
122     pager = config.get('stgit.pager')
123     if pager:
124         os.environ['PAGER'] = pager
125     # FIXME: handle EDITOR the same way ?
126
127 class ConfigOption:
128     """Delayed cached reading of a configuration option.
129     """
130     def __init__(self, section, option):
131         self.__section = section
132         self.__option = option
133         self.__value = None
134
135     def __str__(self):
136         if not self.__value:
137             self.__value = config.get(self.__section + '.' + self.__option)
138         return self.__value
139
140
141 # cached extensions
142 __extensions = None
143
144 def file_extensions():
145     """Returns a dictionary with the conflict file extensions
146     """
147     global __extensions
148
149     if not __extensions:
150         cfg_ext = config.get('stgit.extensions').split()
151         if len(cfg_ext) != 3:
152             raise CmdException, '"extensions" configuration error'
153
154         __extensions = { 'ancestor': cfg_ext[0],
155                          'current':  cfg_ext[1],
156                          'patched':  cfg_ext[2] }
157
158     return __extensions