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

lib: add --deprecate-soon and util.deprecateSoon() #9483

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ added: v0.11.14

Throw errors for deprecations.

### `--deprecated-in-docs`
<!-- YAML
added: REPLACEME
-->

Show warnings for APIs that have been deprecated in the documentation.

### `--no-warnings`
<!-- YAML
added: v6.0.0
Expand Down
4 changes: 4 additions & 0 deletions doc/node.1
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ Print stack traces for deprecations.
.BR \-\-throw\-deprecation
Throw errors for deprecations.

.TP
.BR \-\-deprecated-in-docs
Show warnings for APIs that have been deprecated in the documentation.

.TP
.BR \-\-no\-warnings
Silence all process warnings (including deprecations).
Expand Down
30 changes: 30 additions & 0 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,33 @@ exports.cachedResult = function cachedResult(fn) {
return result;
};
};

// Used to emit a warning when a function has been deprecated
// in the docs. Only has an effect when the --deprecated-in-docs
// command line argument is used (off by default).
exports.deprecatedInDocs = function(fn, msg) {
if (process.binding('config').deprecateInDocs !== true)
return fn;

var warned = false;
function deprecatedInDocs() {
if (!warned) {
warned = true;
process.emitWarning(msg, 'DeprecatedInDocsWarning', deprecatedInDocs);
}
if (new.target) {
return Reflect.construct(fn, arguments, new.target);
}
return fn.apply(this, arguments);
}
// The wrapper will keep the same prototype as fn to maintain prototype chain
Object.setPrototypeOf(deprecatedInDocs, fn);
if (fn.prototype) {
// Setting this (rather than using Object.setPrototype, as above) ensures
// that calling the unwrapped constructor gives an instanceof the wrapped
// constructor.
deprecatedInDocs.prototype = fn.prototype;
}

return deprecatedInDocs;
};
10 changes: 10 additions & 0 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ bool trace_warnings = false;
// that is used by lib/module.js
bool config_preserve_symlinks = false;

// Set in node.cc by ParseArgs when --deprecated-in-docs is used.
// Used in node_config.cc to set a constant on process.binding('config')
// that is used by the emitDeprecatedInDocsWarning() method in
// lib/internal/util.js
bool config_deprecated_in_docs = false;

bool v8_initialized = false;

// process-relative uptime base, initialized at start-up
Expand Down Expand Up @@ -3539,6 +3545,8 @@ static void PrintHelp() {
" --trace-deprecation show stack traces on deprecations\n"
" --throw-deprecation throw an exception anytime a deprecated "
"function is used\n"
" --deprecated-in-docs show warnings for APIs that are deprecated\n"
" in the docs\n"
" --no-warnings silence all process warnings\n"
" --trace-warnings show stack traces on process warnings\n"
" --trace-sync-io show stack trace when use of sync IO\n"
Expand Down Expand Up @@ -3695,6 +3703,8 @@ static void ParseArgs(int* argc,
track_heap_objects = true;
} else if (strcmp(arg, "--throw-deprecation") == 0) {
throw_deprecation = true;
} else if (strcmp(arg, "--deprecated-in-docs") == 0) {
config_deprecated_in_docs = true;
} else if (strncmp(arg, "--security-revert=", 18) == 0) {
const char* cve = arg + 18;
Revert(cve);
Expand Down
3 changes: 3 additions & 0 deletions src/node_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ void InitConfig(Local<Object> target,

if (config_preserve_symlinks)
READONLY_BOOLEAN_PROPERTY("preserveSymlinks");

if (config_deprecated_in_docs)
READONLY_BOOLEAN_PROPERTY("deprecatedInDocs");
} // InitConfig

} // namespace node
Expand Down
2 changes: 2 additions & 0 deletions src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ extern const char* openssl_config;
// that is used by lib/module.js
extern bool config_preserve_symlinks;

extern bool config_deprecated_in_docs;

// Tells whether it is safe to call v8::Isolate::GetCurrent().
extern bool v8_initialized;

Expand Down
37 changes: 37 additions & 0 deletions test/parallel/test-deprecate-soon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

// Tests the --deprecated-in-docs command line option and warning emission.

const common = require('../common');
const assert = require('assert');
const spawnSync = require('child_process').spawnSync;
const deprecateInDocs = process.binding('config').deprecateInDocs;

if (process.argv[2] === 'child') {
const util = require('internal/util');
const fn = util.deprecatedInDocs(() => {}, 'this is deprecated in the docs');

process.on('warning', common.mustCall((warning) => {
assert.strictEqual(warning.name, 'DeprecatedInDocsWarning');
assert.strictEqual(warning.message, 'this is deprecated in the docs');
}, deprecateInDocs ? 1 : 0));
fn();
} else {
const options = [
'--expose-internals',
__filename,
'child'
];

// Do not emit the deprecated in docs warning
assert.strictEqual(
spawnSync(process.execPath, options).status, 0,
'deprecation warning was printed');

options.unshift('--deprecated-in-docs');

// Emit the deprecated in docs warning
assert.strictEqual(
spawnSync(process.execPath, options).status, 0,
'deprecation warning was not printed properly');
}