From 5cfa3cb3cf37859b2af20af0b1cf8e34e9a4c924 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Tue, 30 May 2023 21:03:36 -0700 Subject: [PATCH 1/3] fix: turn off no-unused-vars for TypeScript --- package.json | 4 +- pnpm-lock.yaml | 134 ++++++++++++++++++++++++---------------------- src/typescript.js | 6 ++- 3 files changed, 76 insertions(+), 68 deletions(-) diff --git a/package.json b/package.json index b9aeafa..33ce269 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "prettier": "prettier-config-atomic", "dependencies": { - "@babel/core": "^7.21.8", + "@babel/core": "^7.22.1", "@babel/eslint-parser": "^7.21.8", "@babel/plugin-syntax-flow": "^7.21.4", "@babel/plugin-syntax-jsx": "^7.21.4", @@ -44,7 +44,7 @@ "typescript": "^5.0.4" }, "devDependencies": { - "@types/node": "^20.2.3", + "@types/node": "^20.2.5", "@types/semver": "^7.5.0", "execa": "^5.1.1", "gitly": "^2.4.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bb69aa0..8dd1cca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,18 +1,22 @@ -lockfileVersion: '6.0' +lockfileVersion: '6.1' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false dependencies: '@babel/core': - specifier: ^7.21.8 - version: 7.21.8 + specifier: ^7.22.1 + version: 7.22.1 '@babel/eslint-parser': specifier: ^7.21.8 - version: 7.21.8(@babel/core@7.21.8)(eslint@8.41.0) + version: 7.21.8(@babel/core@7.22.1)(eslint@8.41.0) '@babel/plugin-syntax-flow': specifier: ^7.21.4 - version: 7.21.4(@babel/core@7.21.8) + version: 7.21.4(@babel/core@7.22.1) '@babel/plugin-syntax-jsx': specifier: ^7.21.4 - version: 7.21.4(@babel/core@7.21.8) + version: 7.21.4(@babel/core@7.22.1) '@typescript-eslint/eslint-plugin': specifier: 6.0.0-alpha.138 version: 6.0.0-alpha.138(@typescript-eslint/parser@6.0.0-alpha.138)(eslint@8.41.0)(typescript@5.0.4) @@ -78,8 +82,8 @@ optionalDependencies: devDependencies: '@types/node': - specifier: ^20.2.3 - version: 20.2.3 + specifier: ^20.2.5 + version: 20.2.5 '@types/semver': specifier: ^7.5.0 version: 7.5.0 @@ -121,25 +125,25 @@ packages: '@babel/highlight': 7.18.6 dev: false - /@babel/compat-data@7.21.9: - resolution: {integrity: sha512-FUGed8kfhyWvbYug/Un/VPJD41rDIgoVVcR+FuzhzOYyRz5uED+Gd3SLZml0Uw2l2aHFb7ZgdW5mGA3G2cCCnQ==} + /@babel/compat-data@7.22.3: + resolution: {integrity: sha512-aNtko9OPOwVESUFp3MZfD8Uzxl7JzSeJpd7npIoxCasU37PFbAQRpKglkaKwlHOyeJdrREpo8TW8ldrkYWwvIQ==} engines: {node: '>=6.9.0'} dev: false - /@babel/core@7.21.8: - resolution: {integrity: sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==} + /@babel/core@7.22.1: + resolution: {integrity: sha512-Hkqu7J4ynysSXxmAahpN1jjRwVJ+NdpraFLIWflgjpVob3KNyK3/tIUc7Q7szed8WMp0JNa7Qtd1E9Oo22F9gA==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 '@babel/code-frame': 7.21.4 - '@babel/generator': 7.21.9 - '@babel/helper-compilation-targets': 7.21.5(@babel/core@7.21.8) - '@babel/helper-module-transforms': 7.21.5 - '@babel/helpers': 7.21.5 - '@babel/parser': 7.21.9 + '@babel/generator': 7.22.3 + '@babel/helper-compilation-targets': 7.22.1(@babel/core@7.22.1) + '@babel/helper-module-transforms': 7.22.1 + '@babel/helpers': 7.22.3 + '@babel/parser': 7.22.4 '@babel/template': 7.21.9 - '@babel/traverse': 7.21.5 - '@babel/types': 7.21.5 + '@babel/traverse': 7.22.4 + '@babel/types': 7.22.4 convert-source-map: 1.9.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -149,46 +153,46 @@ packages: - supports-color dev: false - /@babel/eslint-parser@7.21.8(@babel/core@7.21.8)(eslint@8.41.0): + /@babel/eslint-parser@7.21.8(@babel/core@7.22.1)(eslint@8.41.0): resolution: {integrity: sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: '@babel/core': '>=7.11.0' eslint: ^7.5.0 || ^8.0.0 dependencies: - '@babel/core': 7.21.8 + '@babel/core': 7.22.1 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 eslint: 8.41.0 eslint-visitor-keys: 2.1.0 semver: 6.3.0 dev: false - /@babel/generator@7.21.9: - resolution: {integrity: sha512-F3fZga2uv09wFdEjEQIJxXALXfz0+JaOb7SabvVMmjHxeVTuGW8wgE8Vp1Hd7O+zMTYtcfEISGRzPkeiaPPsvg==} + /@babel/generator@7.22.3: + resolution: {integrity: sha512-C17MW4wlk//ES/CJDL51kPNwl+qiBQyN7b9SKyVp11BLGFeSPoVaHrv+MNt8jwQFhQWowW88z1eeBx3pFz9v8A==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.5 + '@babel/types': 7.22.4 '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 jsesc: 2.5.2 dev: false - /@babel/helper-compilation-targets@7.21.5(@babel/core@7.21.8): - resolution: {integrity: sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==} + /@babel/helper-compilation-targets@7.22.1(@babel/core@7.22.1): + resolution: {integrity: sha512-Rqx13UM3yVB5q0D/KwQ8+SPfX/+Rnsy1Lw1k/UwOC4KC6qrzIQoY3lYnBu5EHKBlEHHcj0M0W8ltPSkD8rqfsQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/compat-data': 7.21.9 - '@babel/core': 7.21.8 + '@babel/compat-data': 7.22.3 + '@babel/core': 7.22.1 '@babel/helper-validator-option': 7.21.0 browserslist: 4.21.5 lru-cache: 5.1.1 semver: 6.3.0 dev: false - /@babel/helper-environment-visitor@7.21.5: - resolution: {integrity: sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==} + /@babel/helper-environment-visitor@7.22.1: + resolution: {integrity: sha512-Z2tgopurB/kTbidvzeBrc2To3PUP/9i5MUe+fU6QJCQDyPwSH2oRapkLw3KGECDYSjhQZCNxEvNvZlLw8JjGwA==} engines: {node: '>=6.9.0'} dev: false @@ -197,35 +201,35 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.21.9 - '@babel/types': 7.21.5 + '@babel/types': 7.22.4 dev: false /@babel/helper-hoist-variables@7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.5 + '@babel/types': 7.22.4 dev: false /@babel/helper-module-imports@7.21.4: resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.5 + '@babel/types': 7.22.4 dev: false - /@babel/helper-module-transforms@7.21.5: - resolution: {integrity: sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==} + /@babel/helper-module-transforms@7.22.1: + resolution: {integrity: sha512-dxAe9E7ySDGbQdCVOY/4+UcD8M9ZFqZcZhSPsPacvCG4M+9lwtDDQfI2EoaSvmf7W/8yCBkGU0m7Pvt1ru3UZw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-environment-visitor': 7.21.5 + '@babel/helper-environment-visitor': 7.22.1 '@babel/helper-module-imports': 7.21.4 '@babel/helper-simple-access': 7.21.5 '@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-validator-identifier': 7.19.1 '@babel/template': 7.21.9 - '@babel/traverse': 7.21.5 - '@babel/types': 7.21.5 + '@babel/traverse': 7.22.4 + '@babel/types': 7.22.4 transitivePeerDependencies: - supports-color dev: false @@ -239,14 +243,14 @@ packages: resolution: {integrity: sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.5 + '@babel/types': 7.22.4 dev: false /@babel/helper-split-export-declaration@7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.5 + '@babel/types': 7.22.4 dev: false /@babel/helper-string-parser@7.21.5: @@ -264,13 +268,13 @@ packages: engines: {node: '>=6.9.0'} dev: false - /@babel/helpers@7.21.5: - resolution: {integrity: sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==} + /@babel/helpers@7.22.3: + resolution: {integrity: sha512-jBJ7jWblbgr7r6wYZHMdIqKc73ycaTcCaWRq4/2LpuPHcx7xMlZvpGQkOYc9HeSjn6rcx15CPlgVcBtZ4WZJ2w==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.21.9 - '@babel/traverse': 7.21.5 - '@babel/types': 7.21.5 + '@babel/traverse': 7.22.4 + '@babel/types': 7.22.4 transitivePeerDependencies: - supports-color dev: false @@ -284,31 +288,31 @@ packages: js-tokens: 4.0.0 dev: false - /@babel/parser@7.21.9: - resolution: {integrity: sha512-q5PNg/Bi1OpGgx5jYlvWZwAorZepEudDMCLtj967aeS7WMont7dUZI46M2XwcIQqvUlMxWfdLFu4S/qSxeUu5g==} + /@babel/parser@7.22.4: + resolution: {integrity: sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.21.5 + '@babel/types': 7.22.4 dev: false - /@babel/plugin-syntax-flow@7.21.4(@babel/core@7.21.8): + /@babel/plugin-syntax-flow@7.21.4(@babel/core@7.22.1): resolution: {integrity: sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.8 + '@babel/core': 7.22.1 '@babel/helper-plugin-utils': 7.21.5 dev: false - /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.21.8): + /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.22.1): resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.8 + '@babel/core': 7.22.1 '@babel/helper-plugin-utils': 7.21.5 dev: false @@ -325,30 +329,30 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.21.4 - '@babel/parser': 7.21.9 - '@babel/types': 7.21.5 + '@babel/parser': 7.22.4 + '@babel/types': 7.22.4 dev: false - /@babel/traverse@7.21.5: - resolution: {integrity: sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==} + /@babel/traverse@7.22.4: + resolution: {integrity: sha512-Tn1pDsjIcI+JcLKq1AVlZEr4226gpuAQTsLMorsYg9tuS/kG7nuwwJ4AB8jfQuEgb/COBwR/DqJxmoiYFu5/rQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.21.4 - '@babel/generator': 7.21.9 - '@babel/helper-environment-visitor': 7.21.5 + '@babel/generator': 7.22.3 + '@babel/helper-environment-visitor': 7.22.1 '@babel/helper-function-name': 7.21.0 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.21.9 - '@babel/types': 7.21.5 + '@babel/parser': 7.22.4 + '@babel/types': 7.22.4 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: false - /@babel/types@7.21.5: - resolution: {integrity: sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==} + /@babel/types@7.22.4: + resolution: {integrity: sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.21.5 @@ -654,7 +658,7 @@ packages: resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.2.3 + '@types/node': 20.2.5 dev: true /@types/http-cache-semantics@4.0.1: @@ -683,8 +687,8 @@ packages: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: true - /@types/node@20.2.3: - resolution: {integrity: sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==} + /@types/node@20.2.5: + resolution: {integrity: sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==} dev: true /@types/normalize-package-data@2.4.1: @@ -2123,7 +2127,7 @@ packages: peerDependencies: eslint: ^3.17.0 || ^4 || ^5 || ^6 || ^7 dependencies: - '@babel/traverse': 7.21.5 + '@babel/traverse': 7.22.4 eslint: 8.41.0 eslint-plugin-react-native-globals: 0.1.2 transitivePeerDependencies: diff --git a/src/typescript.js b/src/typescript.js index 27d0187..34235e3 100644 --- a/src/typescript.js +++ b/src/typescript.js @@ -13,6 +13,10 @@ if (!projectedBasedRules) { ) } +// turn-off no-unused-vars for typescript files +const typeScriptEslintExtra = { ...eslintRulesExtra } +typeScriptEslintExtra["no-unused-vars"] = "off" + const pluginTypeScriptRulesExtra = { "@typescript-eslint/no-unused-vars": [ "error", @@ -76,7 +80,7 @@ exports.tsConfig = { "prettier", ], rules: { - ...eslintRulesExtra, + ...typeScriptEslintExtra, ...pluginTypeScriptRulesExtra, ...pluginTypeScriptProjectRules, ...pluginNodeRules, From fb5198dd92184d7d956f2366a5ffae310a4d8aee Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Tue, 30 May 2023 22:30:05 -0700 Subject: [PATCH 2/3] fix: only warn on project-based rules in case there is a TypeScript file --- package.json | 1 - pnpm-lock.yaml | 3 --- src/typescript.js | 68 ++++++++++++++++++++++++++++++++++++----------- 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 33ce269..faa74dd 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,6 @@ "eslint-plugin-optimize-regex": "^1.2.1", "eslint-plugin-react": "^7.32.2", "eslint-plugin-yaml": "^0.5.0", - "fast-glob": "^3.2.12", "prettier": "2.8.8", "read-pkg-up": "^7.0.1", "semver": "^7.5.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8dd1cca..189e34b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -53,9 +53,6 @@ dependencies: eslint-plugin-yaml: specifier: ^0.5.0 version: 0.5.0 - fast-glob: - specifier: ^3.2.12 - version: 3.2.12 prettier: specifier: 2.8.8 version: 2.8.8 diff --git a/src/typescript.js b/src/typescript.js index 34235e3..1f6cfc2 100644 --- a/src/typescript.js +++ b/src/typescript.js @@ -1,21 +1,57 @@ const { eslintRulesExtra } = require("./official-eslint-rules") const { pluginImportRulesExtra, pluginImportTypeScriptRulesExtra } = require("./plugin-import-rules") const { pluginNodeRules } = require("./plugin-node-rules") -const glob = require("fast-glob") +const fs = require("fs") +const path = require("path") -const project = ["./**/tsconfig.json", "!./**/node_modules/**/tsconfig.json"] +const tsFiles = ["**/*.tsx", "**/*.ts"] +const project = ["**/tsconfig.json", "!**/node_modules/**/tsconfig.json"] -const projectedBasedRules = glob.sync(project, { onlyFiles: true, suppressErrors: true }).length !== 0 -if (!projectedBasedRules) { - console.warn( - "\x1b[33m%s\x1b[0m", - "No tsconfig.json found, disabling the project-based rules. To enable them, include all the **/*.ts(x)? files in the includes of the tsconfig.json files and run eslint again." - ) +function findOneFile(cwd, fileEnding, ignoredFolders) { + // recursively search the current folder for a file with the given fileEnding, ignoring the given folders, and return true as soon as one is found + const files = fs.readdirSync(cwd, { withFileTypes: true, recursive: false }) + for (const file of files) { + if (file.isDirectory()) { + if (!ignoredFolders.includes(file.name)) { + // if the folder is not ignored, search it recursively + const found = findOneFile(path.join(cwd, file.name), fileEnding, ignoredFolders) + if (found) { + return true + } + } + } else if (file.name.endsWith(fileEnding)) { + // if the file ends with the given fileEnding, return true + return true + } + } + return false +} + +/** Check if there are any tsconfig.json files */ +function disableProjectBasedRules() { + const hasTsFile = findOneFile(process.cwd(), ".ts", ["node_modules", ".git"]) + const hasTsConfig = findOneFile(process.cwd(), "tsconfig.json", ["node_modules", ".git"]) + + // if there is no tsconfig.json file, but there are ts files, disable the project-based rules + const disable = !hasTsConfig && hasTsFile + + if (disable) { + console.warn( + "\x1b[33m%s\x1b[0m", + "No tsconfig.json found, disabling the project-based rules. To enable them, include all the **/*.ts(x)? files in the includes of the tsconfig.json files and run eslint again." + ) + } + + return disable } -// turn-off no-unused-vars for typescript files -const typeScriptEslintExtra = { ...eslintRulesExtra } -typeScriptEslintExtra["no-unused-vars"] = "off" +function javaScriptRules() { + // turn-off no-unused-vars for typescript files + const typeScriptEslintExtra = { ...eslintRulesExtra } + typeScriptEslintExtra["no-unused-vars"] = "off" + + return typeScriptEslintExtra +} const pluginTypeScriptRulesExtra = { "@typescript-eslint/no-unused-vars": [ @@ -46,8 +82,9 @@ const pluginTypeScriptRulesExtra = { // "@typescript-eslint/prefer-string-starts-ends-with": "error", } -const pluginTypeScriptProjectRules = projectedBasedRules - ? { +const pluginTypeScriptProjectRules = disableProjectBasedRules() + ? {} + : { "@typescript-eslint/no-floating-promises": "error", "@typescript-eslint/no-unnecessary-boolean-literal-compare": "error", "@typescript-eslint/no-unnecessary-condition": "error", @@ -60,11 +97,10 @@ const pluginTypeScriptProjectRules = projectedBasedRules "@typescript-eslint/strict-boolean-expressions": "error", "@typescript-eslint/switch-exhaustiveness-check": "warn", } - : {} exports.tsConfig = { // TypeScript files - files: ["**/*.tsx", "**/*.ts"], + files: tsFiles, parser: "@typescript-eslint/parser", parserOptions: { project, @@ -80,7 +116,7 @@ exports.tsConfig = { "prettier", ], rules: { - ...typeScriptEslintExtra, + ...javaScriptRules(), ...pluginTypeScriptRulesExtra, ...pluginTypeScriptProjectRules, ...pluginNodeRules, From c9d3c9894b58d14b68eacb850241526224b00031 Mon Sep 17 00:00:00 2001 From: Amin Yahyaabadi Date: Tue, 30 May 2023 22:55:24 -0700 Subject: [PATCH 3/3] feat: fix checking for existence of typescript files --- .vscode/settings.json | 3 + package.json | 3 + pnpm-lock.yaml | 155 ++++++++++++++++++++++++++++++++++++++++++ src/typescript.js | 44 ++++++------ src/utils.js | 30 ++++++++ 5 files changed, 211 insertions(+), 24 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/utils.js diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a2b5c76 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cSpell.words": ["globify"] +} diff --git a/package.json b/package.json index faa74dd..9e0e73f 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@babel/plugin-syntax-jsx": "^7.21.4", "@typescript-eslint/eslint-plugin": "6.0.0-alpha.138", "@typescript-eslint/parser": "6.0.0-alpha.138", + "anymatch": "^3.1.3", "eslint": "^8.41.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-html": "^7.1.0", @@ -37,6 +38,8 @@ "eslint-plugin-optimize-regex": "^1.2.1", "eslint-plugin-react": "^7.32.2", "eslint-plugin-yaml": "^0.5.0", + "globify-gitignore": "^1.0.3", + "make-synchronous": "^0.1.1", "prettier": "2.8.8", "read-pkg-up": "^7.0.1", "semver": "^7.5.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 189e34b..44b4770 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ dependencies: '@typescript-eslint/parser': specifier: 6.0.0-alpha.138 version: 6.0.0-alpha.138(eslint@8.41.0)(typescript@5.0.4) + anymatch: + specifier: ^3.1.3 + version: 3.1.3 eslint: specifier: ^8.41.0 version: 8.41.0 @@ -53,6 +56,12 @@ dependencies: eslint-plugin-yaml: specifier: ^0.5.0 version: 0.5.0 + globify-gitignore: + specifier: ^1.0.3 + version: 1.0.3 + make-synchronous: + specifier: ^0.1.1 + version: 0.1.1 prettier: specifier: 2.8.8 version: 2.8.8 @@ -930,6 +939,14 @@ packages: engines: {node: '>=12'} dev: true + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: false + /aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} dev: true @@ -974,6 +991,12 @@ packages: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + /array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + dev: false + optional: true + /array.prototype.flat@1.3.1: resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} engines: {node: '>= 0.4'} @@ -1287,6 +1310,12 @@ packages: resolution: {integrity: sha512-x1mgZEXK8jHIfAxm+xgdpHpk50IN3z3q3zP261/WS+uvePxW8izXuCu6AHz0lkuYTlATDehiZ/tNyYBdSQsOUQ==} dev: false + /chainsaw@0.0.9: + resolution: {integrity: sha512-nG8PYH+/4xB+8zkV4G844EtfvZ5tTiLFoX3dZ4nhF4t3OCKIb9UvaFyNmeZO2zOSmRWzBoTD+napN6hiL+EgcA==} + dependencies: + traverse: 0.3.9 + dev: false + /chalk@1.1.3: resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} engines: {node: '>=0.10.0'} @@ -1477,6 +1506,11 @@ packages: shebang-command: 2.0.0 which: 2.0.2 + /crypto-random-string@2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + dev: false + /crypto-random-string@4.0.0: resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} engines: {node: '>=12'} @@ -1540,6 +1574,10 @@ packages: mimic-response: 3.1.0 dev: true + /dedent@0.7.0: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + dev: false + /deep-equal@2.2.1: resolution: {integrity: sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ==} dependencies: @@ -1876,6 +1914,11 @@ packages: engines: {node: '>=0.8.0'} dev: false + /escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: false + /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -2686,6 +2729,17 @@ packages: slash: 4.0.0 dev: true + /globify-gitignore@1.0.3: + resolution: {integrity: sha512-yfwxPrXeIf6EvirmOZ8LOPxETorIbusANNnHdpXtmDwMW10NSEv4j2kgjWUR9OTRHtdchc07AFmgXLc29Wv89w==} + dependencies: + dedent: 0.7.0 + is-valid-path: 0.1.1 + remove: 0.1.5 + optionalDependencies: + make-unique: 1.0.4 + sort-es: 1.6.10 + dev: false + /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: @@ -2785,6 +2839,12 @@ packages: dependencies: function-bind: 1.1.1 + /hashish@0.0.4: + resolution: {integrity: sha512-xyD4XgslstNAs72ENaoFvgMwtv8xhiDtC2AtzCG+8yF7W/Knxxm9BX+e2s25mm+HxMKh0rBmXVOEGF3zNImXvA==} + dependencies: + traverse: 0.6.7 + dev: false + /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: false @@ -3035,6 +3095,11 @@ packages: hasBin: true dev: true + /is-extglob@1.0.0: + resolution: {integrity: sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==} + engines: {node: '>=0.10.0'} + dev: false + /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -3044,6 +3109,13 @@ packages: engines: {node: '>=8'} dev: true + /is-glob@2.0.1: + resolution: {integrity: sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 1.0.0 + dev: false + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -3066,6 +3138,13 @@ packages: is-path-inside: 3.0.3 dev: true + /is-invalid-path@0.1.0: + resolution: {integrity: sha512-aZMG0T3F34mTg4eTdszcGXx54oiZ4NtHSft3hWNJMGJXUUqdIj3cOZuHcU0nCWWcY3jd7yRe/3AEm3vSNTpBGQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-glob: 2.0.1 + dev: false + /is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} dev: true @@ -3173,6 +3252,13 @@ packages: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} dev: true + /is-valid-path@0.1.1: + resolution: {integrity: sha512-+kwPrVDu9Ms03L90Qaml+79+6DZHqHyRoANI6IsZJ/g8frhnfchDOBCa0RbQ6/kdHt5CS5OeIEyrYznNuVN+8A==} + engines: {node: '>=0.10.0'} + dependencies: + is-invalid-path: 0.1.0 + dev: false + /is-weakmap@2.0.1: resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} dev: false @@ -3476,6 +3562,23 @@ packages: - supports-color dev: true + /make-synchronous@0.1.1: + resolution: {integrity: sha512-Y4SxxqhaoyMDokJQ0AZz0E+bLhRkOSR7Z/IQoTKPdS6HYi3aobal2kMHoHHoqBadPWjf07P4K1FQLXOx3wf9Yw==} + engines: {node: '>=12'} + dependencies: + subsume: 3.0.0 + type-fest: 0.16.0 + dev: false + + /make-unique@1.0.4: + resolution: {integrity: sha512-fhy5iusM7DNzilx1gW1YvAm1d6VjZ1TRoD52+U4ZrfMwIMzHObPGEcvssZwvUgO9R2ef8XOakx6lGMVgS68QcQ==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dependencies: + array-uniq: 1.0.3 + dev: false + optional: true + /mdast-util-from-markdown@1.3.0: resolution: {integrity: sha512-HN3W1gRIuN/ZW295c7zi7g9lVBllMgZE40RxCX37wrTPWXCWtpvOZdfnuK+1WNpvZje6XuJeI3Wnb4TJEUem+g==} dependencies: @@ -3921,6 +4024,11 @@ packages: validate-npm-package-license: 3.0.4 dev: true + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: false + /normalize-url@8.0.0: resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==} engines: {node: '>=14.16'} @@ -4563,6 +4671,12 @@ packages: engines: {node: '>=8'} dev: true + /remove@0.1.5: + resolution: {integrity: sha512-AJMA9oWvJzdTjwIGwSQZsjGQiRx73YTmiOWmfCp1fpLa/D4n7jKcpoA+CZiVLJqKcEKUuh1Suq80c5wF+L/qVQ==} + dependencies: + seq: 0.3.5 + dev: false + /require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} @@ -4688,6 +4802,13 @@ packages: dependencies: lru-cache: 6.0.0 + /seq@0.3.5: + resolution: {integrity: sha512-sisY2Ln1fj43KBkRtXkesnRHYNdswIkIibvNe/0UKm2GZxjMbqmccpiatoKr/k2qX5VKiLU8xm+tz/74LAho4g==} + dependencies: + chainsaw: 0.0.9 + hashish: 0.0.4 + dev: false + /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true @@ -4778,6 +4899,12 @@ packages: smart-buffer: 4.2.0 dev: true + /sort-es@1.6.10: + resolution: {integrity: sha512-ak1DcREJVojhwOz89bL4Yezh11G8+DnQFM9EkN+2+h9jphtYDuw1iPdPepyMPVHIIhFc849OXC5kXf0TfrmMpw==} + requiresBuild: true + dev: false + optional: true + /sort-object-keys@1.1.3: resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} dev: true @@ -4976,6 +5103,14 @@ packages: engines: {node: '>=14.16'} dev: true + /subsume@3.0.0: + resolution: {integrity: sha512-6n/UfV8UWKwJNO8OAOiKntwEMihuBeeoJfzpL542C+OuvT4iWG9SwjrXkOmsxjb4SteHUsos9SvrdqZ9+ICwTQ==} + engines: {node: '>=8'} + dependencies: + escape-string-regexp: 2.0.0 + unique-string: 2.0.0 + dev: false + /supports-color@2.0.0: resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} engines: {node: '>=0.8.0'} @@ -5046,6 +5181,14 @@ packages: dependencies: is-number: 7.0.0 + /traverse@0.3.9: + resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==} + dev: false + + /traverse@0.6.7: + resolution: {integrity: sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==} + dev: false + /ts-api-utils@0.0.46(typescript@5.0.4): resolution: {integrity: sha512-YKJeSx39n0mMk+hrpyHKyTgxA3s7Pz/j1cXYR+t8HcwwZupzOR5xDGKnOEw3gmLaUeFUQt3FJD39AH9Ajn/mdA==} engines: {node: '>=16.13.0'} @@ -5086,6 +5229,11 @@ packages: prelude-ls: 1.2.1 dev: false + /type-fest@0.16.0: + resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} + engines: {node: '>=10'} + dev: false + /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} @@ -5168,6 +5316,13 @@ packages: imurmurhash: 0.1.4 dev: true + /unique-string@2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + dependencies: + crypto-random-string: 2.0.0 + dev: false + /unique-string@3.0.0: resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} engines: {node: '>=12'} diff --git a/src/typescript.js b/src/typescript.js index 1f6cfc2..bde5009 100644 --- a/src/typescript.js +++ b/src/typescript.js @@ -1,36 +1,32 @@ const { eslintRulesExtra } = require("./official-eslint-rules") const { pluginImportRulesExtra, pluginImportTypeScriptRulesExtra } = require("./plugin-import-rules") const { pluginNodeRules } = require("./plugin-node-rules") -const fs = require("fs") -const path = require("path") +const { globifyGitIgnoreFile } = require("globify-gitignore") +const makeSynchronous = require("make-synchronous") +const { findOneFile } = require("./utils") const tsFiles = ["**/*.tsx", "**/*.ts"] const project = ["**/tsconfig.json", "!**/node_modules/**/tsconfig.json"] -function findOneFile(cwd, fileEnding, ignoredFolders) { - // recursively search the current folder for a file with the given fileEnding, ignoring the given folders, and return true as soon as one is found - const files = fs.readdirSync(cwd, { withFileTypes: true, recursive: false }) - for (const file of files) { - if (file.isDirectory()) { - if (!ignoredFolders.includes(file.name)) { - // if the folder is not ignored, search it recursively - const found = findOneFile(path.join(cwd, file.name), fileEnding, ignoredFolders) - if (found) { - return true - } - } - } else if (file.name.endsWith(fileEnding)) { - // if the file ends with the given fileEnding, return true - return true +/** Check if there are any tsconfig.json files */ +async function disableProjectBasedRules() { + // get all the files that are ignored by git + const ignore = (await globifyGitIgnoreFile(".", true)).map((entry) => { + if (entry.included) { + return `!${entry.glob}` } + return entry.glob + }) + ignore.push("./**/.git/**") + + // check if there are any ts files + const hasTsFile = findOneFile(process.cwd(), tsFiles, ignore) + if (!hasTsFile) { + return true } - return false -} -/** Check if there are any tsconfig.json files */ -function disableProjectBasedRules() { - const hasTsFile = findOneFile(process.cwd(), ".ts", ["node_modules", ".git"]) - const hasTsConfig = findOneFile(process.cwd(), "tsconfig.json", ["node_modules", ".git"]) + // check if there is a tsconfig.json file + const hasTsConfig = findOneFile(process.cwd(), project, ignore) // if there is no tsconfig.json file, but there are ts files, disable the project-based rules const disable = !hasTsConfig && hasTsFile @@ -82,7 +78,7 @@ const pluginTypeScriptRulesExtra = { // "@typescript-eslint/prefer-string-starts-ends-with": "error", } -const pluginTypeScriptProjectRules = disableProjectBasedRules() +const pluginTypeScriptProjectRules = makeSynchronous(disableProjectBasedRules()) ? {} : { "@typescript-eslint/no-floating-promises": "error", diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..471fcfa --- /dev/null +++ b/src/utils.js @@ -0,0 +1,30 @@ +const { readdirSync } = require("fs") +const { join } = require("path") +const { default: anymatch } = require("anymatch") + +/** + * @param {string} cwd + * @param {string} search + * @param {string[]} ignored + */ +function findOneFile(cwd, search, ignored) { + // recursively search the current folder for a file with the given fileEnding, ignoring the given folders, and return true as soon as one is found + const files = readdirSync(cwd, { withFileTypes: true, recursive: false }) + for (const file of files) { + const path = join(cwd, file.name) + if (file.isDirectory()) { + if (!anymatch(ignored, path)) { + // if the folder is not ignored, search it recursively + const found = findOneFile(path, search, ignored) + if (found) { + return true + } + } + } else if (anymatch(search, path)) { + // if the file ends with the given fileEnding, return true + return true + } + } + return false +} +exports.findOneFile = findOneFile