##// END OF EJS Templates
fsmonitor: normalize exception types to bytes...
Gregory Szorc -
r43716:9a8f8c6e stable
parent child Browse files
Show More
@@ -1,119 +1,129 b''
1 # watchmanclient.py - Watchman client for the fsmonitor extension
1 # watchmanclient.py - Watchman client for the fsmonitor extension
2 #
2 #
3 # Copyright 2013-2016 Facebook, Inc.
3 # Copyright 2013-2016 Facebook, Inc.
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 __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import getpass
10 import getpass
11
11
12 from mercurial import util
12 from mercurial import (
13 from mercurial.utils import procutil
13 encoding,
14 util,
15 )
16 from mercurial.utils import (
17 procutil,
18 stringutil,
19 )
14
20
15 from . import pywatchman
21 from . import pywatchman
16
22
17
23
18 class Unavailable(Exception):
24 class Unavailable(Exception):
19 def __init__(self, msg, warn=True, invalidate=False):
25 def __init__(self, msg, warn=True, invalidate=False):
20 self.msg = msg
26 self.msg = msg
21 self.warn = warn
27 self.warn = warn
22 if self.msg == b'timed out waiting for response':
28 if self.msg == b'timed out waiting for response':
23 self.warn = False
29 self.warn = False
24 self.invalidate = invalidate
30 self.invalidate = invalidate
25
31
26 def __str__(self):
32 def __bytes__(self):
27 if self.warn:
33 if self.warn:
28 return b'warning: Watchman unavailable: %s' % self.msg
34 return b'warning: Watchman unavailable: %s' % self.msg
29 else:
35 else:
30 return b'Watchman unavailable: %s' % self.msg
36 return b'Watchman unavailable: %s' % self.msg
31
37
38 __str__ = encoding.strmethod(__bytes__)
39
32
40
33 class WatchmanNoRoot(Unavailable):
41 class WatchmanNoRoot(Unavailable):
34 def __init__(self, root, msg):
42 def __init__(self, root, msg):
35 self.root = root
43 self.root = root
36 super(WatchmanNoRoot, self).__init__(msg)
44 super(WatchmanNoRoot, self).__init__(msg)
37
45
38
46
39 class client(object):
47 class client(object):
40 def __init__(self, ui, root, timeout=1.0):
48 def __init__(self, ui, root, timeout=1.0):
41 err = None
49 err = None
42 if not self._user:
50 if not self._user:
43 err = b"couldn't get user"
51 err = b"couldn't get user"
44 warn = True
52 warn = True
45 if self._user in ui.configlist(b'fsmonitor', b'blacklistusers'):
53 if self._user in ui.configlist(b'fsmonitor', b'blacklistusers'):
46 err = b'user %s in blacklist' % self._user
54 err = b'user %s in blacklist' % self._user
47 warn = False
55 warn = False
48
56
49 if err:
57 if err:
50 raise Unavailable(err, warn)
58 raise Unavailable(err, warn)
51
59
52 self._timeout = timeout
60 self._timeout = timeout
53 self._watchmanclient = None
61 self._watchmanclient = None
54 self._root = root
62 self._root = root
55 self._ui = ui
63 self._ui = ui
56 self._firsttime = True
64 self._firsttime = True
57
65
58 def settimeout(self, timeout):
66 def settimeout(self, timeout):
59 self._timeout = timeout
67 self._timeout = timeout
60 if self._watchmanclient is not None:
68 if self._watchmanclient is not None:
61 self._watchmanclient.setTimeout(timeout)
69 self._watchmanclient.setTimeout(timeout)
62
70
63 def getcurrentclock(self):
71 def getcurrentclock(self):
64 result = self.command(b'clock')
72 result = self.command(b'clock')
65 if not util.safehasattr(result, 'clock'):
73 if not util.safehasattr(result, 'clock'):
66 raise Unavailable(
74 raise Unavailable(
67 b'clock result is missing clock value', invalidate=True
75 b'clock result is missing clock value', invalidate=True
68 )
76 )
69 return result.clock
77 return result.clock
70
78
71 def clearconnection(self):
79 def clearconnection(self):
72 self._watchmanclient = None
80 self._watchmanclient = None
73
81
74 def available(self):
82 def available(self):
75 return self._watchmanclient is not None or self._firsttime
83 return self._watchmanclient is not None or self._firsttime
76
84
77 @util.propertycache
85 @util.propertycache
78 def _user(self):
86 def _user(self):
79 try:
87 try:
80 return getpass.getuser()
88 return getpass.getuser()
81 except KeyError:
89 except KeyError:
82 # couldn't figure out our user
90 # couldn't figure out our user
83 return None
91 return None
84
92
85 def _command(self, *args):
93 def _command(self, *args):
86 watchmanargs = (args[0], self._root) + args[1:]
94 watchmanargs = (args[0], self._root) + args[1:]
87 try:
95 try:
88 if self._watchmanclient is None:
96 if self._watchmanclient is None:
89 self._firsttime = False
97 self._firsttime = False
90 watchman_exe = self._ui.configpath(
98 watchman_exe = self._ui.configpath(
91 b'fsmonitor', b'watchman_exe'
99 b'fsmonitor', b'watchman_exe'
92 )
100 )
93 self._watchmanclient = pywatchman.client(
101 self._watchmanclient = pywatchman.client(
94 timeout=self._timeout,
102 timeout=self._timeout,
95 useImmutableBser=True,
103 useImmutableBser=True,
96 binpath=procutil.tonativestr(watchman_exe),
104 binpath=procutil.tonativestr(watchman_exe),
97 )
105 )
98 return self._watchmanclient.query(*watchmanargs)
106 return self._watchmanclient.query(*watchmanargs)
99 except pywatchman.CommandError as ex:
107 except pywatchman.CommandError as ex:
100 if b'unable to resolve root' in ex.msg:
108 if b'unable to resolve root' in ex.msg:
101 raise WatchmanNoRoot(self._root, ex.msg)
109 raise WatchmanNoRoot(
110 self._root, stringutil.forcebytestr(ex.msg)
111 )
102 raise Unavailable(ex.msg)
112 raise Unavailable(ex.msg)
103 except pywatchman.WatchmanError as ex:
113 except pywatchman.WatchmanError as ex:
104 raise Unavailable(str(ex))
114 raise Unavailable(stringutil.forcebytestr(ex))
105
115
106 def command(self, *args):
116 def command(self, *args):
107 try:
117 try:
108 try:
118 try:
109 return self._command(*args)
119 return self._command(*args)
110 except WatchmanNoRoot:
120 except WatchmanNoRoot:
111 # this 'watch' command can also raise a WatchmanNoRoot if
121 # this 'watch' command can also raise a WatchmanNoRoot if
112 # watchman refuses to accept this root
122 # watchman refuses to accept this root
113 self._command(b'watch')
123 self._command(b'watch')
114 return self._command(*args)
124 return self._command(*args)
115 except Unavailable:
125 except Unavailable:
116 # this is in an outer scope to catch Unavailable form any of the
126 # this is in an outer scope to catch Unavailable form any of the
117 # above _command calls
127 # above _command calls
118 self._watchmanclient = None
128 self._watchmanclient = None
119 raise
129 raise
General Comments 0
You need to be logged in to leave comments. Login now