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

Refactor executor to pass shell arguments as array #57

Merged
merged 6 commits into from
Feb 23, 2022

Conversation

Discookie
Copy link
Collaborator

Closes #56.

Previously, we .join(' ')-ed the executor arguments. With this refactor, the executor no longer constructs the full command-line, but rather directly passes the args array to child_process.spawn.

For the user-facing input (arguments setting) and output (command-line preview), the shell-quote package is used.

Copy link

@steakhal steakhal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great.

src/backend/executor/bridge.ts Show resolved Hide resolved
@@ -228,5 +226,8 @@
"vsce": "^1.100.1",
"webpack": "^5.19.0",
"webpack-cli": "^4.4.0"
},
"dependencies": {
"shell-quote": "^1.7.3"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type annotations are for a different version of this library.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, the public API hasn't changed between the patch versions - .2 was a regression fix, and .3 was a CVE fix.
There's no newer version of the @types either, so it should be fine like this.

package.json Outdated
"description": "Path to a custom compilation database, in case of a custom build system",
"default": null,
"order": 3
},
"codechecker.executor.arguments": {
"type": "string",
"description": "Additional arguments to CodeChecker analyze command. For supported arguments, run `CodeChecker analyze --help`. The command `CodeChecker: Show full command line` command shows the resulting command line.",
"description": "Additional arguments to CodeChecker analyze command. For supported arguments, run `CodeChecker analyze --help`. The command `CodeChecker: Show full command line` command shows the resulting command line. Also accepts arguments in a string-array form.",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also accepts arguments in a string-array form.

What is the syntax for that? Should I use a brackets [ .. ] or only a comma-separated list?
Which should the user prefer?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decided to remove the string-array input by the user in the end.

Basically I had 3 options:

  • Don't let the user input string-arrays
  • Let the user input the array in the textbox - but it's a minefield since there's no syntax or other kind of checks inside the textbox.
  • Let the user input them as literal arrays in the settings.json - but this way the user doesn't have a textbox to enter args, only a convoluted Edit in settings.json button.

And the other options both sacrifice considerable UX.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user can still escape the characters properly themselves using one of their own tools if need be, and shell-quote should still be able to parse those args the same way.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How should one interpret the added sentence?
If there is no clear interpretation, why do we need that? Wouldn't it confuse the users?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to say the sentence was removed, but it is not there anymore, so it should be fine as is.

@csordasmarton csordasmarton added this to the 1.1.1 milestone Jan 31, 2022
@Discookie Discookie force-pushed the ericsson/fix-serialize-path branch 2 times, most recently from f85d611 to b8ab95a Compare February 2, 2022 02:48
Copy link

@steakhal steakhal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the escape bug is fixed.
I have a couple of comments though.

};
for (const [key, val] of Object.entries(process.env)) {
if (val !== undefined) {
env[`env.${key}`] = val;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be env[key] = val instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default VS Code settings handle environment variables a bit differently (docs), so the env variables are accessible via ${env:<env>} in eg. other settings as well.

VSCode doesn't provide an auto-substitute function, that's the only reason it is done manually here.

(There's also a typo here, env. instead of env:, fixed.)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. It looks correct.

Comment on lines 196 to +207
const filePaths = files.length
? `--file ${files.map((uri) => `"${uri.fsPath}"`).join(' ')}`
: '';
? ['--file', ...files.map((uri) => uri.fsPath)]
: [];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the parse command contain an option specifying the skiplist file?
--file and --skip options are mutually exclusive options AFAIK.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally to this, the file option will parse the file path and do a lookup in the compdb.json to find the corresponding entry for that TU. However, if there are symbolic links, the two might mismatch. It happens for me at least, and it basically a blocker for analyzing any files. However, we might need to fix this on the CodeChecker side. Im not sure.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed they are, created an issue for this: #74.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if it's even possible to solve the second issue on our side without resolving all paths in the comp. db.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, well. I saw once that the plugin copied the json. That being said, you can lookup all entries there and resolve than replace the occurrances. Basically patching the local copy db, where the canonical representation would be the resolved paths to the given TU. Keep in mind that the original db cannot be modified, since that might be generated by cmake for example. Alternatively you should document this behavior and even better, have a foolproof test in code and a popup-hint that there is a mismatch. You should 'log' and create a db.json using the resolved path as a working directory. BTW the CodeChecker ldlogger should be able to workaround this, but thats a different topic.

@csordasmarton csordasmarton modified the milestones: 1.2.0, 1.3.0 Feb 14, 2022
@csordasmarton
Copy link
Contributor

@Discookie can you please rebase your branch. It contains some merge conflict. I would like to try it out and merge it if I don't find any problem.

Copy link
Contributor

@csordasmarton csordasmarton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolve the merge conflict.

Copy link
Contributor

@csordasmarton csordasmarton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I wasn't able to review this patch fully because when I tried it out I got a version check error when I started the VSCode from your branch.

const ccPath = getConfigAndReplaceVariables('codechecker.executor', 'executablePath')
?? 'CodeChecker';

public getVersionCmdArgs(): string[] | undefined {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I started VSCode with your branch I got the following error:
image

In the console I saw this:

>>> Process 'CodeChecker version' errored: spawn ~/CodeChecker/bin/CodeChecker ENOENT
>>> CodeChecker error while checking version

In the settings I set the CodeChecker binary path to ~/CodeChecker/bin/CodeChecker. Previously it worked so I think there is some bug in your patch.

Also please change this line to analyzer-version because the error message above is a little bit misleading (we do not run CodeChecker version command but CodeChecker analyzer-version):

version = 'CodeChecker version',

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that my CodeChecker executable path started with ~ and the spawn doesn't work properly with such cases. See: nodejs/node#684

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the docs to say the setting requires an absolute path.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not enough. ~/CodeChecker/bin/CodeChecker is an absolute path and I still get this exception.

If we do not remove { shell: true } option from the spawn method it will work:

this.activeProcess = child_process.spawn(this.commandLine, { shell: true });

Otherwise we have to untildify the path.

Maybe the first option is better and simplier because in that case we don't have to untildify every path arguments.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should still remove shell true.

Copy link
Contributor

@csordasmarton csordasmarton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@csordasmarton csordasmarton merged commit a458bc9 into Ericsson:main Feb 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Properly shell-escape for constructing commands
3 participants