def test_no_input_files_in_workspace(self) -> None: program_text = b'#!/usr/bin/python\nprint("hello")' binary = self.create_mock_binary(program_text) with self.assertRaises(ValueError): InteractiveProcessRequest(argv=("/usr/bin/python", ), run_in_workspace=True, input_files=binary.digest)
async def debug_python_test(test_setup: TestTargetSetup) -> TestDebugRequest: run_request = InteractiveProcessRequest( argv=(test_setup.test_runner_pex.output_filename, *test_setup.args), run_in_workspace=False, input_digest=test_setup.input_digest, ) return TestDebugRequest(run_request)
def run(console: Console, workspace: Workspace, runner: InteractiveRunner, bfa: BuildFileAddress) -> Run: target = bfa.to_address() binary = yield Get(CreatedBinary, Address, target) with temporary_dir(cleanup=True) as tmpdir: dirs_to_materialize = (DirectoryToMaterialize( path=str(tmpdir), directory_digest=binary.digest), ) workspace.materialize_directories(dirs_to_materialize) console.write_stdout(f"Running target: {target}\n") full_path = str(Path(tmpdir, binary.binary_name)) run_request = InteractiveProcessRequest( argv=[full_path], run_in_workspace=True, ) try: result = runner.run_local_interactive_process(run_request) exit_code = result.process_exit_code if result.process_exit_code == 0: console.write_stdout(f"{target} ran successfully.\n") else: console.write_stderr( f"{target} failed with code {result.process_exit_code}!\n") except Exception as e: console.write_stderr( f"Exception when attempting to run {target} : {e}\n") exit_code = -1 yield Run(exit_code)
def test_materialize_input_files(self) -> None: program_text = b'#!/usr/bin/python\nprint("hello")' binary = self.create_mock_binary(program_text) interactive_runner = InteractiveRunner(self.scheduler) request = InteractiveProcessRequest( argv=("./program.py",), run_in_workspace=False, input_files=binary.digest, ) result = interactive_runner.run_local_interactive_process(request) self.assertEqual(result.process_exit_code, 0)
async def run_repl( console: Console, workspace: Workspace, runner: InteractiveRunner, options: ReplOptions, transitive_targets: TransitiveTargets, build_root: BuildRoot, union_membership: UnionMembership, global_options: GlobalOptions, ) -> Repl: # We can guarantee that we will only even enter this `goal_rule` if there exists an implementer # of the `ReplImplementation` union because `LegacyGraphSession.run_goal_rules()` will not # execute this rule's body if there are no implementations registered. membership: Iterable[Type[ ReplImplementation]] = union_membership.union_rules[ReplImplementation] implementations = {impl.name: impl for impl in membership} default_repl = "python" repl_shell_name = cast(str, options.values.shell or default_repl) repl_implementation_cls = implementations.get(repl_shell_name) if repl_implementation_cls is None: available = sorted(set(implementations.keys())) console.write_stdout( f"{repl_shell_name} is not an installed REPL program. Available REPLs: {available}" ) return Repl(-1) repl_impl = repl_implementation_cls(targets=Targets( tgt for tgt in transitive_targets.closure if repl_implementation_cls.is_valid(tgt))) repl_binary = await Get[ReplBinary](ReplImplementation, repl_impl) with temporary_dir(root_dir=global_options.options.pants_workdir, cleanup=False) as tmpdir: path_relative_to_build_root = PurePath(tmpdir).relative_to( build_root.path).as_posix() workspace.materialize_directory( DirectoryToMaterialize(repl_binary.digest, path_prefix=path_relative_to_build_root)) full_path = PurePath(tmpdir, repl_binary.binary_name).as_posix() run_request = InteractiveProcessRequest( argv=(full_path, ), run_in_workspace=True, ) result = runner.run_local_interactive_process(run_request) exit_code = result.process_exit_code if exit_code == 0: console.write_stdout("REPL exited successfully.") else: console.write_stdout(f"REPL exited with error: {exit_code}.") return Repl(exit_code)
def make_ipr(self) -> InteractiveProcessRequest: input_files_content = InputFilesContent( (FileContent(path="program.py", content=b"def test(): pass"), )) digest = self.request_single_product(Digest, input_files_content) return InteractiveProcessRequest( argv=( "/usr/bin/python", "program.py", ), run_in_workspace=False, input_digest=digest, )
def make_ipr(self, content: bytes) -> InteractiveProcessRequest: input_files_content = InputFilesContent( (FileContent(path='program.py', content=content, is_executable=True), )) digest = self.request_single_product(Digest, input_files_content) return InteractiveProcessRequest( argv=( "/usr/bin/python", "program.py", ), run_in_workspace=False, input_files=digest, )
async def run( console: Console, workspace: Workspace, runner: InteractiveRunner, build_root: BuildRoot, options: RunOptions, global_options: GlobalOptions, ) -> Run: targets_to_valid_configs = await Get[TargetsToValidConfigurations]( TargetsToValidConfigurationsRequest( BinaryConfiguration, goal_description=f"the `{options.name}` goal", error_if_no_valid_targets=True, expect_single_config=True, )) config = targets_to_valid_configs.configurations[0] binary = await Get[CreatedBinary](BinaryConfiguration, config) workdir = global_options.options.pants_workdir with temporary_dir(root_dir=workdir, cleanup=True) as tmpdir: path_relative_to_build_root = PurePath(tmpdir).relative_to( build_root.path).as_posix() workspace.materialize_directory( DirectoryToMaterialize(binary.digest, path_prefix=path_relative_to_build_root)) console.write_stdout(f"Running target: {config.address}\n") full_path = PurePath(tmpdir, binary.binary_name).as_posix() run_request = InteractiveProcessRequest( argv=(full_path, *options.values.args), run_in_workspace=True, ) try: result = runner.run_local_interactive_process(run_request) exit_code = result.process_exit_code if result.process_exit_code == 0: console.write_stdout(f"{config.address} ran successfully.\n") else: console.write_stderr( f"{config.address} failed with code {result.process_exit_code}!\n" ) except Exception as e: console.write_stderr( f"Exception when attempting to run {config.address}: {e!r}\n") exit_code = -1 return Run(exit_code)
def run(console: Console, runner: InteractiveRunner, build_file_addresses: BuildFileAddresses) -> Run: console.write_stdout("Running the `run` goal\n") request = InteractiveProcessRequest( argv=["/usr/bin/python"], env=("TEST_ENV", "TEST"), run_in_workspace=False, ) try: res = runner.run_local_interactive_process(request) print(f"Subprocess exited with result: {res.process_exit_code}") yield Run(res.process_exit_code) except Exception as e: print(f"Exception when running local interactive process: {e}") yield Run(-1)
async def run_repl( console: Console, workspace: Workspace, runner: InteractiveRunner, options: ReplOptions, transitive_targets: TransitiveTargets, build_root: BuildRoot, union_membership: UnionMembership, global_options: GlobalOptions, ) -> Repl: default_repl = "python" repl_shell_name = cast(str, options.values.shell) or default_repl implementations: Dict[str, Type[ReplImplementation]] = { impl.name: impl for impl in union_membership[ReplImplementation] } repl_implementation_cls = implementations.get(repl_shell_name) if repl_implementation_cls is None: available = sorted(implementations.keys()) console.print_stderr( f"{repr(repl_shell_name)} is not a registered REPL. Available REPLs (which may " f"be specified through the option `--repl-shell`): {available}") return Repl(-1) repl_impl = repl_implementation_cls(targets=Targets( tgt for tgt in transitive_targets.closure if repl_implementation_cls.is_valid(tgt))) repl_binary = await Get[ReplBinary](ReplImplementation, repl_impl) with temporary_dir(root_dir=global_options.options.pants_workdir, cleanup=False) as tmpdir: path_relative_to_build_root = PurePath(tmpdir).relative_to( build_root.path).as_posix() workspace.materialize_directory( DirectoryToMaterialize(repl_binary.digest, path_prefix=path_relative_to_build_root)) full_path = PurePath(tmpdir, repl_binary.binary_name).as_posix() run_request = InteractiveProcessRequest( argv=(full_path, ), run_in_workspace=True, ) result = runner.run_local_interactive_process(run_request) return Repl(result.process_exit_code)
async def run( console: Console, workspace: Workspace, runner: InteractiveRunner, build_root: BuildRoot, addresses: Addresses, options: RunOptions, ) -> Run: address = addresses.expect_single() binary = await Get[CreatedBinary](Address, address) with temporary_dir(root_dir=PurePath(build_root.path, ".pants.d").as_posix(), cleanup=True) as tmpdir: path_relative_to_build_root = PurePath(tmpdir).relative_to( build_root.path).as_posix() workspace.materialize_directory( DirectoryToMaterialize(binary.digest, path_prefix=path_relative_to_build_root)) console.write_stdout(f"Running target: {address}\n") full_path = PurePath(tmpdir, binary.binary_name).as_posix() run_request = InteractiveProcessRequest( argv=(full_path, *options.values.args), run_in_workspace=True, ) try: result = runner.run_local_interactive_process(run_request) exit_code = result.process_exit_code if result.process_exit_code == 0: console.write_stdout(f"{address} ran successfully.\n") else: console.write_stderr( f"{address} failed with code {result.process_exit_code}!\n" ) except Exception as e: console.write_stderr( f"Exception when attempting to run {address}: {e!r}\n") exit_code = -1 return Run(exit_code)
async def run( options: RunOptions, global_options: GlobalOptions, console: Console, runner: InteractiveRunner, workspace: Workspace, build_root: BuildRoot, ) -> Run: targets_to_valid_field_sets = await Get[TargetsToValidFieldSets]( TargetsToValidFieldSetsRequest( BinaryFieldSet, goal_description=f"the `{options.name}` goal", error_if_no_valid_targets=True, expect_single_field_set=True, )) field_set = targets_to_valid_field_sets.field_sets[0] binary = await Get[CreatedBinary](BinaryFieldSet, field_set) workdir = global_options.options.pants_workdir with temporary_dir(root_dir=workdir, cleanup=True) as tmpdir: path_relative_to_build_root = PurePath(tmpdir).relative_to( build_root.path).as_posix() workspace.materialize_directory( DirectoryToMaterialize(binary.digest, path_prefix=path_relative_to_build_root)) full_path = PurePath(tmpdir, binary.binary_name).as_posix() run_request = InteractiveProcessRequest( argv=(full_path, *options.values.args), run_in_workspace=True, ) try: result = runner.run_local_interactive_process(run_request) exit_code = result.process_exit_code except Exception as e: console.print_stderr( f"Exception when attempting to run {field_set.address}: {e!r}") exit_code = -1 return Run(exit_code)
async def run( console: Console, workspace: Workspace, runner: InteractiveRunner, build_root: BuildRoot, bfa: BuildFileAddress, ) -> Run: target = bfa.to_address() binary = await Get[CreatedBinary](Address, target) with temporary_dir(root_dir=str(Path(build_root.path, ".pants.d")), cleanup=True) as tmpdir: path_relative_to_build_root = str( Path(tmpdir).relative_to(build_root.path)) workspace.materialize_directory( DirectoryToMaterialize(binary.digest, path_prefix=path_relative_to_build_root)) console.write_stdout(f"Running target: {target}\n") full_path = str(Path(tmpdir, binary.binary_name)) run_request = InteractiveProcessRequest( argv=(full_path, ), run_in_workspace=True, ) try: result = runner.run_local_interactive_process(run_request) exit_code = result.process_exit_code if result.process_exit_code == 0: console.write_stdout(f"{target} ran successfully.\n") else: console.write_stderr( f"{target} failed with code {result.process_exit_code}!\n") except Exception as e: console.write_stderr( f"Exception when attempting to run {target} : {e}\n") exit_code = -1 return Run(exit_code)
def _iter_openers( self, files: Iterable[PurePath]) -> Iterator[InteractiveProcessRequest]: for f in files: yield InteractiveProcessRequest(argv=(self.program, str(f)), run_in_workspace=True)
async def run( console: Console, workspace: Workspace, runner: InteractiveRunner, build_root: BuildRoot, targets_with_origins: TargetsWithOrigins, options: RunOptions, global_options: GlobalOptions, union_membership: UnionMembership, registered_target_types: RegisteredTargetTypes, ) -> Run: valid_config_types_by_target = gather_valid_binary_configuration_types( goal_subsytem=options, targets_with_origins=targets_with_origins, union_membership=union_membership, registered_target_types=registered_target_types, ) bulleted_list_sep = "\n * " if len(valid_config_types_by_target) > 1: binary_target_addresses = sorted( binary_target.address.spec for binary_target in valid_config_types_by_target) raise ValueError( f"The `run` goal only works on one binary target but was given multiple targets that " f"can produce a binary:" f"{bulleted_list_sep}{bulleted_list_sep.join(binary_target_addresses)}\n\n" f"Please select one of these targets to run.") target, valid_config_types = list(valid_config_types_by_target.items())[0] if len(valid_config_types) > 1: possible_config_types = sorted(config_type.__name__ for config_type in valid_config_types) # TODO: improve this error message. (It's never actually triggered yet because we only have # Python implemented with V2.) A better error message would explain to users how they can # resolve the issue. raise ValueError( f"Multiple of the registered binary implementations work for {target.address} " f"(target type {repr(target.alias)}).\n\n" f"It is ambiguous which implementation to use. Possible implementations:" f"{bulleted_list_sep}{bulleted_list_sep.join(possible_config_types)}." ) config_type = valid_config_types[0] binary = await Get[CreatedBinary](BinaryConfiguration, config_type.create(target)) workdir = global_options.options.pants_workdir with temporary_dir(root_dir=workdir, cleanup=True) as tmpdir: path_relative_to_build_root = PurePath(tmpdir).relative_to( build_root.path).as_posix() workspace.materialize_directory( DirectoryToMaterialize(binary.digest, path_prefix=path_relative_to_build_root)) console.write_stdout(f"Running target: {target.address}\n") full_path = PurePath(tmpdir, binary.binary_name).as_posix() run_request = InteractiveProcessRequest( argv=(full_path, *options.values.args), run_in_workspace=True, ) try: result = runner.run_local_interactive_process(run_request) exit_code = result.process_exit_code if result.process_exit_code == 0: console.write_stdout(f"{target.address} ran successfully.\n") else: console.write_stderr( f"{target.address} failed with code {result.process_exit_code}!\n" ) except Exception as e: console.write_stderr( f"Exception when attempting to run {target.address}: {e!r}\n") exit_code = -1 return Run(exit_code)