From a62e721456a8dfb2757d341d78966238cc26b287 Mon Sep 17 00:00:00 2001 From: prisis Date: Thu, 5 Oct 2023 18:35:06 +0200 Subject: [PATCH] fix: fixed wrong handling of eslint rule overwrite, removed cross-env Signed-off-by: prisis --- package.json | 2 +- packages/lint-staged-config/package.json | 2 +- packages/lint-staged-config/src/global.d.ts | 6 ++-- .../groups/eslint/create-eslint-commands.ts | 33 +++++++++++-------- .../src/groups/eslint/index.ts | 3 +- .../lint-staged-config/src/groups/json.ts | 11 +++++-- .../lint-staged-config/src/groups/markdown.ts | 11 ++++--- .../src/groups/secretlint.ts | 4 ++- .../src/groups/stylesheets.ts | 5 +-- .../lint-staged-config/src/groups/tests.ts | 28 +++++++++------- .../src/groups/typescript.ts | 3 +- .../src/utils/get-package-manager.ts | 29 ++++++++++++++++ 12 files changed, 97 insertions(+), 40 deletions(-) create mode 100644 packages/lint-staged-config/src/utils/get-package-manager.ts diff --git a/package.json b/package.json index 92d5eb718..3e7a7f18c 100644 --- a/package.json +++ b/package.json @@ -84,6 +84,7 @@ "test:stylelint-config": "pnpm --filter \"stylelint-config\" run test" }, "dependencies": { + "@anolilab/multi-semantic-release": "^1.0.2", "@babel/cli": "^7.23.0", "@babel/core": "^7.23.0", "@babel/preset-env": "^7.22.20", @@ -95,7 +96,6 @@ "@nrwl/nx-cloud": "16.4.0", "@nrwl/tao": "16.9.1", "@nrwl/workspace": "16.9.1", - "@anolilab/multi-semantic-release": "^1.0.2", "@secretlint/secretlint-rule-preset-recommend": "^7.0.7", "@tsconfig/node16": "^16.1.1", "@tsconfig/strictest": "^2.0.2", diff --git a/packages/lint-staged-config/package.json b/packages/lint-staged-config/package.json index 67af7b25a..fde1cca95 100644 --- a/packages/lint-staged-config/package.json +++ b/packages/lint-staged-config/package.json @@ -95,7 +95,6 @@ }, "dependencies": { "@anolilab/package-json-utils": "3.0.7", - "cross-env": "^7.0.3", "find-up": "5.0.0", "shell-quote": "^1.8.1" }, @@ -105,6 +104,7 @@ "@types/lint-staged": "^13.2.0", "@types/shell-quote": "^1.7.2", "@vitest/coverage-v8": "^0.34.6", + "cross-env": "^7.0.3", "husky": "^8.0.3", "lint-staged": "^14.0.1", "rimraf": "^5.0.5", diff --git a/packages/lint-staged-config/src/global.d.ts b/packages/lint-staged-config/src/global.d.ts index d32bfebfc..baafe8033 100644 --- a/packages/lint-staged-config/src/global.d.ts +++ b/packages/lint-staged-config/src/global.d.ts @@ -5,9 +5,11 @@ export {}; declare global { var hasAnolilabStagedLintConfigLoaded: undefined | boolean; - var anolilabLintStagedPackageJsonConfig: undefined | { [key: string]: boolean | undefined }; - var hasAnolilabLintStagedMarkdownCli: undefined | boolean; var hasAnolilabLintStagedMarkdownCli2: undefined | boolean; + + var anolilabLintStagedPackageJsonConfig: undefined | { [key: string]: boolean | undefined }; + + var anolilabLintStagedPackageManager: undefined | "pnpm" | "npm" | "yarn"; } diff --git a/packages/lint-staged-config/src/groups/eslint/create-eslint-commands.ts b/packages/lint-staged-config/src/groups/eslint/create-eslint-commands.ts index 9647b6b8e..aa3fa03b7 100644 --- a/packages/lint-staged-config/src/groups/eslint/create-eslint-commands.ts +++ b/packages/lint-staged-config/src/groups/eslint/create-eslint-commands.ts @@ -1,4 +1,7 @@ +import { hasDependency, hasDevDependency, isPackageAvailable } from "@anolilab/package-json-utils"; + import getNearestConfigPath from "../../utils/get-nearest-config-path"; +import getPackageManager from "../../utils/get-package-manager"; import anolilabLintStagedConfig from "../../utils/lint-staged-config"; import groupFilePathsByDirectoryName from "./group-file-paths-by-directory-name"; import removeIgnoredFiles from "./remove-ignored-files"; @@ -20,7 +23,9 @@ interface ESLintSettings { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition const eslintSettings: EslintConfig = (anolilabLintStagedConfig as ESLintSettings)?.settings?.eslint ?? ({} as EslintConfig); -const eslintGlobalRulesForFix = [ +const eslintGlobalRulesForFix: string[] = []; + +if (hasDependency("eslint-plugin-react-hooks") || hasDevDependency("eslint-plugin-react-hooks")) { // react-hooks/eslint and react in general is very strict about exhaustively // declaring the dependencies when using the useEffect, useCallback... hooks. // @@ -40,8 +45,16 @@ const eslintGlobalRulesForFix = [ // // @see https://reactjs.org/docs/hooks-rules.html // @see https://eslint.org/docs/2.13.1/user-guide/configuring#disabling-rules-with-inline-comments - "react-hooks/exhaustive-deps: off", -]; + eslintGlobalRulesForFix.push("react-hooks/exhaustive-deps:off"); +} + +if ( + hasDependency("eslint-plugin-eslint-comments") || + hasDevDependency("eslint-plugin-eslint-comments") || + isPackageAvailable("eslint-plugin-eslint-comments") +) { + eslintGlobalRulesForFix.push("eslint-comments/no-unused-disable:off"); +} const configFile = ".eslintrc"; @@ -54,16 +67,10 @@ const createEslintArguments = (): string[] => { eslintArguments.push("--max-warnings=0"); } - const rules = []; - - if (eslintSettings.rules !== undefined && Array.isArray(eslintSettings.rules)) { - rules.push([...eslintSettings.rules, ...eslintGlobalRulesForFix].filter((rule) => rule.trim().length > 0).map((r) => `"${r.trim()}"`)); - } else { - rules.push(eslintGlobalRulesForFix.map((r) => `"${r.trim()}"`)); - } + const rules = [...(eslintSettings.rules ?? []), ...eslintGlobalRulesForFix].filter((rule) => rule.trim().length > 0); if (rules.length > 0) { - eslintArguments.push(`--rule ${rules.join(" --rule ")}`); + eslintArguments.push(rules.map((rule) => `--rule "${rule}"`).join(" ")); } // For lint-staged it's safer to not apply the fix command if it changes the AST @@ -89,7 +96,7 @@ const createEslintCommands = async (filenames: string[]): Promise => { if (eslintSettings.config) { eslintArguments.push(`--config ${eslintSettings.config}`); - return [`cross-env NO_LOGS=true eslint ${eslintArguments.join(" ")} ${filteredFiles.join(" ")}`]; + return [`${getPackageManager()} exec eslint ${eslintArguments.join(" ")} ${filteredFiles.join(" ")}`]; } const groupedFilesNames = groupFilePathsByDirectoryName(filteredFiles); @@ -112,7 +119,7 @@ const createEslintCommands = async (filenames: string[]): Promise => { }); if (config) { - eslintCommands.push(`cross-env NO_LOGS=true eslint ${eslintArguments.join(" ")} --config ${config} ${filePaths.join(" ")}`); + eslintCommands.push(`${getPackageManager()} exec eslint ${eslintArguments.join(" ")} --config ${config} ${filePaths.join(" ")}`); } }); diff --git a/packages/lint-staged-config/src/groups/eslint/index.ts b/packages/lint-staged-config/src/groups/eslint/index.ts index 7e820b19f..5422c3e15 100644 --- a/packages/lint-staged-config/src/groups/eslint/index.ts +++ b/packages/lint-staged-config/src/groups/eslint/index.ts @@ -2,6 +2,7 @@ import { hasDependency, hasDevDependency } from "@anolilab/package-json-utils"; import type { Config } from "lint-staged"; import concatFiles from "../../utils/concat-files"; +import getPackageManager from "../../utils/get-package-manager"; import createEslintCommands from "./create-eslint-commands"; const extensions = ["cjs", "js", "mjs", "cts", "ts", "mts", "yml", "yaml", "jsx", "tsx", "mdx", "toml"]; @@ -21,7 +22,7 @@ if (!global.hasAnolilabLintStagedMarkdownCli && !global.hasAnolilabLintStagedMar const group: Config = { [`**/*.{${["json", "json5", "jsonc"].join(",")}}`]: async (filenames: string[]) => [...(await createEslintCommands(filenames))], [`**/*.{${[extensions].join(",")}}`]: async (filenames: string[]) => [ - `prettier --write ${concatFiles(filenames)}`, + `${getPackageManager()} execprettier --write ${concatFiles(filenames)}`, ...(await createEslintCommands(filenames)), ], }; diff --git a/packages/lint-staged-config/src/groups/json.ts b/packages/lint-staged-config/src/groups/json.ts index 7673f7fbe..eb6588a3a 100644 --- a/packages/lint-staged-config/src/groups/json.ts +++ b/packages/lint-staged-config/src/groups/json.ts @@ -2,12 +2,19 @@ import { hasDependency, hasDevDependency } from "@anolilab/package-json-utils"; import type { Config } from "lint-staged"; import concatFiles from "../utils/concat-files"; +import getPackageManager from "../utils/get-package-manager"; const hasSortPackageJson = hasDependency("sort-package-json") || hasDevDependency("sort-package-json"); const group: Config = { - [`**/*.{${["json", "json5", "jsonc"].join(",")}}`]: (filenames: string[]) => [`prettier --write ${concatFiles(filenames)}`], - ...(hasSortPackageJson ? { "package.json,{packages,apps}/*/package.json": (filenames: string[]) => [`sort-package-json ${concatFiles(filenames)}`] } : {}), + [`**/*.{${["json", "json5", "jsonc"].join(",")}}`]: (filenames: string[]) => [`${getPackageManager()} exec prettier --write ${concatFiles(filenames)}`], + ...(hasSortPackageJson + ? { + "package.json,{packages,apps}/*/package.json": (filenames: string[]) => [ + `${getPackageManager()} exec sort-package-json ${concatFiles(filenames)}`, + ], + } + : {}), }; export default group; diff --git a/packages/lint-staged-config/src/groups/markdown.ts b/packages/lint-staged-config/src/groups/markdown.ts index 51e6450a9..2d06dd011 100644 --- a/packages/lint-staged-config/src/groups/markdown.ts +++ b/packages/lint-staged-config/src/groups/markdown.ts @@ -2,6 +2,7 @@ import { hasDependency, hasDevDependency } from "@anolilab/package-json-utils"; import type { Config } from "lint-staged"; import concatFiles from "../utils/concat-files"; +import getPackageManager from "../utils/get-package-manager"; if (!global.hasAnolilabLintStagedMarkdownCli) { global.hasAnolilabLintStagedMarkdownCli = hasDependency("markdownlint-cli") || hasDevDependency("markdownlint-cli"); @@ -12,13 +13,15 @@ if (!global.hasAnolilabLintStagedMarkdownCli2) { const group: Config = { "**/*.md": (filenames: string[]) => [ - `prettier --write ${concatFiles(filenames)}`, + `${getPackageManager()} exec prettier --write ${concatFiles(filenames)}`, ...(global.hasAnolilabLintStagedMarkdownCli - ? [`markdownlint --fix --ignore '**/node_modules/**' --ignore '**/CHANGELOG.md' ${concatFiles(filenames)}`] + ? [`${getPackageManager()} exec markdownlint --fix --ignore '**/node_modules/**' --ignore '**/CHANGELOG.md' ${concatFiles(filenames)}`] + : []), + ...(global.hasAnolilabLintStagedMarkdownCli2 + ? [`${getPackageManager()} exec markdownlint-cli2 --fix '!**/node_modules/**' '!**/CHANGELOG.md' ${concatFiles(filenames)}`] : []), - ...(global.hasAnolilabLintStagedMarkdownCli2 ? [`markdownlint-cli2 --fix '!**/node_modules/**' '!**/CHANGELOG.md' ${concatFiles(filenames)}`] : []), ], - "**/*.mdx": (filenames) => [`prettier --write ${concatFiles(filenames)}`], + "**/*.mdx": (filenames) => [`${getPackageManager()} exec prettier --write ${concatFiles(filenames)}`], }; export default group; diff --git a/packages/lint-staged-config/src/groups/secretlint.ts b/packages/lint-staged-config/src/groups/secretlint.ts index 79c72b844..64a73a22c 100644 --- a/packages/lint-staged-config/src/groups/secretlint.ts +++ b/packages/lint-staged-config/src/groups/secretlint.ts @@ -1,7 +1,9 @@ import type { Config } from "lint-staged"; +import getPackageManager from "../utils/get-package-manager"; + const group: Config = { - "*": ["secretlint"], + "*": [`${getPackageManager()} exec secretlint`], }; export default group; diff --git a/packages/lint-staged-config/src/groups/stylesheets.ts b/packages/lint-staged-config/src/groups/stylesheets.ts index bdc68b744..9613d5af8 100644 --- a/packages/lint-staged-config/src/groups/stylesheets.ts +++ b/packages/lint-staged-config/src/groups/stylesheets.ts @@ -1,11 +1,12 @@ import type { Config } from "lint-staged"; import concatFiles from "../utils/concat-files"; +import getPackageManager from "../utils/get-package-manager"; const group: Config = { [`**/*.{${["css", "sass", "scss", "less"].join(",")}}`]: (filenames: string[]) => [ - `prettier --ignore-unknown --write ${concatFiles(filenames)}`, - "stylelint --fix", + `${getPackageManager()} exec prettier --ignore-unknown --write ${concatFiles(filenames)}`, + `${getPackageManager()} exec stylelint --fix`, ], }; diff --git a/packages/lint-staged-config/src/groups/tests.ts b/packages/lint-staged-config/src/groups/tests.ts index 3b0fff81a..bf4b3177a 100644 --- a/packages/lint-staged-config/src/groups/tests.ts +++ b/packages/lint-staged-config/src/groups/tests.ts @@ -2,27 +2,31 @@ import { hasDependency, hasDevDependency } from "@anolilab/package-json-utils"; import type { Config } from "lint-staged"; import concatFiles from "../utils/concat-files"; +import getPackageManager from "../utils/get-package-manager"; const hasVitest = hasDependency("vitest") || hasDevDependency("vitest"); const hasJest = hasDependency("jest") || hasDevDependency("jest"); const hasAva = hasDependency("ava") || hasDevDependency("ava"); const group: Config = { - ...(hasVitest && { "**/?(*.){test,spec}.?(c|m)[jt]s?(x)": ["vitest related --run"], "**/__tests__/**/*.?(c|m)[jt]s?(x)": ["vitest related --run"] }), + ...(hasVitest && { + "**/?(*.){test,spec}.?(c|m)[jt]s?(x)": ["vitest related --run"], + "**/__tests__/**/*.?(c|m)[jt]s?(x)": [`${getPackageManager()} exec vitest related --run`], + }), ...(hasJest && { - "**/*.spec.{js,ts,tsx}": ["jest --findRelatedTests"], - "**/*.test.{js,ts,tsx}": ["jest --findRelatedTests"], - "**/?(*.){test,spec}.?(c|m)[jt]s?(x)": ["jest --findRelatedTests"], - "**/__mocks__/*.{js,ts,tsx}": ["jest --findRelatedTests"], - "**/__tests__/**/*.?(c|m)[jt]s?(x)": ["jest --findRelatedTests"], - "**/__tests__/*.{js,ts,tsx}": ["jest --findRelatedTests"], - "**/test/*.{js,ts,tsx}": ["jest --findRelatedTests"], + "**/*.spec.{js,ts,tsx}": [`${getPackageManager()} exec jest --findRelatedTests`], + "**/*.test.{js,ts,tsx}": [`${getPackageManager()} exec jest --findRelatedTests`], + "**/?(*.){test,spec}.?(c|m)[jt]s?(x)": [`${getPackageManager()} exec jest --findRelatedTests`], + "**/__mocks__/*.{js,ts,tsx}": [`${getPackageManager()} exec jest --findRelatedTests`], + "**/__tests__/**/*.?(c|m)[jt]s?(x)": [`${getPackageManager()} exec jest --findRelatedTests`], + "**/__tests__/*.{js,ts,tsx}": [`${getPackageManager()} exec jest --findRelatedTests`], + "**/test/*.{js,ts,tsx}": [`${getPackageManager()} exec jest --findRelatedTests`], }), ...(hasAva && { - "**/(test|tests|__tests__)/**/*.js": (filenames: string[]) => [`ava ${concatFiles(filenames)}`], - "**/*.(spec|test).js": (filenames: string[]) => [`ava ${concatFiles(filenames)}`], - "**/test.js": (filenames: string[]) => [`ava ${concatFiles(filenames)}`], - "**/test-*.js": (filenames: string[]) => [`ava ${concatFiles(filenames)}`], + "**/(test|tests|__tests__)/**/*.js": (filenames: string[]) => [`${getPackageManager()} exec ava ${concatFiles(filenames)}`], + "**/*.(spec|test).js": (filenames: string[]) => [`${getPackageManager()} exec ava ${concatFiles(filenames)}`], + "**/test.js": (filenames: string[]) => [`${getPackageManager()} exec ava ${concatFiles(filenames)}`], + "**/test-*.js": (filenames: string[]) => [`${getPackageManager()} exec ava ${concatFiles(filenames)}`], }), }; diff --git a/packages/lint-staged-config/src/groups/typescript.ts b/packages/lint-staged-config/src/groups/typescript.ts index f907c4741..fe48b0c91 100644 --- a/packages/lint-staged-config/src/groups/typescript.ts +++ b/packages/lint-staged-config/src/groups/typescript.ts @@ -3,6 +3,7 @@ import { env } from "node:process"; import type { Config } from "lint-staged"; import getNearestConfigPath from "../utils/get-nearest-config-path"; +import getPackageManager from "../utils/get-package-manager"; const group: Config = { [`**/*.{${["ts", "mts", "cts"].join(",")}}`]: (filenames: string[]) => { @@ -13,7 +14,7 @@ const group: Config = { // eslint-disable-next-line no-template-curly-in-string const tsconfigPath = getNearestConfigPath("tsconfig.json", filePath as "/${string}") as string; - commands.add(`tsc --noEmit --project ${tsconfigPath}`); + commands.add(`${getPackageManager()} exec tsc --noEmit --project ${tsconfigPath}`); } catch (error) { if (env["DEBUG"]) { console.error(error); diff --git a/packages/lint-staged-config/src/utils/get-package-manager.ts b/packages/lint-staged-config/src/utils/get-package-manager.ts new file mode 100644 index 000000000..2c29d3bbe --- /dev/null +++ b/packages/lint-staged-config/src/utils/get-package-manager.ts @@ -0,0 +1,29 @@ +import { hasFile } from "@anolilab/package-json-utils"; + +const getPackageManager = (): "npm" | "pnpm" | "yarn" => { + if (global.anolilabLintStagedPackageManager) { + return global.anolilabLintStagedPackageManager; + } + + if (hasFile("pnpm-lock.yaml")) { + global.anolilabLintStagedPackageManager = "pnpm"; + + return "pnpm"; + } + + if (hasFile("yarn.lock")) { + global.anolilabLintStagedPackageManager = "yarn"; + + return "yarn"; + } + + if (hasFile("package-lock.json")) { + global.anolilabLintStagedPackageManager = "npm"; + + return "npm"; + } + + throw new Error("No package manager found"); +}; + +export default getPackageManager;