-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
process/task/terminal: refactor escaping/quoting #6836
Conversation
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.
I've only looked through the code, will test later. If some tests in the meantime it would help.
6ce6613
to
949bce1
Compare
Thanks for the test @elaihau ! I was missing some task related tests, added them back and fixed the issue you reported :) Although, the specific example you are using is annoying me in some way, because in my opinion it illustrates a behavior that I don't like from VS Code: Essentially, they battle to see if a user already escaped part of an argument, see related code. From what I understand, when dealing with user defined shell task arguments, I see 2 scenarios:
With all of that said, I still tried to mimic what VS Code is doing, without doing it the same way either. The quotation mechanism should be more stable and robust, and user shouldn't care about escaping a thing, unless it is running in an unknown shell for which Theia doesn't know how to escape. But that's kinda asking for trouble, and practically it shouldn't happen. Now if you have a task command complex enough that you need crazy escaping, that Theia would natively handle but not VS Code, the solution is simply to refactor the command into a script and write a simple task to trigger said script, it will avoid a lot of trouble for everyone ahah. |
I would even go as far as adding a property for shell tasks named |
949bce1
to
73a2ce1
Compare
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.
Although, the specific example you are using is annoying me in some way, because in my opinion it illustrates a behavior that I don't like from VS Code: Essentially, they battle to see if a user already escaped part of an argument, see related code.
We can do as we like, but we should support whatever VS Code allows as minimum.
Indeed, but to me it seems a bit like bad UX from VS Code, having to think about 3 escaping stages (JSON, VS Code, Shell) instead of just having to care about escaping a string for JSON and leaving the rest to Theia. And if you want to escape yourself, either add the verbatim option, or write a full command line in the |
73a2ce1
to
727b276
Compare
Having little issues with Windows, will fix. |
bc4ca6e
to
6c08675
Compare
@marechal-p do you mind rebasing the pull-request (resolve the conflicts), I can take another high-level look at the pull-request :) |
8d55945
to
7ebe8ab
Compare
I will now have to fix the new issues on Windows that appeared after the rebase, sigh. CQ still pending too, so it's fine I guess. |
@marechal-p CQ has checkin tag, it means we can merge |
Looking forword to the landing of this PR which will fix the debug failure when using existing |
@tom-shan I'm having issues with escaping for |
7ebe8ab
to
ee68ad8
Compare
ee68ad8
to
e25e24c
Compare
I think I managed to tackle most of the issues I was having. Hopefully the CI will be green now. This PR is finally re-ready for review. Sorry for the delay, it definitely was a struggle. The code might not be perfect, but I'll leave this up to reviewers. |
4d4b18a
to
3bf8666
Compare
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.
Code wise looks very good. I have not time to test changes yet.
I hope @elaihau @RomanNikitenko can help with testing the task extension.
And @vince-fugnitto @tolusha with testing the debug extension
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.
Besides common use cases I tested 2 edge cases this time:
{
"type": "shell",
"command": "node",
"args": [
"-e",
"\"console.log(\"1 + 2\")\""
],
"label": "test node command"
}
and
{
"type": "shell",
"command": "node",
"args": [
"-e",
"\"console.log(\\\"1 + 2\\\")\""
],
"label": "test node command"
}
This one works too
{
"type": "shell",
"command": "node",
"args": [
"-e",
"let a = 3; a+=\"5\"; console.log(a);"
],
"label": "test node command"
}
3bf8666
to
b674aa9
Compare
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.
I confirmed that debugging still works, and the use case in 'how to test' works successfully.
I am able to debug python files with spaces in their names, something that was otherwise not possible (ex: master
).
I'm happy that we included multiple test cases for different edge cases and escaping for different shell types 👍
Add utility functions in `@theia/process/lib/common` to escape common shells' arguments. Refactored terminal processes to not handle shell escaping anymore, it is the caller's responsability to provide the escaped spawn options. Escaping is now done for DAP's `runInTerminal` requests. Changelog: - Moved quoting types and functions from `process/lib/node/termina-process.ts` to `process/lib/common/shell-quoting.ts`. - Added a `ShellCommandBuilder` component, used to build commands for evaluation in a shell (as if someone was typing manually). - `TerminalProcess` no longer supports running things in a shell as part of its options. Execution in a shell must be encoded in the spawn options by the caller. You can use `createShellCommandLine` to process arguments. Signed-off-by: Paul Maréchal <[email protected]>
b674aa9
to
f5f68aa
Compare
@marechal-p, I have noticed test failures in
I was looking into the history of CC: @akosyakov |
Hmm this PR was merged early April, since then the CI was green on all 3 platforms. @vince-fugnitto tried to run master's task tests on his own OS X and the only failure seemed to be related to nvm behaving weird and killing a terminal (1 failure only). Is it possible that one of our dependencies updated? (not necessarily npm-related) Something new in the environments where the failure happens? note: I just tried on my Windows machine and the tests are passing. |
Yes, I know. BTW, some tests are skipped on Windows.
I know. It is strange, I agree.
Well, I do not know, but I can reproduce the test failure with this change and it works without, so I do not think this is a non-npm dependency issue. |
Just tried on an Ubuntu 18.04 and no failure either. I cannot efficiently troubleshoot your issue if I cannot reproduce though... Can you try to find the cause of the failures caused by this patch in your environment? |
Where did you get these, @marechal-p? For example, we did not have this code, or similar before, my command is Edit: (copied code because GH linking does not work)
if (/bash(.exe)?$/.test(command)) {
quotingFunctions = BashQuotingFunctions;
execArgs = ['-l', '-c'];
} else if (/wsl(.exe)?$/.test(command)) {
quotingFunctions = BashQuotingFunctions;
execArgs = ['-e'];
} else if (/cmd(.exe)?$/.test(command)) {
quotingFunctions = CmdQuotingFunctions;
execArgs = ['/S', '/C'];
} else if (/(ps|pwsh|powershell)(.exe)?/.test(command)) {
quotingFunctions = PowershellQuotingFunctions;
execArgs = ['-c'];
} |
OK, I got it. Seems like we are already outdated compared to VS Code: |
Maybe just a matter of picking better defaults than what we currently have, see VS Code: } else if (env.isWindows) {
shellType = ShellType.cmd; // pick a good default for Windows
} else {
shellType = ShellType.bash; // pick a good default for anything else
} Currently there's no default being used. |
What it does
Add utility functions in
@theia/process/lib/common
to escape commonshells' arguments. Refactored terminal processes to not handle shell
escaping anymore, it is the caller's responsability to provide the
escaped spawn options.
Escaping is now done for DAP's
runInTerminal
requests.Most of the design is taken from VS Code, with minor tweaks.
Tried to test as much as possible since escaping rules can get complicated in corner cases.
Fixes #6684
How to test
@theia/process
,@theia/task
, and@theia/debug
).shell
tasks, using quoted strings (see VS Code Custom Tasks).Review checklist
Reminder for reviewers