diff --git a/lib/internal/debugger/inspect.js b/lib/internal/debugger/inspect.js index 97c4b5922c978a..d6645acd6b1806 100644 --- a/lib/internal/debugger/inspect.js +++ b/lib/internal/debugger/inspect.js @@ -317,6 +317,34 @@ function parseInspectMode(args) { return { mode: 'interactive' }; } +// `node inspect` runs the debugger. If a file named after the command +// (e.g. `inspect.js`) also exists in the current directory, the user may have +// meant to run that file instead. That shadowing is otherwise silent, so emit +// a warning. Refs: https://github.com/nodejs/node/issues/64111 +function warnIfShadowedByLocalFile() { + const command = process.argv[1]; + if (typeof command !== 'string' || command.length === 0) return; + + const { existsSync } = require('fs'); + const { resolve } = require('path'); + const cwd = process.cwd(); + + let candidate; + if (existsSync(resolve(cwd, `${command}.js`))) { + candidate = `${command}.js`; + } else if (existsSync(resolve(cwd, command))) { + candidate = command; + } else { + return; + } + + process.emitWarning( + `'${process.argv0} ${command}' started the debugger; the file ` + + `'${candidate}' in the current directory was not run. To run it instead, ` + + `use '${process.argv0} ./${candidate}'.`, + ); +} + function startInspect(argv = ArrayPrototypeSlice(process.argv, 2), stdin = process.stdin, stdout = process.stdout) { @@ -343,6 +371,8 @@ function startInspect(argv = ArrayPrototypeSlice(process.argv, 2), return; } + warnIfShadowedByLocalFile(); + const options = parseInteractiveArgs(argv); const inspector = new NodeInspector(options, stdin, stdout); diff --git a/test/parallel/test-debugger-shadowed-by-local-file.js b/test/parallel/test-debugger-shadowed-by-local-file.js new file mode 100644 index 00000000000000..f6f7fa78d78b13 --- /dev/null +++ b/test/parallel/test-debugger-shadowed-by-local-file.js @@ -0,0 +1,35 @@ +'use strict'; +const common = require('../common'); + +common.skipIfInspectorDisabled(); + +const assert = require('assert'); +const fs = require('fs'); + +const fixtures = require('../common/fixtures'); +const startCLI = require('../common/debugger'); +const tmpdir = require('../common/tmpdir'); + +// When `node inspect` starts the debugger and a file named after the command +// (e.g. `inspect.js`) exists in the current directory, a warning is emitted so +// the shadowing is not silent. +// Refs: https://github.com/nodejs/node/issues/64111 +tmpdir.refresh(); +fs.writeFileSync(tmpdir.resolve('inspect.js'), '// not run\n'); + +const script = fixtures.path('debugger', 'three-lines.js'); +const cli = startCLI([script], [], { cwd: tmpdir.path }); + +(async function() { + try { + await cli.waitForInitialBreak(); + await cli.waitForPrompt(); + assert.match( + cli.output, + /started the debugger; the file 'inspect\.js' in the current directory was not run/, + ); + } finally { + const code = await cli.quit(); + assert.strictEqual(code, 0); + } +})().then(common.mustCall());