The case of drive letter (i.e. j: vs J:) causes different behavior. Moreover, this difference is opposite in various shells.
cmd.exe:
j:\temp\_git\node-fork> node j:/temp/_git/node-fork/tools/node_modules/eslint/bin/eslint.js .eslintrc.js
[no errors]
j:\temp\_git\node-fork> node J:/temp/_git/node-fork/tools/node_modules/eslint/bin/eslint.js .eslintrc.js
j:\temp\_git\node-fork\.eslintrc.js
1:1 error Definition for rule 'node-core/no-unescaped-regexp-dot' was not found node-core/no-unescaped-regexp-dot
✖ 1 problem (1 error, 0 warnings)
Git Bash:
vmb@vmb-nb MINGW64 /j/temp/_git/node-fork (master)
$ node j:/temp/_git/node-fork/tools/node_modules/eslint/bin/eslint.js .eslintrc.js
J:\temp\_git\node-fork\.eslintrc.js
1:1 error Definition for rule 'node-core/no-unescaped-regexp-dot' was not found node-core/no-unescaped-regexp-dot
✖ 1 problem (1 error, 0 warnings)
vmb@vmb-nb MINGW64 /j/temp/_git/node-fork (master)
$ node J:/temp/_git/node-fork/tools/node_modules/eslint/bin/eslint.js .eslintrc.js
[no errors]
cc @nodejs/linting @nodejs/platform-windows
It seems the issue is not in a drive letter, but in case of any letters in a path within case insensitive OS like Windows. Compare (the first directory is titlecased):
j:\temp\_git\node-fork>node j:/temp/_git/node-fork/tools/node_modules/eslint/bin/eslint.js .eslintrc.js
[no errors]
j:\temp\_git\node-fork>node j:/Temp/_git/node-fork/tools/node_modules/eslint/bin/eslint.js .eslintrc.js
j:\temp\_git\node-fork\.eslintrc.js
1:1 error Definition for rule 'node-core/no-unescaped-regexp-dot' was not found node-core/no-unescaped-regexp-dot
✖ 1 problem (1 error, 0 warnings)
Probably an issue in eslint.
Maybe. I was trying to debug, but I cannot catch the cause, I am not so aware how plugin rules are integrated.
Drive letter miscasing is more often issue than any other miscasing in a path. For example, there is a Windows way to make it possible to call script in the shell instead of node script.js:
ftype JSFile="C:\Program Files\nodejs\node.exe" "%1" %*
assoc .js=JSFile
So, if this is set and a user runs:
tools\node_modules\eslint\bin\eslint .eslintrc.js
it will be expanded by a shell into:
"C:\Program Files\nodejs\node.exe" "J:/temp/_git/node-fork/tools/node_modules/eslint/bin/eslint.js" .eslintrc.js
— with uppercased drive letter. This is how I have stumbled upon this issue.
More info to consider re drive letter case:
__filename, __dirname and process.argv are dependent on script argument.process.cwd() is dependent on a shell.test.js:
'use strict';
console.log(__filename);
console.log(__dirname);
console.log(process.argv);
console.log(process.cwd());
cmd.exe:
e:\DOC\prg\js\node\-test> node e:\DOC\prg\js\node\-test\test.js
e:\DOC\prg\js\node\-test\test.js
e:\DOC\prg\js\node\-test
[ 'C:\\Program Files\\nodejs\\node.exe',
'e:\\DOC\\prg\\js\\node\\-test\\test.js' ]
e:\DOC\prg\js\node\-test
e:\DOC\prg\js\node\-test> node E:\DOC\prg\js\node\-test\test.js
E:\DOC\prg\js\node\-test\test.js
E:\DOC\prg\js\node\-test
[ 'C:\\Program Files\\nodejs\\node.exe',
'E:\\DOC\\prg\\js\\node\\-test\\test.js' ]
e:\DOC\prg\js\node\-test
Git bash:
vmb@vmb-nb MINGW64 /e/DOC/prg/js/node/-test
$ node e:\\DOC\\prg\\js\\node\\-test\\test.js
e:\DOC\prg\js\node\-test\test.js
e:\DOC\prg\js\node\-test
[ 'C:\\Program Files\\nodejs\\node.exe',
'e:\\DOC\\prg\\js\\node\\-test\\test.js' ]
E:\DOC\prg\js\node\-test
vmb@vmb-nb MINGW64 /e/DOC/prg/js/node/-test
$ node E:\\DOC\\prg\\js\\node\\-test\\test.js
E:\DOC\prg\js\node\-test\test.js
E:\DOC\prg\js\node\-test
[ 'C:\\Program Files\\nodejs\\node.exe',
'E:\\DOC\\prg\\js\\node\\-test\\test.js' ]
E:\DOC\prg\js\node\-test
It seems ESLint or plugin try to compare these items case-sensitively somewhere.
Why it is so difficult to debug: https://github.com/nodejs/node/issues/19273
Breakpoints in dependent files set in this call:
node --inspect-brk j:/temp/_git/node-fork/tools/node_modules/eslint/bin/eslint.js .eslintrc.js
are not activated at all,
Breakpoints in dependent files set in this call:
node --inspect-brk J:/temp/_git/node-fork/tools/node_modules/eslint/bin/eslint.js .eslintrc.js
are skipped if the code is not accessed due to a bug.
It's not ESLint, it's us) This is what happens in two mentioned calls:
node j:/temp/_git/node-fork/tools/node_modules/eslint/bin/eslint.js .eslintrc.js:.eslintrc.js#L6 requires the eslint-plugin-node-core and puts it in the cache with 'j:\[full_path]' id (require.resolve('./tools/node_modules/eslint-plugin-node-core') === 'j:\[full_path]' there).
.eslintrc.js#L7 assigns the rule path to the cached module.
eslint/lib/config/plugins.js#L101 gets the cached module with the assigned rule path (require.resolve(longName) === 'j:\[full_path]' there).
eslint-plugin-node-core/index.js#L9 gets the rule path from the cached module.
eslint-plugin-node-core/index.js#L22 returns the rule list.
node J:/temp/_git/node-fork/tools/node_modules/eslint/bin/eslint.js .eslintrc.js:the same: .eslintrc.js#L6 requires the eslint-plugin-node-core and puts it in the cache with 'j:\[full_path]' id (require.resolve('./tools/node_modules/eslint-plugin-node-core') === 'j:\[full_path]' there).
the same: .eslintrc.js#L7 assigns the rule path to the cached module.
bug: eslint/lib/config/plugins.js#L101 requires a new module without a rule path (require.resolve(longName) === 'J:\[full_path]' there).
bug: eslint-plugin-node-core/index.js#L9 gets undefined instead of the rule path (this module item has no such property).
bug: eslint-plugin-node-core/index.js#L11 returns an empty rule list.
@devsnek, would it be more comfortable for you to find a fix?
I have no idea what's going on here and I don't have a Windows machine so it might be best for someone else to tackle this :)
Additional refs:
https://nodejs.org/api/modules.html#modules_module_caching_caveats
https://github.com/nodejs/node/issues/17611 (the references to other issues and the discussion in comments)
I usually don't like closing confirmed-bug issues but I really don't know what we can do here and it doesn't seem like anyone else does either.