##// END OF EJS Templates
error: add new ParseError for various parsing errors
Matt Mackall -
r11288:2123aad2 default
parent child Browse files
Show More
@@ -1,144 +1,143 b''
1 # config.py - configuration parsing for Mercurial
1 # config.py - configuration parsing for Mercurial
2 #
2 #
3 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others
3 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import _
8 from i18n import _
9 import error, util
9 import error, util
10 import re, os
10 import re, os
11
11
12 class sortdict(dict):
12 class sortdict(dict):
13 'a simple sorted dictionary'
13 'a simple sorted dictionary'
14 def __init__(self, data=None):
14 def __init__(self, data=None):
15 self._list = []
15 self._list = []
16 if data:
16 if data:
17 self.update(data)
17 self.update(data)
18 def copy(self):
18 def copy(self):
19 return sortdict(self)
19 return sortdict(self)
20 def __setitem__(self, key, val):
20 def __setitem__(self, key, val):
21 if key in self:
21 if key in self:
22 self._list.remove(key)
22 self._list.remove(key)
23 self._list.append(key)
23 self._list.append(key)
24 dict.__setitem__(self, key, val)
24 dict.__setitem__(self, key, val)
25 def __iter__(self):
25 def __iter__(self):
26 return self._list.__iter__()
26 return self._list.__iter__()
27 def update(self, src):
27 def update(self, src):
28 for k in src:
28 for k in src:
29 self[k] = src[k]
29 self[k] = src[k]
30 def items(self):
30 def items(self):
31 return [(k, self[k]) for k in self._list]
31 return [(k, self[k]) for k in self._list]
32 def __delitem__(self, key):
32 def __delitem__(self, key):
33 dict.__delitem__(self, key)
33 dict.__delitem__(self, key)
34 self._list.remove(key)
34 self._list.remove(key)
35
35
36 class config(object):
36 class config(object):
37 def __init__(self, data=None):
37 def __init__(self, data=None):
38 self._data = {}
38 self._data = {}
39 self._source = {}
39 self._source = {}
40 if data:
40 if data:
41 for k in data._data:
41 for k in data._data:
42 self._data[k] = data[k].copy()
42 self._data[k] = data[k].copy()
43 self._source = data._source.copy()
43 self._source = data._source.copy()
44 def copy(self):
44 def copy(self):
45 return config(self)
45 return config(self)
46 def __contains__(self, section):
46 def __contains__(self, section):
47 return section in self._data
47 return section in self._data
48 def __getitem__(self, section):
48 def __getitem__(self, section):
49 return self._data.get(section, {})
49 return self._data.get(section, {})
50 def __iter__(self):
50 def __iter__(self):
51 for d in self.sections():
51 for d in self.sections():
52 yield d
52 yield d
53 def update(self, src):
53 def update(self, src):
54 for s in src:
54 for s in src:
55 if s not in self:
55 if s not in self:
56 self._data[s] = sortdict()
56 self._data[s] = sortdict()
57 self._data[s].update(src._data[s])
57 self._data[s].update(src._data[s])
58 self._source.update(src._source)
58 self._source.update(src._source)
59 def get(self, section, item, default=None):
59 def get(self, section, item, default=None):
60 return self._data.get(section, {}).get(item, default)
60 return self._data.get(section, {}).get(item, default)
61 def source(self, section, item):
61 def source(self, section, item):
62 return self._source.get((section, item), "")
62 return self._source.get((section, item), "")
63 def sections(self):
63 def sections(self):
64 return sorted(self._data.keys())
64 return sorted(self._data.keys())
65 def items(self, section):
65 def items(self, section):
66 return self._data.get(section, {}).items()
66 return self._data.get(section, {}).items()
67 def set(self, section, item, value, source=""):
67 def set(self, section, item, value, source=""):
68 if section not in self:
68 if section not in self:
69 self._data[section] = sortdict()
69 self._data[section] = sortdict()
70 self._data[section][item] = value
70 self._data[section][item] = value
71 self._source[(section, item)] = source
71 self._source[(section, item)] = source
72
72
73 def parse(self, src, data, sections=None, remap=None, include=None):
73 def parse(self, src, data, sections=None, remap=None, include=None):
74 sectionre = re.compile(r'\[([^\[]+)\]')
74 sectionre = re.compile(r'\[([^\[]+)\]')
75 itemre = re.compile(r'([^=\s][^=]*?)\s*=\s*(.*\S|)')
75 itemre = re.compile(r'([^=\s][^=]*?)\s*=\s*(.*\S|)')
76 contre = re.compile(r'\s+(\S|\S.*\S)\s*$')
76 contre = re.compile(r'\s+(\S|\S.*\S)\s*$')
77 emptyre = re.compile(r'(;|#|\s*$)')
77 emptyre = re.compile(r'(;|#|\s*$)')
78 unsetre = re.compile(r'%unset\s+(\S+)')
78 unsetre = re.compile(r'%unset\s+(\S+)')
79 includere = re.compile(r'%include\s+(\S|\S.*\S)\s*$')
79 includere = re.compile(r'%include\s+(\S|\S.*\S)\s*$')
80 section = ""
80 section = ""
81 item = None
81 item = None
82 line = 0
82 line = 0
83 cont = False
83 cont = False
84
84
85 for l in data.splitlines(True):
85 for l in data.splitlines(True):
86 line += 1
86 line += 1
87 if cont:
87 if cont:
88 m = contre.match(l)
88 m = contre.match(l)
89 if m:
89 if m:
90 if sections and section not in sections:
90 if sections and section not in sections:
91 continue
91 continue
92 v = self.get(section, item) + "\n" + m.group(1)
92 v = self.get(section, item) + "\n" + m.group(1)
93 self.set(section, item, v, "%s:%d" % (src, line))
93 self.set(section, item, v, "%s:%d" % (src, line))
94 continue
94 continue
95 item = None
95 item = None
96 cont = False
96 cont = False
97 m = includere.match(l)
97 m = includere.match(l)
98 if m:
98 if m:
99 inc = util.expandpath(m.group(1))
99 inc = util.expandpath(m.group(1))
100 base = os.path.dirname(src)
100 base = os.path.dirname(src)
101 inc = os.path.normpath(os.path.join(base, inc))
101 inc = os.path.normpath(os.path.join(base, inc))
102 if include:
102 if include:
103 try:
103 try:
104 include(inc, remap=remap, sections=sections)
104 include(inc, remap=remap, sections=sections)
105 except IOError, inst:
105 except IOError, inst:
106 msg = _("config error at %s:%d: "
106 raise error.ParseError(
107 "cannot include %s (%s)") \
107 _("cannot include %s (%s)")
108 % (src, line, inc, inst.strerror)
108 % (inc, inst.strerror),
109 raise error.ConfigError(msg)
109 msg, "%s:%s" % (src, line))
110 continue
110 continue
111 if emptyre.match(l):
111 if emptyre.match(l):
112 continue
112 continue
113 m = sectionre.match(l)
113 m = sectionre.match(l)
114 if m:
114 if m:
115 section = m.group(1)
115 section = m.group(1)
116 if remap:
116 if remap:
117 section = remap.get(section, section)
117 section = remap.get(section, section)
118 if section not in self:
118 if section not in self:
119 self._data[section] = sortdict()
119 self._data[section] = sortdict()
120 continue
120 continue
121 m = itemre.match(l)
121 m = itemre.match(l)
122 if m:
122 if m:
123 item = m.group(1)
123 item = m.group(1)
124 cont = True
124 cont = True
125 if sections and section not in sections:
125 if sections and section not in sections:
126 continue
126 continue
127 self.set(section, item, m.group(2), "%s:%d" % (src, line))
127 self.set(section, item, m.group(2), "%s:%d" % (src, line))
128 continue
128 continue
129 m = unsetre.match(l)
129 m = unsetre.match(l)
130 if m:
130 if m:
131 name = m.group(1)
131 name = m.group(1)
132 if sections and section not in sections:
132 if sections and section not in sections:
133 continue
133 continue
134 if self.get(section, name) != None:
134 if self.get(section, name) != None:
135 del self._data[section][name]
135 del self._data[section][name]
136 continue
136 continue
137
137
138 raise error.ConfigError(_("config error at %s:%d: '%s'")
138 raise error.ParseError(l.rstrip(), ("%s:%s" % (src, line)))
139 % (src, line, l.rstrip()))
140
139
141 def read(self, path, fp=None, sections=None, remap=None):
140 def read(self, path, fp=None, sections=None, remap=None):
142 if not fp:
141 if not fp:
143 fp = open(path)
142 fp = open(path)
144 self.parse(path, fp.read(), sections, remap, self.read)
143 self.parse(path, fp.read(), sections, remap, self.read)
@@ -1,522 +1,531 b''
1 # dispatch.py - command dispatching for mercurial
1 # dispatch.py - command dispatching for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import _
8 from i18n import _
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time
9 import os, sys, atexit, signal, pdb, socket, errno, shlex, time
10 import util, commands, hg, fancyopts, extensions, hook, error
10 import util, commands, hg, fancyopts, extensions, hook, error
11 import cmdutil, encoding
11 import cmdutil, encoding
12 import ui as uimod
12 import ui as uimod
13
13
14 def run():
14 def run():
15 "run the command in sys.argv"
15 "run the command in sys.argv"
16 sys.exit(dispatch(sys.argv[1:]))
16 sys.exit(dispatch(sys.argv[1:]))
17
17
18 def dispatch(args):
18 def dispatch(args):
19 "run the command specified in args"
19 "run the command specified in args"
20 try:
20 try:
21 u = uimod.ui()
21 u = uimod.ui()
22 if '--traceback' in args:
22 if '--traceback' in args:
23 u.setconfig('ui', 'traceback', 'on')
23 u.setconfig('ui', 'traceback', 'on')
24 except util.Abort, inst:
24 except util.Abort, inst:
25 sys.stderr.write(_("abort: %s\n") % inst)
25 sys.stderr.write(_("abort: %s\n") % inst)
26 return -1
26 return -1
27 except error.ConfigError, inst:
27 except error.ParseError, inst:
28 sys.stderr.write(_("hg: %s\n") % inst)
28 if len(inst.args) > 1:
29 sys.stderr.write(_("hg: parse error at %s: %s\n") %
30 (inst.args[1], inst.args[0]))
31 else:
32 sys.stderr.write(_("hg: parse error: %s\n") % ints.args[0])
29 return -1
33 return -1
30 return _runcatch(u, args)
34 return _runcatch(u, args)
31
35
32 def _runcatch(ui, args):
36 def _runcatch(ui, args):
33 def catchterm(*args):
37 def catchterm(*args):
34 raise error.SignalInterrupt
38 raise error.SignalInterrupt
35
39
36 try:
40 try:
37 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
41 for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
38 num = getattr(signal, name, None)
42 num = getattr(signal, name, None)
39 if num:
43 if num:
40 signal.signal(num, catchterm)
44 signal.signal(num, catchterm)
41 except ValueError:
45 except ValueError:
42 pass # happens if called in a thread
46 pass # happens if called in a thread
43
47
44 try:
48 try:
45 try:
49 try:
46 # enter the debugger before command execution
50 # enter the debugger before command execution
47 if '--debugger' in args:
51 if '--debugger' in args:
48 pdb.set_trace()
52 pdb.set_trace()
49 try:
53 try:
50 return _dispatch(ui, args)
54 return _dispatch(ui, args)
51 finally:
55 finally:
52 ui.flush()
56 ui.flush()
53 except:
57 except:
54 # enter the debugger when we hit an exception
58 # enter the debugger when we hit an exception
55 if '--debugger' in args:
59 if '--debugger' in args:
56 pdb.post_mortem(sys.exc_info()[2])
60 pdb.post_mortem(sys.exc_info()[2])
57 ui.traceback()
61 ui.traceback()
58 raise
62 raise
59
63
60 # Global exception handling, alphabetically
64 # Global exception handling, alphabetically
61 # Mercurial-specific first, followed by built-in and library exceptions
65 # Mercurial-specific first, followed by built-in and library exceptions
62 except error.AmbiguousCommand, inst:
66 except error.AmbiguousCommand, inst:
63 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
67 ui.warn(_("hg: command '%s' is ambiguous:\n %s\n") %
64 (inst.args[0], " ".join(inst.args[1])))
68 (inst.args[0], " ".join(inst.args[1])))
65 except error.ConfigError, inst:
69 except error.ParseError, inst:
66 ui.warn(_("hg: %s\n") % inst.args[0])
70 if len(inst.args) > 1:
71 ui.warn(_("hg: parse error at %s: %s\n") %
72 (inst.args[1], inst.args[0]))
73 else:
74 ui.warn(_("hg: parse error: %s\n") % inst.args[0])
75 return -1
67 except error.LockHeld, inst:
76 except error.LockHeld, inst:
68 if inst.errno == errno.ETIMEDOUT:
77 if inst.errno == errno.ETIMEDOUT:
69 reason = _('timed out waiting for lock held by %s') % inst.locker
78 reason = _('timed out waiting for lock held by %s') % inst.locker
70 else:
79 else:
71 reason = _('lock held by %s') % inst.locker
80 reason = _('lock held by %s') % inst.locker
72 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
81 ui.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason))
73 except error.LockUnavailable, inst:
82 except error.LockUnavailable, inst:
74 ui.warn(_("abort: could not lock %s: %s\n") %
83 ui.warn(_("abort: could not lock %s: %s\n") %
75 (inst.desc or inst.filename, inst.strerror))
84 (inst.desc or inst.filename, inst.strerror))
76 except error.CommandError, inst:
85 except error.CommandError, inst:
77 if inst.args[0]:
86 if inst.args[0]:
78 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
87 ui.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
79 commands.help_(ui, inst.args[0])
88 commands.help_(ui, inst.args[0])
80 else:
89 else:
81 ui.warn(_("hg: %s\n") % inst.args[1])
90 ui.warn(_("hg: %s\n") % inst.args[1])
82 commands.help_(ui, 'shortlist')
91 commands.help_(ui, 'shortlist')
83 except error.RepoError, inst:
92 except error.RepoError, inst:
84 ui.warn(_("abort: %s!\n") % inst)
93 ui.warn(_("abort: %s!\n") % inst)
85 except error.ResponseError, inst:
94 except error.ResponseError, inst:
86 ui.warn(_("abort: %s") % inst.args[0])
95 ui.warn(_("abort: %s") % inst.args[0])
87 if not isinstance(inst.args[1], basestring):
96 if not isinstance(inst.args[1], basestring):
88 ui.warn(" %r\n" % (inst.args[1],))
97 ui.warn(" %r\n" % (inst.args[1],))
89 elif not inst.args[1]:
98 elif not inst.args[1]:
90 ui.warn(_(" empty string\n"))
99 ui.warn(_(" empty string\n"))
91 else:
100 else:
92 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
101 ui.warn("\n%r\n" % util.ellipsis(inst.args[1]))
93 except error.RevlogError, inst:
102 except error.RevlogError, inst:
94 ui.warn(_("abort: %s!\n") % inst)
103 ui.warn(_("abort: %s!\n") % inst)
95 except error.SignalInterrupt:
104 except error.SignalInterrupt:
96 ui.warn(_("killed!\n"))
105 ui.warn(_("killed!\n"))
97 except error.UnknownCommand, inst:
106 except error.UnknownCommand, inst:
98 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
107 ui.warn(_("hg: unknown command '%s'\n") % inst.args[0])
99 try:
108 try:
100 # check if the command is in a disabled extension
109 # check if the command is in a disabled extension
101 # (but don't check for extensions themselves)
110 # (but don't check for extensions themselves)
102 commands.help_(ui, inst.args[0], unknowncmd=True)
111 commands.help_(ui, inst.args[0], unknowncmd=True)
103 except error.UnknownCommand:
112 except error.UnknownCommand:
104 commands.help_(ui, 'shortlist')
113 commands.help_(ui, 'shortlist')
105 except util.Abort, inst:
114 except util.Abort, inst:
106 ui.warn(_("abort: %s\n") % inst)
115 ui.warn(_("abort: %s\n") % inst)
107 except ImportError, inst:
116 except ImportError, inst:
108 ui.warn(_("abort: %s!\n") % inst)
117 ui.warn(_("abort: %s!\n") % inst)
109 m = str(inst).split()[-1]
118 m = str(inst).split()[-1]
110 if m in "mpatch bdiff".split():
119 if m in "mpatch bdiff".split():
111 ui.warn(_("(did you forget to compile extensions?)\n"))
120 ui.warn(_("(did you forget to compile extensions?)\n"))
112 elif m in "zlib".split():
121 elif m in "zlib".split():
113 ui.warn(_("(is your Python install correct?)\n"))
122 ui.warn(_("(is your Python install correct?)\n"))
114 except IOError, inst:
123 except IOError, inst:
115 if hasattr(inst, "code"):
124 if hasattr(inst, "code"):
116 ui.warn(_("abort: %s\n") % inst)
125 ui.warn(_("abort: %s\n") % inst)
117 elif hasattr(inst, "reason"):
126 elif hasattr(inst, "reason"):
118 try: # usually it is in the form (errno, strerror)
127 try: # usually it is in the form (errno, strerror)
119 reason = inst.reason.args[1]
128 reason = inst.reason.args[1]
120 except: # it might be anything, for example a string
129 except: # it might be anything, for example a string
121 reason = inst.reason
130 reason = inst.reason
122 ui.warn(_("abort: error: %s\n") % reason)
131 ui.warn(_("abort: error: %s\n") % reason)
123 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
132 elif hasattr(inst, "args") and inst.args[0] == errno.EPIPE:
124 if ui.debugflag:
133 if ui.debugflag:
125 ui.warn(_("broken pipe\n"))
134 ui.warn(_("broken pipe\n"))
126 elif getattr(inst, "strerror", None):
135 elif getattr(inst, "strerror", None):
127 if getattr(inst, "filename", None):
136 if getattr(inst, "filename", None):
128 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
137 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
129 else:
138 else:
130 ui.warn(_("abort: %s\n") % inst.strerror)
139 ui.warn(_("abort: %s\n") % inst.strerror)
131 else:
140 else:
132 raise
141 raise
133 except OSError, inst:
142 except OSError, inst:
134 if getattr(inst, "filename", None):
143 if getattr(inst, "filename", None):
135 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
144 ui.warn(_("abort: %s: %s\n") % (inst.strerror, inst.filename))
136 else:
145 else:
137 ui.warn(_("abort: %s\n") % inst.strerror)
146 ui.warn(_("abort: %s\n") % inst.strerror)
138 except KeyboardInterrupt:
147 except KeyboardInterrupt:
139 try:
148 try:
140 ui.warn(_("interrupted!\n"))
149 ui.warn(_("interrupted!\n"))
141 except IOError, inst:
150 except IOError, inst:
142 if inst.errno == errno.EPIPE:
151 if inst.errno == errno.EPIPE:
143 if ui.debugflag:
152 if ui.debugflag:
144 ui.warn(_("\nbroken pipe\n"))
153 ui.warn(_("\nbroken pipe\n"))
145 else:
154 else:
146 raise
155 raise
147 except MemoryError:
156 except MemoryError:
148 ui.warn(_("abort: out of memory\n"))
157 ui.warn(_("abort: out of memory\n"))
149 except SystemExit, inst:
158 except SystemExit, inst:
150 # Commands shouldn't sys.exit directly, but give a return code.
159 # Commands shouldn't sys.exit directly, but give a return code.
151 # Just in case catch this and and pass exit code to caller.
160 # Just in case catch this and and pass exit code to caller.
152 return inst.code
161 return inst.code
153 except socket.error, inst:
162 except socket.error, inst:
154 ui.warn(_("abort: %s\n") % inst.args[-1])
163 ui.warn(_("abort: %s\n") % inst.args[-1])
155 except:
164 except:
156 ui.warn(_("** unknown exception encountered, details follow\n"))
165 ui.warn(_("** unknown exception encountered, details follow\n"))
157 ui.warn(_("** report bug details to "
166 ui.warn(_("** report bug details to "
158 "http://mercurial.selenic.com/bts/\n"))
167 "http://mercurial.selenic.com/bts/\n"))
159 ui.warn(_("** or mercurial@selenic.com\n"))
168 ui.warn(_("** or mercurial@selenic.com\n"))
160 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
169 ui.warn(_("** Python %s\n") % sys.version.replace('\n', ''))
161 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
170 ui.warn(_("** Mercurial Distributed SCM (version %s)\n")
162 % util.version())
171 % util.version())
163 ui.warn(_("** Extensions loaded: %s\n")
172 ui.warn(_("** Extensions loaded: %s\n")
164 % ", ".join([x[0] for x in extensions.extensions()]))
173 % ", ".join([x[0] for x in extensions.extensions()]))
165 raise
174 raise
166
175
167 return -1
176 return -1
168
177
169 def aliasargs(fn):
178 def aliasargs(fn):
170 if hasattr(fn, 'args'):
179 if hasattr(fn, 'args'):
171 return fn.args
180 return fn.args
172 return []
181 return []
173
182
174 class cmdalias(object):
183 class cmdalias(object):
175 def __init__(self, name, definition, cmdtable):
184 def __init__(self, name, definition, cmdtable):
176 self.name = name
185 self.name = name
177 self.definition = definition
186 self.definition = definition
178 self.args = []
187 self.args = []
179 self.opts = []
188 self.opts = []
180 self.help = ''
189 self.help = ''
181 self.norepo = True
190 self.norepo = True
182 self.badalias = False
191 self.badalias = False
183
192
184 try:
193 try:
185 cmdutil.findcmd(self.name, cmdtable, True)
194 cmdutil.findcmd(self.name, cmdtable, True)
186 self.shadows = True
195 self.shadows = True
187 except error.UnknownCommand:
196 except error.UnknownCommand:
188 self.shadows = False
197 self.shadows = False
189
198
190 if not self.definition:
199 if not self.definition:
191 def fn(ui, *args):
200 def fn(ui, *args):
192 ui.warn(_("no definition for alias '%s'\n") % self.name)
201 ui.warn(_("no definition for alias '%s'\n") % self.name)
193 return 1
202 return 1
194 self.fn = fn
203 self.fn = fn
195 self.badalias = True
204 self.badalias = True
196
205
197 return
206 return
198
207
199 args = shlex.split(self.definition)
208 args = shlex.split(self.definition)
200 cmd = args.pop(0)
209 cmd = args.pop(0)
201 args = map(util.expandpath, args)
210 args = map(util.expandpath, args)
202
211
203 try:
212 try:
204 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
213 tableentry = cmdutil.findcmd(cmd, cmdtable, False)[1]
205 if len(tableentry) > 2:
214 if len(tableentry) > 2:
206 self.fn, self.opts, self.help = tableentry
215 self.fn, self.opts, self.help = tableentry
207 else:
216 else:
208 self.fn, self.opts = tableentry
217 self.fn, self.opts = tableentry
209
218
210 self.args = aliasargs(self.fn) + args
219 self.args = aliasargs(self.fn) + args
211 if cmd not in commands.norepo.split(' '):
220 if cmd not in commands.norepo.split(' '):
212 self.norepo = False
221 self.norepo = False
213 if self.help.startswith("hg " + cmd):
222 if self.help.startswith("hg " + cmd):
214 # drop prefix in old-style help lines so hg shows the alias
223 # drop prefix in old-style help lines so hg shows the alias
215 self.help = self.help[4 + len(cmd):]
224 self.help = self.help[4 + len(cmd):]
216 self.__doc__ = self.fn.__doc__
225 self.__doc__ = self.fn.__doc__
217
226
218 except error.UnknownCommand:
227 except error.UnknownCommand:
219 def fn(ui, *args):
228 def fn(ui, *args):
220 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
229 ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \
221 % (self.name, cmd))
230 % (self.name, cmd))
222 try:
231 try:
223 # check if the command is in a disabled extension
232 # check if the command is in a disabled extension
224 commands.help_(ui, cmd, unknowncmd=True)
233 commands.help_(ui, cmd, unknowncmd=True)
225 except error.UnknownCommand:
234 except error.UnknownCommand:
226 pass
235 pass
227 return 1
236 return 1
228 self.fn = fn
237 self.fn = fn
229 self.badalias = True
238 self.badalias = True
230 except error.AmbiguousCommand:
239 except error.AmbiguousCommand:
231 def fn(ui, *args):
240 def fn(ui, *args):
232 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
241 ui.warn(_("alias '%s' resolves to ambiguous command '%s'\n") \
233 % (self.name, cmd))
242 % (self.name, cmd))
234 return 1
243 return 1
235 self.fn = fn
244 self.fn = fn
236 self.badalias = True
245 self.badalias = True
237
246
238 def __call__(self, ui, *args, **opts):
247 def __call__(self, ui, *args, **opts):
239 if self.shadows:
248 if self.shadows:
240 ui.debug("alias '%s' shadows command\n" % self.name)
249 ui.debug("alias '%s' shadows command\n" % self.name)
241
250
242 return self.fn(ui, *args, **opts)
251 return self.fn(ui, *args, **opts)
243
252
244 def addaliases(ui, cmdtable):
253 def addaliases(ui, cmdtable):
245 # aliases are processed after extensions have been loaded, so they
254 # aliases are processed after extensions have been loaded, so they
246 # may use extension commands. Aliases can also use other alias definitions,
255 # may use extension commands. Aliases can also use other alias definitions,
247 # but only if they have been defined prior to the current definition.
256 # but only if they have been defined prior to the current definition.
248 for alias, definition in ui.configitems('alias'):
257 for alias, definition in ui.configitems('alias'):
249 aliasdef = cmdalias(alias, definition, cmdtable)
258 aliasdef = cmdalias(alias, definition, cmdtable)
250 cmdtable[alias] = (aliasdef, aliasdef.opts, aliasdef.help)
259 cmdtable[alias] = (aliasdef, aliasdef.opts, aliasdef.help)
251 if aliasdef.norepo:
260 if aliasdef.norepo:
252 commands.norepo += ' %s' % alias
261 commands.norepo += ' %s' % alias
253
262
254 def _parse(ui, args):
263 def _parse(ui, args):
255 options = {}
264 options = {}
256 cmdoptions = {}
265 cmdoptions = {}
257
266
258 try:
267 try:
259 args = fancyopts.fancyopts(args, commands.globalopts, options)
268 args = fancyopts.fancyopts(args, commands.globalopts, options)
260 except fancyopts.getopt.GetoptError, inst:
269 except fancyopts.getopt.GetoptError, inst:
261 raise error.CommandError(None, inst)
270 raise error.CommandError(None, inst)
262
271
263 if args:
272 if args:
264 cmd, args = args[0], args[1:]
273 cmd, args = args[0], args[1:]
265 aliases, entry = cmdutil.findcmd(cmd, commands.table,
274 aliases, entry = cmdutil.findcmd(cmd, commands.table,
266 ui.config("ui", "strict"))
275 ui.config("ui", "strict"))
267 cmd = aliases[0]
276 cmd = aliases[0]
268 args = aliasargs(entry[0]) + args
277 args = aliasargs(entry[0]) + args
269 defaults = ui.config("defaults", cmd)
278 defaults = ui.config("defaults", cmd)
270 if defaults:
279 if defaults:
271 args = map(util.expandpath, shlex.split(defaults)) + args
280 args = map(util.expandpath, shlex.split(defaults)) + args
272 c = list(entry[1])
281 c = list(entry[1])
273 else:
282 else:
274 cmd = None
283 cmd = None
275 c = []
284 c = []
276
285
277 # combine global options into local
286 # combine global options into local
278 for o in commands.globalopts:
287 for o in commands.globalopts:
279 c.append((o[0], o[1], options[o[1]], o[3]))
288 c.append((o[0], o[1], options[o[1]], o[3]))
280
289
281 try:
290 try:
282 args = fancyopts.fancyopts(args, c, cmdoptions, True)
291 args = fancyopts.fancyopts(args, c, cmdoptions, True)
283 except fancyopts.getopt.GetoptError, inst:
292 except fancyopts.getopt.GetoptError, inst:
284 raise error.CommandError(cmd, inst)
293 raise error.CommandError(cmd, inst)
285
294
286 # separate global options back out
295 # separate global options back out
287 for o in commands.globalopts:
296 for o in commands.globalopts:
288 n = o[1]
297 n = o[1]
289 options[n] = cmdoptions[n]
298 options[n] = cmdoptions[n]
290 del cmdoptions[n]
299 del cmdoptions[n]
291
300
292 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
301 return (cmd, cmd and entry[0] or None, args, options, cmdoptions)
293
302
294 def _parseconfig(ui, config):
303 def _parseconfig(ui, config):
295 """parse the --config options from the command line"""
304 """parse the --config options from the command line"""
296 for cfg in config:
305 for cfg in config:
297 try:
306 try:
298 name, value = cfg.split('=', 1)
307 name, value = cfg.split('=', 1)
299 section, name = name.split('.', 1)
308 section, name = name.split('.', 1)
300 if not section or not name:
309 if not section or not name:
301 raise IndexError
310 raise IndexError
302 ui.setconfig(section, name, value)
311 ui.setconfig(section, name, value)
303 except (IndexError, ValueError):
312 except (IndexError, ValueError):
304 raise util.Abort(_('malformed --config option: %r '
313 raise util.Abort(_('malformed --config option: %r '
305 '(use --config section.name=value)') % cfg)
314 '(use --config section.name=value)') % cfg)
306
315
307 def _earlygetopt(aliases, args):
316 def _earlygetopt(aliases, args):
308 """Return list of values for an option (or aliases).
317 """Return list of values for an option (or aliases).
309
318
310 The values are listed in the order they appear in args.
319 The values are listed in the order they appear in args.
311 The options and values are removed from args.
320 The options and values are removed from args.
312 """
321 """
313 try:
322 try:
314 argcount = args.index("--")
323 argcount = args.index("--")
315 except ValueError:
324 except ValueError:
316 argcount = len(args)
325 argcount = len(args)
317 shortopts = [opt for opt in aliases if len(opt) == 2]
326 shortopts = [opt for opt in aliases if len(opt) == 2]
318 values = []
327 values = []
319 pos = 0
328 pos = 0
320 while pos < argcount:
329 while pos < argcount:
321 if args[pos] in aliases:
330 if args[pos] in aliases:
322 if pos + 1 >= argcount:
331 if pos + 1 >= argcount:
323 # ignore and let getopt report an error if there is no value
332 # ignore and let getopt report an error if there is no value
324 break
333 break
325 del args[pos]
334 del args[pos]
326 values.append(args.pop(pos))
335 values.append(args.pop(pos))
327 argcount -= 2
336 argcount -= 2
328 elif args[pos][:2] in shortopts:
337 elif args[pos][:2] in shortopts:
329 # short option can have no following space, e.g. hg log -Rfoo
338 # short option can have no following space, e.g. hg log -Rfoo
330 values.append(args.pop(pos)[2:])
339 values.append(args.pop(pos)[2:])
331 argcount -= 1
340 argcount -= 1
332 else:
341 else:
333 pos += 1
342 pos += 1
334 return values
343 return values
335
344
336 def runcommand(lui, repo, cmd, fullargs, ui, options, d):
345 def runcommand(lui, repo, cmd, fullargs, ui, options, d):
337 # run pre-hook, and abort if it fails
346 # run pre-hook, and abort if it fails
338 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
347 ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
339 if ret:
348 if ret:
340 return ret
349 return ret
341 ret = _runcommand(ui, options, cmd, d)
350 ret = _runcommand(ui, options, cmd, d)
342 # run post-hook, passing command result
351 # run post-hook, passing command result
343 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
352 hook.hook(lui, repo, "post-%s" % cmd, False, args=" ".join(fullargs),
344 result = ret)
353 result = ret)
345 return ret
354 return ret
346
355
347 _loaded = set()
356 _loaded = set()
348 def _dispatch(ui, args):
357 def _dispatch(ui, args):
349 # read --config before doing anything else
358 # read --config before doing anything else
350 # (e.g. to change trust settings for reading .hg/hgrc)
359 # (e.g. to change trust settings for reading .hg/hgrc)
351 _parseconfig(ui, _earlygetopt(['--config'], args))
360 _parseconfig(ui, _earlygetopt(['--config'], args))
352
361
353 # check for cwd
362 # check for cwd
354 cwd = _earlygetopt(['--cwd'], args)
363 cwd = _earlygetopt(['--cwd'], args)
355 if cwd:
364 if cwd:
356 os.chdir(cwd[-1])
365 os.chdir(cwd[-1])
357
366
358 # read the local repository .hgrc into a local ui object
367 # read the local repository .hgrc into a local ui object
359 path = cmdutil.findrepo(os.getcwd()) or ""
368 path = cmdutil.findrepo(os.getcwd()) or ""
360 if not path:
369 if not path:
361 lui = ui
370 lui = ui
362 else:
371 else:
363 try:
372 try:
364 lui = ui.copy()
373 lui = ui.copy()
365 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
374 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
366 except IOError:
375 except IOError:
367 pass
376 pass
368
377
369 # now we can expand paths, even ones in .hg/hgrc
378 # now we can expand paths, even ones in .hg/hgrc
370 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
379 rpath = _earlygetopt(["-R", "--repository", "--repo"], args)
371 if rpath:
380 if rpath:
372 path = lui.expandpath(rpath[-1])
381 path = lui.expandpath(rpath[-1])
373 lui = ui.copy()
382 lui = ui.copy()
374 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
383 lui.readconfig(os.path.join(path, ".hg", "hgrc"))
375
384
376 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
385 # Configure extensions in phases: uisetup, extsetup, cmdtable, and
377 # reposetup. Programs like TortoiseHg will call _dispatch several
386 # reposetup. Programs like TortoiseHg will call _dispatch several
378 # times so we keep track of configured extensions in _loaded.
387 # times so we keep track of configured extensions in _loaded.
379 extensions.loadall(lui)
388 extensions.loadall(lui)
380 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
389 exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded]
381
390
382 # (uisetup and extsetup are handled in extensions.loadall)
391 # (uisetup and extsetup are handled in extensions.loadall)
383
392
384 for name, module in exts:
393 for name, module in exts:
385 cmdtable = getattr(module, 'cmdtable', {})
394 cmdtable = getattr(module, 'cmdtable', {})
386 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
395 overrides = [cmd for cmd in cmdtable if cmd in commands.table]
387 if overrides:
396 if overrides:
388 ui.warn(_("extension '%s' overrides commands: %s\n")
397 ui.warn(_("extension '%s' overrides commands: %s\n")
389 % (name, " ".join(overrides)))
398 % (name, " ".join(overrides)))
390 commands.table.update(cmdtable)
399 commands.table.update(cmdtable)
391 _loaded.add(name)
400 _loaded.add(name)
392
401
393 # (reposetup is handled in hg.repository)
402 # (reposetup is handled in hg.repository)
394
403
395 addaliases(lui, commands.table)
404 addaliases(lui, commands.table)
396
405
397 # check for fallback encoding
406 # check for fallback encoding
398 fallback = lui.config('ui', 'fallbackencoding')
407 fallback = lui.config('ui', 'fallbackencoding')
399 if fallback:
408 if fallback:
400 encoding.fallbackencoding = fallback
409 encoding.fallbackencoding = fallback
401
410
402 fullargs = args
411 fullargs = args
403 cmd, func, args, options, cmdoptions = _parse(lui, args)
412 cmd, func, args, options, cmdoptions = _parse(lui, args)
404
413
405 if options["config"]:
414 if options["config"]:
406 raise util.Abort(_("Option --config may not be abbreviated!"))
415 raise util.Abort(_("Option --config may not be abbreviated!"))
407 if options["cwd"]:
416 if options["cwd"]:
408 raise util.Abort(_("Option --cwd may not be abbreviated!"))
417 raise util.Abort(_("Option --cwd may not be abbreviated!"))
409 if options["repository"]:
418 if options["repository"]:
410 raise util.Abort(_(
419 raise util.Abort(_(
411 "Option -R has to be separated from other options (e.g. not -qR) "
420 "Option -R has to be separated from other options (e.g. not -qR) "
412 "and --repository may only be abbreviated as --repo!"))
421 "and --repository may only be abbreviated as --repo!"))
413
422
414 if options["encoding"]:
423 if options["encoding"]:
415 encoding.encoding = options["encoding"]
424 encoding.encoding = options["encoding"]
416 if options["encodingmode"]:
425 if options["encodingmode"]:
417 encoding.encodingmode = options["encodingmode"]
426 encoding.encodingmode = options["encodingmode"]
418 if options["time"]:
427 if options["time"]:
419 def get_times():
428 def get_times():
420 t = os.times()
429 t = os.times()
421 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
430 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
422 t = (t[0], t[1], t[2], t[3], time.clock())
431 t = (t[0], t[1], t[2], t[3], time.clock())
423 return t
432 return t
424 s = get_times()
433 s = get_times()
425 def print_time():
434 def print_time():
426 t = get_times()
435 t = get_times()
427 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
436 ui.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
428 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
437 (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
429 atexit.register(print_time)
438 atexit.register(print_time)
430
439
431 if options['verbose'] or options['debug'] or options['quiet']:
440 if options['verbose'] or options['debug'] or options['quiet']:
432 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
441 ui.setconfig('ui', 'verbose', str(bool(options['verbose'])))
433 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
442 ui.setconfig('ui', 'debug', str(bool(options['debug'])))
434 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
443 ui.setconfig('ui', 'quiet', str(bool(options['quiet'])))
435 if options['traceback']:
444 if options['traceback']:
436 ui.setconfig('ui', 'traceback', 'on')
445 ui.setconfig('ui', 'traceback', 'on')
437 if options['noninteractive']:
446 if options['noninteractive']:
438 ui.setconfig('ui', 'interactive', 'off')
447 ui.setconfig('ui', 'interactive', 'off')
439
448
440 if options['help']:
449 if options['help']:
441 return commands.help_(ui, cmd, options['version'])
450 return commands.help_(ui, cmd, options['version'])
442 elif options['version']:
451 elif options['version']:
443 return commands.version_(ui)
452 return commands.version_(ui)
444 elif not cmd:
453 elif not cmd:
445 return commands.help_(ui, 'shortlist')
454 return commands.help_(ui, 'shortlist')
446
455
447 repo = None
456 repo = None
448 if cmd not in commands.norepo.split():
457 if cmd not in commands.norepo.split():
449 try:
458 try:
450 repo = hg.repository(ui, path=path)
459 repo = hg.repository(ui, path=path)
451 ui = repo.ui
460 ui = repo.ui
452 if not repo.local():
461 if not repo.local():
453 raise util.Abort(_("repository '%s' is not local") % path)
462 raise util.Abort(_("repository '%s' is not local") % path)
454 ui.setconfig("bundle", "mainreporoot", repo.root)
463 ui.setconfig("bundle", "mainreporoot", repo.root)
455 except error.RepoError:
464 except error.RepoError:
456 if cmd not in commands.optionalrepo.split():
465 if cmd not in commands.optionalrepo.split():
457 if args and not path: # try to infer -R from command args
466 if args and not path: # try to infer -R from command args
458 repos = map(cmdutil.findrepo, args)
467 repos = map(cmdutil.findrepo, args)
459 guess = repos[0]
468 guess = repos[0]
460 if guess and repos.count(guess) == len(repos):
469 if guess and repos.count(guess) == len(repos):
461 return _dispatch(ui, ['--repository', guess] + fullargs)
470 return _dispatch(ui, ['--repository', guess] + fullargs)
462 if not path:
471 if not path:
463 raise error.RepoError(_("There is no Mercurial repository"
472 raise error.RepoError(_("There is no Mercurial repository"
464 " here (.hg not found)"))
473 " here (.hg not found)"))
465 raise
474 raise
466 args.insert(0, repo)
475 args.insert(0, repo)
467 elif rpath:
476 elif rpath:
468 ui.warn("warning: --repository ignored\n")
477 ui.warn("warning: --repository ignored\n")
469
478
470 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
479 d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
471 return runcommand(lui, repo, cmd, fullargs, ui, options, d)
480 return runcommand(lui, repo, cmd, fullargs, ui, options, d)
472
481
473 def _runcommand(ui, options, cmd, cmdfunc):
482 def _runcommand(ui, options, cmd, cmdfunc):
474 def checkargs():
483 def checkargs():
475 try:
484 try:
476 return cmdfunc()
485 return cmdfunc()
477 except error.SignatureError:
486 except error.SignatureError:
478 raise error.CommandError(cmd, _("invalid arguments"))
487 raise error.CommandError(cmd, _("invalid arguments"))
479
488
480 if options['profile']:
489 if options['profile']:
481 format = ui.config('profiling', 'format', default='text')
490 format = ui.config('profiling', 'format', default='text')
482
491
483 if not format in ['text', 'kcachegrind']:
492 if not format in ['text', 'kcachegrind']:
484 ui.warn(_("unrecognized profiling format '%s'"
493 ui.warn(_("unrecognized profiling format '%s'"
485 " - Ignored\n") % format)
494 " - Ignored\n") % format)
486 format = 'text'
495 format = 'text'
487
496
488 output = ui.config('profiling', 'output')
497 output = ui.config('profiling', 'output')
489
498
490 if output:
499 if output:
491 path = ui.expandpath(output)
500 path = ui.expandpath(output)
492 ostream = open(path, 'wb')
501 ostream = open(path, 'wb')
493 else:
502 else:
494 ostream = sys.stderr
503 ostream = sys.stderr
495
504
496 try:
505 try:
497 from mercurial import lsprof
506 from mercurial import lsprof
498 except ImportError:
507 except ImportError:
499 raise util.Abort(_(
508 raise util.Abort(_(
500 'lsprof not available - install from '
509 'lsprof not available - install from '
501 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
510 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
502 p = lsprof.Profiler()
511 p = lsprof.Profiler()
503 p.enable(subcalls=True)
512 p.enable(subcalls=True)
504 try:
513 try:
505 return checkargs()
514 return checkargs()
506 finally:
515 finally:
507 p.disable()
516 p.disable()
508
517
509 if format == 'kcachegrind':
518 if format == 'kcachegrind':
510 import lsprofcalltree
519 import lsprofcalltree
511 calltree = lsprofcalltree.KCacheGrind(p)
520 calltree = lsprofcalltree.KCacheGrind(p)
512 calltree.output(ostream)
521 calltree.output(ostream)
513 else:
522 else:
514 # format == 'text'
523 # format == 'text'
515 stats = lsprof.Stats(p.getstats())
524 stats = lsprof.Stats(p.getstats())
516 stats.sort()
525 stats.sort()
517 stats.pprint(top=10, file=ostream, climit=5)
526 stats.pprint(top=10, file=ostream, climit=5)
518
527
519 if output:
528 if output:
520 ostream.close()
529 ostream.close()
521 else:
530 else:
522 return checkargs()
531 return checkargs()
@@ -1,75 +1,78 b''
1 # error.py - Mercurial exceptions
1 # error.py - Mercurial exceptions
2 #
2 #
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 """Mercurial exceptions.
8 """Mercurial exceptions.
9
9
10 This allows us to catch exceptions at higher levels without forcing
10 This allows us to catch exceptions at higher levels without forcing
11 imports.
11 imports.
12 """
12 """
13
13
14 # Do not import anything here, please
14 # Do not import anything here, please
15
15
16 class RevlogError(Exception):
16 class RevlogError(Exception):
17 pass
17 pass
18
18
19 class LookupError(RevlogError, KeyError):
19 class LookupError(RevlogError, KeyError):
20 def __init__(self, name, index, message):
20 def __init__(self, name, index, message):
21 self.name = name
21 self.name = name
22 if isinstance(name, str) and len(name) == 20:
22 if isinstance(name, str) and len(name) == 20:
23 from node import short
23 from node import short
24 name = short(name)
24 name = short(name)
25 RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
25 RevlogError.__init__(self, '%s@%s: %s' % (index, name, message))
26
26
27 def __str__(self):
27 def __str__(self):
28 return RevlogError.__str__(self)
28 return RevlogError.__str__(self)
29
29
30 class CommandError(Exception):
30 class CommandError(Exception):
31 """Exception raised on errors in parsing the command line."""
31 """Exception raised on errors in parsing the command line."""
32
32
33 class ConfigError(Exception):
33 class Abort(Exception):
34 """Raised if a command needs to print an error and exit."""
35
36 class ConfigError(Abort):
34 'Exception raised when parsing config files'
37 'Exception raised when parsing config files'
35
38
39 class ParseError(Abort):
40 'Exception raised when parsing config files (msg[, pos])'
41
36 class RepoError(Exception):
42 class RepoError(Exception):
37 pass
43 pass
38
44
39 class RepoLookupError(RepoError):
45 class RepoLookupError(RepoError):
40 pass
46 pass
41
47
42 class CapabilityError(RepoError):
48 class CapabilityError(RepoError):
43 pass
49 pass
44
50
45 class LockError(IOError):
51 class LockError(IOError):
46 def __init__(self, errno, strerror, filename, desc):
52 def __init__(self, errno, strerror, filename, desc):
47 IOError.__init__(self, errno, strerror, filename)
53 IOError.__init__(self, errno, strerror, filename)
48 self.desc = desc
54 self.desc = desc
49
55
50 class LockHeld(LockError):
56 class LockHeld(LockError):
51 def __init__(self, errno, filename, desc, locker):
57 def __init__(self, errno, filename, desc, locker):
52 LockError.__init__(self, errno, 'Lock held', filename, desc)
58 LockError.__init__(self, errno, 'Lock held', filename, desc)
53 self.locker = locker
59 self.locker = locker
54
60
55 class LockUnavailable(LockError):
61 class LockUnavailable(LockError):
56 pass
62 pass
57
63
58 class ResponseError(Exception):
64 class ResponseError(Exception):
59 """Raised to print an error with part of output and exit."""
65 """Raised to print an error with part of output and exit."""
60
66
61 class UnknownCommand(Exception):
67 class UnknownCommand(Exception):
62 """Exception raised if command is not in the command table."""
68 """Exception raised if command is not in the command table."""
63
69
64 class AmbiguousCommand(Exception):
70 class AmbiguousCommand(Exception):
65 """Exception raised if command shortcut matches more than one command."""
71 """Exception raised if command shortcut matches more than one command."""
66
72
67 # derived from KeyboardInterrupt to simplify some breakout code
73 # derived from KeyboardInterrupt to simplify some breakout code
68 class SignalInterrupt(KeyboardInterrupt):
74 class SignalInterrupt(KeyboardInterrupt):
69 """Exception raised on SIGTERM and SIGHUP."""
75 """Exception raised on SIGTERM and SIGHUP."""
70
76
71 class SignatureError(Exception):
77 class SignatureError(Exception):
72 pass
78 pass
73
74 class Abort(Exception):
75 """Raised if a command needs to print an error and exit."""
General Comments 0
You need to be logged in to leave comments. Login now