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

repl: remove NODE_REPL_HISTORY_FILE #13876

Closed
wants to merge 1 commit 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
8 changes: 8 additions & 0 deletions doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,14 @@ Use [`asyncResource.runInAsyncScope()`][] API instead which provides a much
safer, and more convenient, alternative. See
https://github.com/nodejs/node/pull/18513 for more details.

<a id="DEP0XXX"></a>
### DEP0XXX: NODE_REPL_HISTORY_FILE environment variable

Type: End-of-life

`NODE_REPL_HISTORY_FILE` environment variable was removed. Please use
`NODE_REPL_HISTORY` instead.

[`--pending-deprecation`]: cli.html#cli_pending_deprecation
[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size
[`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array
Expand Down
16 changes: 0 additions & 16 deletions doc/api/repl.md
Original file line number Diff line number Diff line change
Expand Up @@ -506,22 +506,6 @@ by saving inputs to a `.node_repl_history` file located in the user's home
directory. This can be disabled by setting the environment variable
`NODE_REPL_HISTORY=""`.

#### NODE_REPL_HISTORY_FILE
<!-- YAML
added: v2.0.0
deprecated: v3.0.0
-->

> Stability: 0 - Deprecated: Use `NODE_REPL_HISTORY` instead.

Previously in Node.js/io.js v2.x, REPL history was controlled by using a
`NODE_REPL_HISTORY_FILE` environment variable, and the history was saved in JSON
format. This variable has now been deprecated, and the old JSON REPL history
file will be automatically converted to a simplified plain text format. This new
file will be saved to either the user's home directory, or a directory defined
by the `NODE_REPL_HISTORY` variable, as documented in the
[Environment Variable Options](#repl_environment_variable_options).

### Using the Node.js REPL with advanced line-editors

For advanced line-editors, start Node.js with the environment variable
Expand Down
60 changes: 8 additions & 52 deletions lib/internal/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ function createInternalRepl(env, opts, cb) {
if (parseInt(env.NODE_NO_READLINE)) {
opts.terminal = false;
}
// the "dumb" special terminal, as defined by terminfo, doesn't support
// ANSI color control codes.
// The "dumb" special terminal, as defined by terminfo, doesn't support
// ANSI colour control codes.
// see http://invisible-island.net/ncurses/terminfo.ti.html#toc-_Specials
if (parseInt(env.NODE_DISABLE_COLORS) || env.TERM === 'dumb') {
opts.useColors = false;
Expand All @@ -61,17 +61,15 @@ function createInternalRepl(env, opts, cb) {

const repl = REPL.start(opts);
if (opts.terminal) {
return setupHistory(repl, env.NODE_REPL_HISTORY,
env.NODE_REPL_HISTORY_FILE, cb);
return setupHistory(repl, env.NODE_REPL_HISTORY, cb);
}

repl._historyPrev = _replHistoryMessage;
cb(null, repl);
}

function setupHistory(repl, historyPath, oldHistoryPath, ready) {
// Empty string disables persistent history.

function setupHistory(repl, historyPath, ready) {
// Empty string disables persistent history
if (typeof historyPath === 'string')
historyPath = historyPath.trim();

Expand Down Expand Up @@ -131,50 +129,8 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) {

if (data) {
repl.history = data.split(/[\n\r]+/, repl.historySize);
} else if (oldHistoryPath === historyPath) {
// If pre-v3.0, the user had set NODE_REPL_HISTORY_FILE to
// ~/.node_repl_history, warn the user about it and proceed.
_writeToOutput(
repl,
'\nThe old repl history file has the same name and location as ' +
`the new one i.e., ${historyPath} and is empty.\nUsing it as is.\n`);

} else if (oldHistoryPath) {
let threw = false;
try {
// Pre-v3.0, repl history was stored as JSON.
// Try and convert it to line separated history.
const oldReplJSONHistory = fs.readFileSync(oldHistoryPath, 'utf8');

// Only attempt to use the history if there was any.
if (oldReplJSONHistory) repl.history = JSON.parse(oldReplJSONHistory);

if (Array.isArray(repl.history)) {
repl.history = repl.history.slice(0, repl.historySize);
} else {
threw = true;
_writeToOutput(
repl,
'\nError: The old history file data has to be an Array.\n' +
'REPL session history will not be persisted.\n');
}
} catch (err) {
// Cannot open or parse history file.
// Don't crash, just don't persist history.
threw = true;
const type = err instanceof SyntaxError ? 'parse' : 'open';
_writeToOutput(repl, `\nError: Could not ${type} old history file.\n` +
'REPL session history will not be persisted.\n');
}
if (!threw) {
// Grab data from the older pre-v3.0 JSON NODE_REPL_HISTORY_FILE format.
_writeToOutput(
repl,
'\nConverted old JSON repl history to line-separated history.\n' +
`The new repl history file can be found at ${historyPath}.\n`);
} else {
repl.history = [];
}
} else {
repl.history = [];
}

fs.open(historyPath, 'r+', onhandle);
Expand All @@ -188,7 +144,7 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) {
repl._historyHandle = hnd;
repl.on('line', online);

// reading the file data out erases it
// Reading the file data out erases it
repl.once('flushHistory', function() {
repl.resume();
ready(null, repl);
Expand Down
4 changes: 0 additions & 4 deletions test/fixtures/old-repl-history-file.json

This file was deleted.

82 changes: 4 additions & 78 deletions test/parallel/test-repl-persistent-history.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,6 @@ const CLEAR = { ctrl: true, name: 'u' };
const historyFixturePath = fixtures.path('.node_repl_history');
const historyPath = path.join(tmpdir.path, '.fixture_copy_repl_history');
const historyPathFail = fixtures.path('nonexistent_folder', 'filename');
const oldHistoryPathObj = fixtures.path('old-repl-history-file-obj.json');
const oldHistoryPathFaulty = fixtures.path('old-repl-history-file-faulty.json');
const oldHistoryPath = fixtures.path('old-repl-history-file.json');
const enoentHistoryPath = fixtures.path('enoent-repl-history-file.json');
const emptyHistoryPath = fixtures.path('.empty-repl-history-file');
const defaultHistoryPath = path.join(tmpdir.path, '.node_repl_history');
const emptyHiddenHistoryPath = fixtures.path('.empty-hidden-repl-history-file');
const devNullHistoryPath = path.join(tmpdir.path,
Expand All @@ -72,23 +67,10 @@ const prompt = '> ';
const replDisabled = '\nPersistent history support disabled. Set the ' +
'NODE_REPL_HISTORY environment\nvariable to a valid, ' +
'user-writable path to enable.\n';
const convertMsg = '\nConverted old JSON repl history to line-separated ' +
'history.\nThe new repl history file can be found at ' +
`${defaultHistoryPath}.\n`;
const homedirErr = '\nError: Could not get the home directory.\n' +
'REPL session history will not be persisted.\n';
const replFailedRead = '\nError: Could not open history file.\n' +
'REPL session history will not be persisted.\n';
const oldHistoryFailedOpen = '\nError: Could not open old history file.\n' +
'REPL session history will not be persisted.\n';
const oldHistoryFailedParse = '\nError: Could not parse old history file.\n' +
'REPL session history will not be persisted.\n';
const oldHistoryObj = '\nError: The old history file data has to be an Array' +
'.\nREPL session history will not be persisted.\n';
const sameHistoryFilePaths = '\nThe old repl history file has the same name ' +
'and location as the new one i.e., ' +
`${defaultHistoryPath}` +
' and is empty.\nUsing it as is.\n';

const tests = [
{
Expand All @@ -101,84 +83,28 @@ const tests = [
test: [UP],
expected: [prompt, replDisabled, prompt]
},
{
env: { NODE_REPL_HISTORY_FILE: enoentHistoryPath },
test: [UP],
expected: [prompt, oldHistoryFailedOpen, prompt]
},
{
env: { NODE_REPL_HISTORY_FILE: oldHistoryPathObj },
test: [UP],
expected: [prompt, oldHistoryObj, prompt]
},
{
env: { NODE_REPL_HISTORY_FILE: oldHistoryPathFaulty },
test: [UP],
expected: [prompt, oldHistoryFailedParse, prompt]
},
{
env: { NODE_REPL_HISTORY: '',
NODE_REPL_HISTORY_FILE: oldHistoryPath },
test: [UP],
expected: [prompt, replDisabled, prompt]
},
{
env: { NODE_REPL_HISTORY_FILE: emptyHistoryPath },
test: [UP],
expected: [prompt, convertMsg, prompt]
},
{
env: { NODE_REPL_HISTORY_FILE: defaultHistoryPath },
test: [UP],
expected: [prompt, sameHistoryFilePaths, prompt]
},
{
env: { NODE_REPL_HISTORY: historyPath },
test: [UP, CLEAR],
expected: [prompt, `${prompt}'you look fabulous today'`, prompt]
},
{
env: { NODE_REPL_HISTORY: historyPath,
NODE_REPL_HISTORY_FILE: oldHistoryPath },
test: [UP, CLEAR],
expected: [prompt, `${prompt}'you look fabulous today'`, prompt]
},
{
env: { NODE_REPL_HISTORY: historyPath,
NODE_REPL_HISTORY_FILE: '' },
test: [UP, CLEAR],
expected: [prompt, `${prompt}'you look fabulous today'`, prompt]
},
{
env: {},
test: [UP],
expected: [prompt]
},
{
env: { NODE_REPL_HISTORY_FILE: oldHistoryPath },
test: [UP, CLEAR, '\'42\'', ENTER],
expected: [prompt, convertMsg, prompt, `${prompt}'=^.^='`, prompt, '\'',
'4', '2', '\'', '\'42\'\n', prompt, prompt],
test: [UP, '\'42\'', ENTER],
expected: [prompt, '\'', '4', '2', '\'', '\'42\'\n', prompt, prompt],
clean: false
},
{ // Requires the above testcase
{ // Requires the above test case
env: {},
test: [UP, UP, ENTER],
expected: [prompt, `${prompt}'42'`, `${prompt}'=^.^='`, '\'=^.^=\'\n',
prompt]
expected: [prompt, `${prompt}'42'`, '\'42\'\n', prompt]
},
{
env: { NODE_REPL_HISTORY: historyPath,
NODE_REPL_HISTORY_SIZE: 1 },
test: [UP, UP, CLEAR],
expected: [prompt, `${prompt}'you look fabulous today'`, prompt]
},
{
env: { NODE_REPL_HISTORY_FILE: oldHistoryPath,
NODE_REPL_HISTORY_SIZE: 1 },
test: [UP, UP, UP, CLEAR],
expected: [prompt, convertMsg, prompt, `${prompt}'=^.^='`, prompt]
},
{
env: { NODE_REPL_HISTORY: historyPathFail,
NODE_REPL_HISTORY_SIZE: 1 },
Expand Down