mirror of https://github.com/nodejs/node.git
node: add -c|--check CLI arg to syntax check script
PR-URL: https://github.com/nodejs/node/pull/2411 Reviewed-By: Rod Vagg <rod@vagg.org> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Evan Lucas <evanlucas@me.com>
This commit is contained in:
parent
5bbc6df7de
commit
2e6ece44e1
|
@ -49,6 +49,8 @@ and servers.
|
|||
|
||||
-p, --print print result of --eval
|
||||
|
||||
-c, --check syntax check script without executing
|
||||
|
||||
-i, --interactive always enter the REPL even if stdin
|
||||
does not appear to be a terminal
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
'use strict';
|
||||
|
||||
module.exports.stripBOM = stripBOM;
|
||||
|
||||
/**
|
||||
* Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
|
||||
* because the buffer-to-string conversion in `fs.readFileSync()`
|
||||
* translates it to FEFF, the UTF-16 BOM.
|
||||
*/
|
||||
function stripBOM(content) {
|
||||
if (content.charCodeAt(0) === 0xFEFF) {
|
||||
content = content.slice(1);
|
||||
}
|
||||
return content;
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
const NativeModule = require('native_module');
|
||||
const util = require('util');
|
||||
const internalModule = require('internal/module');
|
||||
const internalUtil = require('internal/util');
|
||||
const runInThisContext = require('vm').runInThisContext;
|
||||
const assert = require('assert').ok;
|
||||
|
@ -435,21 +436,10 @@ Module.prototype._compile = function(content, filename) {
|
|||
};
|
||||
|
||||
|
||||
function stripBOM(content) {
|
||||
// Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
|
||||
// because the buffer-to-string conversion in `fs.readFileSync()`
|
||||
// translates it to FEFF, the UTF-16 BOM.
|
||||
if (content.charCodeAt(0) === 0xFEFF) {
|
||||
content = content.slice(1);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
// Native extension for .js
|
||||
Module._extensions['.js'] = function(module, filename) {
|
||||
var content = fs.readFileSync(filename, 'utf8');
|
||||
module._compile(stripBOM(content), filename);
|
||||
module._compile(internalModule.stripBOM(content), filename);
|
||||
};
|
||||
|
||||
|
||||
|
@ -457,7 +447,7 @@ Module._extensions['.js'] = function(module, filename) {
|
|||
Module._extensions['.json'] = function(module, filename) {
|
||||
var content = fs.readFileSync(filename, 'utf8');
|
||||
try {
|
||||
module.exports = JSON.parse(stripBOM(content));
|
||||
module.exports = JSON.parse(internalModule.stripBOM(content));
|
||||
} catch (err) {
|
||||
err.message = filename + ': ' + err.message;
|
||||
throw err;
|
||||
|
|
1
node.gyp
1
node.gyp
|
@ -70,6 +70,7 @@
|
|||
'lib/zlib.js',
|
||||
'lib/internal/child_process.js',
|
||||
'lib/internal/freelist.js',
|
||||
'lib/internal/module.js',
|
||||
'lib/internal/socket_list.js',
|
||||
'lib/internal/repl.js',
|
||||
'lib/internal/util.js',
|
||||
|
|
|
@ -121,6 +121,7 @@ using v8::Value;
|
|||
|
||||
static bool print_eval = false;
|
||||
static bool force_repl = false;
|
||||
static bool syntax_check_only = false;
|
||||
static bool trace_deprecation = false;
|
||||
static bool throw_deprecation = false;
|
||||
static bool abort_on_uncaught_exception = false;
|
||||
|
@ -2811,6 +2812,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()));
|
||||
}
|
||||
|
||||
// -i, --interactive
|
||||
if (force_repl) {
|
||||
READONLY_PROPERTY(process, "_forceRepl", True(env->isolate()));
|
||||
|
@ -3067,6 +3073,7 @@ static void PrintHelp() {
|
|||
" -v, --version print Node.js version\n"
|
||||
" -e, --eval script evaluate script\n"
|
||||
" -p, --print evaluate script and print result\n"
|
||||
" -c, --check syntax check script without executing\n"
|
||||
" -i, --interactive always enter the REPL even if stdin\n"
|
||||
" does not appear to be a terminal\n"
|
||||
" -r, --require module to preload (option can be repeated)\n"
|
||||
|
@ -3196,6 +3203,8 @@ static void ParseArgs(int* argc,
|
|||
}
|
||||
args_consumed += 1;
|
||||
local_preload_modules[preload_module_count++] = module;
|
||||
} else if (strcmp(arg, "--check") == 0 || strcmp(arg, "-c") == 0) {
|
||||
syntax_check_only = true;
|
||||
} else if (strcmp(arg, "--interactive") == 0 || strcmp(arg, "-i") == 0) {
|
||||
force_repl = true;
|
||||
} else if (strcmp(arg, "--no-deprecation") == 0) {
|
||||
|
|
16
src/node.js
16
src/node.js
|
@ -93,6 +93,22 @@
|
|||
process.argv[1] = path.resolve(process.argv[1]);
|
||||
|
||||
var Module = NativeModule.require('module');
|
||||
|
||||
// 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');
|
||||
var internalModule = NativeModule.require('internal/module');
|
||||
// read the source
|
||||
var filename = Module._resolveFilename(process.argv[1]);
|
||||
var source = fs.readFileSync(filename, 'utf-8');
|
||||
// remove shebang and BOM
|
||||
source = internalModule.stripBOM(source.replace(/^\#\!.*/, ''));
|
||||
// compile the script, this will throw if it fails
|
||||
new vm.Script(source, {filename: filename, displayErrors: true});
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
startup.preloadModules();
|
||||
if (global.v8debug &&
|
||||
process.execArgv.some(function(arg) {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
var foo bar;
|
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env node
|
||||
var foo bar;
|
|
@ -0,0 +1 @@
|
|||
var foo = 'bar';
|
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env node
|
||||
var foo = 'bar';
|
|
@ -0,0 +1,84 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const spawnSync = require('child_process').spawnSync;
|
||||
const path = require('path');
|
||||
|
||||
const common = require('../common');
|
||||
|
||||
var node = process.execPath;
|
||||
|
||||
// test both sets of arguments that check syntax
|
||||
var syntaxArgs = [
|
||||
['-c'],
|
||||
['--check']
|
||||
];
|
||||
|
||||
// test good syntax with and without shebang
|
||||
[
|
||||
'syntax/good_syntax.js',
|
||||
'syntax/good_syntax',
|
||||
'syntax/good_syntax_shebang.js',
|
||||
'syntax/good_syntax_shebang',
|
||||
].forEach(function(file) {
|
||||
file = path.join(common.fixturesDir, file);
|
||||
|
||||
// loop each possible option, `-c` or `--check`
|
||||
syntaxArgs.forEach(function(args) {
|
||||
var _args = args.concat(file);
|
||||
var c = spawnSync(node, _args, {encoding: 'utf8'});
|
||||
|
||||
// no output should be produced
|
||||
assert.equal(c.stdout, '', 'stdout produced');
|
||||
assert.equal(c.stderr, '', 'stderr produced');
|
||||
assert.equal(c.status, 0, 'code == ' + c.status);
|
||||
});
|
||||
});
|
||||
|
||||
// test bad syntax with and without shebang
|
||||
[
|
||||
'syntax/bad_syntax.js',
|
||||
'syntax/bad_syntax',
|
||||
'syntax/bad_syntax_shebang.js',
|
||||
'syntax/bad_syntax_shebang'
|
||||
].forEach(function(file) {
|
||||
file = path.join(common.fixturesDir, file);
|
||||
|
||||
// loop each possible option, `-c` or `--check`
|
||||
syntaxArgs.forEach(function(args) {
|
||||
var _args = args.concat(file);
|
||||
var c = spawnSync(node, _args, {encoding: 'utf8'});
|
||||
|
||||
// no stdout should be produced
|
||||
assert.equal(c.stdout, '', 'stdout 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);
|
||||
});
|
||||
});
|
||||
|
||||
// test file not found
|
||||
[
|
||||
'syntax/file_not_found.js',
|
||||
'syntax/file_not_found'
|
||||
].forEach(function(file) {
|
||||
file = path.join(common.fixturesDir, file);
|
||||
|
||||
// loop each possible option, `-c` or `--check`
|
||||
syntaxArgs.forEach(function(args) {
|
||||
var _args = args.concat(file);
|
||||
var c = spawnSync(node, _args, {encoding: 'utf8'});
|
||||
|
||||
// no stdout should be produced
|
||||
assert.equal(c.stdout, '', 'stdout 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);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue