Skip to content

Conversation

maclover7
Copy link
Contributor

Refs: #13876

Just a note that I've been trying to add tests for this, but it's been
difficult because it seems like most REPL tests directly patch into
internals, and are not run via a child process.

Also, not sure if this should even be landing, since it's very close to the v9 release candidate release... cc @jasnell

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

repl

@nodejs-github-bot nodejs-github-bot added the repl Issues and PRs related to the REPL subsystem. label Oct 25, 2017
@@ -167,6 +168,12 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) {
'REPL session history will not be persisted.\n');
}
if (!threw) {
deprecate(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem correct to me. Who calls the function returned by deprecate()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lpinca sorry, I didn't read internal/util source correctly, I thought deprecate auto-printed the deprecation. updated my pr.

@@ -167,6 +174,8 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) {
'REPL session history will not be persisted.\n');
}
if (!threw) {
_printHistoryDeprecation(oldHistoryPath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be called in setupHistory() iff oldHistoryPath is not null or undefined. By calling it here, it won't be displayed for users who have set the NODE_REPL_HISTORY_FILE env variable, but opening or parsing that history file throws an Error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, fair point. But wouldn't we want to only show the error message to NODE_REPL_HISTORY_FILEs that actually parse correctly? If the file is broken, they probably wouldn't be able to convert it to the new file format anyway, right? 😬

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm - ping @lance @maclover7 ?

My guess would be that there's nobody left using the old format anyway by now and that this particular difference would really not matter anyway

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for my latency. @addaleax @maclover7 your points are valid. TBH, I think it would be more correct if moved to setupHistory(), but I won't block the PR on that.

@BridgeAR
Copy link
Member

Ping @maclover7

@maclover7
Copy link
Contributor Author

@maclover7
Copy link
Contributor Author

const { deprecate } = require('internal/util');
const _printHistoryDeprecation = deprecate(
() => path,
'NODE_REPL_HISTORY_FILE is deprecated. Use the plaintext format instead.',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might it be more clear to say "use NODE_REPL_HISTORY instead"? That's what the docs say.

Copy link
Member

@Trott Trott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with a suggestion

@Trott Trott added the semver-major PRs that contain breaking changes and should be released in the next major version. label Dec 4, 2017
@Trott
Copy link
Member

Trott commented Dec 4, 2017

Labeled semver-major due to policy that the introduction of a runtime deprecation is treated as a breaking change.

@Trott
Copy link
Member

Trott commented Dec 4, 2017

This needs one more TSC approval if it is to land. @nodejs/tsc

@@ -167,6 +174,8 @@ function setupHistory(repl, historyPath, oldHistoryPath, ready) {
'REPL session history will not be persisted.\n');
}
if (!threw) {
_printHistoryDeprecation(oldHistoryPath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it doesn't seem necessary to pass a value to the function

@maclover7
Copy link
Contributor Author

updated @targos @Trott

@@ -10,6 +10,13 @@ const debug = util.debuglog('repl');
module.exports = Object.create(REPL);
module.exports.createInternalRepl = createRepl;

const { deprecate } = require('internal/util');
const _printHistoryDeprecation = deprecate(
() => {},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extraneous space after the arrow

@maclover7
Copy link
Contributor Author

removed extra space, good catch @targos

CI: https://ci.nodejs.org/job/node-test-pull-request/11871/

@BridgeAR
Copy link
Member

BridgeAR commented Dec 6, 2017

@maclover7
Copy link
Contributor Author

cc @nodejs/platform-windows trying to debug this locally, it looks like per the TAP extended results the deprecation warning is being emitted (is visible in the tap stack), but for some reason the common.hijackStderr is not being called -- is this a windows specific thing?

@BridgeAR
Copy link
Member

Ping @nodejs/platform-windows PTAL

@bzoz
Copy link
Contributor

bzoz commented Dec 29, 2017

The common.hijakStderr works as expected, deprecation message you see in the TAP results is from one of the tests that is missing deprecated: true:
https://github.com/maclover7/node/blob/2476814b0a315655d3eac33cd6eb6f4a710a9510/test/parallel/test-repl-persistent-history.js#L130-L134

The test is failing because of this test-case:
https://github.com/maclover7/node/blob/2476814b0a315655d3eac33cd6eb6f4a710a9510/test/parallel/test-repl-persistent-history.js#L177-L183

For whatever reason data buffer passed to hijakStderr callback is empty.

Refs: #13876

Just a note that I've been trying to add tests for this, but it's been
difficult because it seems like most REPL tests directly patch into
internals, and are not run via a child process.
@maclover7
Copy link
Contributor Author

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@maclover7
Copy link
Contributor Author

@bzoz Tried to remediate, ran another CI, and Windows is still failing. Can you think of why an empty data buffer is being passed from common.hijackStderr -- would appreciate any leads. Definitely a Windows specific issue at this point.

@bzoz
Copy link
Contributor

bzoz commented Jan 4, 2018

I investigated this, I did not diagnose this correctly the first time around, it looks like this:

This fails only on Windows because only on that platform this test uses execSync to call ATTRIB +H to set make file hidden. This will in turn always write something to stderr, even if it is an empty buffer. In the hijackStderr callback if (data) { ... } will evaluate to true (even if the data is an empty buffer) and this will make the assert in that test fail. With {stdio: 'ignore'} option added to the execSync call, nothing will be written to stderr and the test will pass on Windows. But, it will also pass on the current master.

The hijakStderr callback needs something like common.mustCall, e.g.:

  if (deprecated) {
    common.hijackStderr(common.mustCall((data) => {
      assert.ok(deprecated && depMsg.test(data));
    }));
  }

As you observed in the TAP results, the deprecation message was only displayed once. With the test like this, it will fail for all but the first "deprecated: true" test cases, for which no deprecated message is shown. This will happen on both Windows and Linux.

@lance
Copy link
Member

lance commented Jan 4, 2018

@bzoz fwiw (and I don't know if this will add anything of value to the conversation), but I mucked around with the history file quite a bit about a year and a half ago. There is a lot of discussion about those changes here. This #7005 (comment) and the few comments below it might shed a little light. At the moment I don't have the bandwidth to dig deeper - just wanted to point out that there has been some work around some of these Windows permissions issues in the past.

@BridgeAR BridgeAR added the wip Issues and PRs that are still a work in progress. label Jan 5, 2018
assert.ok(deprecated && depMsg.test(data));
}
});
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me it looks like the hijack is called multiple times and will therefore also trigger for tests that have nothing to do with the current test.
So I think the hijack should be deactivated as soon as it is not required anymore.

In that case the inner deprecated check should also be obsolete.

@BridgeAR
Copy link
Member

@maclover7 would you be so kind and have another look?

@bzoz I am not sure how to follow your example code in combination with your comment. How should a common.mustCall fix the issue? As far as I understand it the error is coming from inside that function, so it is called anyway. So adding the mustCall should only verify that it was indeed triggered properly.

@BridgeAR
Copy link
Member

Ping @maclover7

Copy link
Contributor

@bzoz bzoz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make the test pass on Windows, add {stdio: 'ignore'} to the execSync call.

However, this test is broken, since it does not check if the deprecation message was shown at all. This is why common.mustCall should be used in hijakStderr. Otherwise, this test will also pass with the current master.

@BridgeAR
Copy link
Member

BridgeAR commented Feb 7, 2018

Closing due to long inactivity. To be frank: I personally feel like in this very seldom case it is possible to remove that environment variable without a proper deprecation cycle. The reason is not only that no one has probably really used it for more than a few days but also that I do not see how removing would really do anyone harm. Relying on the repl history file should be very rare...

@BridgeAR BridgeAR closed this Feb 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
repl Issues and PRs related to the REPL subsystem. semver-major PRs that contain breaking changes and should be released in the next major version. wip Issues and PRs that are still a work in progress.
Projects
None yet
Development

Successfully merging this pull request may close these issues.