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