From 9758032fd2c30c8a8e5d385e0e298051cdaf62af Mon Sep 17 00:00:00 2001 From: Radiosterne Date: Thu, 13 Dec 2018 19:56:05 +0300 Subject: [PATCH 1/2] fix throwing error on first line diagnostic --- src/NormalizedMessage.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/NormalizedMessage.ts b/src/NormalizedMessage.ts index c9ef7625..950c7889 100644 --- a/src/NormalizedMessage.ts +++ b/src/NormalizedMessage.ts @@ -51,7 +51,7 @@ export class NormalizedMessage { let character: number | undefined; if (diagnostic.file) { file = diagnostic.file.fileName; - if (!diagnostic.start) { + if (typeof diagnostic.start === 'undefined') { throw new Error('Expected diagnostics to have start'); } const position = diagnostic.file.getLineAndCharacterOfPosition( @@ -92,7 +92,10 @@ export class NormalizedMessage { return new NormalizedMessage(json); } - public static compare(messageA: NormalizedMessage, messageB: NormalizedMessage) { + public static compare( + messageA: NormalizedMessage, + messageB: NormalizedMessage + ) { if (!(messageA instanceof NormalizedMessage)) { return -1; } @@ -102,18 +105,12 @@ export class NormalizedMessage { return ( NormalizedMessage.compareTypes(messageA.type, messageB.type) || - NormalizedMessage.compareOptionalStrings( - messageA.file, - messageB.file - ) || + NormalizedMessage.compareOptionalStrings(messageA.file, messageB.file) || NormalizedMessage.compareSeverities( messageA.severity, messageB.severity ) || - NormalizedMessage.compareNumbers( - messageA.line, - messageB.line - ) || + NormalizedMessage.compareNumbers(messageA.line, messageB.line) || NormalizedMessage.compareNumbers( messageA.character, messageB.character @@ -131,7 +128,10 @@ export class NormalizedMessage { ); } - public static equals(messageA: NormalizedMessage, messageB: NormalizedMessage) { + public static equals( + messageA: NormalizedMessage, + messageB: NormalizedMessage + ) { return this.compare(messageA, messageB) === 0; } From 1c590b899bcd8675fe61ece5f7612d7ec9975548 Mon Sep 17 00:00:00 2001 From: Radiosterne Date: Thu, 13 Dec 2018 23:03:16 +0300 Subject: [PATCH 2/2] Removed deprecated fs.existsSync; package.json and CHANGELOG.md bump --- CHANGELOG.md | 4 ++++ package.json | 2 +- src/CancellationToken.ts | 9 +++++++-- src/FsHelper.ts | 16 ++++++++++++++++ src/IncrementalChecker.ts | 3 ++- src/NormalizedMessage.ts | 2 +- src/formatter/codeframeFormatter.ts | 9 +++------ src/index.ts | 28 ++++++++++++++++++---------- test/unit/CancellationToken.spec.js | 10 ++++++---- 9 files changed, 58 insertions(+), 25 deletions(-) create mode 100644 src/FsHelper.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dd47e8f..ef6dc88c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v0.5.2 + +* [Fix erroneous error on diagnostics at 0 line; remove deprecated fs.existsSync](https://github.com/Realytics/fork-ts-checker-webpack-plugin/pull/190) (#190) + ## v0.5.1 * [Make the checker compile with TypeScript 3.2](https://github.com/Realytics/fork-ts-checker-webpack-plugin/pull/189) diff --git a/package.json b/package.json index 41165cd6..e816ac03 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fork-ts-checker-webpack-plugin", - "version": "0.5.1", + "version": "0.5.2", "description": "Runs typescript type checker and linter on separate process.", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/CancellationToken.ts b/src/CancellationToken.ts index 0ea27674..1f948d19 100644 --- a/src/CancellationToken.ts +++ b/src/CancellationToken.ts @@ -4,6 +4,8 @@ import * as os from 'os'; import * as path from 'path'; import * as ts from 'typescript'; +import { FsHelper } from './FsHelper'; + interface CancellationTokenData { isCancelled: boolean; cancellationFileName: string; @@ -46,7 +48,7 @@ export class CancellationToken { if (duration > 10) { // check no more than once every 10ms this.lastCancellationCheckTime = time; - this.isCancelled = fs.existsSync(this.getCancellationFilePath()); + this.isCancelled = FsHelper.existsSync(this.getCancellationFilePath()); } return this.isCancelled; @@ -64,7 +66,10 @@ export class CancellationToken { } public cleanupCancellation() { - if (this.isCancelled && fs.existsSync(this.getCancellationFilePath())) { + if ( + this.isCancelled && + FsHelper.existsSync(this.getCancellationFilePath()) + ) { fs.unlinkSync(this.getCancellationFilePath()); this.isCancelled = false; } diff --git a/src/FsHelper.ts b/src/FsHelper.ts new file mode 100644 index 00000000..9674a1b4 --- /dev/null +++ b/src/FsHelper.ts @@ -0,0 +1,16 @@ +import * as fs from 'fs'; + +export class FsHelper { + public static existsSync(filePath: fs.PathLike) { + try { + fs.statSync(filePath); + } catch (err) { + if (err.code === 'ENOENT') { + return false; + } else { + throw err; + } + } + return true; + } +} diff --git a/src/IncrementalChecker.ts b/src/IncrementalChecker.ts index 0ad6610d..c1b92820 100644 --- a/src/IncrementalChecker.ts +++ b/src/IncrementalChecker.ts @@ -9,6 +9,7 @@ import { NormalizedMessage } from './NormalizedMessage'; import { CancellationToken } from './CancellationToken'; import * as minimatch from 'minimatch'; import { VueProgram } from './VueProgram'; +import { FsHelper } from './FsHelper'; // Need some augmentation here - linterOptions.exclude is not (yet) part of the official // types for tslint. @@ -284,7 +285,7 @@ export class IncrementalChecker { linter.lint(fileName, undefined!, this.linterConfig); } catch (e) { if ( - fs.existsSync(fileName) && + FsHelper.existsSync(fileName) && // check the error type due to file system lag !(e instanceof Error) && !(e.constructor.name === 'FatalError') && diff --git a/src/NormalizedMessage.ts b/src/NormalizedMessage.ts index 950c7889..46328ef1 100644 --- a/src/NormalizedMessage.ts +++ b/src/NormalizedMessage.ts @@ -51,7 +51,7 @@ export class NormalizedMessage { let character: number | undefined; if (diagnostic.file) { file = diagnostic.file.fileName; - if (typeof diagnostic.start === 'undefined') { + if (diagnostic.start === undefined) { throw new Error('Expected diagnostics to have start'); } const position = diagnostic.file.getLineAndCharacterOfPosition( diff --git a/src/formatter/codeframeFormatter.ts b/src/formatter/codeframeFormatter.ts index 05eb5729..faaf974d 100644 --- a/src/formatter/codeframeFormatter.ts +++ b/src/formatter/codeframeFormatter.ts @@ -3,6 +3,7 @@ import codeFrame = require('babel-code-frame'); import chalk from 'chalk'; import * as fs from 'fs'; import { NormalizedMessage } from '../NormalizedMessage'; +import { FsHelper } from '../FsHelper'; /** * Create new code frame formatter. @@ -23,9 +24,7 @@ export function createCodeframeFormatter(options: any) { const file = message.file; const source = - file && - fs.existsSync(file) && - fs.readFileSync(file, 'utf-8'); + file && FsHelper.existsSync(file) && fs.readFileSync(file, 'utf-8'); let frame = ''; if (source) { @@ -41,9 +40,7 @@ export function createCodeframeFormatter(options: any) { } return ( - messageColor( - message.severity.toUpperCase() + ' in ' + message.file - ) + + messageColor(message.severity.toUpperCase() + ' in ' + message.file) + os.EOL + positionColor(message.line + ':' + message.character) + ' ' + diff --git a/src/index.ts b/src/index.ts index 0750bea6..08972ee6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,7 +2,6 @@ import * as path from 'path'; import * as process from 'process'; import * as childProcess from 'child_process'; import chalk, { Chalk } from 'chalk'; -import * as fs from 'fs'; import * as micromatch from 'micromatch'; import * as os from 'os'; import * as webpack from 'webpack'; @@ -10,6 +9,7 @@ import { CancellationToken } from './CancellationToken'; import { NormalizedMessage } from './NormalizedMessage'; import { createDefaultFormatter } from './formatter/defaultFormatter'; import { createCodeframeFormatter } from './formatter/codeframeFormatter'; +import { FsHelper } from './FsHelper'; import { Message } from './Message'; import { AsyncSeriesHook, SyncHook } from 'tapable'; @@ -68,8 +68,14 @@ class ForkTsCheckerWebpackPlugin { public static readonly DEFAULT_MEMORY_LIMIT = 2048; public static readonly ONE_CPU = 1; public static readonly ALL_CPUS = os.cpus && os.cpus() ? os.cpus().length : 1; - public static readonly ONE_CPU_FREE = Math.max(1, ForkTsCheckerWebpackPlugin.ALL_CPUS - 1); - public static readonly TWO_CPUS_FREE = Math.max(1, ForkTsCheckerWebpackPlugin.ALL_CPUS - 2); + public static readonly ONE_CPU_FREE = Math.max( + 1, + ForkTsCheckerWebpackPlugin.ALL_CPUS - 1 + ); + public static readonly TWO_CPUS_FREE = Math.max( + 1, + ForkTsCheckerWebpackPlugin.ALL_CPUS - 2 + ); public readonly options: Partial; private tsconfig: string; @@ -129,9 +135,8 @@ class ForkTsCheckerWebpackPlugin { : options.tslint : undefined; this.tslintAutoFix = options.tslintAutoFix || false; - this.watch = (typeof options.watch === 'string') - ? [options.watch] - : options.watch || []; + this.watch = + typeof options.watch === 'string' ? [options.watch] : options.watch || []; this.ignoreDiagnostics = options.ignoreDiagnostics || []; this.ignoreLints = options.ignoreLints || []; this.reportFiles = options.reportFiles || []; @@ -145,7 +150,7 @@ class ForkTsCheckerWebpackPlugin { this.useColors = options.colors !== false; // default true this.colors = new chalk.constructor({ enabled: this.useColors }); this.formatter = - options.formatter && (typeof options.formatter === 'function') + options.formatter && typeof options.formatter === 'function' ? options.formatter : ForkTsCheckerWebpackPlugin.createFormatter( (options.formatter as 'default' | 'codeframe') || 'default', @@ -201,8 +206,8 @@ class ForkTsCheckerWebpackPlugin { this.watchPaths = this.watch.map(this.computeContextPath.bind(this)); // validate config - const tsconfigOk = fs.existsSync(this.tsconfigPath); - const tslintOk = !this.tslintPath || fs.existsSync(this.tslintPath); + const tsconfigOk = FsHelper.existsSync(this.tsconfigPath); + const tslintOk = !this.tslintPath || FsHelper.existsSync(this.tslintPath); // validate logger if (this.logger) { @@ -745,7 +750,10 @@ class ForkTsCheckerWebpackPlugin { } } - private createEmitCallback(compilation: webpack.compilation.Compilation, callback: () => void) { + private createEmitCallback( + compilation: webpack.compilation.Compilation, + callback: () => void + ) { return function emitCallback(this: ForkTsCheckerWebpackPlugin) { if (!this.elapsed) { throw new Error('Execution order error'); diff --git a/test/unit/CancellationToken.spec.js b/test/unit/CancellationToken.spec.js index 09d84523..c838e7d9 100644 --- a/test/unit/CancellationToken.spec.js +++ b/test/unit/CancellationToken.spec.js @@ -2,13 +2,13 @@ var describe = require('mocha').describe; var it = require('mocha').it; var os = require('os'); var ts = require('typescript'); -var fs = require('fs'); var beforeEach = require('mocha').beforeEach; var afterEach = require('mocha').afterEach; var expect = require('chai').expect; var mockFs = require('mock-fs'); var CancellationToken = require('../../lib/CancellationToken') .CancellationToken; +var FsHelper = require('../../lib/FsHelper').FsHelper; describe('[UNIT] CancellationToken', function() { beforeEach(function() { @@ -72,7 +72,9 @@ describe('[UNIT] CancellationToken', function() { var tokenB = new CancellationToken('rgeer#R23r$#T$3t#$t43', true); expect(function() { tokenB.throwIfCancellationRequested(); - }).to.throw().instanceOf(ts.OperationCanceledException); + }) + .to.throw() + .instanceOf(ts.OperationCanceledException); }); it('should write file in filesystem on requestCancellation', function() { @@ -80,7 +82,7 @@ describe('[UNIT] CancellationToken', function() { tokenA.requestCancellation(); expect(tokenA.isCancellationRequested()).to.be.true; - expect(fs.existsSync(tokenA.getCancellationFilePath())).to.be.true; + expect(FsHelper.existsSync(tokenA.getCancellationFilePath())).to.be.true; }); it('should cleanup file on cleanupCancellation', function() { @@ -89,7 +91,7 @@ describe('[UNIT] CancellationToken', function() { tokenA.cleanupCancellation(); expect(tokenA.isCancellationRequested()).to.be.false; - expect(fs.existsSync(tokenA.getCancellationFilePath())).to.be.false; + expect(FsHelper.existsSync(tokenA.getCancellationFilePath())).to.be.false; // make sure we can call it as many times as we want to expect(function() {