Skip to content

Commit

Permalink
[Feature][#67] Adds tslint autofix as a flag to ForkTsCheckerWebpackP…
Browse files Browse the repository at this point in the history
…lugin plugin (#174)

* Adds tslintAutoFix flag to ForkTsCheckerWebpackPlugin

* Updates Vue integration test based on IncrementalChecker class update

* Adds integration testing for tslintAutoFix flag

* Updates README file to add description about tslintAutoFix flag

* Removes unnecessary tslint checks

* Adds a check to verify formatted file contents

* Adds seperate tslint autofix json to avoid formatting files other than autofix files in integration test

* Bumps package.json and updates CHANGELOG file for tslintAutoFix option

* Updates README for tslintAutoFix with default value as false
  • Loading branch information
ajainarayanan authored and johnnyreilly committed Nov 7, 2018
1 parent 7967402 commit 97c86d6
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 6 deletions.
1 change: 1 addition & 0 deletions .prettierignore
@@ -0,0 +1 @@
./test/integration/project/lintingError.ts
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,7 @@
## v0.4.15

* [Add `tslintAutoFix` option to be passed on to tslint to auto format typescript files](https://github.com/Realytics/fork-ts-checker-webpack-plugin/pull/174) (#174)

## v0.4.14

* [Add support for `reportFiles` option](https://github.com/Realytics/fork-ts-checker-webpack-plugin/pull/179) (#179)
Expand Down
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -66,6 +66,9 @@ Allows overriding TypeScript options. Should be specified in the same format as
* **tslint** `string | true`:
Path to *tslint.json* file or `true`. If `true`, uses `path.resolve(compiler.options.context, './tslint.json')`. Default: `undefined`.

* **tslintAutoFix** `boolean `:
Passes on `--fix` flag while running `tslint` to auto fix linting errors. Default: false.

* **watch** `string | string[]`:
Directories or files to watch by service. Not necessary but improves performance (reduces number of `fs.stat` calls).

Expand Down
Binary file added fork-ts-checker-webpack-plugin-v0.4.11.tgz
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "fork-ts-checker-webpack-plugin",
"version": "0.4.14",
"version": "0.4.15",
"description": "Runs typescript type checker and linter on separate process.",
"main": "lib/index.js",
"types": "lib/types/index.d.ts",
Expand Down
9 changes: 6 additions & 3 deletions src/IncrementalChecker.ts
Expand Up @@ -24,6 +24,7 @@ export class IncrementalChecker {
programConfigFile: string;
compilerOptions: object;
linterConfigFile: string | false;
linterAutoFix: boolean;
watchPaths: string[];
workNumber: number;
workDivision: number;
Expand All @@ -44,6 +45,7 @@ export class IncrementalChecker {
programConfigFile: string,
compilerOptions: object,
linterConfigFile: string | false,
linterAutoFix: boolean,
watchPaths: string[],
workNumber: number,
workDivision: number,
Expand All @@ -53,6 +55,7 @@ export class IncrementalChecker {
this.programConfigFile = programConfigFile;
this.compilerOptions = compilerOptions;
this.linterConfigFile = linterConfigFile;
this.linterAutoFix = linterAutoFix;
this.watchPaths = watchPaths;
this.workNumber = workNumber || 0;
this.workDivision = workDivision || 1;
Expand Down Expand Up @@ -137,10 +140,10 @@ export class IncrementalChecker {
);
}

static createLinter(program: ts.Program) {
createLinter(program: ts.Program) {
const tslint = require('tslint');

return new tslint.Linter({ fix: false }, program);
return new tslint.Linter({ fix: this.linterAutoFix }, program);
}

static isFileExcluded(
Expand Down Expand Up @@ -192,7 +195,7 @@ export class IncrementalChecker {
this.program = this.vue ? this.loadVueProgram() : this.loadDefaultProgram();

if (this.linterConfig) {
this.linter = IncrementalChecker.createLinter(this.program);
this.linter = this.createLinter(this.program);
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/index.ts
Expand Up @@ -42,6 +42,7 @@ interface Options {
tsconfig: string;
compilerOptions: object;
tslint: string | true;
tslintAutoFix: boolean;
watch: string | string[];
async: boolean;
ignoreDiagnostics: number[];
Expand Down Expand Up @@ -76,6 +77,7 @@ class ForkTsCheckerWebpackPlugin {
tsconfig: string;
compilerOptions: object;
tslint: string | true;
tslintAutoFix: boolean;
watch: string[];
ignoreDiagnostics: number[];
ignoreLints: string[];
Expand Down Expand Up @@ -128,6 +130,7 @@ class ForkTsCheckerWebpackPlugin {
? './tslint.json'
: options.tslint
: undefined;
this.tslintAutoFix = options.tslintAutoFix || false;
this.watch = isString(options.watch)
? [options.watch]
: options.watch || [];
Expand Down Expand Up @@ -566,6 +569,7 @@ class ForkTsCheckerWebpackPlugin {
TSCONFIG: this.tsconfigPath,
COMPILER_OPTIONS: JSON.stringify(this.compilerOptions),
TSLINT: this.tslintPath || '',
TSLINTAUTOFIX: this.tslintAutoFix,
WATCH: this.isWatching ? this.watchPaths.join('|') : '',
WORK_DIVISION: Math.max(1, this.workersNumber),
MEMORY_LIMIT: this.memoryLimit,
Expand Down
1 change: 1 addition & 0 deletions src/service.ts
Expand Up @@ -8,6 +8,7 @@ const checker = new IncrementalChecker(
process.env.TSCONFIG,
JSON.parse(process.env.COMPILER_OPTIONS),
process.env.TSLINT === '' ? false : process.env.TSLINT,
process.env.TSLINTAUTOFIX === 'true',
process.env.WATCH === '' ? [] : process.env.WATCH.split('|'),
parseInt(process.env.WORK_NUMBER, 10),
parseInt(process.env.WORK_DIVISION, 10),
Expand Down
113 changes: 111 additions & 2 deletions test/integration/index.spec.js
@@ -1,3 +1,4 @@
var fs = require('fs');
var describe = require('mocha').describe;
var it = require('mocha').it;
var chai = require('chai');
Expand All @@ -9,12 +10,31 @@ chai.config.truncateThreshold = 0;
var expect = chai.expect;

var webpackMajorVersion = require('./webpackVersion')();
const writeContentsToLintingErrorFile = (fileName, data) => {
const promise = new Promise((resolve, reject) => {
try {
fs.writeFileSync(
path.resolve(__dirname, `./project/src/${fileName}.ts`),
data,
{ flag: 'w' }
);
} catch (e) {
return reject(e);
}
return resolve();
});
return promise;
};

describe('[INTEGRATION] index', function() {
this.timeout(60000);
var plugin;

function createCompiler(options, happyPackMode) {
function createCompiler(
options,
happyPackMode,
entryPoint = './src/index.ts'
) {
plugin = new ForkTsCheckerWebpackPlugin(
Object.assign({}, options, { silent: true })
);
Expand All @@ -26,7 +46,7 @@ describe('[INTEGRATION] index', function() {
return webpack({
...(webpackMajorVersion >= 4 ? { mode: 'development' } : {}),
context: path.resolve(__dirname, './project'),
entry: './src/index.ts',
entry: entryPoint,
output: {
path: path.resolve(__dirname, '../../tmp')
},
Expand Down Expand Up @@ -92,6 +112,95 @@ describe('[INTEGRATION] index', function() {
});
});

it('should fix linting errors with tslintAutofix flag set to true', function(callback) {
const lintErrorFileContents = `function someFunctionName(param1,param2){return param1+param2};
`;
const formattedFileContents = `function someFunctionName(param1, param2) {return param1 + param2; }
`;
const fileName = 'lintingError1';
writeContentsToLintingErrorFile(fileName, lintErrorFileContents).then(
() => {
var compiler = createCompiler(
{
tslintAutoFix: true,
tslint: path.resolve(__dirname, './project/tslint.autofix.json'),
tsconfig: false
},
false,
`./src/${fileName}.ts`
);
const deleteFile = () =>
fs.unlinkSync(
path.resolve(__dirname, `./project/src/${fileName}.ts`)
);
compiler.run(function(err, stats) {
expect(stats.compilation.warnings.length).to.be.eq(0);
let fileContents;
try {
fileContents = fs.readFileSync(
path.resolve(__dirname, `./project/src/${fileName}.ts`),
{
encoding: 'utf-8'
}
);
} catch (e) {
throw e;
}
/*
Helpful to wrap this in a try catch.
If the assertion fails we still need to cleanup
the temporary file created as part of the test
*/
try {
expect(fileContents).to.be.eq(formattedFileContents);
} catch (e) {
deleteFile();
throw e;
}
deleteFile();
callback();
});
},
err => {
throw err;
}
);
});
it('should not fix linting by default', function(callback) {
const lintErrorFileContents = `function someFunctionName(param1,param2){return param1+param2};
`;
const fileName = 'lintingError2';
const deleteFile = () =>
fs.unlinkSync(path.resolve(__dirname, `./project/src/${fileName}.ts`));
writeContentsToLintingErrorFile(fileName, lintErrorFileContents).then(
() => {
var compiler = createCompiler(
{ tslint: true },
false,
`./src/${fileName}.ts`
);
compiler.run(function(err, stats) {
/*
Helpful to wrap this in a try catch.
If the assertion fails we still need to cleanup
the temporary file created as part of the test
*/
try {
expect(stats.compilation.warnings.length).to.be.eq(7);
} catch (e) {
deleteFile();
throw e;
}
deleteFile();
callback();
});
},
err => {
throw err;
}
);
});

it('should block emit on build mode', function(callback) {
var compiler = createCompiler();

Expand Down
14 changes: 14 additions & 0 deletions test/integration/project/tslint.autofix.json
@@ -0,0 +1,14 @@
{
"defaultSeverity": "warning",
"extends": [
"tslint:recommended"
],
"linterOptions": {
"exclude": [
"src/index.ts"
]
},
"jsRules": {},
"rules": {},
"rulesDirectory": []
}
1 change: 1 addition & 0 deletions test/integration/vue.spec.js
Expand Up @@ -78,6 +78,7 @@ describe('[INTEGRATION] vue', function() {
plugin.tsconfigPath,
{},
plugin.tslintPath || false,
plugin.tslintAutoFix || false,
[compiler.context],
ForkTsCheckerWebpackPlugin.ONE_CPU,
1,
Expand Down

0 comments on commit 97c86d6

Please sign in to comment.