diff --git a/CHANGELOG.md b/CHANGELOG.md index b988875..80c5b4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.5.0] - 2025-11-18 + +### Added + +- Add script `check-strict-comments` to remove `//@ts-strict-ignore` comments on files already strict + ## [2.4.1] - 2024-04-09 ### Fixed diff --git a/README.md b/README.md index 25140fa..80c8c07 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,14 @@ just need to run: update-strict-comments ``` +## Check for files already strict and remove `//@ts-strict-ignore` comments + +When working on a large project, files can become strict without the authors noticing. Unless someone removes the `//@ts-strict-ignore` comment, the file will remain non-strict longer than necessary. To clean up such files and see the actual progress you can run: + +``` +check-strict-comments +``` + ## VSCode support VSCode supports this plugin out of the box. However, sometimes it can use its own typescript version diff --git a/package-lock.json b/package-lock.json index a168dc7..c15ed92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-strict-plugin", - "version": "2.4.3", + "version": "2.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-strict-plugin", - "version": "2.4.3", + "version": "2.5.0", "license": "MIT", "dependencies": { "chalk": "^3.0.0", @@ -16,6 +16,7 @@ "yargs": "^16.2.0" }, "bin": { + "check-strict-comments": "dist/cli/check-strict-comments/index.js", "tsc-strict": "dist/cli/tsc-strict/index.js", "update-strict-comments": "dist/cli/update-strict-comments/index.js" }, @@ -94,6 +95,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", "dev": true, + "peer": true, "dependencies": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -2576,7 +2578,8 @@ "version": "14.18.63", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@types/ora": { "version": "3.2.0", @@ -2706,6 +2709,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", "integrity": "sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.7.3", "@typescript-eslint/types": "6.7.3", @@ -2950,6 +2954,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3352,6 +3357,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001587", "electron-to-chromium": "^1.4.668", @@ -3845,6 +3851,7 @@ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dev": true, + "peer": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -3887,6 +3894,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4955,6 +4963,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -7149,6 +7158,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", "dev": true, + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -8044,6 +8054,7 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", "dev": true, + "peer": true, "dependencies": { "@cspotcode/source-map-support": "0.7.0", "@tsconfig/node10": "^1.0.7", @@ -8124,6 +8135,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 35b77a1..cff26cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-strict-plugin", - "version": "2.4.4", + "version": "2.5.0", "description": "Typescript tools that help with migration to the strict mode", "author": "Allegro", "contributors": [ @@ -22,7 +22,8 @@ "license": "MIT", "bin": { "tsc-strict": "dist/cli/tsc-strict/index.js", - "update-strict-comments": "dist/cli/update-strict-comments/index.js" + "update-strict-comments": "dist/cli/update-strict-comments/index.js", + "check-strict-comments": "dist/cli/check-strict-comments/index.js" }, "main": "dist/plugin/index.js", "private": false, diff --git a/sample-project/package-lock.json b/sample-project/package-lock.json index 9abe84d..bfc5860 100644 --- a/sample-project/package-lock.json +++ b/sample-project/package-lock.json @@ -15,17 +15,19 @@ } }, "..": { - "version": "2.2.0", + "version": "2.5.0", "integrity": "sha512-XZKE7g88LEzbAm1ch60rp5pHZ8is7snW3Sfx1b8a66xahzq+438VUPSCulbpqE0HnPyt9VS3mY0gIHxiCzaOig==", "dev": true, "license": "MIT", "dependencies": { "chalk": "^3.0.0", "execa": "^4.0.0", + "minimatch": "^9.0.3", "ora": "^5.4.1", "yargs": "^16.2.0" }, "bin": { + "check-strict-comments": "dist/cli/check-strict-comments/index.js", "tsc-strict": "dist/cli/tsc-strict/index.js", "update-strict-comments": "dist/cli/update-strict-comments/index.js" }, @@ -36,21 +38,22 @@ "@types/jest": "27.4.0", "@types/node": "^14.14.35", "@types/ora": "^3.2.0", - "@typescript-eslint/eslint-plugin": "6.7.2", - "@typescript-eslint/parser": "6.7.2", - "eslint": "7.28.0", - "eslint-config-prettier": "8.3.0", - "eslint-plugin-prettier": "3.4.0", + "@typescript-eslint/eslint-plugin": "6.7.3", + "@typescript-eslint/parser": "6.7.3", + "eslint": "8.50.0", + "eslint-config-prettier": "9.0.0", + "eslint-plugin-prettier": "5.0.0", "glob": "^7.1.6", "husky": "4.2.3", - "jest": "27.4.7", + "jest": "^29.7.0", "lint-staged": "^10.5.4", - "prettier": "2.3.1", + "prettier": "3.0.3", "pretty-quick": "3.1.0", "tmp-promise": "2.0.2", - "ts-jest": "27.1.2", + "ts-jest": "^29.1.2", "ts-node": "10.4.0", - "typescript": "5.2.2", + "typescript": "^5.4.5", + "typescript-strict-plugin": "file:./", "which-module": "^2.0.0" } }, @@ -8863,24 +8866,26 @@ "@types/jest": "27.4.0", "@types/node": "^14.14.35", "@types/ora": "^3.2.0", - "@typescript-eslint/eslint-plugin": "6.7.2", - "@typescript-eslint/parser": "6.7.2", + "@typescript-eslint/eslint-plugin": "6.7.3", + "@typescript-eslint/parser": "6.7.3", "chalk": "^3.0.0", - "eslint": "7.28.0", - "eslint-config-prettier": "8.3.0", - "eslint-plugin-prettier": "3.4.0", + "eslint": "8.50.0", + "eslint-config-prettier": "9.0.0", + "eslint-plugin-prettier": "5.0.0", "execa": "^4.0.0", "glob": "^7.1.6", "husky": "4.2.3", - "jest": "27.4.7", + "jest": "^29.7.0", "lint-staged": "^10.5.4", + "minimatch": "^9.0.3", "ora": "^5.4.1", - "prettier": "2.3.1", + "prettier": "3.0.3", "pretty-quick": "3.1.0", "tmp-promise": "2.0.2", - "ts-jest": "27.1.2", + "ts-jest": "^29.1.2", "ts-node": "10.4.0", - "typescript": "5.2.2", + "typescript": "^5.4.5", + "typescript-strict-plugin": "file:", "which-module": "^2.0.0", "yargs": "^16.2.0" }, diff --git a/sample-project/src/alreadyStrict.ts b/sample-project/src/alreadyStrict.ts new file mode 100644 index 0000000..a4ef21d --- /dev/null +++ b/sample-project/src/alreadyStrict.ts @@ -0,0 +1,21 @@ +// @ts-strict-ignore +export {}; // make this file a module to avoid global redeclaration errors + +interface TestType { + bar: string; +} + +const getFoo = (): TestType | undefined => { + // Simulate fetching or computing the value + return Math.random() > 0.5 ? { bar: 'value from getFoo' } : undefined; +} + +const foo: TestType | undefined = getFoo(); + +const isTestType = (obj: unknown): obj is TestType => { + if (obj == null || typeof obj !== 'object') return false; + if (!Object.prototype.hasOwnProperty.call(obj, 'bar')) return false; + return typeof (obj as Record).bar === 'string'; +} + +const barValue: string = isTestType(foo) ? foo.bar : 'some default value'; \ No newline at end of file diff --git a/sample-project/src/notStrict.ts b/sample-project/src/notStrict.ts new file mode 100644 index 0000000..31bd752 --- /dev/null +++ b/sample-project/src/notStrict.ts @@ -0,0 +1,15 @@ +// @ts-strict-ignore +export {}; // make this file a module to avoid global redeclaration errors + +interface TestType { + bar: string; +} + +const getFoo = (): TestType | undefined => { + // Simulate fetching or computing the value + return Math.random() > 0.5 ? { bar: 'value from getFoo' } : undefined; +} + +const foo: TestType | undefined = getFoo(); + +const barValue: string = foo.bar; \ No newline at end of file diff --git a/src/cli/update-strict-comments/__tests__/commentOperations.spec.ts b/src/cli/__tests__/commentOperations.spec.ts similarity index 63% rename from src/cli/update-strict-comments/__tests__/commentOperations.spec.ts rename to src/cli/__tests__/commentOperations.spec.ts index bc3a42b..5b461d4 100644 --- a/src/cli/update-strict-comments/__tests__/commentOperations.spec.ts +++ b/src/cli/__tests__/commentOperations.spec.ts @@ -1,6 +1,10 @@ import { mocked } from 'jest-mock'; import { readFileSync, writeFileSync } from 'fs'; -import { insertIgnoreComment, removeStrictComment } from '../commentOperations'; +import { + insertIgnoreComment, + removeIgnoreComment, + removeStrictComment, +} from '../commentOperations'; jest.mock('fs', () => ({ readFileSync: jest.fn(), @@ -27,6 +31,34 @@ describe('insertIgnoreComment', () => { }); }); +describe('removeIgnoreComment', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should remove comment', () => { + // given + readFileSyncMock.mockReturnValue('// @ts-strict-ignore\nconst x = 0;'); + + // when + removeIgnoreComment('file.ts'); + + // then + expect(writeFileSyncMock).toBeCalledWith('file.ts', 'const x = 0;'); + }); + + it('should not change file content without strict comment', () => { + // given + readFileSyncMock.mockReturnValue('const x = 0;'); + + // when + removeIgnoreComment('file.ts'); + + // then + expect(writeFileSyncMock).not.toBeCalled(); + }); +}); + describe('removeStrictComment', () => { beforeEach(() => { jest.clearAllMocks(); diff --git a/src/cli/check-strict-comments/__tests__/index.spec.ts b/src/cli/check-strict-comments/__tests__/index.spec.ts new file mode 100644 index 0000000..93d892e --- /dev/null +++ b/src/cli/check-strict-comments/__tests__/index.spec.ts @@ -0,0 +1,121 @@ +import { getPluginConfig } from '../../getPluginConfig'; +import { getFilesCheckedByTs, getStrictFilePaths } from '../../findStrictFiles'; +import { isWorkspaceClean } from '../isWorkspaceClean'; +import { insertIgnoreComment, removeIgnoreComment } from '../../commentOperations'; +import { getFilePathsWithErrors } from '../../getFilePaths'; +import { run } from '../index'; + +jest.mock('../isWorkspaceClean', () => ({ + isWorkspaceClean: jest.fn(), +})); + +jest.mock('../../getPluginConfig', () => ({ + getPluginConfig: jest.fn(), +})); + +jest.mock('../../findStrictFiles', () => ({ + getFilesCheckedByTs: jest.fn(), + getStrictFilePaths: jest.fn(), +})); + +jest.mock('../../commentOperations', () => ({ + insertIgnoreComment: jest.fn(), + removeIgnoreComment: jest.fn(), +})); + +jest.mock('../../getFilePaths', () => ({ + getFilePathsWithErrors: jest.fn(), +})); + +const isWorkspaceCleanMock = jest.mocked(isWorkspaceClean); +const getPluginConfigMock = jest.mocked(getPluginConfig); + +const getFilesCheckedByTsMock = jest.mocked(getFilesCheckedByTs); +const getStrictFilePathsMock = jest.mocked(getStrictFilePaths); +const getFilePathsWithErrorsMock = jest.mocked(getFilePathsWithErrors); + +const removeIgnoreCommentMock = jest.mocked(removeIgnoreComment); +const insertIgnoreCommentMock = jest.mocked(insertIgnoreComment); + +jest.spyOn(process, 'exit').mockImplementation(); +jest.spyOn(console, 'log').mockImplementation(); + +describe('check-strict-comments root', () => { + beforeEach(() => { + jest.clearAllMocks(); + + isWorkspaceCleanMock.mockResolvedValue(true); + getPluginConfigMock.mockResolvedValue({}); + + removeIgnoreCommentMock.mockImplementation(() => {}); + insertIgnoreCommentMock.mockImplementation(() => {}); + }); + + it('should display working directory not clean error', async () => { + // given + isWorkspaceCleanMock.mockResolvedValue(false); + + // when + await run(); + + // then + expect(console.log).toHaveBeenCalledWith( + expect.stringMatching( + /Your working directory is not clean! Please commit or stash your changes before trying again/i, + ), + ); + expect(process.exit).toHaveBeenCalledWith(1); + }); + + it('should display no config error', async () => { + // given + getPluginConfigMock.mockResolvedValue(undefined); + + // when + await run(); + + // then + expect(console.log).toHaveBeenCalledWith( + expect.stringMatching(/typescript-strict-plugin isn't configured in tsconfig.json/i), + ); + expect(process.exit).toHaveBeenCalledWith(1); + }); + + it('should display the correct numbers with already strict file', async () => { + // given + getFilesCheckedByTsMock.mockResolvedValue(['1.ts', '2.ts', '3.ts', '4.ts', '5.ts']); + getStrictFilePathsMock.mockReturnValue(['2.ts', '3.ts']); + getFilePathsWithErrorsMock.mockResolvedValue(['1.ts', '4.ts']); // 5.ts is the already strict one + + // when + await run(); + + // then + expect(console.log).toHaveBeenCalledWith(expect.stringMatching(/# files in project:/i), 5); + expect(console.log).toHaveBeenCalledWith(expect.stringMatching(/# files already strict:/i), 2); + expect(console.log).toHaveBeenCalledWith(expect.stringMatching(/# files not strict:/i), 3); + expect(console.log).toHaveBeenCalledWith(expect.stringMatching(/# files with errors:/i), 2); + expect(console.log).toHaveBeenCalledWith( + expect.stringMatching(/Removed strict ignore comments in 1 file/i), + ); + }); + + it('should display the correct numbers without already strict file', async () => { + // given + getFilesCheckedByTsMock.mockResolvedValue(['1.ts', '2.ts', '3.ts', '4.ts']); + getStrictFilePathsMock.mockReturnValue(['2.ts', '3.ts']); + getFilePathsWithErrorsMock.mockResolvedValue(['1.ts', '4.ts']); + + // when + await run(); + + // then + expect(console.log).toHaveBeenCalledWith(expect.stringMatching(/# files in project:/i), 4); + expect(console.log).toHaveBeenCalledWith(expect.stringMatching(/# files already strict:/i), 2); + expect(console.log).toHaveBeenCalledWith(expect.stringMatching(/# files not strict:/i), 2); + expect(console.log).toHaveBeenCalledWith(expect.stringMatching(/# files with errors:/i), 2); + expect(console.log).toHaveBeenCalledWith( + expect.stringMatching(/No strict ignore comments changed/i), + ); + }); +}); diff --git a/src/cli/check-strict-comments/index.ts b/src/cli/check-strict-comments/index.ts new file mode 100644 index 0000000..d242dab --- /dev/null +++ b/src/cli/check-strict-comments/index.ts @@ -0,0 +1,70 @@ +#!/usr/bin/env node + +import { getFilesCheckedByTs, getStrictFilePaths } from '../findStrictFiles'; +import chalk from 'chalk'; +import { waitWithSpinner } from '../waitWithSpinner'; +import { notConfiguredError } from '../errorMessages'; +import { getPluginConfig } from '../getPluginConfig'; +import { insertIgnoreComment, removeIgnoreComment } from '../commentOperations'; +import { getFilePathsWithErrors } from '../getFilePaths'; +import { isWorkspaceClean } from './isWorkspaceClean'; +import { pluralize } from '../../common/utils'; + +const printResult = (notStrictFilePaths: string[], filesWithErrors: string[]) => { + const numberOfIgnoreCommentsRemoved = notStrictFilePaths.length - filesWithErrors.length; + if (numberOfIgnoreCommentsRemoved > 0) { + console.log( + chalk.yellow( + `=> Removed strict ignore comments in ${numberOfIgnoreCommentsRemoved} ${pluralize( + 'file', + numberOfIgnoreCommentsRemoved, + )}`, + ), + ); + } else { + console.log(chalk.green('=> No strict ignore comments changed')); + } +}; + +export const run = async () => { + if (!(await waitWithSpinner(isWorkspaceClean, 'Checking if workspace is clean...'))) { + console.log( + chalk.red( + 'Your working directory is not clean! Please commit or stash your changes before trying again', + ), + ); + process.exit(1); + return; + } + + const pluginConfig = await getPluginConfig(); + + if (!pluginConfig) { + console.log(chalk.red(notConfiguredError)); + process.exit(1); + return; + } + + const allFilePaths = await waitWithSpinner( + getFilesCheckedByTs, + 'Looking for files checked by TS...', + ); + console.log('# files in project:\t', allFilePaths.length); + + const strictFilePaths = getStrictFilePaths(allFilePaths, pluginConfig); + console.log('# files already strict:\t', strictFilePaths.length); + + const notStrictFilePaths = allFilePaths.filter((el) => !strictFilePaths.includes(el)); + console.log('# files not strict:\t', notStrictFilePaths.length); + + notStrictFilePaths.forEach((filePath) => removeIgnoreComment(filePath)); + + const erroredFilePaths = await getFilePathsWithErrors(notStrictFilePaths); + console.log('# files with errors:\t', erroredFilePaths.length); + + erroredFilePaths.forEach((filePath) => insertIgnoreComment(filePath)); + + printResult(notStrictFilePaths, erroredFilePaths); +}; + +run(); diff --git a/src/cli/check-strict-comments/isWorkspaceClean.ts b/src/cli/check-strict-comments/isWorkspaceClean.ts new file mode 100644 index 0000000..5d0ec26 --- /dev/null +++ b/src/cli/check-strict-comments/isWorkspaceClean.ts @@ -0,0 +1,16 @@ +import { execFile } from 'child_process'; + +export const isWorkspaceClean = (): Promise => { + return new Promise((resolve) => { + let isWorkspaceClean = true; + const childProcess = execFile('git', ['status', '--porcelain'], { cwd: process.cwd() }); + + childProcess.stdout?.on('data', () => { + isWorkspaceClean = false; + }); + + childProcess.on('close', () => { + resolve(isWorkspaceClean); + }); + }); +}; diff --git a/src/cli/update-strict-comments/commentOperations.ts b/src/cli/commentOperations.ts similarity index 52% rename from src/cli/update-strict-comments/commentOperations.ts rename to src/cli/commentOperations.ts index 4f3891f..c79807f 100644 --- a/src/cli/update-strict-comments/commentOperations.ts +++ b/src/cli/commentOperations.ts @@ -1,22 +1,30 @@ import { readFileSync, writeFileSync } from 'fs'; -import { TS_STRICT_COMMENT, TS_STRICT_IGNORE_COMMENT } from '../../common/constants'; +import { TS_STRICT_COMMENT, TS_STRICT_IGNORE_COMMENT } from '../common/constants'; -export function insertIgnoreComment(filePath: string) { +export const insertIgnoreComment = (filePath: string) => { const fileContent = readFileSync(filePath, 'utf-8'); const data = '// ' + TS_STRICT_IGNORE_COMMENT + '\n' + fileContent; writeFileSync(filePath, data); -} +}; -export function removeStrictComment(filePath: string) { +const removeComment = (filePath: string, comment: string) => { const fileContent = readFileSync(filePath, 'utf-8'); const data = fileContent .split('\n') - .filter((line) => !line.includes(TS_STRICT_COMMENT)) + .filter((line) => !line.includes(comment)) .join('\n'); if (data !== fileContent) { writeFileSync(filePath, data); } -} +}; + +export const removeIgnoreComment = (filePath: string) => { + removeComment(filePath, TS_STRICT_IGNORE_COMMENT); +}; + +export const removeStrictComment = (filePath: string) => { + removeComment(filePath, TS_STRICT_COMMENT); +}; diff --git a/src/cli/findStrictFiles.ts b/src/cli/findStrictFiles.ts index cffa05f..0bca814 100644 --- a/src/cli/findStrictFiles.ts +++ b/src/cli/findStrictFiles.ts @@ -2,27 +2,30 @@ import { getPosixFilePath, isFile } from '../common/utils'; import * as typescript from './typescript/typescript'; import { CliStrictFileChecker } from './CliStrictFileChecker'; import { getPluginConfig } from './getPluginConfig'; +import { Config } from '../common/types'; export async function findStrictFiles(): Promise { const filesCheckedByTS = await getFilesCheckedByTs(); - const cliStrictFileChecker = new CliStrictFileChecker(); const pluginConfig = await getPluginConfig(); if (!pluginConfig) { return []; } - return filesCheckedByTS.filter((filePath) => - cliStrictFileChecker.isFileStrict(filePath, pluginConfig), - ); + return getStrictFilePaths(filesCheckedByTS, pluginConfig); } +export const getStrictFilePaths = (filePaths: string[], config: Config): string[] => { + const cliStrictFileChecker = new CliStrictFileChecker(); + return filePaths.filter((filePath) => cliStrictFileChecker.isFileStrict(filePath, config)); +}; + const filterOutNodeModulesFiles = (files: string[]): string[] => { return files.filter((filePath) => !filePath.includes('/node_modules/')); }; -async function getFilesCheckedByTs(): Promise { +export async function getFilesCheckedByTs(): Promise { const filesCheckedByTs = await typescript.compile(); const filePaths = filesCheckedByTs.split(/\r?\n/).filter(isFile).map(getPosixFilePath); diff --git a/src/cli/update-strict-comments/getFilePaths.ts b/src/cli/getFilePaths.ts similarity index 75% rename from src/cli/update-strict-comments/getFilePaths.ts rename to src/cli/getFilePaths.ts index 67e7bb1..d5c31a1 100644 --- a/src/cli/update-strict-comments/getFilePaths.ts +++ b/src/cli/getFilePaths.ts @@ -1,6 +1,6 @@ -import { isFileStrictByPath } from '../../common/isFileStrictByPath'; -import { getAbsolutePath } from '../../common/getAbsolutePath'; -import { findStrictErrors } from '../findStrictErrors'; +import { isFileStrictByPath } from '../common/isFileStrictByPath'; +import { getAbsolutePath } from '../common/getAbsolutePath'; +import { findStrictErrors } from './findStrictErrors'; export const getFilePathsWithErrors = async (allFilePaths: string[]) => { const errors = await findStrictErrors(allFilePaths); diff --git a/src/cli/update-strict-comments/__tests__/updateStrictComments.spec.ts b/src/cli/update-strict-comments/__tests__/updateStrictComments.spec.ts index f33468c..1fb8acb 100644 --- a/src/cli/update-strict-comments/__tests__/updateStrictComments.spec.ts +++ b/src/cli/update-strict-comments/__tests__/updateStrictComments.spec.ts @@ -1,14 +1,14 @@ import { mocked } from 'jest-mock'; import { isIgnoreCommentPresent, isStrictCommentPresent } from '../../isCommentPresent'; -import { getFilePathsWithErrors, getFilePathsOnPathWithoutErrors } from '../getFilePaths'; +import { getFilePathsWithErrors, getFilePathsOnPathWithoutErrors } from '../../getFilePaths'; import { updateStrictComments } from '../updateStrictComments'; -import { insertIgnoreComment, removeStrictComment } from '../commentOperations'; +import { insertIgnoreComment, removeStrictComment } from '../../commentOperations'; jest.mock('../../findStrictErrors', () => ({ findStrictErrors: jest.fn(), })); -jest.mock('../getFilePaths', () => ({ +jest.mock('../../getFilePaths', () => ({ getFilePathsWithErrors: jest.fn(), getFilePathsOnPathWithoutErrors: jest.fn(), })); @@ -18,7 +18,7 @@ jest.mock('../../isCommentPresent', () => ({ isIgnoreCommentPresent: jest.fn(), })); -jest.mock('../commentOperations', () => ({ +jest.mock('../../commentOperations', () => ({ removeStrictComment: jest.fn(), insertIgnoreComment: jest.fn(), })); diff --git a/src/cli/update-strict-comments/updateStrictComments.ts b/src/cli/update-strict-comments/updateStrictComments.ts index 44c0c40..06b19c0 100644 --- a/src/cli/update-strict-comments/updateStrictComments.ts +++ b/src/cli/update-strict-comments/updateStrictComments.ts @@ -1,7 +1,7 @@ -import { getFilePathsWithErrors, getFilePathsOnPathWithoutErrors } from './getFilePaths'; +import { getFilePathsWithErrors, getFilePathsOnPathWithoutErrors } from '../getFilePaths'; import { isIgnoreCommentPresent, isStrictCommentPresent } from '../isCommentPresent'; import { isFileStrictByPath } from '../../common/isFileStrictByPath'; -import { insertIgnoreComment, removeStrictComment } from './commentOperations'; +import { insertIgnoreComment, removeStrictComment } from '../commentOperations'; interface UpdateStrictCommentsResult { updatedFileCount: number;