diff --git a/src/python/pants/backend/python/goals/pytest_runner.py b/src/python/pants/backend/python/goals/pytest_runner.py index e869fd2f07d..094124b4c65 100644 --- a/src/python/pants/backend/python/goals/pytest_runner.py +++ b/src/python/pants/backend/python/goals/pytest_runner.py @@ -34,6 +34,7 @@ TestResult, TestSubsystem, ) +from pants.core.subsystems.debug_adapter import DebugAdapterSubsystem from pants.core.util_rules.config_files import ConfigFiles, ConfigFilesRequest from pants.core.util_rules.source_files import SourceFiles, SourceFilesRequest from pants.engine.addresses import Address @@ -405,6 +406,7 @@ async def debug_python_test(field_set: PythonTestFieldSet) -> TestDebugRequest: async def debugpy_python_test( field_set: PythonTestFieldSet, debugpy: DebugPy, + debug_adapter: DebugAdapterSubsystem, pytest: PyTest, ) -> TestDebugAdapterRequest: debugpy_pex = await Get(Pex, PexRequest, debugpy.to_pex_request()) @@ -426,7 +428,7 @@ async def debugpy_python_test( main=debugpy.main, prepend_argv=( "--listen", - f"{debugpy.host}:{debugpy.port}", + f"{debug_adapter.host}:{debug_adapter.port}", "--wait-for-client", # @TODO: Techincally we should use `pytest.main`, however `debugpy` doesn't support # launching an entry_point. diff --git a/src/python/pants/backend/python/subsystems/debugpy.py b/src/python/pants/backend/python/subsystems/debugpy.py index d876bbadcd9..a4aa946ef7e 100644 --- a/src/python/pants/backend/python/subsystems/debugpy.py +++ b/src/python/pants/backend/python/subsystems/debugpy.py @@ -11,7 +11,6 @@ from pants.core.goals.generate_lockfiles import GenerateToolLockfileSentinel from pants.engine.rules import collect_rules, rule from pants.engine.unions import UnionRule -from pants.option.option_types import IntOption, StrOption from pants.util.docutil import git_url @@ -30,15 +29,6 @@ class DebugPy(PythonToolBase): default_lockfile_path = "src/python/pants/backend/python/subsystems/debugpy.lock" default_lockfile_url = git_url(default_lockfile_path) - host = StrOption( - "--host", default="127.0.0.1", help="The hostname to use when launching the debugpy server." - ) - port = IntOption( - "--port", - default=5678, # The canonical port - help="The port to use when launching the debugpy server.", - ) - class DebugPyLockfileSentinel(GenerateToolLockfileSentinel): resolve_name = DebugPy.options_scope diff --git a/src/python/pants/core/goals/test.py b/src/python/pants/core/goals/test.py index 11b3987db58..6cd8e55d77e 100644 --- a/src/python/pants/core/goals/test.py +++ b/src/python/pants/core/goals/test.py @@ -12,6 +12,7 @@ from typing import Any, ClassVar, TypeVar, cast from pants.core.goals.package import BuiltPackage, PackageFieldSet +from pants.core.subsystems.debug_adapter import DebugAdapterSubsystem from pants.core.util_rules.distdir import DistDir from pants.engine.addresses import Address, UnparsedAddressInputs from pants.engine.collection import Collection @@ -413,6 +414,7 @@ class Test(Goal): @rule_helper async def _run_debug_tests( test_subsystem: TestSubsystem, + debug_adapter: DebugAdapterSubsystem, ) -> Test: targets_to_valid_field_sets = await Get( TargetRootsToFieldSets, @@ -435,7 +437,14 @@ async def _run_debug_tests( exit_code = 0 for debug_request in debug_requests: if test_subsystem.debug_adapter: - logger.info("Launching debug adapter, which will wait for a client connection...") + logger.info( + softwrap( + f""" + Launching debug adapter at '{debug_adapter.host}:{debug_adapter.port}', + which will wait for a client connection... + """ + ) + ) debug_result = await Effect( InteractiveProcessResult, InteractiveProcess, debug_request.process @@ -449,13 +458,14 @@ async def _run_debug_tests( async def run_tests( console: Console, test_subsystem: TestSubsystem, + debug_adapter: DebugAdapterSubsystem, workspace: Workspace, union_membership: UnionMembership, distdir: DistDir, run_id: RunId, ) -> Test: if test_subsystem.debug or test_subsystem.debug_adapter: - return await _run_debug_tests(test_subsystem) + return await _run_debug_tests(test_subsystem, debug_adapter) shard, num_shards = parse_shard_spec(test_subsystem.shard, "the [test].shard option") targets_to_valid_field_sets = await Get( diff --git a/src/python/pants/core/goals/test_test.py b/src/python/pants/core/goals/test_test.py index e81c647ea4d..b2e2b0d1f24 100644 --- a/src/python/pants/core/goals/test_test.py +++ b/src/python/pants/core/goals/test_test.py @@ -34,6 +34,7 @@ build_runtime_package_dependencies, run_tests, ) +from pants.core.subsystems.debug_adapter import DebugAdapterSubsystem from pants.core.util_rules.distdir import DistDir from pants.engine.addresses import Address from pants.engine.console import Console @@ -55,7 +56,7 @@ TargetRootsToFieldSetsRequest, ) from pants.engine.unions import UnionMembership -from pants.testutil.option_util import create_goal_subsystem +from pants.testutil.option_util import create_goal_subsystem, create_subsystem from pants.testutil.rule_runner import ( MockEffect, MockGet, @@ -167,6 +168,11 @@ def run_test_rule( extra_env_vars=[], shard="", ) + debug_adapter_subsystem = create_subsystem( + DebugAdapterSubsystem, + host="127.0.0.1", + port="5678", + ) workspace = Workspace(rule_runner.scheduler, _enforce_effects=False) union_membership = UnionMembership( { @@ -207,6 +213,7 @@ def mock_coverage_report_generation( rule_args=[ console, test_subsystem, + debug_adapter_subsystem, workspace, union_membership, DistDir(relpath=Path("dist")), diff --git a/src/python/pants/core/subsystems/debug_adapter.py b/src/python/pants/core/subsystems/debug_adapter.py new file mode 100644 index 00000000000..33ab9865372 --- /dev/null +++ b/src/python/pants/core/subsystems/debug_adapter.py @@ -0,0 +1,28 @@ +# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md). +# Licensed under the Apache License, Version 2.0 (see LICENSE). + +from __future__ import annotations + +from pants.option.option_types import IntOption, StrOption +from pants.option.subsystem import Subsystem +from pants.util.strutil import softwrap + + +class DebugAdapterSubsystem(Subsystem): + options_scope = "debug-adapter" + help = softwrap( + """ + Options used to configure and launch a Debug Adapter server. + + See https://microsoft.github.io/debug-adapter-protocol/ for more information. + """ + ) + + host = StrOption( + "--host", default="127.0.0.1", help="The hostname to use when launching the server." + ) + port = IntOption( + "--port", + default=5678, + help="The port to use when launching the server.", + )