view hgext/fsmonitor/watchmanclient.py @ 41847:0f49b56d5d74

inno: replace add_path.exe with a Pascal script While attempting to build the Inno installer, I was unable to find a copy of add_path.exe from the source site previously listed in the docs. Some quick Googling revealed that achieving this functionality in native Pascal scripts seems to be preferred these days. This commit vendors "Modify Path" (fetched from https://www.legroom.net/software/modpath) and plugs it into our Inno config file per its instructions. The existing Inno installer appears to only modify PATH for the current user (as opposed to at the system level). I've maintained this behavior with Modify Path. Although it would be trivial to change or add checkboxes to control the behavior. I'll leave this as a follow-up. Differential Revision: https://phab.mercurial-scm.org/D6060
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 28 Feb 2019 12:54:48 -0800
parents b0a0f7b9ed90
children 57264906a996
line wrap: on
line source

# watchmanclient.py - Watchman client for the fsmonitor extension
#
# Copyright 2013-2016 Facebook, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.

from __future__ import absolute_import

import getpass

from mercurial import util

from . import pywatchman

class Unavailable(Exception):
    def __init__(self, msg, warn=True, invalidate=False):
        self.msg = msg
        self.warn = warn
        if self.msg == 'timed out waiting for response':
            self.warn = False
        self.invalidate = invalidate

    def __str__(self):
        if self.warn:
            return 'warning: Watchman unavailable: %s' % self.msg
        else:
            return 'Watchman unavailable: %s' % self.msg

class WatchmanNoRoot(Unavailable):
    def __init__(self, root, msg):
        self.root = root
        super(WatchmanNoRoot, self).__init__(msg)

class client(object):
    def __init__(self, repo, timeout=1.0):
        err = None
        if not self._user:
            err = "couldn't get user"
            warn = True
        if self._user in repo.ui.configlist('fsmonitor', 'blacklistusers'):
            err = 'user %s in blacklist' % self._user
            warn = False

        if err:
            raise Unavailable(err, warn)

        self._timeout = timeout
        self._watchmanclient = None
        self._root = repo.root
        self._ui = repo.ui
        self._firsttime = True

    def settimeout(self, timeout):
        self._timeout = timeout
        if self._watchmanclient is not None:
            self._watchmanclient.setTimeout(timeout)

    def getcurrentclock(self):
        result = self.command('clock')
        if not util.safehasattr(result, 'clock'):
            raise Unavailable('clock result is missing clock value',
                              invalidate=True)
        return result.clock

    def clearconnection(self):
        self._watchmanclient = None

    def available(self):
        return self._watchmanclient is not None or self._firsttime

    @util.propertycache
    def _user(self):
        try:
            return getpass.getuser()
        except KeyError:
            # couldn't figure out our user
            return None

    def _command(self, *args):
        watchmanargs = (args[0], self._root) + args[1:]
        try:
            if self._watchmanclient is None:
                self._firsttime = False
                self._watchmanclient = pywatchman.client(
                    timeout=self._timeout,
                    useImmutableBser=True)
            return self._watchmanclient.query(*watchmanargs)
        except pywatchman.CommandError as ex:
            if 'unable to resolve root' in ex.msg:
                raise WatchmanNoRoot(self._root, ex.msg)
            raise Unavailable(ex.msg)
        except pywatchman.WatchmanError as ex:
            raise Unavailable(str(ex))

    def command(self, *args):
        try:
            try:
                return self._command(*args)
            except WatchmanNoRoot:
                # this 'watch' command can also raise a WatchmanNoRoot if
                # watchman refuses to accept this root
                self._command('watch')
                return self._command(*args)
        except Unavailable:
            # this is in an outer scope to catch Unavailable form any of the
            # above _command calls
            self._watchmanclient = None
            raise