diff --git a/CHANGELOG.md b/CHANGELOG.md index f6d5003..5257dd1 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.2.0] - 2022-10-17 + +### Added + +- Add feature to exclude files from strict check based on `exclude` config property + ## [2.1.0] - 2022-10-14 ### Added diff --git a/README.md b/README.md index 71034ec..b8c8300 100644 --- a/README.md +++ b/README.md @@ -60,9 +60,9 @@ comment. To make these files strict too, just remove its' ignore comments. ## Configuration -Plugin takes one extra non-mandatory argument `paths` that is an array of relative or absolute paths -of directories that should be included. To add strict mode to files from ignored paths you can -insert `//@ts-strict` comment. +Plugin takes extra, non-mandatory arguments `paths` and `exlude`. Both of them take an array of +relative or absolute paths that should be included (property `paths`) or excluded (property +`exclude`). To add strict mode to files from ignored paths you can insert `//@ts-strict` comment. ```json { @@ -75,6 +75,10 @@ insert `//@ts-strict` comment. "paths": [ "./src", "/absolute/path/to/source/" + ], + "exclude": [ + "./src/tests", + "./src/fileToExclude.ts" ] } ] diff --git a/package.json b/package.json index 8cf1c42..b07949a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-strict-plugin", - "version": "2.1.0", + "version": "2.2.0", "description": "Typescript tools that help with migration to the strict mode", "author": "Allegro", "contributors": [ diff --git a/src/common/__tests__/isFileStrict.spec.ts b/src/common/__tests__/isFileStrict.spec.ts index ac6c4c8..a3b8024 100644 --- a/src/common/__tests__/isFileStrict.spec.ts +++ b/src/common/__tests__/isFileStrict.spec.ts @@ -41,6 +41,20 @@ describe('isFileStrict', () => { expect(result).toBe(true); }); + it('should return true when strict comment is present and file is excluded', () => { + // given + isCommentPresent.mockImplementation((comment) => comment === '@ts-strict'); + const config: Config = { + exclude: [filePath], + }; + + // when + const result = isFileStrict({ filePath, isCommentPresent, config }); + + // then + expect(result).toBe(true); + }); + it('should return false when both strict and ignore update-strict-comments are present', () => { // given isCommentPresent.mockImplementation( @@ -110,6 +124,20 @@ describe('isFileStrict', () => { expect(result).toBe(false); }); + it('should return false when file is on path and in exclude', () => { + // given + const config: Config = { + paths: ['otherFilePath', filePath, 'otherFilePath'], + exclude: [filePath], + }; + + // when + const result = isFileStrict({ filePath, isCommentPresent, config }); + + // then + expect(result).toBe(false); + }); + it('should return true when path config is empty', () => { // given const config: Config = { @@ -122,4 +150,32 @@ describe('isFileStrict', () => { // then expect(result).toBe(true); }); + + it('should return false when path config is empty and file is excluded', () => { + // given + const config: Config = { + paths: [], + exclude: [filePath], + }; + + // when + const result = isFileStrict({ filePath, isCommentPresent, config }); + + // then + expect(result).toBe(false); + }); + + it('should return true when path config is empty and different file is excluded (check for false-positive)', () => { + // given + const config: Config = { + paths: [], + exclude: ['otherFile'], + }; + + // when + const result = isFileStrict({ filePath, isCommentPresent, config }); + + // then + expect(result).toBe(true); + }); }); diff --git a/src/common/isFileExcludedByPath.ts b/src/common/isFileExcludedByPath.ts new file mode 100644 index 0000000..4153288 --- /dev/null +++ b/src/common/isFileExcludedByPath.ts @@ -0,0 +1,25 @@ +import { isFileOnPath } from './isFileOnPath'; + +interface IsFileExcludedByPathParams { + filePath: string; + projectPath?: string; + configExclude?: string[]; +} + +export function isFileExcludedByPath({ + filePath, + projectPath, + configExclude, +}: IsFileExcludedByPathParams): boolean { + if (configExclude === undefined) { + return false; + } + + return configExclude?.some((path) => + isFileOnPath({ + filePath, + targetPath: path, + projectPath, + }), + ); +} diff --git a/src/common/isFileStrict.ts b/src/common/isFileStrict.ts index 9ed08a6..f336cfa 100644 --- a/src/common/isFileStrict.ts +++ b/src/common/isFileStrict.ts @@ -1,6 +1,7 @@ import { Config } from './types'; import { isFileStrictByPath } from './isFileStrictByPath'; import { TS_STRICT_COMMENT, TS_STRICT_IGNORE_COMMENT } from './constants'; +import { isFileExcludedByPath } from './isFileExcludedByPath'; type IsFileStrictConfig = { filePath: string; @@ -24,6 +25,18 @@ export function isFileStrict({ return true; } + const configExclude = config?.exclude ?? []; + + if ( + isFileExcludedByPath({ + filePath, + configExclude, + projectPath, + }) + ) { + return false; + } + const configPaths = config?.paths ?? []; const fileStrictByPath = isFileStrictByPath({ filePath, configPaths, projectPath }); diff --git a/src/common/types.ts b/src/common/types.ts index 08fae91..1b4e16b 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -1,3 +1,4 @@ export interface Config { paths?: string[]; + exclude?: string[]; }