chiark / gitweb /
Rename branch section in config when the branch is renamed
[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 rename_section(self, from_name, to_name):
100         self.__run('git-repo-config --rename-section', [from_name, to_name])
101
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()
120
121 def config_setup():
122     global config
123
124     # Set the PAGER environment to the config value (if any)
125     pager = config.get('stgit.pager')
126     if pager:
127         os.environ['PAGER'] = pager
128     # FIXME: handle EDITOR the same way ?
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:
140             self.__value = config.get(self.__section + '.' + self.__option)
141         return self.__value
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:
153         cfg_ext = config.get('stgit.extensions').split()
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