Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat(typescript-estree): rename automaticSingleRunInference to disallowAutomaticSingleRunInference#8922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
12 commits
Select commitHold shift + click to select a range
5124835
feat(typescript-estree): disallowAutomaticSingleRunInference, off (fa…
JoshuaKGoldbergApr 15, 2024
400a6b0
Unnecessary Infinity cache lifetime too
JoshuaKGoldbergApr 15, 2024
0930620
disallowAutomaticSingleRunInference in RuleTester
JoshuaKGoldbergApr 15, 2024
8f398e3
Add more explicit disallowAutomaticSingleRunInference: true,s
JoshuaKGoldbergApr 15, 2024
1ed1c52
Fixed for parse.test.ts
JoshuaKGoldbergApr 15, 2024
2fb418b
Fixed persistentParse.test.ts and semanticInfo.test.ts
JoshuaKGoldbergApr 15, 2024
568489f
disallowAutomaticSingleRunInference in docs.test.ts
JoshuaKGoldbergApr 15, 2024
dd20f36
Reset plugin .shot files
JoshuaKGoldbergApr 15, 2024
52aa2db
Merge branch 'v8'
JoshuaKGoldbergApr 22, 2024
86f1a86
Fix unit tests for Windows
JoshuaKGoldbergApr 22, 2024
fa48c88
lint
JoshuaKGoldbergApr 22, 2024
da356bb
Merge branch 'v8' into single-run-inference-by-default
JoshuaKGoldbergApr 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletionsdocs/packages/Parser.mdx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -30,10 +30,10 @@ The following additional configuration options are available by specifying them

```ts
interface ParserOptions {
allowAutomaticSingleRunInference?: boolean;
cacheLifetime?: {
glob?: number | 'Infinity';
};
disallowAutomaticSingleRunInference?: boolean;
ecmaFeatures?: {
jsx?: boolean;
globalReturn?: boolean;
Expand All@@ -55,22 +55,23 @@ interface ParserOptions {
}
```

### `allowAutomaticSingleRunInference`
### `disallowAutomaticSingleRunInference`

> Default `process.env.TSESTREE_SINGLE_RUN` or `false`.
> Default `process.env.TSESTREE_SINGLE_RUN` or `true`.

Whether to use common heuristics to infer whether ESLint is being used as part of a single run (as opposed to `--fix` mode or in a persistent session such as an editor extension).
Whether to stop using common heuristics to infer whether ESLint is being used as part of a single run (as opposed to `--fix` mode or in a persistent session such as an editor extension).
In other words, typescript-eslint is faster by default, and this option disables an automatic performance optimization.

When typescript-eslint handles TypeScript Program management behind the scenes for [linting with type information](../getting-started/Typed_Linting.mdx), this distinction is important for performance.
There is significant overhead to managing TypeScript "Watch" Programs needed for the long-running use-case.
Being able to assume the single run case allows typescript-eslint to faster immutable Programs instead.

This setting's default value can be specified by setting a `TSESTREE_SINGLE_RUN` environment variable to `"false"` or `"true"`.
For example, `TSESTREE_SINGLE_RUN=true npx eslint .` willenable it.
For example, `TSESTREE_SINGLE_RUN=false npx eslint .` willdisable it.

:::tip
We've seen `allowAutomaticSingleRunInference` improve linting speed in CI by up to 10-20%.
Our plan is to [enable `allowAutomaticSingleRunInference` by defaultinan upcoming major version](https://github.com/typescript-eslint/typescript-eslint/issues/8121).
:::note
We recommend leaving this option off if possible.
We've seen allowing automatic single run inference improve linting speedinCI by up to 10-20%.
:::

### `cacheLifetime`
Expand All@@ -79,7 +80,7 @@ This option allows you to granularly control our internal cache expiry lengths.

You can specify the number of seconds as an integer number, or the string 'Infinity' if you never want the cache to expire.

By default cache entries will be evicted after 30 seconds, or will persist indefinitely if the parser infers that it is a single run (see [`allowAutomaticSingleRunInference`](#allowAutomaticSingleRunInference)).
By default cache entries will be evicted after 30 seconds, or will persist indefinitely if the parser infers that it is a single run (see [`disallowAutomaticSingleRunInference`](#disallowAutomaticSingleRunInference)).

### `ecmaFeatures`

Expand Down
71 changes: 38 additions & 33 deletionsdocs/packages/TypeScript_ESTree.mdx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -155,6 +155,44 @@ Parses the given string of code with the options provided and returns an ESTree-

```ts
interface ParseAndGenerateServicesOptions extends ParseOptions {
/**
* Granular control of the expiry lifetime of our internal caches.
* You can specify the number of seconds as an integer number, or the string
* 'Infinity' if you never want the cache to expire.
*
* By default cache entries will be evicted after 30 seconds, or will persist
* indefinitely if `disallowAutomaticSingleRunInference = false` AND the parser
* infers that it is a single run.
*/
cacheLifetime?: {
/**
* Glob resolution for `parserOptions.project` values.
*/
glob?: number | 'Infinity';
};

/**
* ESLint (and therefore typescript-eslint) is used in both "single run"/one-time contexts,
* such as an ESLint CLI invocation, and long-running sessions (such as continuous feedback
* on a file in an IDE).
*
* When typescript-eslint handles TypeScript Program management behind the scenes, this distinction
* is important because there is significant overhead to managing the so called Watch Programs
* needed for the long-running use-case.
*
* By default, we will use common heuristics to infer whether ESLint is being
* used as part of a single run. This option disables those heuristics, and
* therefore the performance optimizations gained by them.
*
* In other words, typescript-eslint is faster by default, and this option
* disables an automatic performance optimization.
*
* This setting's default value can be specified by setting a `TSESTREE_SINGLE_RUN`
* environment variable to `"false"` or `"true"`.
* Otherwise, the default value is `false`.
*/
disallowAutomaticSingleRunInference?: boolean;

/**
* Causes the parser to error if the TypeScript compiler returns any unexpected syntax/semantic errors.
*/
Expand DownExpand Up@@ -234,39 +272,6 @@ interface ParseAndGenerateServicesOptions extends ParseOptions {
* All linted files must be part of the provided program(s).
*/
programs?: Program[];

/**
* ESLint (and therefore typescript-eslint) is used in both "single run"/one-time contexts,
* such as an ESLint CLI invocation, and long-running sessions (such as continuous feedback
* on a file in an IDE).
*
* When typescript-eslint handles TypeScript Program management behind the scenes, this distinction
* is important because there is significant overhead to managing the so called Watch Programs
* needed for the long-running use-case.
*
* When allowAutomaticSingleRunInference is enabled, we will use common heuristics to infer
* whether or not ESLint is being used as part of a single run.
*
* This setting's default value can be specified by setting a `TSESTREE_SINGLE_RUN`
* environment variable to `"false"` or `"true"`.
*/
allowAutomaticSingleRunInference?: boolean;

/**
* Granular control of the expiry lifetime of our internal caches.
* You can specify the number of seconds as an integer number, or the string
* 'Infinity' if you never want the cache to expire.
*
* By default cache entries will be evicted after 30 seconds, or will persist
* indefinitely if `allowAutomaticSingleRunInference = true` AND the parser
* infers that it is a single run.
*/
cacheLifetime?: {
/**
* Glob resolution for `parserOptions.project` values.
*/
glob?: number | 'Infinity';
};
}

/**
Expand Down
6 changes: 0 additions & 6 deletionseslint.config.mjs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -76,12 +76,6 @@ export default tseslint.config(
...globals.node,
},
parserOptions: {
allowAutomaticSingleRunInference: true,
cacheLifetime: {
// we pretty well never create/change tsconfig structure - so no need to ever evict the cache
// in the rare case that we do - just need to manually restart their IDE.
glob: 'Infinity',
},
project: [
'tsconfig.json',
'packages/*/tsconfig.json',
Expand Down
1 change: 1 addition & 0 deletionspackages/eslint-plugin/tests/docs.test.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -391,6 +391,7 @@ describe('Validating rule docs', () => {
{
parser: '@typescript-eslint/parser',
parserOptions: {
disallowAutomaticSingleRunInference: true,
tsconfigRootDir: rootPath,
project: './tsconfig.json',
},
Expand Down
17 changes: 10 additions & 7 deletionspackages/rule-tester/src/RuleTester.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -214,13 +214,16 @@ export class RuleTester extends TestFramework {
if (test.parser === TYPESCRIPT_ESLINT_PARSER) {
throw new Error(DUPLICATE_PARSER_ERROR_MESSAGE);
}
if (!test.filename) {
return {
...test,
filename: getFilename(test.parserOptions),
};
}
return test;
return {
...test,
filename: test.filename || getFilename(test.parserOptions),
parserOptions: {
// Re-running simulates --fix mode, which implies an isolated program
// (i.e. parseAndGenerateServicesCalls[test.filename] > 1).
disallowAutomaticSingleRunInference: true,
...test.parserOptions,
},
};
};

const normalizedTests = {
Expand Down
1 change: 1 addition & 0 deletionspackages/type-utils/tests/TypeOrValueSpecifier.test.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -131,6 +131,7 @@ describe('TypeOrValueSpecifier', () => {
): void {
const rootDir = path.join(__dirname, 'fixtures');
const { ast, services } = parseForESLint(code, {
disallowAutomaticSingleRunInference: true,
project: './tsconfig.json',
filePath: path.join(rootDir, 'file.ts'),
tsconfigRootDir: rootDir,
Expand Down
1 change: 1 addition & 0 deletionspackages/type-utils/tests/isTypeReadonly.test.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,6 +16,7 @@ describe('isTypeReadonly', () => {
program: ts.Program;
} {
const { ast, services } = parseForESLint(code, {
disallowAutomaticSingleRunInference: true,
project: './tsconfig.json',
filePath: path.join(rootDir, 'file.ts'),
tsconfigRootDir: rootDir,
Expand Down
1 change: 1 addition & 0 deletionspackages/type-utils/tests/isUnsafeAssignment.test.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,7 @@ describe('isUnsafeAssignment', () => {
checker: ts.TypeChecker;
} {
const { ast, services } = parseForESLint(code, {
disallowAutomaticSingleRunInference: true,
project: './tsconfig.json',
filePath: path.join(rootDir, 'file.ts'),
tsconfigRootDir: rootDir,
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
import{ normalize } from 'path';
importpath from 'path';

import type { TSESTreeOptions } from '../parser-options';

Expand DownExpand Up@@ -33,8 +33,8 @@ export function inferSingleRun(options: TSESTreeOptions | undefined): boolean {
return true;
}

//Currently behind a flag while we gather real-world feedback
if (options.allowAutomaticSingleRunInference) {
//Ideally, we'd like to try to auto-detect CI or CLI usage that lets us infer a single CLI run.
if (!options.disallowAutomaticSingleRunInference) {
const possibleEslintBinPaths = [
'node_modules/.bin/eslint', // npm or yarn repo
'node_modules/eslint/bin/eslint.js', // pnpm repo
Expand All@@ -43,8 +43,8 @@ export function inferSingleRun(options: TSESTreeOptions | undefined): boolean {
// Default to single runs for CI processes. CI=true is set by most CI providers by default.
process.env.CI === 'true' ||
// This will be true for invocations such as `npx eslint ...` and `./node_modules/.bin/eslint ...`
possibleEslintBinPaths.some(path =>
process.argv[1].endsWith(normalize(path)),
possibleEslintBinPaths.some(binPath =>
process.argv[1].endsWith(path.normalize(binPath)),
)
) {
return true;
Expand Down
71 changes: 38 additions & 33 deletionspackages/typescript-estree/src/parser-options.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -117,6 +117,44 @@ export interface ProjectServiceOptions {
}

interface ParseAndGenerateServicesOptions extends ParseOptions {
/**
* Granular control of the expiry lifetime of our internal caches.
* You can specify the number of seconds as an integer number, or the string
* 'Infinity' if you never want the cache to expire.
*
* By default cache entries will be evicted after 30 seconds, or will persist
* indefinitely if `disallowAutomaticSingleRunInference = false` AND the parser
* infers that it is a single run.
*/
cacheLifetime?: {
/**
* Glob resolution for `parserOptions.project` values.
*/
glob?: CacheDurationSeconds;
};

/**
* ESLint (and therefore typescript-eslint) is used in both "single run"/one-time contexts,
* such as an ESLint CLI invocation, and long-running sessions (such as continuous feedback
* on a file in an IDE).
*
* When typescript-eslint handles TypeScript Program management behind the scenes, this distinction
* is important because there is significant overhead to managing the so called Watch Programs
* needed for the long-running use-case.
*
* By default, we will use common heuristics to infer whether ESLint is being
* used as part of a single run. This option disables those heuristics, and
* therefore the performance optimizations gained by them.
*
* In other words, typescript-eslint is faster by default, and this option
* disables an automatic performance optimization.
*
* This setting's default value can be specified by setting a `TSESTREE_SINGLE_RUN`
* environment variable to `"false"` or `"true"`.
* Otherwise, the default value is `false`.
*/
disallowAutomaticSingleRunInference?: boolean;

/**
* Causes the parser to error if the TypeScript compiler returns any unexpected syntax/semantic errors.
*/
Expand DownExpand Up@@ -196,39 +234,6 @@ interface ParseAndGenerateServicesOptions extends ParseOptions {
* All linted files must be part of the provided program(s).
*/
programs?: ts.Program[] | null;

/**
* ESLint (and therefore typescript-eslint) is used in both "single run"/one-time contexts,
* such as an ESLint CLI invocation, and long-running sessions (such as continuous feedback
* on a file in an IDE).
*
* When typescript-eslint handles TypeScript Program management behind the scenes, this distinction
* is important because there is significant overhead to managing the so called Watch Programs
* needed for the long-running use-case.
*
* When allowAutomaticSingleRunInference is enabled, we will use common heuristics to infer
* whether or not ESLint is being used as part of a single run.
*
* This setting's default value can be specified by setting a `TSESTREE_SINGLE_RUN`
* environment variable to `"false"` or `"true"`.
*/
allowAutomaticSingleRunInference?: boolean;

/**
* Granular control of the expiry lifetime of our internal caches.
* You can specify the number of seconds as an integer number, or the string
* 'Infinity' if you never want the cache to expire.
*
* By default cache entries will be evicted after 30 seconds, or will persist
* indefinitely if `allowAutomaticSingleRunInference = true` AND the parser
* infers that it is a single run.
*/
cacheLifetime?: {
/**
* Glob resolution for `parserOptions.project` values.
*/
glob?: CacheDurationSeconds;
};
}

export type TSESTreeOptions = ParseAndGenerateServicesOptions;
Expand Down
78 changes: 78 additions & 0 deletionspackages/typescript-estree/tests/lib/inferSingleRun.test.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
import path from 'path';

import { inferSingleRun } from '../../src/parseSettings/inferSingleRun';

describe('inferSingleRun', () => {
beforeEach(() => {
process.argv = ['node', 'eslint'];
process.env.CI = undefined;
process.env.TSESTREE_SINGLE_RUN = undefined;
});

it('returns false when options is undefined', () => {
const actual = inferSingleRun(undefined);

expect(actual).toBe(false);
});

it('returns false when options.project is null', () => {
const actual = inferSingleRun({ project: null });

expect(actual).toBe(false);
});

it('returns false when options.program is defined', () => {
const actual = inferSingleRun({ programs: [], project: true });

expect(actual).toBe(false);
});

it("returns false when TSESTREE_SINGLE_RUN is 'false'", () => {
process.env.TSESTREE_SINGLE_RUN = 'false';

const actual = inferSingleRun({ project: true });

expect(actual).toBe(false);
});

it("returns true when TSESTREE_SINGLE_RUN is 'true'", () => {
process.env.TSESTREE_SINGLE_RUN = 'true';

const actual = inferSingleRun({ project: true });

expect(actual).toBe(true);
});

it("returns true when CI is 'true'", () => {
process.env.CI = 'true';

const actual = inferSingleRun({ project: true });

expect(actual).toBe(true);
});

it('returns true when run by the ESLint CLI in npm/yarn', () => {
process.argv = ['node', path.normalize('node_modules/.bin/eslint')];

const actual = inferSingleRun({ project: true });

expect(actual).toBe(true);
});

it('returns true when run by the ESLint CLI in pnpm', () => {
process.argv = [
'node',
path.normalize('node_modules/eslint/bin/eslint.js'),
];

const actual = inferSingleRun({ project: true });

expect(actual).toBe(true);
});

it('returns false when none of the known cases are true', () => {
const actual = inferSingleRun({ project: true });

expect(actual).toBe(false);
});
});
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp