From 258fdd059526175431dbfe60dc88e0cc9d99c33e Mon Sep 17 00:00:00 2001 From: tieTYT Date: Mon, 23 Mar 2020 13:26:19 -0700 Subject: [PATCH 01/10] docs: title wording in root readme (#1787) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 95cfe76c5eb4..c298f8069507 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ ## Table of Contents -- [Getting Started](#getting-started) +- [Getting Started / Installation](#getting-started--installation) - [What are ESLint and TypeScript, and how do they compare?](#what-are-eslint-and-typescript-and-how-do-they-compare) - [Why does this project exist?](#why-does-this-project-exist) - [What about TSLint?](#what-about-tslint) @@ -32,7 +32,7 @@ - [Contributors](#contributors) - [Contributing Guide](#contributing-guide) -## Getting Started +## Getting Started / Installation - **[You can find our Getting Started docs here](./docs/getting-started/README.md)** - **[You can find our Linting FAQ / Troubleshooting docs here](./docs/getting-started/linting/FAQ.md)** From b1b82847aa1db5040b18daf7b601f9c63c96a99c Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 23 Mar 2020 16:06:15 -0700 Subject: [PATCH 02/10] docs(eslint-plugin): [prefer-readonly-parameter-types] fix invalid example (#1791) --- .../docs/rules/prefer-readonly-parameter-types.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/docs/rules/prefer-readonly-parameter-types.md b/packages/eslint-plugin/docs/rules/prefer-readonly-parameter-types.md index c69b3b21c345..74697f2d3e66 100644 --- a/packages/eslint-plugin/docs/rules/prefer-readonly-parameter-types.md +++ b/packages/eslint-plugin/docs/rules/prefer-readonly-parameter-types.md @@ -74,7 +74,8 @@ function object3(arg: { readonly prop: { readonly prop2: string } }) {} interface CustomArrayType extends ReadonlyArray { readonly prop: string; } -function custom1(arg: CustomArrayType) {} +function custom1(arg: Readonly) {} +// interfaces that extend the array types are not considered arrays, and thus must be made readonly. interface CustomFunction { (): void; From 4fa710754ecc412b65ac3864fe0c7857c254ac1b Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Wed, 25 Mar 2020 20:09:04 -0700 Subject: [PATCH 03/10] fix(eslint-plugin): [no-unsafe-call] allow import expressions (#1800) --- packages/eslint-plugin/src/rules/no-unsafe-call.ts | 6 +++--- packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-unsafe-call.ts b/packages/eslint-plugin/src/rules/no-unsafe-call.ts index 42630181936a..13cabc87d924 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-call.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-call.ts @@ -41,10 +41,10 @@ export default util.createRule<[], MessageIds>({ } return { - 'CallExpression, OptionalCallExpression'( - node: TSESTree.CallExpression | TSESTree.OptionalCallExpression, + ':matches(CallExpression, OptionalCallExpression) > :not(Import)'( + node: Exclude, ): void { - checkCall(node.callee, node.callee, 'unsafeCall'); + checkCall(node, node, 'unsafeCall'); }, NewExpression(node): void { checkCall(node.callee, node, 'unsafeNew'); diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts index 1930db273267..a51273c9b9cf 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-call.test.ts @@ -20,6 +20,7 @@ ruleTester.run('no-unsafe-call', rule, { 'function foo(x: { a?: () => void }) { x.a?.() }', 'new Map()', 'String.raw`foo`', + 'const x = import("./foo");', ], invalid: [ ...batchedSingleLineTests({ From 638d84ddd77d07117b3ec7c5431f3b0e44b1995d Mon Sep 17 00:00:00 2001 From: doniyor2109 Date: Thu, 26 Mar 2020 13:04:48 +0500 Subject: [PATCH 04/10] fix(eslint-plugin): [no-explicit-any] error with ignoreRestArgs (#1796) --- packages/eslint-plugin/src/rules/no-explicit-any.ts | 9 ++------- .../eslint-plugin/tests/rules/no-explicit-any.test.ts | 11 +++++++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-explicit-any.ts b/packages/eslint-plugin/src/rules/no-explicit-any.ts index 29fb16651a2c..91765c40e262 100644 --- a/packages/eslint-plugin/src/rules/no-explicit-any.ts +++ b/packages/eslint-plugin/src/rules/no-explicit-any.ts @@ -131,9 +131,7 @@ export default util.createRule({ */ function isGreatGrandparentRestElement(node: TSESTree.Node): boolean { return ( - typeof node.parent !== 'undefined' && - typeof node.parent.parent !== 'undefined' && - typeof node.parent.parent.parent !== 'undefined' && + node?.parent?.parent?.parent != null && isNodeRestElementInFunction(node.parent.parent.parent) ); } @@ -146,11 +144,8 @@ export default util.createRule({ */ function isGreatGreatGrandparentRestElement(node: TSESTree.Node): boolean { return ( - typeof node.parent !== 'undefined' && - typeof node.parent.parent !== 'undefined' && + node.parent?.parent?.parent?.parent != null && isNodeValidTSType(node.parent.parent) && - typeof node.parent.parent.parent !== 'undefined' && - typeof node.parent.parent.parent.parent !== 'undefined' && isNodeRestElementInFunction(node.parent.parent.parent.parent) ); } diff --git a/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts index d065c4109877..fa68b09919eb 100644 --- a/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts +++ b/packages/eslint-plugin/tests/rules/no-explicit-any.test.ts @@ -925,6 +925,17 @@ const test = >() => {}; }, ], }, + { + code: `type Any = any;`, + options: [{ ignoreRestArgs: true }], + errors: [ + { + messageId: 'unexpectedAny', + line: 1, + column: 12, + }, + ], + }, { code: `function foo5(...args: any) {}`, options: [{ ignoreRestArgs: true }], From 7d963fd846935acd91b7b0cd31c56a70a2b994d1 Mon Sep 17 00:00:00 2001 From: crfrolik <60711200+crfrolik@users.noreply.github.com> Date: Thu, 26 Mar 2020 14:53:43 -0400 Subject: [PATCH 05/10] feat(eslint-plugin-tslint): support tslint 6 (#1809) --- package.json | 2 +- packages/eslint-plugin-tslint/package.json | 2 +- yarn.lock | 17 +++++++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index db9c7201528c..5aa87589e193 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "prettier": "^1.19.1", "ts-jest": "^25.0.0", "ts-node": "^8.5.0", - "tslint": "^5.20.1", + "tslint": "^6.1.0", "typescript": ">=3.2.1 <3.9.0" }, "resolutions": { diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index a10074080b20..1c422e8fa117 100644 --- a/packages/eslint-plugin-tslint/package.json +++ b/packages/eslint-plugin-tslint/package.json @@ -36,7 +36,7 @@ }, "peerDependencies": { "eslint": "^5.0.0 || ^6.0.0", - "tslint": "^5.0.0", + "tslint": "^5.0.0 || ^6.0.0", "typescript": "*" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 4e2a78cbd7e8..8fb6fd0a838d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8065,15 +8065,20 @@ ts-node@^8.5.0: source-map-support "^0.5.6" yn "^3.0.0" -tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.10.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + +tslib@^1.8.1, tslib@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== -tslint@^5.20.1: - version "5.20.1" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.20.1.tgz#e401e8aeda0152bc44dd07e614034f3f80c67b7d" - integrity sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg== +tslint@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.0.tgz#c6c611b8ba0eed1549bf5a59ba05a7732133d851" + integrity sha512-fXjYd/61vU6da04E505OZQGb2VCN2Mq3doeWcOIryuG+eqdmFUXTYVwdhnbEu2k46LNLgUYt9bI5icQze/j0bQ== dependencies: "@babel/code-frame" "^7.0.0" builtin-modules "^1.1.1" @@ -8086,7 +8091,7 @@ tslint@^5.20.1: mkdirp "^0.5.1" resolve "^1.3.2" semver "^5.3.0" - tslib "^1.8.0" + tslib "^1.10.0" tsutils "^2.29.0" tsutils@^2.29.0: From 1e29e69b289d61107a7de67592beae331ba50222 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 27 Mar 2020 09:31:51 -0700 Subject: [PATCH 06/10] feat(typescript-estree): add option to ignore certain folders from glob resolution (#1802) --- .../src/ts-eslint/ParserOptions.ts | 1 + packages/parser/README.md | 19 +++- packages/typescript-estree/README.md | 11 ++ .../typescript-estree/src/parser-options.ts | 91 +++++++++------- packages/typescript-estree/src/parser.ts | 100 ++++++++++++++---- .../projectFolderIgnoreList/ignoreme/file.ts | 1 + .../ignoreme/tsconfig.json | 3 + .../projectFolderIgnoreList/includeme/file.ts | 1 + .../includeme/tsconfig.json | 3 + packages/typescript-estree/tests/lib/parse.ts | 45 ++++++++ tsconfig.eslint.json | 2 +- 11 files changed, 213 insertions(+), 64 deletions(-) create mode 100644 packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/ignoreme/file.ts create mode 100644 packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/ignoreme/tsconfig.json create mode 100644 packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/includeme/file.ts create mode 100644 packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/includeme/tsconfig.json diff --git a/packages/experimental-utils/src/ts-eslint/ParserOptions.ts b/packages/experimental-utils/src/ts-eslint/ParserOptions.ts index d6bf57bb585a..0ff55c81c566 100644 --- a/packages/experimental-utils/src/ts-eslint/ParserOptions.ts +++ b/packages/experimental-utils/src/ts-eslint/ParserOptions.ts @@ -16,6 +16,7 @@ interface ParserOptions { loc?: boolean; noWatch?: boolean; project?: string | string[]; + projectFolderIgnoreList?: (string | RegExp)[]; range?: boolean; sourceType?: 'script' | 'module'; tokens?: boolean; diff --git a/packages/parser/README.md b/packages/parser/README.md index cf69891fb7a0..70cb1cb2ca29 100644 --- a/packages/parser/README.md +++ b/packages/parser/README.md @@ -54,6 +54,7 @@ interface ParserOptions { jsx?: boolean; }; project?: string | string[]; + projectFolderIgnoreList?: (string | RegExp)[]; tsconfigRootDir?: string; extraFileExtensions?: string[]; warnOnUnsupportedTypeScriptVersion?: boolean; @@ -118,26 +119,36 @@ This option allows you to provide a path to your project's `tsconfig.json`. **Th } ``` -### `tsconfigRootDir` +### `parserOptions.tsconfigRootDir` Default `undefined`. This option allows you to provide the root directory for relative tsconfig paths specified in the `project` option above. -### `extraFileExtensions` +### `parserOptions.projectFolderIgnoreList` + +Default `["/node_modules/"]`. + +This option allows you to ignore folders from being included in your provided list of `project`s. +Any resolved project path that matches one or more of the provided regular expressions will be removed from the list. +This is useful if you have configured glob patterns, but want to make sure you ignore certain folders. + +For example, by default it will ensure that a glob like `./**/tsconfig.json` will not match any `tsconfig`s within your `node_modules` folder (some npm packages do not exclude their source files from their published packages). + +### `parserOptions.extraFileExtensions` Default `undefined`. This option allows you to provide one or more additional file extensions which should be considered in the TypeScript Program compilation. The default extensions are `.ts`, `.tsx`, `.js`, and `.jsx`. Add extensions starting with `.`, followed by the file extension. E.g. for a `.vue` file use `"extraFileExtensions: [".vue"]`. -### `warnOnUnsupportedTypeScriptVersion` +### `parserOptions.warnOnUnsupportedTypeScriptVersion` Default `true`. This option allows you to toggle the warning that the parser will give you if you use a version of TypeScript which is not explicitly supported -### `createDefaultProgram` +### `parserOptions.createDefaultProgram` Default `false`. diff --git a/packages/typescript-estree/README.md b/packages/typescript-estree/README.md index 54706cf47f9e..df2492c56b34 100644 --- a/packages/typescript-estree/README.md +++ b/packages/typescript-estree/README.md @@ -182,6 +182,16 @@ interface ParseAndGenerateServicesOptions extends ParseOptions { */ project?: string | string[]; + /** + * If you provide a glob (or globs) to the project option, you can use this option to blacklist + * certain folders from being matched by the globs. + * Any project path that matches one or more of the provided regular expressions will be removed from the list. + * + * Accepts an array of strings that are passed to new RegExp(), or an array of regular expressions. + * By default, this is set to ["/node_modules/"] + */ + projectFolderIgnoreList?: (string | RegExp)[]; + /** * The absolute path to the root directory for all provided `project`s. */ @@ -205,6 +215,7 @@ const PARSE_AND_GENERATE_SERVICES_DEFAULT_OPTIONS: ParseOptions = { extraFileExtensions: [], preserveNodeMaps: false, // or true, if you do not set this, but pass `project` project: undefined, + projectFolderIgnoreList: ['/node_modules/'], tsconfigRootDir: process.cwd(), }; diff --git a/packages/typescript-estree/src/parser-options.ts b/packages/typescript-estree/src/parser-options.ts index 73ea6ba3c04d..c55ace5adb03 100644 --- a/packages/typescript-estree/src/parser-options.ts +++ b/packages/typescript-estree/src/parser-options.ts @@ -29,28 +29,23 @@ export interface Extra { // MAKE SURE THIS IS KEPT IN SYNC WITH THE README // //////////////////////////////////////////////////// -export interface TSESTreeOptions { +interface ParseOptions { /** * create a top-level comments array containing all comments */ comment?: boolean; /** - * For convenience: - * - true === ['typescript-eslint'] - * - false === [] - * * An array of modules to turn explicit debugging on for. * - 'typescript-eslint' is the same as setting the env var `DEBUG=typescript-eslint:*` * - 'eslint' is the same as setting the env var `DEBUG=eslint:*` * - 'typescript' is the same as setting `extendedDiagnostics: true` in your tsconfig compilerOptions + * + * For convenience, also supports a boolean: + * - true === ['typescript-eslint'] + * - false === [] */ - debugLevel?: boolean | DebugModule[]; - - /** - * Causes the parser to error if the TypeScript compiler returns any unexpected syntax/semantic errors. - */ - errorOnTypeScriptSyntacticAndSemanticIssues?: boolean; + debugLevel?: boolean | ('typescript-eslint' | 'eslint' | 'typescript')[]; /** * Cause the parser to error if it encounters an unknown AST node type (useful for testing). @@ -59,14 +54,7 @@ export interface TSESTreeOptions { errorOnUnknownASTType?: boolean; /** - * When `project` is provided, this controls the non-standard file extensions which will be parsed. - * It accepts an array of file extensions, each preceded by a `.`. - */ - extraFileExtensions?: string[]; - - /** - * Absolute (or relative to `tsconfigRootDir`) path to the file being parsed. - * When `project` is provided, this is required, as it is used to fetch the file from the TypeScript compiler's cache. + * Absolute (or relative to `cwd`) path to the file being parsed. */ filePath?: string; @@ -95,6 +83,45 @@ export interface TSESTreeOptions { */ loggerFn?: Function | false; + /** + * Controls whether the `range` property is included on AST nodes. + * The `range` property is a [number, number] which indicates the start/end index of the node in the file contents. + * This is similar to the `loc` property, except this is the absolute index. + */ + range?: boolean; + + /** + * Set to true to create a top-level array containing all tokens from the file. + */ + tokens?: boolean; + + /* + * The JSX AST changed the node type for string literals + * inside a JSX Element from `Literal` to `JSXText`. + * When value is `true`, these nodes will be parsed as type `JSXText`. + * When value is `false`, these nodes will be parsed as type `Literal`. + */ + useJSXTextNode?: boolean; +} + +interface ParseAndGenerateServicesOptions extends ParseOptions { + /** + * Causes the parser to error if the TypeScript compiler returns any unexpected syntax/semantic errors. + */ + errorOnTypeScriptSyntacticAndSemanticIssues?: boolean; + + /** + * When `project` is provided, this controls the non-standard file extensions which will be parsed. + * It accepts an array of file extensions, each preceded by a `.`. + */ + extraFileExtensions?: string[]; + + /** + * Absolute (or relative to `tsconfigRootDir`) path to the file being parsed. + * When `project` is provided, this is required, as it is used to fetch the file from the TypeScript compiler's cache. + */ + filePath?: string; + /** * Allows the user to control whether or not two-way AST node maps are preserved * during the AST conversion process. @@ -114,30 +141,20 @@ export interface TSESTreeOptions { project?: string | string[]; /** - * Controls whether the `range` property is included on AST nodes. - * The `range` property is a [number, number] which indicates the start/end index of the node in the file contents. - * This is similar to the `loc` property, except this is the absolute index. - */ - range?: boolean; - - /** - * Set to true to create a top-level array containing all tokens from the file. + * If you provide a glob (or globs) to the project option, you can use this option to blacklist + * certain folders from being matched by the globs. + * Any project path that matches one or more of the provided regular expressions will be removed from the list. + * + * Accepts an array of strings that are passed to new RegExp(), or an array of regular expressions. + * By default, this is set to ["/node_modules/"] */ - tokens?: boolean; + projectFolderIgnoreList?: (string | RegExp)[]; /** * The absolute path to the root directory for all provided `project`s. */ tsconfigRootDir?: string; - /* - * The JSX AST changed the node type for string literals - * inside a JSX Element from `Literal` to `JSXText`. - * When value is `true`, these nodes will be parsed as type `JSXText`. - * When value is `false`, these nodes will be parsed as type `Literal`. - */ - useJSXTextNode?: boolean; - /** *************************************************************************************** * IT IS RECOMMENDED THAT YOU DO NOT USE THIS OPTION, AS IT CAUSES PERFORMANCE ISSUES. * @@ -150,6 +167,8 @@ export interface TSESTreeOptions { createDefaultProgram?: boolean; } +export type TSESTreeOptions = ParseAndGenerateServicesOptions; + // This lets us use generics to type the return value, and removes the need to // handle the undefined type in the get method export interface ParserWeakMap { diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index b5e75d155595..5e3e9b90261b 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -14,6 +14,8 @@ import { getFirstSemanticOrSyntacticError } from './semantic-or-syntactic-errors import { TSESTree } from './ts-estree'; import { ensureAbsolutePath } from './create-program/shared'; +const log = debug('typescript-eslint:typescript-estree:parser'); + /** * This needs to be kept in sync with the top-level README.md in the * typescript-eslint monorepo @@ -111,6 +113,74 @@ function resetExtra(): void { }; } +/** + * Normalizes, sanitizes, resolves and filters the provided + */ +function prepareAndTransformProjects( + projectsInput: string | string[] | undefined, + ignoreListInput: (string | RegExp)[] | undefined, +): string[] { + let projects: string[] = []; + + // Normalize and sanitize the project paths + if (typeof projectsInput === 'string') { + projects.push(projectsInput); + } else if (Array.isArray(projectsInput)) { + for (const project of projectsInput) { + if (typeof project === 'string') { + projects.push(project); + } + } + } + + if (projects.length === 0) { + return projects; + } + + // Transform glob patterns into paths + projects = projects.reduce( + (projects, project) => + projects.concat( + isGlob(project) + ? globSync(project, { + cwd: extra.tsconfigRootDir, + }) + : project, + ), + [], + ); + + // Normalize and sanitize the ignore regex list + const ignoreRegexes: RegExp[] = []; + if (Array.isArray(ignoreListInput)) { + for (const ignore of ignoreListInput) { + if (ignore instanceof RegExp) { + ignoreRegexes.push(ignore); + } else if (typeof ignore === 'string') { + ignoreRegexes.push(new RegExp(ignore)); + } + } + } else { + ignoreRegexes.push(/\/node_modules\//); + } + + // Remove any paths that match the ignore list + const filtered = projects.filter(project => { + for (const ignore of ignoreRegexes) { + if (ignore.test(project)) { + return false; + } + } + + return true; + }); + + log('parserOptions.project matched projects: %s', projects); + log('ignore list applied to parserOptions.project: %s', filtered); + + return filtered; +} + function applyParserOptionsToExtra(options: TSESTreeOptions): void { /** * Configure Debug logging @@ -205,34 +275,18 @@ function applyParserOptionsToExtra(options: TSESTreeOptions): void { extra.log = Function.prototype; } - if (typeof options.project === 'string') { - extra.projects = [options.project]; - } else if ( - Array.isArray(options.project) && - options.project.every(projectPath => typeof projectPath === 'string') - ) { - extra.projects = options.project; - } - if (typeof options.tsconfigRootDir === 'string') { extra.tsconfigRootDir = options.tsconfigRootDir; } + + // NOTE - ensureAbsolutePath relies upon having the correct tsconfigRootDir in extra extra.filePath = ensureAbsolutePath(extra.filePath, extra); - // Transform glob patterns into paths - if (extra.projects) { - extra.projects = extra.projects.reduce( - (projects, project) => - projects.concat( - isGlob(project) - ? globSync(project, { - cwd: extra.tsconfigRootDir || process.cwd(), - }) - : project, - ), - [], - ); - } + // NOTE - prepareAndTransformProjects relies upon having the correct tsconfigRootDir in extra + extra.projects = prepareAndTransformProjects( + options.project, + options.projectFolderIgnoreList, + ); if ( Array.isArray(options.extraFileExtensions) && diff --git a/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/ignoreme/file.ts b/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/ignoreme/file.ts new file mode 100644 index 000000000000..ad1d380d6cc4 --- /dev/null +++ b/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/ignoreme/file.ts @@ -0,0 +1 @@ +export const x = 1; diff --git a/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/ignoreme/tsconfig.json b/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/ignoreme/tsconfig.json new file mode 100644 index 000000000000..a01e8a941e84 --- /dev/null +++ b/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/ignoreme/tsconfig.json @@ -0,0 +1,3 @@ +{ + "include": ["./file.ts"] +} diff --git a/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/includeme/file.ts b/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/includeme/file.ts new file mode 100644 index 000000000000..25dfdc46133e --- /dev/null +++ b/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/includeme/file.ts @@ -0,0 +1 @@ +export const x = 2; diff --git a/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/includeme/tsconfig.json b/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/includeme/tsconfig.json new file mode 100644 index 000000000000..a01e8a941e84 --- /dev/null +++ b/packages/typescript-estree/tests/fixtures/projectFolderIgnoreList/includeme/tsconfig.json @@ -0,0 +1,3 @@ +{ + "include": ["./file.ts"] +} diff --git a/packages/typescript-estree/tests/lib/parse.ts b/packages/typescript-estree/tests/lib/parse.ts index 1e6a1e972360..c6435508eacc 100644 --- a/packages/typescript-estree/tests/lib/parse.ts +++ b/packages/typescript-estree/tests/lib/parse.ts @@ -557,4 +557,49 @@ describe('parse()', () => { ); }); }); + + describe('projectFolderIgnoreList', () => { + beforeEach(() => { + parser.clearCaches(); + }); + + const PROJECT_DIR = resolve(FIXTURES_DIR, '../projectFolderIgnoreList'); + const code = 'var a = true'; + const config: TSESTreeOptions = { + comment: true, + tokens: true, + range: true, + loc: true, + tsconfigRootDir: PROJECT_DIR, + project: './**/tsconfig.json', + }; + + const testParse = ( + filePath: 'ignoreme' | 'includeme', + projectFolderIgnoreList: TSESTreeOptions['projectFolderIgnoreList'] = [], + ) => (): void => { + parser.parseAndGenerateServices(code, { + ...config, + projectFolderIgnoreList, + filePath: join(PROJECT_DIR, filePath, './file.ts'), + }); + }; + + it('ignores nothing when given nothing', () => { + expect(testParse('ignoreme')).not.toThrow(); + expect(testParse('includeme')).not.toThrow(); + }); + + it('ignores a folder when given a string regexp', () => { + const ignore = ['/ignoreme/']; + expect(testParse('ignoreme', ignore)).toThrow(); + expect(testParse('includeme', ignore)).not.toThrow(); + }); + + it('ignores a folder when given a RegExp', () => { + const ignore = [/\/ignoreme\//]; + expect(testParse('ignoreme', ignore)).toThrow(); + expect(testParse('includeme', ignore)).not.toThrow(); + }); + }); }); diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index 2d9938163eac..40defd4b3b8d 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -1,4 +1,4 @@ { "extends": "./tsconfig.base.json", - "include": ["tests/**/*.ts", "tools/**/*.ts"] + "include": ["tests/**/*.ts", "tools/**/*.ts", ".eslintrc.js"] } From f3160b471f8247e157555b6cf5b40a1f6ccdc233 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 27 Mar 2020 18:31:43 -0700 Subject: [PATCH 07/10] fix(eslint-plugin): [no-unsafe-return] error with Date: Mon, 30 Mar 2020 00:44:52 -0700 Subject: [PATCH 08/10] chore: separate linting checks to their own step (#1801) If linting/formatting/spelling fails, it should not block running the tests. If they do block, they can increase the iteration time for contributors, because they will have to fix them before they can see the status of their tests. By not blocking, a contributor will be able to submit a PR, and come back ~5min later knowing they will be able to see if their code passes linting _and_ tests. This should also knock ~40-60s off of the perceived runtime, as it parallelises some of the work. --- .cspell.json | 3 ++- .github/workflows/ci.yml | 50 +++++++++++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/.cspell.json b/.cspell.json index c65ff294c249..7ee50214e7fd 100644 --- a/.cspell.json +++ b/.cspell.json @@ -11,7 +11,8 @@ "**/**/ROADMAP.md", "**/*.{json,snap}", ".cspell.json", - "yarn.lock" + "yarn.lock", + ".github/workflows/**" ], "dictionaries": [ "typescript", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 933b4895837f..8f6904d879de 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ env: jobs: primary_code_validation_and_tests: - name: Primary code validation and tests + name: Typecheck and tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -49,15 +49,6 @@ jobs: - name: Typecheck all packages run: yarn typecheck - - name: Check code formatting - run: yarn format-check - - - name: Run linting - run: yarn lint - - - name: Validate spelling - run: yarn check:spelling - - name: Run unit tests run: yarn test env: @@ -71,6 +62,43 @@ jobs: flags: unittest name: codecov + linting_and_style: + name: Code style and lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ env.PRIMARY_NODE_VERSION }} + uses: actions/setup-node@v1 + with: + node-version: ${{ env.PRIMARY_NODE_VERSION }} + + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + + - uses: actions/cache@v1 + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + # This also runs a build as part of the postinstall bootstrap + - name: Install dependencies and build + run: | + yarn --ignore-engines --frozen-lockfile + yarn check-clean-workspace-after-install + + - name: Check code formatting + run: yarn format-check + + - name: Run linting + run: yarn lint + + - name: Validate spelling + run: yarn check:spelling + integration_tests: name: Run integration tests on primary Node.js version runs-on: ubuntu-latest @@ -143,7 +171,7 @@ jobs: publish_canary_version: name: Publish the latest code as a canary version runs-on: ubuntu-latest - needs: [primary_code_validation_and_tests, unit_tests_on_other_node_versions, integration_tests] + needs: [primary_code_validation_and_tests, unit_tests_on_other_node_versions, linting_and_style, integration_tests] if: github.ref == 'refs/heads/master' steps: - uses: actions/checkout@v2 From 543bc795733948f4111388a84c807530b68380dd Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 30 Mar 2020 04:56:39 -0400 Subject: [PATCH 09/10] docs(eslint-plugin): add missing invalid-void link to ROADMAP.md (#1816) --- packages/eslint-plugin/ROADMAP.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/eslint-plugin/ROADMAP.md b/packages/eslint-plugin/ROADMAP.md index 32eb363609c6..7ca8048769be 100644 --- a/packages/eslint-plugin/ROADMAP.md +++ b/packages/eslint-plugin/ROADMAP.md @@ -338,6 +338,7 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint- [`adjacent-overload-signatures`]: https://palantir.github.io/tslint/rules/adjacent-overload-signatures [`ban-ts-ignore`]: https://palantir.github.io/tslint/rules/ban-ts-ignore/ [`ban-types`]: https://palantir.github.io/tslint/rules/ban-types +[`invalid-void`]: https://palantir.github.io/tslint/rules/invalid-void [`member-access`]: https://palantir.github.io/tslint/rules/member-access [`member-ordering`]: https://palantir.github.io/tslint/rules/member-ordering [`no-any`]: https://palantir.github.io/tslint/rules/no-any From 151f89b007d3474a4d9b572128388ae4cb3595f7 Mon Sep 17 00:00:00 2001 From: James Henry Date: Mon, 30 Mar 2020 17:01:55 +0000 Subject: [PATCH 10/10] chore: publish v2.26.0 --- CHANGELOG.md | 19 +++++++++++++++++++ lerna.json | 2 +- packages/eslint-plugin-internal/CHANGELOG.md | 8 ++++++++ packages/eslint-plugin-internal/package.json | 4 ++-- packages/eslint-plugin-tslint/CHANGELOG.md | 11 +++++++++++ packages/eslint-plugin-tslint/package.json | 6 +++--- packages/eslint-plugin/CHANGELOG.md | 13 +++++++++++++ packages/eslint-plugin/package.json | 4 ++-- packages/experimental-utils/CHANGELOG.md | 11 +++++++++++ packages/experimental-utils/package.json | 4 ++-- packages/parser/CHANGELOG.md | 11 +++++++++++ packages/parser/package.json | 8 ++++---- packages/shared-fixtures/CHANGELOG.md | 8 ++++++++ packages/shared-fixtures/package.json | 2 +- packages/typescript-estree/CHANGELOG.md | 11 +++++++++++ packages/typescript-estree/package.json | 4 ++-- 16 files changed, 109 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df5d48544946..c4f8ac29ce3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,25 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.26.0](https://github.com/typescript-eslint/typescript-eslint/compare/v2.25.0...v2.26.0) (2020-03-30) + + +### Bug Fixes + +* **eslint-plugin:** [no-explicit-any] error with ignoreRestArgs ([#1796](https://github.com/typescript-eslint/typescript-eslint/issues/1796)) ([638d84d](https://github.com/typescript-eslint/typescript-eslint/commit/638d84ddd77d07117b3ec7c5431f3b0e44b1995d)) +* **eslint-plugin:** [no-unsafe-call] allow import expressions ([#1800](https://github.com/typescript-eslint/typescript-eslint/issues/1800)) ([4fa7107](https://github.com/typescript-eslint/typescript-eslint/commit/4fa710754ecc412b65ac3864fe0c7857c254ac1b)) +* **eslint-plugin:** [no-unsafe-return] error with