-
-
Notifications
You must be signed in to change notification settings - Fork 636
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
Add --debug-adapter
flag to run
#15829
Changes from 21 commits
27ae8bd
03346c2
cad6870
74fc753
fa9c413
ec6a519
904b76e
27e63eb
c094252
ec61845
e31ec67
d94e1a2
6601275
51e010a
5b9a7a0
c03a839
f5cc775
244dc45
4a5cabd
d86cf33
667d17b
3b64bee
0cc4972
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,19 @@ | ||
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
import logging | ||
import os | ||
|
||
from pants.backend.python.goals.package_pex_binary import PexBinaryFieldSet | ||
from pants.backend.python.subsystems.debugpy import DebugPy | ||
from pants.backend.python.target_types import ( | ||
PexBinaryDefaults, | ||
ResolvedPexEntryPoint, | ||
ResolvePexEntryPointRequest, | ||
) | ||
from pants.backend.python.util_rules.interpreter_constraints import InterpreterConstraints | ||
from pants.backend.python.util_rules.local_dists import LocalDistsPex, LocalDistsPexRequest | ||
from pants.backend.python.util_rules.pex import Pex | ||
from pants.backend.python.util_rules.pex import Pex, PexRequest | ||
from pants.backend.python.util_rules.pex_environment import PexEnvironment | ||
from pants.backend.python.util_rules.pex_from_targets import ( | ||
InterpreterConstraintsRequest, | ||
|
@@ -21,12 +23,20 @@ | |
PythonSourceFiles, | ||
PythonSourceFilesRequest, | ||
) | ||
from pants.core.goals.run import RunFieldSet, RunRequest | ||
from pants.core.goals.run import RunDebugAdapterRequest, RunFieldSet, RunRequest | ||
from pants.core.subsystems.debug_adapter import DebugAdapterSubsystem | ||
from pants.engine.fs import Digest, MergeDigests | ||
from pants.engine.rules import Get, MultiGet, collect_rules, rule | ||
from pants.engine.target import TransitiveTargets, TransitiveTargetsRequest | ||
from pants.engine.unions import UnionRule | ||
from pants.util.logging import LogLevel | ||
from pants.util.strutil import softwrap | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def _in_chroot(relpath: str) -> str: | ||
return os.path.join("{chroot}", relpath) | ||
|
||
|
||
@rule(level=LogLevel.DEBUG) | ||
|
@@ -99,13 +109,12 @@ async def create_pex_binary_run_request( | |
] | ||
merged_digest = await Get(Digest, MergeDigests(input_digests)) | ||
|
||
def in_chroot(relpath: str) -> str: | ||
return os.path.join("{chroot}", relpath) | ||
|
||
complete_pex_env = pex_env.in_workspace() | ||
args = complete_pex_env.create_argv(in_chroot(pex.name), python=pex.python) | ||
# NB. If this changes, please consider how it affects the `DebugRequest` below | ||
# (which is not easy to write automated tests for) | ||
args = complete_pex_env.create_argv(_in_chroot(pex.name), python=pex.python) | ||
|
||
chrooted_source_roots = [in_chroot(sr) for sr in sources.source_roots] | ||
chrooted_source_roots = [_in_chroot(sr) for sr in sources.source_roots] | ||
# The order here is important: we want the in-repo sources to take precedence over their | ||
# copies in the sandbox (see above for why those copies exist even in non-sandboxed mode). | ||
source_roots = [ | ||
|
@@ -114,12 +123,62 @@ def in_chroot(relpath: str) -> str: | |
] | ||
extra_env = { | ||
**complete_pex_env.environment_dict(python_configured=pex.python is not None), | ||
"PEX_PATH": in_chroot(local_dists.pex.name), | ||
"PEX_PATH": _in_chroot(local_dists.pex.name), | ||
"PEX_EXTRA_SYS_PATH": os.pathsep.join(source_roots), | ||
} | ||
|
||
return RunRequest(digest=merged_digest, args=args, extra_env=extra_env) | ||
|
||
|
||
@rule | ||
async def run_pex_debug_adapter_binary( | ||
field_set: PexBinaryFieldSet, | ||
debugpy: DebugPy, | ||
debug_adapter: DebugAdapterSubsystem, | ||
) -> RunDebugAdapterRequest: | ||
if field_set.run_in_sandbox: | ||
logger.warning( | ||
softwrap( | ||
f""" | ||
Using `run --debug-adapter` on the target {field_set.address}, which sets the field | ||
`run_in_sandbox` set to `True` will likely cause your breakpoints to not be hit, as | ||
your code will be run under the sandbox's path. | ||
thejcannon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
) | ||
) | ||
|
||
entry_point, regular_run_request, debugpy_pex = await MultiGet( | ||
Get( | ||
ResolvedPexEntryPoint, | ||
ResolvePexEntryPointRequest(field_set.entry_point), | ||
), | ||
Get(RunRequest, PexBinaryFieldSet, field_set), | ||
Get(Pex, PexRequest, debugpy.to_pex_request()), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we avoid installing debugpy if you aren't using it? That saves time and avoids possible issues with the PEX not being installable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is in a |
||
) | ||
|
||
entry_point_or_script = entry_point.val or field_set.script.value | ||
assert entry_point_or_script is not None | ||
merged_digest = await Get( | ||
Digest, MergeDigests([regular_run_request.digest, debugpy_pex.digest]) | ||
) | ||
extra_env = dict(regular_run_request.extra_env) | ||
extra_env["PEX_PATH"] = os.pathsep.join( | ||
[ | ||
extra_env["PEX_PATH"], | ||
# For debugpy to work properly, we need to have just one "environment" for our | ||
# command to run in. Therefore, we cobble one together by exeucting debugpy's PEX, and | ||
# shoehorning in the original PEX through PEX_PATH. | ||
_in_chroot(os.path.basename(regular_run_request.args[1])), | ||
] | ||
) | ||
args = [ | ||
regular_run_request.args[0], # python executable | ||
_in_chroot(debugpy_pex.name), | ||
*debugpy.get_args(debug_adapter, entry_point_or_script), | ||
] | ||
|
||
return RunDebugAdapterRequest(digest=merged_digest, args=args, extra_env=extra_env) | ||
|
||
|
||
def rules(): | ||
return [*collect_rules(), UnionRule(RunFieldSet, PexBinaryFieldSet)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you connect to the server?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's largely editor specific 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With VSCode? I'm wondering if we should link to a certain guide, for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For instance, in VS Code for Python you set up a "Python: Remote Attach"
launch.json
configuration and with the default values, you start it (F5).