diff --git a/doc/node.1 b/doc/node.1 index 2621b94d570140..9603a91ef03548 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -41,6 +41,26 @@ focused on creating simple, easy to build network clients and servers. +.SH OPTIONS + + -v, --version print node's version + + -e, --eval script evaluate script + + -p, --print print result of --eval + + -i, --interactive always enter the REPL even if stdin + does not appear to be a terminal + + --no-deprecation silence deprecation warnings + + --trace-deprecation show stack traces on deprecations + + --v8-options print v8 command line options + + --max-stack-size=val set max v8 stack size (bytes) + + .SH ENVIRONMENT VARIABLES .IP NODE_PATH diff --git a/lib/fs.js b/lib/fs.js index 48724272062669..8bfc10cdd36fc0 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -919,7 +919,7 @@ fs.watchFile = function(filename) { // a little on the slow side but let's stick with it for now to keep // behavioral changes to a minimum. interval: 5007, - persistent: true, + persistent: true }; if ('object' == typeof arguments[1]) { diff --git a/lib/http.js b/lib/http.js index b4b6edc9df3ded..01aa4ebde80bd2 100644 --- a/lib/http.js +++ b/lib/http.js @@ -1831,12 +1831,9 @@ Client.prototype.request = function(method, path, headers) { return c; }; -exports.Client = Client; +exports.Client = util.deprecate(Client, + 'http.Client will be removed soon. Do not use it.'); -// TODO http.Client can be removed in v0.9. Until then leave this message. -module.deprecate('Client', 'It will be removed soon. Do not use it.'); - -exports.createClient = function(port, host) { +exports.createClient = util.deprecate(function(port, host) { return new Client(port, host); -}; -module.deprecate('createClient', 'Use `http.request` instead.'); +}, 'http.createClient is deprecated. Use `http.request` instead.'); diff --git a/lib/net.js b/lib/net.js index 5ffbea7aa534e6..9f03259d96a72f 100644 --- a/lib/net.js +++ b/lib/net.js @@ -133,14 +133,7 @@ function Socket(options) { if (typeof options == 'number') { // Legacy interface. - // Must support legacy interface. Old versions of npm depend on it. - // https://github.com/isaacs/npm/blob/c7824f412f0cb59d6f55cf0bc220253c39e6029f/lib/utils/output.js#L110 var fd = options; - - // Uncomment the following lines after libuv backend is stable and API - // compatibile with legaacy. - // console.error('Deprecated interface net.Socket(fd).'); - // console.trace(); this._handle = createPipe(); this._handle.open(fd); this.readable = this.writable = true; @@ -1092,14 +1085,9 @@ Server.prototype._emitCloseIfDrained = function() { }; -var listenFDwarn = false; -Server.prototype.listenFD = function(fd, type) { - if (!listenFDwarn) { - console.error('listenFD is deprecated. Use server.listen()'); - listenFDwarn = true; - } - this.listen({ fd: fd }); -}; +Server.prototype.listenFD = util.deprecate(function(fd, type) { + return this.listen({ fd: fd }); +}, 'listenFD is deprecated. Use listen({fd: }).'); // when sending a socket using fork IPC this function is executed Server.prototype._setupSlave = function(socketList) { diff --git a/lib/os.js b/lib/os.js index 47d1c565e6ea39..1fe8731033348e 100644 --- a/lib/os.js +++ b/lib/os.js @@ -20,6 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. var binding = process.binding('os'); +var util = require('util'); exports.hostname = binding.getHostname; exports.loadavg = binding.getLoadAvg; @@ -46,10 +47,8 @@ exports.tmpDir = function() { (process.platform === 'win32' ? 'c:\\windows\\temp' : '/tmp'); }; -exports.getNetworkInterfaces = function() { +exports.getNetworkInterfaces = util.deprecate(function() { return exports.networkInterfaces(); -}; -module.deprecate('getNetworkInterfaces', - 'It is now called `os.networkInterfaces`.'); +}, 'getNetworkInterfaces is now called `os.networkInterfaces`.'); exports.EOL = process.platform === 'win32' ? '\r\n' : '\n'; diff --git a/lib/path.js b/lib/path.js index 961dc400a538ac..438b05d8ef6914 100644 --- a/lib/path.js +++ b/lib/path.js @@ -21,7 +21,7 @@ var isWindows = process.platform === 'win32'; -var _deprecationWarning = require('util')._deprecationWarning; +var util = require('util'); // resolves . and .. elements in a path array with directory names there @@ -415,16 +415,14 @@ exports.extname = function(path) { }; -exports.exists = function(path, callback) { +exports.exists = util.deprecate(function(path, callback) { require('fs').exists(path, callback); -}; -module.deprecate('exists', 'It is now called `fs.exists`.'); +}, 'path.exists is now called `fs.exists`.'); -exports.existsSync = function(path) { +exports.existsSync = util.deprecate(function(path) { return require('fs').existsSync(path); -}; -module.deprecate('existsSync', 'It is now called `fs.existsSync`.'); +}, 'path.existsSync is now called `fs.existsSync`.'); if (isWindows) { diff --git a/lib/tty.js b/lib/tty.js index 414eed69861700..9fa18fd38c1d66 100644 --- a/lib/tty.js +++ b/lib/tty.js @@ -24,6 +24,7 @@ var inherits = require('util').inherits; var net = require('net'); var TTY = process.binding('tty_wrap').TTY; var isTTY = process.binding('tty_wrap').isTTY; +var util = require('util'); exports.isatty = function(fd) { return isTTY(fd); @@ -31,13 +32,12 @@ exports.isatty = function(fd) { // backwards-compat -exports.setRawMode = function(flag) { +exports.setRawMode = util.deprecate(function(flag) { if (!process.stdin.isTTY) { throw new Error('can\'t set raw mode on non-tty'); } process.stdin.setRawMode(flag); -}; -module.deprecate('setRawMode', 'Use `process.stdin.setRawMode()` instead.'); +}, 'tty.setRawMode: Use `process.stdin.setRawMode()` instead.'); function ReadStream(fd) { diff --git a/lib/util.js b/lib/util.js index 50595fd3f7a507..580aa81192587f 100644 --- a/lib/util.js +++ b/lib/util.js @@ -54,6 +54,31 @@ exports.format = function(f) { }; +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + exports.print = function() { for (var i = 0, len = arguments.length; i < len; ++i) { process.stdout.write(String(arguments[i])); @@ -407,12 +432,11 @@ function objectToString(o) { } -exports.p = function() { +exports.p = exports.deprecate(function() { for (var i = 0, len = arguments.length; i < len; ++i) { error(exports.inspect(arguments[i])); } -}; -module.deprecate('p', 'Use `util.puts(util.inspect())` instead.'); +}, 'util.p: Use console.error() instead.'); function pad(n) { @@ -438,10 +462,9 @@ exports.log = function(msg) { }; -exports.exec = function() { +exports.exec = exports.deprecate(function() { return require('child_process').exec.apply(this, arguments); -}; -module.deprecate('exec', 'It is now called `child_process.exec`.'); +}, 'util.exec is now called `child_process.exec`.'); exports.pump = function(readStream, writeStream, callback) { diff --git a/src/node.cc b/src/node.cc index d71a21b6938be2..94cc2a5f4896d8 100644 --- a/src/node.cc +++ b/src/node.cc @@ -120,6 +120,8 @@ static Persistent disposed_symbol; static bool print_eval = false; static bool force_repl = false; +static bool no_deprecation = false; +static bool trace_deprecation = false; static char *eval_string = NULL; static int option_end_index = 0; static bool use_debug_agent = false; @@ -1094,12 +1096,16 @@ enum encoding ParseEncoding(Handle encoding_v, enum encoding _default) { } else if (strcasecmp(*encoding, "hex") == 0) { return HEX; } else if (strcasecmp(*encoding, "raw") == 0) { - fprintf(stderr, "'raw' (array of integers) has been removed. " - "Use 'binary'.\n"); + if (!no_deprecation) { + fprintf(stderr, "'raw' (array of integers) has been removed. " + "Use 'binary'.\n"); + } return BINARY; } else if (strcasecmp(*encoding, "raws") == 0) { - fprintf(stderr, "'raws' encoding has been renamed to 'binary'. " - "Please update your code.\n"); + if (!no_deprecation) { + fprintf(stderr, "'raws' encoding has been renamed to 'binary'. " + "Please update your code.\n"); + } return BINARY; } else { return _default; @@ -2224,6 +2230,16 @@ Handle SetupProcessObject(int argc, char *argv[]) { process->Set(String::NewSymbol("_forceRepl"), True()); } + // --no-deprecation + if (no_deprecation) { + process->Set(String::NewSymbol("noDeprecation"), True()); + } + + // --trace-deprecation + if (trace_deprecation) { + process->Set(String::NewSymbol("traceDeprecation"), True()); + } + size_t size = 2*PATH_MAX; char* execPath = new char[size]; if (uv_exepath(execPath, &size) != 0) { @@ -2371,6 +2387,8 @@ static void PrintHelp() { " -p, --print print result of --eval\n" " -i, --interactive always enter the REPL even if stdin\n" " does not appear to be a terminal\n" + " --no-deprecation silence deprecation warnings\n" + " --trace-deprecation show stack traces on deprecations\n" " --v8-options print v8 command line options\n" " --max-stack-size=val set max v8 stack size (bytes)\n" "\n" @@ -2428,6 +2446,12 @@ static void ParseArgs(int argc, char **argv) { argv[i] = const_cast(""); } else if (strcmp(arg, "--v8-options") == 0) { argv[i] = const_cast("--help"); + } else if (strcmp(arg, "--no-deprecation") == 0) { + argv[i] = const_cast(""); + no_deprecation = true; + } else if (strcmp(arg, "--trace-deprecation") == 0) { + argv[i] = const_cast(""); + trace_deprecation = true; } else if (argv[i][0] != '-') { break; } diff --git a/src/node.js b/src/node.js index b2a0277a439af3..6a202fbce15c16 100644 --- a/src/node.js +++ b/src/node.js @@ -600,34 +600,5 @@ NativeModule._cache[this.id] = this; }; - // Wrap a core module's method in a wrapper that will warn on first use - // and then return the result of invoking the original function. After - // first being called the original method is restored. - NativeModule.prototype.deprecate = function(method, message) { - var original = this.exports[method]; - var self = this; - var warned = false; - message = message || ''; - - Object.defineProperty(this.exports, method, { - enumerable: false, - value: function() { - if (!warned) { - warned = true; - message = self.id + '.' + method + ' is deprecated. ' + message; - - var moduleIdCheck = new RegExp('\\b' + self.id + '\\b'); - if (moduleIdCheck.test(process.env.NODE_DEBUG)) - console.trace(message); - else - console.error(message); - - self.exports[method] = original; - } - return original.apply(this, arguments); - } - }); - }; - startup(); }); diff --git a/test/simple/test-deprecation-flags.js b/test/simple/test-deprecation-flags.js new file mode 100644 index 00000000000000..81605da21f39e5 --- /dev/null +++ b/test/simple/test-deprecation-flags.js @@ -0,0 +1,57 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); +var execFile = require('child_process').execFile; +var depmod = require.resolve('../fixtures/deprecated.js'); +var node = process.execPath; + +var normal = [depmod]; +var noDep = ['--no-deprecation', depmod]; +var traceDep = ['--trace-deprecation', depmod]; + +execFile(node, normal, function(er, stdout, stderr) { + console.error('normal: show deprecation warning'); + assert.equal(er, null); + assert.equal(stdout, ''); + assert.equal(stderr, 'util.p: Use console.error() instead.\n\'This is deprecated\'\n'); + console.log('normal ok'); +}); + +execFile(node, noDep, function(er, stdout, stderr) { + console.error('--no-deprecation: silence deprecations'); + assert.equal(er, null); + assert.equal(stdout, ''); + assert.equal(stderr, '\'This is deprecated\'\n'); + console.log('silent ok'); +}); + +execFile(node, traceDep, function(er, stdout, stderr) { + console.error('--trace-deprecation: show stack'); + assert.equal(er, null); + assert.equal(stdout, ''); + var stack = stderr.trim().split('\n'); + // just check the top and bottom. + assert.equal(stack[0], 'Trace: util.p: Use console.error() instead.'); + assert.equal(stack.pop(), '\'This is deprecated\''); + console.log('trace ok'); +});