fix(debug): support shell expansion for debug adapter launch args (#17200)#17224
fix(debug): support shell expansion for debug adapter launch args (#17200)#17224ankitsharma101 wants to merge 7 commits intoeclipse-theia:masterfrom
Conversation
eneufeld
left a comment
There was a problem hiding this comment.
Thank you for the fix. It works in general. It is missing some points though we should fix before merging it, see inline comments.
| // we join the arguments into a single raw command string and send it directly. | ||
| // This prevents Theia from automatically wrapping the variables in single quotes. | ||
| if (argsCanBeInterpretedByShell) { | ||
| const rawCommand = args.join(' ') + '\r'; |
There was a problem hiding this comment.
we should use OS.backend.EOL instead of \r.
I would also reduce the amount of comments.
| // This prevents Theia from automatically wrapping the variables in single quotes. | ||
| if (argsCanBeInterpretedByShell) { | ||
| const rawCommand = args.join(' ') + '\r'; | ||
| await terminal.sendText(rawCommand); |
There was a problem hiding this comment.
This has a bug at the moment. The main issue is the missing cwd.
Check how executeCommand creates the text that is send to the terminal.
So it should be something like: use ShellCommandBuilder to construct the cd && env KEY=VAL ... prefix with proper escaping, then append the raw unquoted args, and send the whole thing via sendText with OS.backend.EOL.
There was a problem hiding this comment.
we should also call resetCommandOutputMarker after the sendText.
Basically it is the same follow more how executeCommand is implemented.
…on for pickArgs - Use ShellCommandBuilder to construct cd+env+executable prefix with proper escaping - Append remaining args raw so shell can expand variables and handle redirections - Use OS.backend.EOL instead of \r - Reduce verbose comments - Fix DebuggerDescription to include variables field so command variables like pickArgs resolve correctly - Pass variables through plugin debug registration chain (debug-ext.ts, debug-main.ts) - Inject ShellCommandBuilder into DefaultDebugSessionFactory and PluginDebugSessionFactory
|
Thank you for the detailed review! I've addressed all the feedback: Addressed review comments:
Regarding Additional fix included in this PR:
All three test cases now pass:
|
Signed-off-by: Ankit Sharma <ankitsharmaeclipse@gmail.com>
Signed-off-by: Ankit Sharma <ankitsharmaeclipse@gmail.com>
eneufeld
left a comment
There was a problem hiding this comment.
I think we are nearly there, but we should use the injected builder otherwise there is no benefit in injecting it. But as it can be extended, the injection is the right choice
| protected readonly workspaceService: WorkspaceService, | ||
| protected readonly debugPreferences: DebugPreferences, | ||
| protected readonly commandService: CommandService, | ||
| protected readonly shellCommandBuilder: ShellCommandBuilder, |
There was a problem hiding this comment.
this needs to be documented in the changelog as this is a breaking change for anybody subclassing this
| await terminal.executeCommand({ cwd, args, env }); | ||
|
|
||
| if (argsCanBeInterpretedByShell) { | ||
| const builder = new ShellCommandBuilder(); |
There was a problem hiding this comment.
why are we not using the injected builder?
| // `multer` handles `multipart/form-data` containing our file to upload. | ||
| multer({ dest }).single('file'), | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| (multer({ dest }).single('file') as any), |
There was a problem hiding this comment.
can't we just not touch this file at all?
|
Thanks for the review! Here's what I've done:
For Also, regarding |
What it does
Fixes #17200
This PR resolves an issue where adapters like
debugpyblock debug execution when passed shell-expanded arguments (e.g.,"args": "${command:pickArgs}").The fix requires two steps to achieve VS Code parity:
supportsArgsCanBeInterpretedByShell: truecapability to the clientinitializepayload. Without this, adapters strictly enforcing DAP capabilities reject the launch request withInvalid message: Shell expansion in "args" is not supported by the client.runInTerminalimplementation indebug-session.tsx. WhenargsCanBeInterpretedByShellis true, Theia now joins the arguments into a single raw command string (sendText) instead of passing the array toexecuteCommand. This prevents Theia from automatically wrapping the variables in single quotes, allowing the underlying shell (like bash) to natively evaluate expansions (like$USERor> output.txt) before passing them to the debugger.How to test
ms-python.pythonandms-python.debugpyextensions in a local Theia browser environment.test.py) that printssys.argv.launch.jsonconfiguration fordebugpythat includes:"args": "${command:pickArgs}"hello world-> script should receive['hello', 'world']$USER-> script should receive your actual environment username, proving the shell expanded it before passing to Python.> output.txt-> script output should be redirected to a file, proving the shell intercepted the command.Follow-ups
None at this time. This aligns Theia's terminal execution for debuggers with VS Code's expected behavior.
Breaking changes
Attribution
Review checklist
nlsservice (for details, please see the Internationalization/Localization section in the Coding Guidelines)Reminder for reviewers