Symbolic links are ignored
See original GitHub issue- ESLint Version: 7.6.0
- Node Version: 12.18.0
- npm Version: 6.14.4
What parser (default, Babel-ESLint, etc.) are you using?
@typescript-eslint/parser
Please show your full configuration:
Configuration
{
"env": {
"browser": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"project": ["./tsconfig.json"]
},
"plugins": [ "@typescript-eslint" ],
"rules": {
"brace-style": ["error", "allman", { "allowSingleLine": true }],
"eol-last": ["error", "always"],
"eqeqeq": ["error", "always"],
"indent": ["error", 4, { "SwitchCase": 1 }],
"linebreak-style": ["error", "unix"],
"lines-between-class-members": ["error", "always"],
"max-len": ["error", { "code": 120 }],
"new-cap": "error",
"no-irregular-whitespace": ["off"],
"no-multiple-empty-lines": "error",
"no-nested-ternary": "error",
"no-trailing-spaces": "error",
"no-unexpected-multiline": ["off"],
"object-curly-spacing": ["error", "always"],
"object-property-newline": "error",
"one-var": ["error", "never"],
"quotes": ["error", "double"],
"semi": ["error", "always"],
"space-before-blocks": ["error", "always"],
"space-in-parens": ["error", "always"],
"spaced-comment": ["error", "always", {
"block": { "balanced": true },
"exceptions": []
}],
"@typescript-eslint/no-empty-interface": ["error", { "allowSingleExtends": true }],
"@typescript-eslint/no-explicit-any": ["error"],
"@typescript-eslint/no-floating-promises": ["error"],
"@typescript-eslint/no-non-null-assertion": ["error"],
"@typescript-eslint/no-unsafe-assignment": ["error"],
"@typescript-eslint/no-unsafe-call": ["error"],
"@typescript-eslint/no-unsafe-member-access": ["error"],
"@typescript-eslint/no-unsafe-return": ["error"],
"@typescript-eslint/no-unused-vars": ["error"],
"@typescript-eslint/restrict-template-expressions": ["error"]
}
}
What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.
// Not relevant, since files are analysed correctly, but not all files are checked.
# This command is executed from `package.json`, i.e. this code is under the `scripts.lint` property.
eslint --ext ts -c .eslintrc.json src
What did you expect to happen?
I’m working on a project which has the following structure of src
directory:
src/
code.ts
utils/ # Folder with files and subfolders.
shared/ # Symbolic link to another folder which is not within the `src/` folder.
I’ve some errors in TS files inside src/shared/
directory. I expected errors and warnings from ESLint when running a lint action.
What actually happened? Please include the actual, raw output from ESLint.
All files, except those in src/shared/
directory have been checked for errors.
After some research, I’ve identified method _iterateFilesRecursive
as problematic in lib/cli-engine/file-enumerator.js
file.
Inside that function all entries inside a specific directory are checked if they are a file or a folder. But if entry is a symbolic link, it’s completely ignored.
Currently, I’ve made a workaround to patch aforementioned file with modified version of _iterateFilesRecursive
method. Of course, that solution is not good since I’m locked to a specific version of ESLint package.
Modified version of `_iterateFilesRecursive`
*_iterateFilesRecursive(directoryPath, options) {
debug(`Enter the directory: ${directoryPath}`);
const { configArrayFactory } = internalSlotsMap.get(this);
/** @type {ConfigArray|null} */
let config = null;
// Enumerate the files of this directory.
for (const entry of readdirSafeSync(directoryPath)) {
const filePath = path.join(directoryPath, entry.name);
// --- CUSTOM CODE STARTS HERE --- //
// A decision will be made differently if the path represents a symbolic link.
let isFile = false;
let isDirectory = false;
if (entry.isSymbolicLink()) {
const fileStat = statSafeSync(filePath);
if (!fileStat) {
continue;
}
isFile = fileStat.isFile();
isDirectory = fileStat.isDirectory();
if (isFile) {
console.log('\nCarefully use symbolic links for files since imports may not be resolved correctly!\n');
}
} else {
isFile = entry.isFile();
isDirectory = entry.isDirectory();
}
// --- CUSTOM CODE ENDS HERE --- //
// Check if the file is matched.
if (isFile) { // -- CHANGED FROM `entry.isFile()`
if (!config) {
config = configArrayFactory.getConfigArrayForFile(
filePath,
/*
* We must ignore `ConfigurationNotFoundError` at this
* point because we don't know if target files exist in
* this directory.
*/
{ ignoreNotFoundError: true }
);
}
const matched = options.selector
// Started with a glob pattern; choose by the pattern.
? options.selector.match(filePath)
// Started with a directory path; choose by file extensions.
: this.isTargetPath(filePath, config);
if (matched) {
const ignored = this._isIgnoredFile(filePath, { ...options, config });
const flag = ignored ? IGNORED_SILENTLY : NONE;
debug(`Yield: ${entry.name}${ignored ? " but ignored" : ""}`);
yield {
config: configArrayFactory.getConfigArrayForFile(filePath),
filePath,
flag
};
} else {
debug(`Didn't match: ${entry.name}`);
}
// Dive into the sub directory.
} else if (options.recursive && isDirectory) { // -- CHANGED FROM `entry.isDirectory()`
if (!config) {
config = configArrayFactory.getConfigArrayForFile(
filePath,
{ ignoreNotFoundError: true }
);
}
const ignored = this._isIgnoredFile(
filePath + path.sep,
{ ...options, config }
);
if (!ignored) {
yield* this._iterateFilesRecursive(filePath, options);
}
}
}
debug(`Leave the directory: ${directoryPath}`);
}
Are you willing to submit a pull request to fix this bug? Yes.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:13 (7 by maintainers)
Top GitHub Comments
Hi @vjekoart, thanks for the bug report!
Looks like a regression from 2c28fbbb563a44282bef0c9fcc9be29d611cc83b
We were previously using
fs.statSync
which returns the stat of the link’s target, butfs.readdirSync
apparently doesn’t work like that.This will be fixed by #14126