Skip to content

[eslint-config] Update TypeScript/ESLint Utilities and Refactor Linting #4883

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
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
4 changes: 2 additions & 2 deletions build-tests/eslint-7-11-test/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ require('local-node-rig/profiles/default/includes/eslint/patch/custom-config-pac

module.exports = {
extends: [
'local-node-rig/profiles/default/includes/eslint/profile/node-trusted-tool',
'local-node-rig/profiles/default/includes/eslint/mixins/friendly-locals'
'@rushstack/eslint-config/profile/node-trusted-tool',
'@rushstack/eslint-config/mixins/friendly-locals'
],
parserOptions: { tsconfigRootDir: __dirname },

Expand Down
3 changes: 2 additions & 1 deletion build-tests/eslint-7-11-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
"_phase:build": "heft run --only build -- --clean"
},
"devDependencies": {
"@rushstack/eslint-config": "3.7.0",
"@rushstack/heft": "workspace:*",
"local-node-rig": "workspace:*",
"@types/node": "18.17.15",
"@typescript-eslint/parser": "~6.19.0",
"eslint": "7.11.0",
"local-node-rig": "workspace:*",
"typescript": "~5.4.2"
}
}
4 changes: 2 additions & 2 deletions build-tests/eslint-7-7-test/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ require('local-node-rig/profiles/default/includes/eslint/patch/custom-config-pac

module.exports = {
extends: [
'local-node-rig/profiles/default/includes/eslint/profile/node-trusted-tool',
'local-node-rig/profiles/default/includes/eslint/mixins/friendly-locals'
'@rushstack/eslint-config/profile/node-trusted-tool',
'@rushstack/eslint-config/mixins/friendly-locals'
],
parserOptions: { tsconfigRootDir: __dirname },

Expand Down
3 changes: 2 additions & 1 deletion build-tests/eslint-7-7-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
"_phase:build": "heft run --only build -- --clean"
},
"devDependencies": {
"@rushstack/eslint-config": "3.7.0",
"@rushstack/heft": "workspace:*",
"local-node-rig": "workspace:*",
"@types/node": "18.17.15",
"@typescript-eslint/parser": "~6.19.0",
"eslint": "7.7.0",
"local-node-rig": "workspace:*",
"typescript": "~5.4.2"
}
}
4 changes: 2 additions & 2 deletions build-tests/eslint-7-test/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ require('local-node-rig/profiles/default/includes/eslint/patch/custom-config-pac

module.exports = {
extends: [
'local-node-rig/profiles/default/includes/eslint/profile/node-trusted-tool',
'local-node-rig/profiles/default/includes/eslint/mixins/friendly-locals'
'@rushstack/eslint-config/profile/node-trusted-tool',
'@rushstack/eslint-config/mixins/friendly-locals'
],
parserOptions: { tsconfigRootDir: __dirname },

Expand Down
3 changes: 2 additions & 1 deletion build-tests/eslint-7-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
"_phase:build": "heft run --only build -- --clean"
},
"devDependencies": {
"@rushstack/eslint-config": "3.7.0",
"@rushstack/heft": "workspace:*",
"local-node-rig": "workspace:*",
"@types/node": "18.17.15",
"@typescript-eslint/parser": "~6.19.0",
"eslint": "~7.30.0",
"local-node-rig": "workspace:*",
"typescript": "~5.4.2"
}
}
2 changes: 1 addition & 1 deletion build-tests/eslint-8-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"@rushstack/heft": "workspace:*",
"local-node-rig": "workspace:*",
"@types/node": "18.17.15",
"@typescript-eslint/parser": "~6.19.0",
"@typescript-eslint/parser": "~8.1.0",
"eslint": "~8.57.0",
"typescript": "~5.4.2"
}
Expand Down
104 changes: 104 additions & 0 deletions build-tests/eslint-bulk-suppressions-test-legacy/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const { FileSystem, Executable, Text, Import } = require('@rushstack/node-core-library');
const path = require('path');
const {
ESLINT_PACKAGE_NAME_ENV_VAR_NAME
} = require('@rushstack/eslint-patch/lib/eslint-bulk-suppressions/constants');

const eslintBulkStartPath = Import.resolveModule({
modulePath: '@rushstack/eslint-bulk/lib/start',
baseFolderPath: __dirname
});

function tryLoadSuppressions(suppressionsJsonPath) {
try {
return Text.convertToLf(FileSystem.readFile(suppressionsJsonPath)).trim();
} catch (e) {
if (FileSystem.isNotExistError(e)) {
return '';
} else {
throw e;
}
}
}

const RUN_FOLDER_PATHS = ['client', 'server'];
const ESLINT_PACKAGE_NAMES = ['eslint', 'eslint-oldest'];

const updateFilePaths = new Set();

for (const runFolderPath of RUN_FOLDER_PATHS) {
const folderPath = `${__dirname}/${runFolderPath}`;
const suppressionsJsonPath = `${folderPath}/.eslint-bulk-suppressions.json`;

const folderItems = FileSystem.readFolderItems(folderPath);
for (const folderItem of folderItems) {
if (folderItem.isFile() && folderItem.name.match(/^\.eslint\-bulk\-suppressions\-[\d.]+\.json$/)) {
const fullPath = `${folderPath}/${folderItem.name}`;
updateFilePaths.add(fullPath);
}
}

for (const eslintPackageName of ESLINT_PACKAGE_NAMES) {
const { version: eslintVersion } = require(`${eslintPackageName}/package.json`);

const startLoggingMessage = `-- Running eslint-bulk-suppressions for eslint@${eslintVersion} in ${runFolderPath} --`;
console.log(startLoggingMessage);
const referenceSuppressionsJsonPath = `${folderPath}/.eslint-bulk-suppressions-${eslintVersion}.json`;
const existingSuppressions = tryLoadSuppressions(referenceSuppressionsJsonPath);

// The eslint-bulk-suppressions patch expects to find "eslint" in the shell PATH. To ensure deterministic
// test behavior, we need to designate an explicit "node_modules/.bin" folder.
//
// Use the ".bin" folder from @rushstack/eslint-patch as a workaround for this PNPM bug:
// https://github.com/pnpm/pnpm/issues/7833
const dependencyBinFolder = path.join(
__dirname,
'node_modules',
'@rushstack',
'eslint-patch',
'node_modules',
'.bin'
);
const shellPathWithEslint = `${dependencyBinFolder}${path.delimiter}${process.env['PATH']}`;

const executableResult = Executable.spawnSync(
process.argv0,
[eslintBulkStartPath, 'suppress', '--all', 'src'],
{
currentWorkingDirectory: folderPath,
environment: {
...process.env,
PATH: shellPathWithEslint,
[ESLINT_PACKAGE_NAME_ENV_VAR_NAME]: eslintPackageName
}
}
);

if (executableResult.status !== 0) {
console.error('The eslint-bulk-suppressions command failed.');
console.error('STDOUT:');
console.error(executableResult.stdout.toString());
console.error('STDERR:');
console.error(executableResult.stderr.toString());
process.exit(1);
}

const newSuppressions = tryLoadSuppressions(suppressionsJsonPath);
if (newSuppressions === existingSuppressions) {
updateFilePaths.delete(referenceSuppressionsJsonPath);
} else {
updateFilePaths.add(referenceSuppressionsJsonPath);
FileSystem.writeFile(referenceSuppressionsJsonPath, newSuppressions);
}

FileSystem.deleteFile(suppressionsJsonPath);
}
}

if (updateFilePaths.size > 0) {
for (const updateFilePath of updateFilePaths) {
console.log(`The suppressions file "${updateFilePath}" was updated and must be committed to git.`);
}

process.exit(1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

// This is a workaround for https://github.com/eslint/eslint/issues/3458
require('local-node-rig/profiles/default/includes/eslint/patch/modern-module-resolution');
// This is a workaround for https://github.com/microsoft/rushstack/issues/3021
require('local-node-rig/profiles/default/includes/eslint/patch/custom-config-package-names');
require('local-node-rig/profiles/default/includes/eslint/patch/eslint-bulk-suppressions');

module.exports = {
extends: [
'@rushstack/eslint-config/profile/node-trusted-tool',
'@rushstack/eslint-config/mixins/friendly-locals'
],
ignorePatterns: ['.eslintrc.js'],

overrides: [
/**
* Override the parser from @rushstack/eslint-config. Since the config is coming
* from the workspace instead of the external NPM package, the versions of ESLint
* and TypeScript that the config consumes will be resolved from the devDependencies
* of the config instead of from the eslint-8-test package. Overriding the parser
* ensures that the these dependencies come from the eslint-8-test package. See:
* https://github.com/microsoft/rushstack/issues/3021
*/
{
files: ['**/*.ts', '**/*.tsx'],
parser: '@typescript-eslint/parser',
parserOptions: { project: '../tsconfig.json', tsconfigRootDir: __dirname }
}
]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

/* Top-level scope code samples */
// scopeId: '.'
let exampleString: string = 5 + '';

const exampleObject = {
exampleString: exampleString
};

/* Function scope code samples */
export function exampleFunction() {
const {}: Object = exampleObject;

// scopeId: '.exampleFunction'
!!!exampleString as Boolean;
}

// scope: '.ArrowFunctionExpression',
export const x = () => {},
// scopeId: '.y'
y = () => {},
// scopeId: '.z'
z = () => {};

/* Class scope code samples */
export class ExampleClass {
// scopeId: '.ExampleClass'
exampleClassProperty: String = exampleString + '4';

exampleMethod() {
// scopeId: '.exampleClass.exampleMethod'
var exampleVar;
return exampleVar;
}
}

/* Variable and anonymous constructs code samples */
export const exampleArrowFunction = () => {
const exampleBoolean = true;
if (exampleBoolean) {
}

exampleObject['exampleString'];
};

export const exampleAnonymousClass = class {
exampleClassProperty = 'x' + 'y';

// scopeId: '.exampleAnonymousClass.constructor'
constructor() {}

set exampleSetGet(val: string) {
// scopeId: '.exampleAnonymousClass.exampleSetGet'
let exampleVariable: Number = 1;
this.exampleClassProperty = val + exampleVariable;
}

get exampleSetGet() {
// scopeId: '.exampleAnonymousClass.exampleSetGet'
return this.exampleClassProperty as String as string;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
// The "rig.json" file directs tools to look for their config files in an external package.
// Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",

"rigPackageName": "local-node-rig"
}
21 changes: 21 additions & 0 deletions build-tests/eslint-bulk-suppressions-test-legacy/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "eslint-bulk-suppressions-test-legacy",
"description": "Sample code to test eslint bulk suppressions for versions of eslint < 8.57.0",
"version": "1.0.0",
"private": true,
"scripts": {
"_phase:build": "node build.js"
},
"devDependencies": {
"@rushstack/eslint-bulk": "workspace:*",
"@rushstack/eslint-config": "3.7.0",
"@rushstack/eslint-patch": "workspace:*",
"@rushstack/heft": "workspace:*",
"@rushstack/node-core-library": "workspace:*",
"@typescript-eslint/parser": "~6.19.0",
"eslint": "8.23.1",
"eslint-oldest": "npm:eslint@8.6.0",
"local-node-rig": "workspace:*",
"typescript": "~5.4.2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

// This is a workaround for https://github.com/eslint/eslint/issues/3458
require('local-node-rig/profiles/default/includes/eslint/patch/modern-module-resolution');
// This is a workaround for https://github.com/microsoft/rushstack/issues/3021
require('local-node-rig/profiles/default/includes/eslint/patch/custom-config-package-names');
require('local-node-rig/profiles/default/includes/eslint/patch/eslint-bulk-suppressions');

module.exports = {
extends: [
'@rushstack/eslint-config/profile/node-trusted-tool',
'@rushstack/eslint-config/mixins/friendly-locals'
],
ignorePatterns: ['.eslintrc.js'],

overrides: [
/**
* Override the parser from @rushstack/eslint-config. Since the config is coming
* from the workspace instead of the external NPM package, the versions of ESLint
* and TypeScript that the config consumes will be resolved from the devDependencies
* of the config instead of from the eslint-8-test package. Overriding the parser
* ensures that the these dependencies come from the eslint-8-test package. See:
* https://github.com/microsoft/rushstack/issues/3021
*/
{
files: ['**/*.ts', '**/*.tsx'],
parser: '@typescript-eslint/parser',
parserOptions: { project: '../tsconfig.json', tsconfigRootDir: __dirname }
}
]
};
Loading
Loading