Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for run --debug-adapter to match breakpoints when source is running in a sandbox #17566

Merged
merged 3 commits into from
Nov 18, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions src/python/pants/backend/python/goals/run_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

import os
import textwrap
from typing import Iterable, Optional

from pants.backend.python.subsystems.debugpy import DebugPy
Expand All @@ -27,7 +28,7 @@
from pants.core.goals.run import RunDebugAdapterRequest, RunRequest
from pants.core.subsystems.debug_adapter import DebugAdapterSubsystem
from pants.engine.addresses import Address
from pants.engine.fs import Digest, MergeDigests
from pants.engine.fs import CreateDigest, Digest, FileContent, MergeDigests
from pants.engine.rules import Get, MultiGet, rule_helper
from pants.engine.target import TransitiveTargets, TransitiveTargetsRequest

Expand Down Expand Up @@ -140,16 +141,61 @@ async def _create_python_source_run_dap_request(
debug_adapter: DebugAdapterSubsystem,
console_script: Optional[ConsoleScript] = None,
) -> RunDebugAdapterRequest:
entry_point, debugpy_pex = await MultiGet(
entry_point, debugpy_pex, launcher_digest = await MultiGet(
Get(
ResolvedPexEntryPoint,
ResolvePexEntryPointRequest(entry_point_field),
),
Get(Pex, PexRequest, debugpy.to_pex_request()),
Get(
Digest,
CreateDigest(
[
FileContent(
"__debugpy_launcher.py",
textwrap.dedent(
f"""
import os
CHROOT = os.environ["PANTS_CHROOT"]

# See https://github.com/pantsbuild/pants/issues/17540
# For `run --debug-adapter`, the client might send a `pathMappings`
# (this is likely as VS Code likes to configure that by default) with
# a `remoteRoot` of ".". For `run`, CWD is set to the build root, so
# breakpoints set in-repo will never be hit. We fix this by monkeypatching
# pydevd (the library powering debugpy) so that a remoteRoot of "."
# means the sandbox root.

import debugpy._vendored.force_pydevd
from _pydevd_bundle.pydevd_process_net_command_json import PyDevJsonCommandProcessor
orig_resolve_remote_root = PyDevJsonCommandProcessor._resolve_remote_root

def patched_resolve_remote_root(self, local_root, remote_root):
if remote_root == ".":
remote_root = CHROOT
return orig_resolve_remote_root(self, local_root, remote_root)

PyDevJsonCommandProcessor._resolve_remote_root = patched_resolve_remote_root

from debugpy.server import cli
cli.main()
"""
).encode("utf-8"),
),
]
),
),
)

merged_digest = await Get(
Digest, MergeDigests([regular_run_request.digest, debugpy_pex.digest])
Digest,
MergeDigests(
[
regular_run_request.digest,
debugpy_pex.digest,
launcher_digest,
]
),
)
extra_env = dict(regular_run_request.extra_env)
extra_env["PEX_PATH"] = os.pathsep.join(
Expand All @@ -161,11 +207,14 @@ async def _create_python_source_run_dap_request(
_in_chroot(os.path.basename(regular_run_request.args[1])),
]
)
extra_env["PEX_INTERPRETER"] = "1"
extra_env["PANTS_CHROOT"] = _in_chroot("").rstrip("/")
main = console_script or entry_point.val
assert main is not None
args = [
regular_run_request.args[0], # python executable
_in_chroot(debugpy_pex.name),
_in_chroot("__debugpy_launcher.py"),
*debugpy.get_args(debug_adapter, main),
]

Expand Down
1 change: 1 addition & 0 deletions src/python/pants/backend/python/goals/run_python_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
PythonSourceField,
)
from pants.backend.python.util_rules.pex_environment import PexEnvironment
from pants.base.build_root import BuildRoot
from pants.core.goals.run import RunDebugAdapterRequest, RunFieldSet, RunRequest
from pants.core.subsystems.debug_adapter import DebugAdapterSubsystem
from pants.engine.internals.selectors import Get
Expand Down