コード例 #1
0
def mock_console(
    options_bootstrapper: OptionsBootstrapper,
    *,
    stdin_content: bytes | str | None = None,
) -> Iterator[Tuple[Console, StdioReader]]:
    global_bootstrap_options = options_bootstrapper.bootstrap_options.for_global_scope(
    )

    @contextmanager
    def stdin_context():
        if stdin_content is None:
            yield open("/dev/null", "r")
        else:
            with temporary_file(binary_mode=isinstance(stdin_content,
                                                       bytes)) as stdin_file:
                stdin_file.write(stdin_content)
                stdin_file.close()
                yield open(stdin_file.name, "r")

    with initialize_stdio(global_bootstrap_options), stdin_context(
    ) as stdin, temporary_file(binary_mode=False) as stdout, temporary_file(
            binary_mode=False) as stderr, stdio_destination(
                stdin_fileno=stdin.fileno(),
                stdout_fileno=stdout.fileno(),
                stderr_fileno=stderr.fileno(),
            ):
        # NB: We yield a Console without overriding the destination argument, because we have
        # already done a sys.std* level replacement. The replacement is necessary in order for
        # InteractiveProcess to have native file handles to interact with.
        yield Console(use_colors=global_bootstrap_options.colors), StdioReader(
            _stdout=Path(stdout.name), _stderr=Path(stderr.name))
コード例 #2
0
 def __call__(
     self,
     command: str,
     args: Tuple[str, ...],
     env: Dict[str, str],
     cancellation_latch: PySessionCancellationLatch,
     stdin_fileno: int,
     stdout_fileno: int,
     stderr_fileno: int,
 ) -> ExitCode:
     request_timeout = float(env.get("PANTSD_REQUEST_TIMEOUT_LIMIT", -1))
     # NB: Order matters: we acquire a lock before mutating either `sys.std*`, `os.environ`, etc.
     with self._one_run_at_a_time(
         stderr_fileno,
         cancellation_latch=cancellation_latch,
         timeout=request_timeout,
     ):
         # NB: `single_daemonized_run` implements exception handling, so only the most primitive
         # errors will escape this function, where they will be logged by the server.
         logger.info(f"handling request: `{' '.join(args)}`")
         try:
             with stdio_destination(
                 stdin_fileno=stdin_fileno,
                 stdout_fileno=stdout_fileno,
                 stderr_fileno=stderr_fileno,
             ):
                 return self.single_daemonized_run(((command,) + args), env, cancellation_latch)
         finally:
             logger.info(f"request completed: `{' '.join(args)}`")
コード例 #3
0
 def wrapper(*args, **kwargs):
     stdout_fileno, stderr_fileno = sys.stdout.fileno(
     ), sys.stderr.fileno()
     with temporary_dir() as tempdir, initialize_stdio_raw(
             level, False, False, {}, True, [],
             tempdir), stdin_context() as stdin, stdio_destination(
                 stdin.fileno(), stdout_fileno, stderr_fileno):
         return func(*args, **kwargs)
コード例 #4
0
    def run(self, start_time: float) -> ExitCode:
        self.scrub_pythonpath()

        options_bootstrapper = OptionsBootstrapper.create(env=self.env,
                                                          args=self.args,
                                                          allow_pantsrc=True)
        with warnings.catch_warnings(record=True):
            bootstrap_options = options_bootstrapper.bootstrap_options
            global_bootstrap_options = bootstrap_options.for_global_scope()

        # We enable logging here, and everything before it will be routed through regular
        # Python logging.
        stdin_fileno = sys.stdin.fileno()
        stdout_fileno = sys.stdout.fileno()
        stderr_fileno = sys.stderr.fileno()
        with initialize_stdio(global_bootstrap_options), stdio_destination(
                stdin_fileno=stdin_fileno,
                stdout_fileno=stdout_fileno,
                stderr_fileno=stderr_fileno,
        ):
            # N.B. We inline imports to speed up the python thin client run, and avoids importing
            # engine types until after the runner has had a chance to set PANTS_BIN_NAME.

            if self._should_run_with_pantsd(global_bootstrap_options):
                from pants.bin.remote_pants_runner import RemotePantsRunner

                try:
                    remote_runner = RemotePantsRunner(self.args, self.env,
                                                      options_bootstrapper)
                    return remote_runner.run(start_time)
                except RemotePantsRunner.Fallback as e:
                    logger.warning(
                        f"Client exception: {e!r}, falling back to non-daemon mode"
                    )

            from pants.bin.local_pants_runner import LocalPantsRunner

            # We only install signal handling via ExceptionSink if the run will execute in this process.
            ExceptionSink.install(
                log_location=init_workdir(global_bootstrap_options),
                pantsd_instance=False)
            runner = LocalPantsRunner.create(
                env=CompleteEnvironment(self.env),
                options_bootstrapper=options_bootstrapper)
            return runner.run(start_time)
コード例 #5
0
ファイル: rule_runner.py プロジェクト: zomglings/pants
def mock_console(
    options_bootstrapper: OptionsBootstrapper,
) -> Iterator[Tuple[Console, StdioReader]]:
    global_bootstrap_options = options_bootstrapper.bootstrap_options.for_global_scope(
    )
    with initialize_stdio(global_bootstrap_options), open(
            "/dev/null", "r") as stdin, temporary_file(
                binary_mode=False) as stdout, temporary_file(
                    binary_mode=False) as stderr, stdio_destination(
                        stdin_fileno=stdin.fileno(),
                        stdout_fileno=stdout.fileno(),
                        stderr_fileno=stderr.fileno(),
                    ):
        # NB: We yield a Console without overriding the destination argument, because we have
        # already done a sys.std* level replacement. The replacement is necessary in order for
        # InteractiveProcess to have native file handles to interact with.
        yield Console(use_colors=global_bootstrap_options.colors), StdioReader(
            _stdout=Path(stdout.name), _stderr=Path(stderr.name))
コード例 #6
0
def mock_console(
    options_bootstrapper: OptionsBootstrapper,
    *,
    stdin_content: bytes | str | None = None,
) -> Iterator[tuple[Console, StdioReader]]:
    global_bootstrap_options = options_bootstrapper.bootstrap_options.for_global_scope(
    )
    colors = (options_bootstrapper.full_options_for_scopes(
        [GlobalOptions.get_scope_info()],
        allow_unknown_options=True).for_global_scope().colors)

    with initialize_stdio(global_bootstrap_options), stdin_context(
            stdin_content) as stdin, temporary_file(
                binary_mode=False) as stdout, temporary_file(
                    binary_mode=False) as stderr, stdio_destination(
                        stdin_fileno=stdin.fileno(),
                        stdout_fileno=stdout.fileno(),
                        stderr_fileno=stderr.fileno(),
                    ):
        # NB: We yield a Console without overriding the destination argument, because we have
        # already done a sys.std* level replacement. The replacement is necessary in order for
        # InteractiveProcess to have native file handles to interact with.
        yield Console(use_colors=colors), StdioReader(
            _stdout=Path(stdout.name), _stderr=Path(stderr.name))