-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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 CLI option to syntax check script #2411
Conversation
if (process._syntax_check_only != null) { | ||
var vm = NativeModule.require('vm'); | ||
var fs = NativeModule.require('fs'); | ||
var source = fs.readFileSync(process.argv[1], 'utf-8').replace(/^#.*/, ''); |
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 see a couple of issues here:
- It won't work for filenames without an extension (
node app
vs.node app.js
) - It won't skip the UTF-8 BOM (byte order marker) like
require()
does. - The regular expression doesn't match the one in lib/module.js that matches the string
#!
.
It's probably unavoidable that fixing 2 and 3 results in some duplicated code but it should come with regression tests that ensure the implementations won't diverge.
Left some comments. Basic premise of this PR seems alright to me. |
92f6f50
to
8ee8b0d
Compare
Thanks @bnoordhuis for the review.
Additionally I've added to test for |
8ee8b0d
to
3d10585
Compare
@@ -2843,6 +2844,11 @@ void SetupProcessObject(Environment* env, | |||
READONLY_PROPERTY(process, "_print_eval", True(env->isolate())); | |||
} | |||
|
|||
// -c, --check | |||
if (syntax_check_only) { | |||
READONLY_PROPERTY(process, "_syntax_check_only", True(env->isolate())); |
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 would prefer using consistent camel casing. I am not sure if we can fix the _print_eval
above. cc @bnoordhuis
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'd be happy to change this if everyone agrees this should be done - I just tried to match the style I saw in this file.
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.
It's consistent with _print_eval
. I'm fine with it.
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.
Oh okay then. I was just worried that we would introduce non camel case identifiers in to the js land.
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.
Is this needed? the syntax check won't actually launch the script so there will never be access to process._syntax_check_only
.
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.
wait. nm. was thinking from the users' perspective. forgot about internal tooling.
Hey @bahamas10, welcome! This does seem like something that could easily be achieved by a userland module, surely there's already something in npm that does this, so what's the case for putting it in core? |
Hey @rvagg The indirect answer is here nodejs/node-v0.x-archive#9426 But to be more specific, to syntax check scripts:
etc. Most interpreted language interpreters support some way of saying "are the contents of the file given valid for interpretation?". This does not check style nor does it lint the content - just syntax. However, I realize the argument that "a bunch of people are doing it" is not sufficient. The node core is already the source of truth when it comes to compiling JavaScript source and determining if it is valid. For example, an As an example, imagine the following script (downloaded from #!/usr/bin/env node
var vm = require('vm');
var fs = require('fs');
var source = fs.readFileSync(process.argv[2], 'utf8').replace(/^#.*/, '');
new vm.Script(source, {displayErrors: true}); You could then call this script in the following way to achieve almost the same results as this PR
However, this only checks the validity of it against whichever
This requires a lot of knowledge about the underlying system, and also forces a specific interpreter for the script, going against what is in the shebang (ie. what the user intended it to be executed with) - thus running a script downloaded from I think it makes the most sense to cut out anything in the middle - any 3rd party script - and just ask the |
3d10585
to
d2809a3
Compare
|
The commit log should conform to the guidelines from CONTRIBUTING.md but otherwise LGTM. Let's see what the CI thinks: https://jenkins-iojs.nodesource.com/job/node-test-pull-request/104/ |
d2809a3
to
8c8998a
Compare
updated commit message based on CONTRIBUTING.md guidelines. |
OK, I'm -0 on this, I won't hold up merging if other collaborators feel strongly enough that this is a good thing to have |
8c8998a
to
64d8bf5
Compare
(merge conflicts resolved and rebased with latest master) |
@rvagg I don't feel comfortable about this being merged if you are having reservations about it. Is there anything specific about this you don't like? or is it an overall negative feeling about adding something extra to the node core? If you're available I'm happy to talk about this and make sure we are both on the same side with regards to this change. |
I didn't comment on it last time but FWIW, it seems like a reasonable addition to me with precedent in other scripting environments. Putting it in a npm package makes it markedly less convenient. |
yeah, sorry for not responding earlier, this is fine by me, the fact that other runtimes have the same functionality makes this easier to swallow |
https://ci.nodejs.org/job/node-test-pull-request/254/ again, the last one looked pretty flaky |
// check if user passed `-c` or `--check` arguments to Node. | ||
if (process._syntax_check_only != null) { | ||
var vm = NativeModule.require('vm'); | ||
var fs = NativeModule.require('fs'); |
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.
Use const
wherever the values are assigned once and never changed again.
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.
this could go either way cause it's not at all consistent in the file, we might be shifting that way but there's only one use of const
amongst the 20 NativeModule.require
calls already in this file, someone's probably going to do a round of cleanup at some point and this change could be done then
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.
@rvagg Oh, okay. I thought if we allowed the new code being landed to follow this rule strictly, then we just have to cleanup only the old code.
all green, https://ci.nodejs.org/job/node-test-commit/506/, that's pretty good given the recent state of our suite, lgtm |
|
||
const common = require('../common'); | ||
|
||
var node = process.argv[0]; |
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.
Use process.execPath
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.
@bahamas10 could you change this please?
Seems fine. |
+1 |
@bahamas10 I see 2 outstanding items, pointed them out inline, then I'll merge this and we should be able to get it into v4.x |
64d8bf5
to
03e1aa9
Compare
thanks @thefourtheye for the problems you've spotted. @rvagg i've force pushed a new commit with the changes... here is the intermediate diff to easily spot the changes $ gd
diff --git a/test/parallel/test-cli-syntax.js b/test/parallel/test-cli-syntax.js
index 059e3ef..20fdfdc 100644
--- a/test/parallel/test-cli-syntax.js
+++ b/test/parallel/test-cli-syntax.js
@@ -6,7 +6,7 @@ const path = require('path');
const common = require('../common');
-var node = process.argv[0];
+var node = process.execPath;
// test both sets of arguments that check syntax
var syntaxArgs = [
@@ -49,9 +49,13 @@ var syntaxArgs = [
var _args = args.concat(file);
var c = spawnSync(node, _args, {encoding: 'utf8'});
- // no output should be produced
+ // no stdout should be produced
assert.equal(c.stdout, '', 'stdout produced');
- assert(c.stderr, 'stderr not produced');
+
+ // stderr should have a syntax error message
+ var match = c.stderr.match(/^SyntaxError: Unexpected identifier$/m);
+ assert(match, 'stderr incorrect');
+
assert.equal(c.status, 1, 'code == ' + c.status);
});
});
@@ -68,9 +72,13 @@ var syntaxArgs = [
var _args = args.concat(file);
var c = spawnSync(node, _args, {encoding: 'utf8'});
- // no output should be produced
+ // no stdout should be produced
assert.equal(c.stdout, '', 'stdout produced');
- assert(c.stderr, 'stderr not produced');
+
+ // stderr should have a module not found error message
+ var match = c.stderr.match(/^Error: Cannot find module/m);
+ assert(match, 'stderr incorrect');
+
assert.equal(c.status, 1, 'code == ' + c.status);
});
}); |
I'd say to please use |
grf, bikeshed, can we defer the |
PR-URL: #2411 Reviewed-By: Rod Vagg <rod@vagg.org> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Evan Lucas <evanlucas@me.com>
landed @ 2e6ece4 with commit summary modification thanks @bahamas10 and congrats on first commit, and it's a significant one too! |
@rvagg + all. nice! thanks everyone. |
Nice to see this landed 👍 |
PR-URL: #2411 Reviewed-By: Rod Vagg <rod@vagg.org> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Evan Lucas <evanlucas@me.com>
The first Node.js LTS release! See https://github.com/nodejs/LTS/ for details of the LTS process. * **icu**: Updated to version 56 with significant performance improvements (Steven R. Loomis) #3281 * **node**: - Added new `-c` (or `--check`) command line argument for checking script syntax without executing the code (Dave Eddy) #2411 - Added `process.versions.icu` to hold the current ICU library version (Evan Lucas) #3102 - Added `process.release.lts` to hold the current LTS codename when the binary is from an active LTS release line (Rod Vagg) #3212 * **npm**: Upgraded to npm 2.14.7 from 2.14.4, see release notes: https://github.com/npm/npm/releases/tag/v2.14.7 for full details (Kat Marchán) #3299 PR-URL: #3258
The first Node.js LTS release! See https://github.com/nodejs/LTS/ for details of the LTS process. * **icu**: Updated to version 56 with significant performance improvements (Steven R. Loomis) #3281 * **node**: - Added new `-c` (or `--check`) command line argument for checking script syntax without executing the code (Dave Eddy) #2411 - Added `process.versions.icu` to hold the current ICU library version (Evan Lucas) #3102 - Added `process.release.lts` to hold the current LTS codename when the binary is from an active LTS release line (Rod Vagg) #3212 * **npm**: Upgraded to npm 2.14.7 from 2.14.4, see release notes: https://github.com/npm/npm/releases/tag/v2.14.7 for full details (Kat Marchán) #3299 PR-URL: #3258
The first Node.js LTS release! See https://github.com/nodejs/LTS/ for details of the LTS process. * **icu**: Updated to version 56 with significant performance improvements (Steven R. Loomis) #3281 * **node**: - Added new `-c` (or `--check`) command line argument for checking script syntax without executing the code (Dave Eddy) #2411 - Added `process.versions.icu` to hold the current ICU library version (Evan Lucas) #3102 - Added `process.release.lts` to hold the current LTS codename when the binary is from an active LTS release line (Rod Vagg) #3212 * **npm**: Upgraded to npm 2.14.7 from 2.14.4, see release notes: https://github.com/npm/npm/releases/tag/v2.14.7 for full details (Kat Marchán) #3299 PR-URL: #3258
The first Node.js LTS release! See https://github.com/nodejs/LTS/ for details of the LTS process. * **icu**: Updated to version 56 with significant performance improvements (Steven R. Loomis) #3281 * **node**: - Added new `-c` (or `--check`) command line argument for checking script syntax without executing the code (Dave Eddy) #2411 - Added `process.versions.icu` to hold the current ICU library version (Evan Lucas) #3102 - Added `process.release.lts` to hold the current LTS codename when the binary is from an active LTS release line (Rod Vagg) #3212 * **npm**: Upgraded to npm 2.14.7 from 2.14.4, see release notes: https://github.com/npm/npm/releases/tag/v2.14.7 for full details (Kat Marchán) #3299 PR-URL: #3258
I understand that we are done talking about this topic. However, I am writing to ask you one question.
if (true) {
return;
} But 'node -c test.js' occurs error "SyntaxError: Illegal return statement". 'return' statement works in function. But node module system wraps files in a self-executing function. so "node test.js" works but "node -c test.js" not works. |
@jays1204 I'd consider that a bug. Can you open an issue? |
@bnoordhuis already someone opened it :) |
original PR: nodejs/node-v0.x-archive#9447
original discussion: nodejs/node-v0.x-archive#9426
examples
tests pass