def start(self):
        args = [
            'watchman',
            '--foreground',
            '--log-level=2',
        ]
        args.extend(self.get_state_args())
        env = os.environ.copy()
        env["WATCHMAN_CONFIG_FILE"] = self.cfg_file
        self.proc = subprocess.Popen(args,
                                     env=env,
                                     stdin=None,
                                     stdout=self.cli_log_file,
                                     stderr=self.cli_log_file)

        # wait for it to come up
        deadline = time.time() + self.start_timeout
        while time.time() < deadline:
            try:
                client = pywatchman.client(sockpath=self.sock_file)
                self.pid = client.query('get-pid')['pid']
                break
            except Exception as e:
                t, val, tb = sys.exc_info()
                time.sleep(0.1)
            finally:
                client.close()

        if self.pid is None:
            pywatchman.compat.reraise(t, val, tb)
Example #2
0
    def start(self):
        args = [
            'watchman',
            '--foreground',
            '--sockname={0}'.format(self.sock_file),
            '--logfile={0}'.format(self.log_file_name),
            '--statefile={0}'.format(self.state_file),
            '--log-level=2',
        ]
        env = os.environ.copy()
        env["WATCHMAN_CONFIG_FILE"] = self.cfg_file
        self.proc = subprocess.Popen(args,
                                     env=env,
                                     stdin=None,
                                     stdout=self.log_file,
                                     stderr=self.log_file)

        # wait for it to come up
        last_err = None
        for i in range(1, 10):
            try:
                client = pywatchman.client(sockpath=self.sock_file)
                self.pid = client.query('get-pid')['pid']
                break
            except Exception as e:
                t, val, tb = sys.exc_info()
                last_err = ''.join(traceback.format_exception(t, val, tb))
                time.sleep(0.1)
            finally:
                client.close()

        if self.pid is None:
            raise Exception(last_err)
Example #3
0
    def start(self):
        args = [
            'watchman',
            '--foreground',
            '--sockname={}'.format(self.sock_file),
            '--logfile={}'.format(self.log_file_name),
            '--statefile={}'.format(self.state_file),
            '--log-level=2',
        ]
        env = os.environ.copy()
        env["WATCHMAN_CONFIG_FILE"] = self.cfg_file
        self.proc = subprocess.Popen(args,
                                     env=env,
                                     stdin=None,
                                     stdout=self.log_file,
                                     stderr=self.log_file)

        # wait for it to come up
        last_err = None
        for i in xrange(1, 10):
            try:
                client = pywatchman.client(sockpath=self.sock_file)
                self.pid = client.query('get-pid')['pid']
                break
            except Exception as e:
                last_err = e
                time.sleep(0.1)

        if not self.pid:
            raise last_err
Example #4
0
    def start(self):
        args = [self.watchmanBinary(), "--foreground", "--log-level=2"]
        args.extend(self.get_state_args())
        env = os.environ.copy()
        env["WATCHMAN_CONFIG_FILE"] = self.cfg_file
        with open(self.cli_log_file_name, "w+") as cli_log_file:
            self.proc = subprocess.Popen(
                args, env=env, stdin=None, stdout=cli_log_file, stderr=cli_log_file
            )
        if self.debug_watchman:
            print("Watchman instance PID: " + str(self.proc.pid))
            if pywatchman.compat.PYTHON3:
                user_input = input
            else:
                user_input = raw_input  # noqa:F821
            user_input("Press Enter to continue...")

        # wait for it to come up
        deadline = time.time() + self.start_timeout
        while time.time() < deadline:
            try:
                client = pywatchman.client(sockpath=self.sock_file)
                self.pid = client.query("get-pid")["pid"]
                break
            except pywatchman.SocketConnectError:
                t, val, tb = sys.exc_info()
                time.sleep(0.1)
            finally:
                client.close()

        if self.pid is None:
            # self.proc didn't come up: wait for it to die
            self.stop()
            pywatchman.compat.reraise(t, val, tb)
Example #5
0
 def test_client(self):
     # verify that we can talk to the instance set up by the harness
     # we're just verifying that the socket set in the environment works
     # and that we can understand the result
     sock = os.getenv('WATCHMAN_SOCK')
     c = pywatchman.client()
     res = c.query('get-sockname')
     self.assertEquals(sock, res['sockname'])
Example #6
0
 def getClient(self):
     if not hasattr(self, 'client'):
         self.client = pywatchman.client(
             transport=self.transport,
             sendEncoding=self.encoding,
             recvEncoding=self.encoding,
             sockpath=WatchmanInstance.getSharedInstance().getSockPath())
     return self.client
 def getClient(self):
     if not hasattr(self, 'client'):
         self.client = pywatchman.client(
             # ASAN-enabled builds can be slower enough that we hit timeouts
             # with the default of 1 second
             timeout=3.0,
             transport=self.transport,
             sendEncoding=self.encoding,
             recvEncoding=self.encoding,
             sockpath=WatchmanInstance.getSharedInstance().getSockPath())
     return self.client
Example #8
0
 def getClient(self, inst=None, replace_cached=False, no_cache=False):
     if inst or not hasattr(self, "client") or no_cache:
         client = pywatchman.client(
             timeout=self.socketTimeout,
             transport=self.transport,
             sendEncoding=self.encoding,
             recvEncoding=self.encoding,
             sockpath=(inst or WatchmanInstance.getSharedInstance()).getSockPath(),
         )
         if (not inst or replace_cached) and not no_cache:
             # only cache the client if it points to the shared instance
             self.client = client
             self.addCleanup(lambda: self.__clearClient())
         return client
     return self.client
Example #9
0
 def check_availability(cls):
     if not pywatchman:
         raise WatchmanUnavailable('pywatchman not installed.')
     client = pywatchman.client(timeout=0.1)
     try:
         result = client.capabilityCheck()
     except Exception:
         # The service is down?
         raise WatchmanUnavailable('Cannot connect to the watchman service.')
     version = get_version_tuple(result['version'])
     # Watchman 4.9 includes multiple improvements to watching project
     # directories as well as case insensitive filesystems.
     logger.debug('Watchman version %s', version)
     if version < (4, 9):
         raise WatchmanUnavailable('Watchman 4.9 or later is required.')
Example #10
0
 def getClient(self, inst=None):
     if inst or not hasattr(self, 'client'):
         client = pywatchman.client(
             # ASAN-enabled builds can be slower enough that we hit timeouts
             # with the default of 1 second
             timeout=3.0,
             transport=self.transport,
             sendEncoding=self.encoding,
             recvEncoding=self.encoding,
             sockpath=(inst or
                       WatchmanInstance.getSharedInstance()).getSockPath())
         if not inst:
             # only cache the client if it points to the shared instance
             self.client = client
         return client
     return self.client
Example #11
0
    def test_transport_error(self):
        buf = '{"foo":"bar"}'
        failAfterBytesRead = 5

        class FakeFailingTransport(Transport):
            def __init__(self, sockpath, timeout):
                self.readBuf = buf
                self.readBufPos = 0
                self.writeBuf = []
                self.closed = False

            def close(self):
                self.closed = True

            def readBytes(self, size):
                readEnd = self.readBufPos + size
                if readEnd > failAfterBytesRead:
                    raise IOError(23, "fnord")
                elif readEnd > len(self.readBuf):
                    return ""
                read = self.readBuf[self.readBufPos : self.readBufPos + size]
                self.readBufPos += size
                return read

            def write(self, buf):
                self.writeBuf.extend(buf)

        c = client(
            sockpath="",
            transport=FakeFailingTransport,
            sendEncoding="json",
            recvEncoding="json",
        )
        try:
            c.query("foobarbaz")
            self.assertTrue(False, "expected a WatchmanError")
        except WatchmanError as e:
            self.assertIn(
                "I/O error communicating with watchman daemon: "
                + "errno=23 errmsg=fnord, while executing "
                + "('foobarbaz',)",
                str(e),
            )
        except Exception as e:
            self.assertTrue(False, "expected a WatchmanError, but got " + str(e))
Example #12
0
    def start(self):
        args = [
            self.watchmanBinary(),
            '--foreground',
            '--log-level=2',
        ]
        args.extend(self.get_state_args())
        env = os.environ.copy()
        env["WATCHMAN_CONFIG_FILE"] = self.cfg_file
        self.proc = subprocess.Popen(args,
                                     env=env,
                                     stdin=None,
                                     stdout=self.cli_log_file,
                                     stderr=self.cli_log_file)
        if self.debug_watchman:
            print('Watchman instance PID: ' + str(self.proc.pid))
            if pywatchman.compat.PYTHON3:
                user_input = input
            else:
                user_input = raw_input
            user_input('Press Enter to continue...')

        # wait for it to come up
        deadline = time.time() + self.start_timeout
        while time.time() < deadline:
            try:
                client = pywatchman.client(sockpath=self.sock_file)
                self.pid = client.query('get-pid')['pid']
                break
            except Exception as e:
                t, val, tb = sys.exc_info()
                time.sleep(0.1)
            finally:
                client.close()

        if self.pid is None:
            # self.proc didn't come up: wait for it to die
            self.stop()
            pywatchman.compat.reraise(t, val, tb)
Example #13
0
 def client(self):
     return pywatchman.client(timeout=self.client_timeout)
Example #14
0
def runner():
    global results_queue
    global tests_queue

    broken = False
    try:
        # Start up a shared watchman instance for the tests.
        inst = WatchmanInstance.Instance({"watcher": args.watcher},
                                         debug_watchman=args.debug_watchman)
        inst.start()
        # Allow tests to locate this default instance
        WatchmanInstance.setSharedInstance(inst)

        if has_asyncio:
            # Each thread will have its own event loop
            asyncio.set_event_loop(asyncio.new_event_loop())

    except Exception as e:
        print("while starting watchman: %s" % str(e))
        traceback.print_exc()
        broken = True

    while not broken:
        test = tests_queue.get()
        try:
            if test == "terminate":
                break

            if Interrupt.wasInterrupted() or broken:
                continue

            result = None
            for attempt in range(0, args.retry_flaky + 1):
                # Check liveness of the server
                try:
                    client = pywatchman.client(timeout=3.0,
                                               sockpath=inst.getSockPath())
                    client.query("version")
                    client.close()
                except Exception as exc:
                    print(
                        "Failed to connect to watchman server: %s; starting a new one"
                        % exc)

                    try:
                        inst.stop()
                    except Exception:
                        pass

                    try:
                        inst = WatchmanInstance.Instance(
                            {"watcher": args.watcher},
                            debug_watchman=args.debug_watchman,
                        )
                        inst.start()
                        # Allow tests to locate this default instance
                        WatchmanInstance.setSharedInstance(inst)
                    except Exception as e:
                        print("while starting watchman: %s" % str(e))
                        traceback.print_exc()
                        broken = True
                        continue

                try:
                    result = Result()
                    result.setAttemptNumber(attempt)

                    if hasattr(test, "setAttemptNumber"):
                        test.setAttemptNumber(attempt)

                    test.run(result)

                    if hasattr(
                            test,
                            "setAttemptNumber") and not result.wasSuccessful():
                        # Facilitate retrying this possibly flaky test
                        continue

                    break
                except Exception as e:
                    print(e)

                    if hasattr(
                            test,
                            "setAttemptNumber") and not result.wasSuccessful():
                        # Facilitate retrying this possibly flaky test
                        continue

            if (not result.wasSuccessful() and "TRAVIS" in os.environ
                    and hasattr(test, "dumpLogs")):
                test.dumpLogs()

            results_queue.put(result)

        finally:
            tests_queue.task_done()

    if not broken:
        inst.stop()
Example #15
0
    def input_changes(self, verbose=True):
        '''
        Return an iterator of `FasterBuildChange` instances as inputs
        to the faster build system change.
        '''

        # TODO: provide the debug diagnostics we want: this print is
        # not immediately before the watch.
        if verbose:
            print_line('watch', 'Connecting to watchman')
        # TODO: figure out why a large timeout is required for the
        # client, and a robust strategy for retrying timed out
        # requests.
        self.client = pywatchman.client(timeout=5.0)

        try:
            if verbose:
                print_line('watch', 'Checking watchman capabilities')
            # TODO: restrict these capabilities to the minimal set.
            self.client.capabilityCheck(required=[
                'clock-sync-timeout',
                'cmd-watch-project',
                'term-dirname',
                'wildmatch',
            ])

            if verbose:
                print_line('watch', 'Subscribing to {}'.format(self.config_environment.topsrcdir))
            self.subscribe_to_topsrcdir()
            if verbose:
                print_line('watch', 'Watching {}'.format(self.config_environment.topsrcdir))

            input_to_outputs = self.file_copier.input_to_outputs_tree()
            for input, outputs in input_to_outputs.items():
                if not outputs:
                    raise Exception("Refusing to watch input ({}) with no outputs".format(input))

            while True:
                try:
                    _watch_result = self.client.receive()

                    changed = self.changed_files()
                    if not changed:
                        continue

                    result = FasterBuildChange()

                    for change in changed:
                        if change in input_to_outputs:
                            result.input_to_outputs[change] = set(input_to_outputs[change])
                        else:
                            result.unrecognized.add(change)

                    for input, outputs in result.input_to_outputs.items():
                        for output in outputs:
                            if output not in result.output_to_inputs:
                                result.output_to_inputs[output] = set()
                            result.output_to_inputs[output].add(input)

                    yield result

                except pywatchman.SocketTimeout:
                    # Let's check to see if we're still functional.
                    _version = self.client.query('version')

        except pywatchman.CommandError as e:
            # Abstract away pywatchman errors.
            raise FasterBuildException(e, 'Command error using pywatchman to watch {}'.format(
                self.config_environment.topsrcdir))

        except pywatchman.SocketTimeout as e:
            # Abstract away pywatchman errors.
            raise FasterBuildException(e, 'Socket timeout using pywatchman to watch {}'.format(
                self.config_environment.topsrcdir))

        finally:
            self.client.close()
Example #16
0
 def getClient(self):
     if not hasattr(self, 'client'):
         self.client = pywatchman.client()
     return self.client
Example #17
0
 def client(self):
     return pywatchman.client(timeout=self.client_timeout)
Example #18
0
def main():
    # Our parent expects to read BSER from our stdout, so if anyone
    # uses print, buck will complain with a helpful "but I wanted an
    # array!" message and quit.  Redirect stdout to stderr so that
    # doesn't happen.  Actually dup2 the file handle so that writing
    # to file descriptor 1, os.system, and so on work as expected too.

    to_parent = os.fdopen(os.dup(sys.stdout.fileno()), 'ab')
    os.dup2(sys.stderr.fileno(), sys.stdout.fileno())

    parser = optparse.OptionParser()
    parser.add_option('--project_root',
                      action='store',
                      type='string',
                      dest='project_root')
    parser.add_option('--build_file_name',
                      action='store',
                      type='string',
                      dest="build_file_name")
    parser.add_option(
        '--allow_empty_globs',
        action='store_true',
        dest='allow_empty_globs',
        help=
        'Tells the parser not to raise an error when glob returns no results.')
    parser.add_option(
        '--use_watchman_glob',
        action='store_true',
        dest='use_watchman_glob',
        help=
        'Invokes `watchman query` to get lists of files instead of globbing in-process.'
    )
    parser.add_option(
        '--watchman_watch_root',
        action='store',
        type='string',
        dest='watchman_watch_root',
        help=
        'Path to root of watchman watch as returned by `watchman watch-project`.'
    )
    parser.add_option(
        '--watchman_socket_path',
        action='store',
        type='string',
        dest='watchman_socket_path',
        help=
        'Path to Unix domain socket/named pipe as returned by `watchman get-sockname`.'
    )
    parser.add_option(
        '--watchman_project_prefix',
        action='store',
        type='string',
        dest='watchman_project_prefix',
        help='Relative project prefix as returned by `watchman watch-project`.'
    )
    parser.add_option(
        '--watchman_query_timeout_ms',
        action='store',
        type='int',
        dest='watchman_query_timeout_ms',
        help=
        'Maximum time in milliseconds to wait for watchman query to respond.')
    parser.add_option('--include', action='append', dest='include')
    parser.add_option('--config',
                      help='BuckConfig settings available at parse time.')
    parser.add_option(
        '--quiet',
        action='store_true',
        dest='quiet',
        help='Stifles exception backtraces printed to stderr during parsing.')
    parser.add_option('--ignore_buck_autodeps_files',
                      action='store_true',
                      help='Profile every buck file execution')
    parser.add_option('--profile',
                      action='store_true',
                      help='Profile every buck file execution')
    (options, args) = parser.parse_args()

    # Even though project_root is absolute path, it may not be concise. For
    # example, it might be like "C:\project\.\rule".
    #
    # Under cygwin, the project root will be invoked from buck as C:\path, but
    # the cygwin python uses UNIX-style paths. They can be converted using
    # cygpath, which is necessary because abspath will treat C:\path as a
    # relative path.
    options.project_root = cygwin_adjusted_path(options.project_root)
    project_root = os.path.abspath(options.project_root)

    watchman_client = None
    watchman_error = None
    if options.use_watchman_glob:
        import pywatchman
        client_args = {}
        if options.watchman_query_timeout_ms is not None:
            # pywatchman expects a timeout as a nonnegative floating-point
            # value in seconds.
            client_args['timeout'] = max(
                0.0, options.watchman_query_timeout_ms / 1000.0)
        if options.watchman_socket_path is not None:
            client_args['sockpath'] = options.watchman_socket_path
            client_args['transport'] = 'local'
        watchman_client = pywatchman.client(**client_args)
        watchman_error = pywatchman.WatchmanError

    configs = {}
    if options.config is not None:
        with open(options.config, 'rb') as f:
            for section, contents in bser.loads(f.read()).iteritems():
                for field, value in contents.iteritems():
                    configs[(section, field)] = value

    buildFileProcessor = BuildFileProcessor(project_root,
                                            options.watchman_watch_root,
                                            options.watchman_project_prefix,
                                            options.build_file_name,
                                            options.allow_empty_globs,
                                            options.ignore_buck_autodeps_files,
                                            watchman_client,
                                            watchman_error,
                                            implicit_includes=options.include
                                            or [],
                                            configs=configs)

    buildFileProcessor.install_builtins(__builtin__.__dict__)

    # While processing, we'll write exceptions as diagnostic messages
    # to the parent then re-raise them to crash the process. While
    # doing so, we don't want Python's default unhandled exception
    # behavior of writing to stderr.
    orig_excepthook = None
    if options.quiet:
        orig_excepthook = sys.excepthook
        sys.excepthook = silent_excepthook

    for build_file in args:
        process_with_diagnostics(build_file,
                                 buildFileProcessor,
                                 to_parent,
                                 should_profile=options.profile)

    # "for ... in sys.stdin" in Python 2.x hangs until stdin is closed.
    for build_file in iter(sys.stdin.readline, ''):
        process_with_diagnostics(build_file,
                                 buildFileProcessor,
                                 to_parent,
                                 should_profile=options.profile)

    if options.quiet:
        sys.excepthook = orig_excepthook

    # Python tries to flush/close stdout when it quits, and if there's a dead
    # pipe on the other end, it will spit some warnings to stderr. This breaks
    # tests sometimes. Prevent that by explicitly catching the error.
    try:
        to_parent.close()
    except IOError:
        pass
Example #19
0
File: buck.py Project: heiniu/buck
def main():
    # Our parent expects to read JSON from our stdout, so if anyone
    # uses print, buck will complain with a helpful "but I wanted an
    # array!" message and quit.  Redirect stdout to stderr so that
    # doesn't happen.  Actually dup2 the file handle so that writing
    # to file descriptor 1, os.system, and so on work as expected too.

    to_parent = os.fdopen(os.dup(sys.stdout.fileno()), 'a')
    os.dup2(sys.stderr.fileno(), sys.stdout.fileno())

    parser = optparse.OptionParser()
    parser.add_option(
        '--project_root',
        action='store',
        type='string',
        dest='project_root')
    parser.add_option(
        '--build_file_name',
        action='store',
        type='string',
        dest="build_file_name")
    parser.add_option(
        '--allow_empty_globs',
        action='store_true',
        dest='allow_empty_globs',
        help='Tells the parser not to raise an error when glob returns no results.')
    parser.add_option(
        '--use_watchman_glob',
        action='store_true',
        dest='use_watchman_glob',
        help='Invokes `watchman query` to get lists of files instead of globbing in-process.')
    parser.add_option(
        '--watchman_watch_root',
        action='store',
        type='string',
        dest='watchman_watch_root',
        help='Path to root of watchman watch as returned by `watchman watch-project`.')
    parser.add_option(
        '--watchman_project_prefix',
        action='store',
        type='string',
        dest='watchman_project_prefix',
        help='Relative project prefix as returned by `watchman watch-project`.')
    parser.add_option(
        '--watchman_query_timeout_ms',
        action='store',
        type='int',
        dest='watchman_query_timeout_ms',
        help='Maximum time in milliseconds to wait for watchman query to respond.')
    parser.add_option(
        '--include',
        action='append',
        dest='include')
    (options, args) = parser.parse_args()

    # Even though project_root is absolute path, it may not be concise. For
    # example, it might be like "C:\project\.\rule".
    #
    # Under cygwin, the project root will be invoked from buck as C:\path, but
    # the cygwin python uses UNIX-style paths. They can be converted using
    # cygpath, which is necessary because abspath will treat C:\path as a
    # relative path.
    options.project_root = cygwin_adjusted_path(options.project_root)
    project_root = os.path.abspath(options.project_root)

    watchman_client = None
    watchman_error = None
    output_format = 'JSON'
    output_encode = lambda val: json.dumps(val, sort_keys=True)
    if options.use_watchman_glob:
        import pywatchman
        client_args = {}
        if options.watchman_query_timeout_ms is not None:
            # pywatchman expects a timeout as a nonnegative floating-point
            # value in seconds.
            client_args['timeout'] = max(0.0, options.watchman_query_timeout_ms / 1000.0)
        watchman_client = pywatchman.client(**client_args)
        watchman_error = pywatchman.WatchmanError
        try:
            import pywatchman.bser as bser
        except ImportError, e:
            import pywatchman.pybser as bser
        output_format = 'BSER'
        output_encode = lambda val: bser.dumps(val)
Example #20
0
def main():
    # Our parent expects to read BSER from our stdout, so if anyone
    # uses print, buck will complain with a helpful "but I wanted an
    # array!" message and quit.  Redirect stdout to stderr so that
    # doesn't happen.  Actually dup2 the file handle so that writing
    # to file descriptor 1, os.system, and so on work as expected too.

    to_parent = os.fdopen(os.dup(sys.stdout.fileno()), "a")
    os.dup2(sys.stderr.fileno(), sys.stdout.fileno())

    parser = optparse.OptionParser()
    parser.add_option("--project_root", action="store", type="string", dest="project_root")
    parser.add_option("--build_file_name", action="store", type="string", dest="build_file_name")
    parser.add_option(
        "--allow_empty_globs",
        action="store_true",
        dest="allow_empty_globs",
        help="Tells the parser not to raise an error when glob returns no results.",
    )
    parser.add_option(
        "--use_watchman_glob",
        action="store_true",
        dest="use_watchman_glob",
        help="Invokes `watchman query` to get lists of files instead of globbing in-process.",
    )
    parser.add_option(
        "--watchman_watch_root",
        action="store",
        type="string",
        dest="watchman_watch_root",
        help="Path to root of watchman watch as returned by `watchman watch-project`.",
    )
    parser.add_option(
        "--watchman_project_prefix",
        action="store",
        type="string",
        dest="watchman_project_prefix",
        help="Relative project prefix as returned by `watchman watch-project`.",
    )
    parser.add_option(
        "--watchman_query_timeout_ms",
        action="store",
        type="int",
        dest="watchman_query_timeout_ms",
        help="Maximum time in milliseconds to wait for watchman query to respond.",
    )
    parser.add_option("--include", action="append", dest="include")
    (options, args) = parser.parse_args()

    # Even though project_root is absolute path, it may not be concise. For
    # example, it might be like "C:\project\.\rule".
    #
    # Under cygwin, the project root will be invoked from buck as C:\path, but
    # the cygwin python uses UNIX-style paths. They can be converted using
    # cygpath, which is necessary because abspath will treat C:\path as a
    # relative path.
    options.project_root = cygwin_adjusted_path(options.project_root)
    project_root = os.path.abspath(options.project_root)

    watchman_client = None
    watchman_error = None
    if options.use_watchman_glob:
        import pywatchman

        client_args = {}
        if options.watchman_query_timeout_ms is not None:
            # pywatchman expects a timeout as a nonnegative floating-point
            # value in seconds.
            client_args["timeout"] = max(0.0, options.watchman_query_timeout_ms / 1000.0)
        watchman_client = pywatchman.client(**client_args)
        watchman_error = pywatchman.WatchmanError

    buildFileProcessor = BuildFileProcessor(
        project_root,
        options.watchman_watch_root,
        options.watchman_project_prefix,
        options.build_file_name,
        options.allow_empty_globs,
        watchman_client,
        watchman_error,
        implicit_includes=options.include or [],
    )

    buildFileProcessor.install_builtins(__builtin__.__dict__)

    for build_file in args:
        build_file = cygwin_adjusted_path(build_file)
        values = buildFileProcessor.process(build_file)
        to_parent.write(bser.dumps(values))
        to_parent.flush()

    # "for ... in sys.stdin" in Python 2.x hangs until stdin is closed.
    for build_file in iter(sys.stdin.readline, ""):
        build_file = cygwin_adjusted_path(build_file)
        values = buildFileProcessor.process(build_file.rstrip())
        to_parent.write(bser.dumps(values))
        to_parent.flush()

    # Python tries to flush/close stdout when it quits, and if there's a dead
    # pipe on the other end, it will spit some warnings to stderr. This breaks
    # tests sometimes. Prevent that by explicitly catching the error.
    try:
        to_parent.close()
    except IOError:
        pass
Example #21
0
def runner():
    global results_queue
    global tests_queue

    broken = False
    try:
        # Start up a shared watchman instance for the tests.
        inst = WatchmanInstance.Instance(
            {"watcher": args.watcher}, debug_watchman=args.debug_watchman
        )
        inst.start()
        # Allow tests to locate this default instance
        WatchmanInstance.setSharedInstance(inst)

        if has_asyncio:
            # Each thread will have its own event loop
            asyncio.set_event_loop(asyncio.new_event_loop())

    except Exception as e:
        print("while starting watchman: %s" % str(e))
        traceback.print_exc()
        broken = True

    while not broken:
        test = tests_queue.get()
        try:
            if test == "terminate":
                break

            if Interrupt.wasInterrupted() or broken:
                continue

            result = None
            for attempt in range(0, args.retry_flaky + 1):
                # Check liveness of the server
                try:
                    client = pywatchman.client(timeout=3.0, sockpath=inst.getSockPath())
                    client.query("version")
                    client.close()
                except Exception as exc:
                    print(
                        "Failed to connect to watchman server: %s; starting a new one"
                        % exc
                    )

                    try:
                        inst.stop()
                    except Exception:
                        pass

                    try:
                        inst = WatchmanInstance.Instance(
                            {"watcher": args.watcher},
                            debug_watchman=args.debug_watchman,
                        )
                        inst.start()
                        # Allow tests to locate this default instance
                        WatchmanInstance.setSharedInstance(inst)
                    except Exception as e:
                        print("while starting watchman: %s" % str(e))
                        traceback.print_exc()
                        broken = True
                        continue

                try:
                    result = Result()
                    result.setAttemptNumber(attempt)

                    if hasattr(test, "setAttemptNumber"):
                        test.setAttemptNumber(attempt)

                    test.run(result)

                    if hasattr(test, "setAttemptNumber") and not result.wasSuccessful():
                        # Facilitate retrying this possibly flaky test
                        continue

                    break
                except Exception as e:
                    print(e)

                    if hasattr(test, "setAttemptNumber") and not result.wasSuccessful():
                        # Facilitate retrying this possibly flaky test
                        continue

            if (
                not result.wasSuccessful()
                and "TRAVIS" in os.environ
                and hasattr(test, "dumpLogs")
            ):
                test.dumpLogs()

            results_queue.put(result)

        finally:
            tests_queue.task_done()

    if not broken:
        inst.stop()
Example #22
0
 def client(self):
     return pywatchman.client()
Example #23
0
 def client(self):
     return pywatchman.client()
Example #24
0
File: buck.py Project: uedev/buck
def main():
    # Our parent expects to read JSON from our stdout, so if anyone
    # uses print, buck will complain with a helpful "but I wanted an
    # array!" message and quit.  Redirect stdout to stderr so that
    # doesn't happen.  Actually dup2 the file handle so that writing
    # to file descriptor 1, os.system, and so on work as expected too.

    to_parent = os.fdopen(os.dup(sys.stdout.fileno()), "a")
    os.dup2(sys.stderr.fileno(), sys.stdout.fileno())

    parser = optparse.OptionParser()
    parser.add_option("--project_root", action="store", type="string", dest="project_root")
    parser.add_option("--build_file_name", action="store", type="string", dest="build_file_name")
    parser.add_option(
        "--allow_empty_globs",
        action="store_true",
        dest="allow_empty_globs",
        help="Tells the parser not to raise an error when glob returns no results.",
    )
    parser.add_option(
        "--use_watchman_glob",
        action="store_true",
        dest="use_watchman_glob",
        help="Invokes `watchman query` to get lists of files instead of globbing in-process.",
    )
    parser.add_option(
        "--watchman_watch_root",
        action="store",
        type="string",
        dest="watchman_watch_root",
        help="Path to root of watchman watch as returned by `watchman watch-project`.",
    )
    parser.add_option(
        "--watchman_project_prefix",
        action="store",
        type="string",
        dest="watchman_project_prefix",
        help="Relative project prefix as returned by `watchman watch-project`.",
    )
    parser.add_option(
        "--watchman_query_timeout_ms",
        action="store",
        type="int",
        dest="watchman_query_timeout_ms",
        help="Maximum time in milliseconds to wait for watchman query to respond.",
    )
    parser.add_option("--include", action="append", dest="include")
    (options, args) = parser.parse_args()

    # Even though project_root is absolute path, it may not be concise. For
    # example, it might be like "C:\project\.\rule".
    #
    # Under cygwin, the project root will be invoked from buck as C:\path, but
    # the cygwin python uses UNIX-style paths. They can be converted using
    # cygpath, which is necessary because abspath will treat C:\path as a
    # relative path.
    options.project_root = cygwin_adjusted_path(options.project_root)
    project_root = os.path.abspath(options.project_root)

    watchman_client = None
    watchman_error = None
    output_format = "JSON"
    output_encode = lambda val: json.dumps(val, sort_keys=True)
    if options.use_watchman_glob:
        try:
            # pywatchman may not be built, so fall back to non-watchman
            # in that case.
            import pywatchman

            client_args = {}
            if options.watchman_query_timeout_ms is not None:
                # pywatchman expects a timeout as a nonnegative floating-point
                # value in seconds.
                client_args["timeout"] = max(0.0, options.watchman_query_timeout_ms / 1000.0)
            watchman_client = pywatchman.client(**client_args)
            watchman_error = pywatchman.WatchmanError
            output_format = "BSER"
            output_encode = lambda val: pywatchman.bser.dumps(val)
        except ImportError, e:
            # TODO(agallagher): Restore this when the PEX builds pywatchman.
            # print >> sys.stderr, \
            #     'Could not import pywatchman (sys.path {}): {}'.format(
            #         sys.path,
            #         repr(e))
            pass
Example #25
0
def main():
    # Our parent expects to read JSON from our stdout, so if anyone
    # uses print, buck will complain with a helpful "but I wanted an
    # array!" message and quit.  Redirect stdout to stderr so that
    # doesn't happen.  Actually dup2 the file handle so that writing
    # to file descriptor 1, os.system, and so on work as expected too.

    to_parent = os.fdopen(os.dup(sys.stdout.fileno()), 'a')
    os.dup2(sys.stderr.fileno(), sys.stdout.fileno())

    parser = optparse.OptionParser()
    parser.add_option(
        '--project_root',
        action='store',
        type='string',
        dest='project_root')
    parser.add_option(
        '--build_file_name',
        action='store',
        type='string',
        dest="build_file_name")
    parser.add_option(
        '--allow_empty_globs',
        action='store_true',
        dest='allow_empty_globs',
        help='Tells the parser not to raise an error when glob returns no results.')
    parser.add_option(
        '--use_watchman_glob',
        action='store_true',
        dest='use_watchman_glob',
        help='Invokes `watchman query` to get lists of files instead of globbing in-process.')
    parser.add_option(
        '--watchman_watch_root',
        action='store',
        type='string',
        dest='watchman_watch_root',
        help='Path to root of watchman watch as returned by `watchman watch-project`.')
    parser.add_option(
        '--watchman_project_prefix',
        action='store',
        type='string',
        dest='watchman_project_prefix',
        help='Relative project prefix as returned by `watchman watch-project`.')
    parser.add_option(
        '--include',
        action='append',
        dest='include')
    (options, args) = parser.parse_args()

    # Even though project_root is absolute path, it may not be concise. For
    # example, it might be like "C:\project\.\rule".
    #
    # Under cygwin, the project root will be invoked from buck as C:\path, but
    # the cygwin python uses UNIX-style paths. They can be converted using
    # cygpath, which is necessary because abspath will treat C:\path as a
    # relative path.
    options.project_root = cygwin_adjusted_path(options.project_root)
    project_root = os.path.abspath(options.project_root)

    watchman_client = None
    output_format = 'JSON'
    output_encode = lambda val: json.dumps(val, sort_keys=True)
    if options.use_watchman_glob:
        try:
            # pywatchman may not be built, so fall back to non-watchman
            # in that case.
            import pywatchman
            watchman_client = pywatchman.client()
            output_format = 'BSER'
            output_encode = lambda val: pywatchman.bser.dumps(val)
        except ImportError, e:
            # TODO(agallagher): Restore this when the PEX builds pywatchman.
            # print >> sys.stderr, \
            #     'Could not import pywatchman (sys.path {}): {}'.format(
            #         sys.path,
            #         repr(e))
            pass
Example #26
0
def main():
    # Our parent expects to read BSER from our stdout, so if anyone
    # uses print, buck will complain with a helpful "but I wanted an
    # array!" message and quit.  Redirect stdout to stderr so that
    # doesn't happen.  Actually dup2 the file handle so that writing
    # to file descriptor 1, os.system, and so on work as expected too.

    to_parent = os.fdopen(os.dup(sys.stdout.fileno()), 'ab')
    os.dup2(sys.stderr.fileno(), sys.stdout.fileno())

    parser = optparse.OptionParser()
    parser.add_option(
        '--project_root',
        action='store',
        type='string',
        dest='project_root')
    parser.add_option(
        '--build_file_name',
        action='store',
        type='string',
        dest="build_file_name")
    parser.add_option(
        '--allow_empty_globs',
        action='store_true',
        dest='allow_empty_globs',
        help='Tells the parser not to raise an error when glob returns no results.')
    parser.add_option(
        '--use_watchman_glob',
        action='store_true',
        dest='use_watchman_glob',
        help='Invokes `watchman query` to get lists of files instead of globbing in-process.')
    parser.add_option(
        '--watchman_watch_root',
        action='store',
        type='string',
        dest='watchman_watch_root',
        help='Path to root of watchman watch as returned by `watchman watch-project`.')
    parser.add_option(
        '--watchman_socket_path',
        action='store',
        type='string',
        dest='watchman_socket_path',
        help='Path to Unix domain socket/named pipe as returned by `watchman get-sockname`.')
    parser.add_option(
        '--watchman_project_prefix',
        action='store',
        type='string',
        dest='watchman_project_prefix',
        help='Relative project prefix as returned by `watchman watch-project`.')
    parser.add_option(
        '--watchman_query_timeout_ms',
        action='store',
        type='int',
        dest='watchman_query_timeout_ms',
        help='Maximum time in milliseconds to wait for watchman query to respond.')
    parser.add_option(
        '--include',
        action='append',
        dest='include')
    parser.add_option(
        '--config',
        help='BuckConfig settings available at parse time.')
    parser.add_option(
        '--quiet',
        action='store_true',
        dest='quiet',
        help='Stifles exception backtraces printed to stderr during parsing.')
    parser.add_option(
        '--ignore_buck_autodeps_files',
        action='store_true',
        help='Profile every buck file execution')
    parser.add_option(
        '--profile',
        action='store_true',
        help='Profile every buck file execution')
    (options, args) = parser.parse_args()

    # Even though project_root is absolute path, it may not be concise. For
    # example, it might be like "C:\project\.\rule".
    #
    # Under cygwin, the project root will be invoked from buck as C:\path, but
    # the cygwin python uses UNIX-style paths. They can be converted using
    # cygpath, which is necessary because abspath will treat C:\path as a
    # relative path.
    options.project_root = cygwin_adjusted_path(options.project_root)
    project_root = os.path.abspath(options.project_root)

    watchman_client = None
    watchman_error = None
    if options.use_watchman_glob:
        import pywatchman
        client_args = {}
        if options.watchman_query_timeout_ms is not None:
            # pywatchman expects a timeout as a nonnegative floating-point
            # value in seconds.
            client_args['timeout'] = max(0.0, options.watchman_query_timeout_ms / 1000.0)
        if options.watchman_socket_path is not None:
            client_args['sockpath'] = options.watchman_socket_path
            client_args['transport'] = 'local'
        watchman_client = pywatchman.client(**client_args)
        watchman_error = pywatchman.WatchmanError

    configs = {}
    if options.config is not None:
        with open(options.config, 'rb') as f:
            for section, contents in bser.loads(f.read()).iteritems():
                for field, value in contents.iteritems():
                    configs[(section, field)] = value

    buildFileProcessor = BuildFileProcessor(
        project_root,
        options.watchman_watch_root,
        options.watchman_project_prefix,
        options.build_file_name,
        options.allow_empty_globs,
        options.ignore_buck_autodeps_files,
        watchman_client,
        watchman_error,
        implicit_includes=options.include or [],
        configs=configs)

    buildFileProcessor.install_builtins(__builtin__.__dict__)

    # While processing, we'll write exceptions as diagnostic messages
    # to the parent then re-raise them to crash the process. While
    # doing so, we don't want Python's default unhandled exception
    # behavior of writing to stderr.
    orig_excepthook = None
    if options.quiet:
        orig_excepthook = sys.excepthook
        sys.excepthook = silent_excepthook

    for build_file in args:
        process_with_diagnostics(build_file, buildFileProcessor, to_parent,
                                 should_profile=options.profile)

    # "for ... in sys.stdin" in Python 2.x hangs until stdin is closed.
    for build_file in iter(sys.stdin.readline, ''):
        process_with_diagnostics(build_file, buildFileProcessor, to_parent,
                                 should_profile=options.profile)

    if options.quiet:
        sys.excepthook = orig_excepthook

    # Python tries to flush/close stdout when it quits, and if there's a dead
    # pipe on the other end, it will spit some warnings to stderr. This breaks
    # tests sometimes. Prevent that by explicitly catching the error.
    try:
        to_parent.close()
    except IOError:
        pass
Example #27
0
def main():
    # Our parent expects to read JSON from our stdout, so if anyone
    # uses print, buck will complain with a helpful "but I wanted an
    # array!" message and quit.  Redirect stdout to stderr so that
    # doesn't happen.  Actually dup2 the file handle so that writing
    # to file descriptor 1, os.system, and so on work as expected too.

    to_parent = os.fdopen(os.dup(sys.stdout.fileno()), 'a')
    os.dup2(sys.stderr.fileno(), sys.stdout.fileno())

    parser = optparse.OptionParser()
    parser.add_option(
        '--project_root',
        action='store',
        type='string',
        dest='project_root')
    parser.add_option(
        '--build_file_name',
        action='store',
        type='string',
        dest="build_file_name")
    parser.add_option(
        '--allow_empty_globs',
        action='store_true',
        dest='allow_empty_globs',
        help='Tells the parser not to raise an error when glob returns no results.')
    parser.add_option(
        '--use_watchman_glob',
        action='store_true',
        dest='use_watchman_glob',
        help='Invokes `watchman query` to get lists of files instead of globbing in-process.')
    parser.add_option(
        '--watchman_watch_root',
        action='store',
        type='string',
        dest='watchman_watch_root',
        help='Path to root of watchman watch as returned by `watchman watch-project`.')
    parser.add_option(
        '--watchman_project_prefix',
        action='store',
        type='string',
        dest='watchman_project_prefix',
        help='Relative project prefix as returned by `watchman watch-project`.')
    parser.add_option(
        '--include',
        action='append',
        dest='include')
    (options, args) = parser.parse_args()

    # Even though project_root is absolute path, it may not be concise. For
    # example, it might be like "C:\project\.\rule".
    #
    # Under cygwin, the project root will be invoked from buck as C:\path, but
    # the cygwin python uses UNIX-style paths. They can be converted using
    # cygpath, which is necessary because abspath will treat C:\path as a
    # relative path.
    options.project_root = cygwin_adjusted_path(options.project_root)
    project_root = os.path.abspath(options.project_root)

    watchman_client = None
    output_format = 'JSON'
    output_encode = lambda val: json.dumps(val, sort_keys=True)
    if options.use_watchman_glob:
        try:
            # pywatchman may not be built, so fall back to non-watchman
            # in that case.
            import pywatchman
            watchman_client = pywatchman.client()
            output_format = 'BSER'
            output_encode = lambda val: pywatchman.bser.dumps(val)
        except ImportError, e:
            # TODO(agallagher): Restore this when the PEX builds pywatchman.
            # print >> sys.stderr, \
            #     'Could not import pywatchman (sys.path {}): {}'.format(
            #         sys.path,
            #         repr(e))
            pass