Skip to content

Commit bc6c544

Browse files
authored
[Feature] Add Support for multiple tsconfigs #254 (#261)
[Feature] Add support to inlining the tsconfig.json within the grunt config #44
1 parent 69e2a2d commit bc6c544

25 files changed

Lines changed: 2160 additions & 607 deletions

README.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,55 @@ module.exports = function(grunt) {
6060
'./src/**/*.ts'
6161
],
6262
out: './out/task1-dist.js'
63+
},
64+
task4: {
65+
// As with task3, since 0.5.0 the tsconfig may have be inlined and specify more
66+
// than just the filename / location of the tsconfig.json
67+
tsconfig: {
68+
name: './task1/tsconfig.json',
69+
src: [
70+
'./src/**/*.ts'
71+
],
72+
out: './out/task1-dist.js'
73+
}
74+
},
75+
task5: {
76+
// As with task3, since 0.5.0 the tsconfig may contain multiple inlined definitions
77+
// and override the content of the loaded tsconfig.json
78+
tsconfig: [
79+
{
80+
name: './task1/tsconfig.json',
81+
src: [
82+
'./src/**/*.ts'
83+
],
84+
out: './out/task5-dist.js'
85+
},
86+
{
87+
name: './task1/tsconfig.json',
88+
tsconfig: {
89+
compilerOptions: {
90+
target: "es6"
91+
}
92+
}
93+
src: [
94+
'./src/**/*.ts'
95+
],
96+
out: './out/task5-es6-dist.js'
97+
},
98+
{
99+
name: './task1/tsconfig.json',
100+
tsconfig: {
101+
compilerOptions: {
102+
target: "esnext"
103+
}
104+
}
105+
src: [
106+
'./src/**/*.ts'
107+
],
108+
out: './out/task5-esnext-dist.js'
109+
}
110+
]
63111
}
64-
}
65112
});
66113
grunt.loadNpmTasks("@nevware21/grunt-ts-plugin");
67114
grunt.registerTask("default", ["ts"]);

common/config/rush/npm-shrinkwrap.json

Lines changed: 361 additions & 361 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

eslint-ts-plugin/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"scripts": {
1717
"clean": "grunt clean",
1818
"build": "grunt eslint_ts_plugin --verbose && npm run package",
19-
"rebuild": "npm run build",
19+
"rebuild": "npm run build && npm run test",
2020
"package": "rollup -c rollup.config.mjs",
2121
"test": "grunt eslint_ts_plugin_test",
2222
"lint": "grunt doLint"

eslint-ts-plugin/src/eslint-ts-plugin.ts

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
* Licensed under the MIT license.
88
*/
99

10-
import { arrForEach, dumpObj, isString } from "@nevware21/ts-utils";
11-
import { getGruntMultiTaskOptions, resolveValue, deepMerge, getTsConfigDetails, IGruntWrapperOptions, GruntWrapper } from "@nevware21/grunt-plugins-shared-utils";
10+
import { arrForEach, dumpObj, isIterable, isIterator, isString, iterForOf } from "@nevware21/ts-utils";
11+
import { getGruntMultiTaskOptions, resolveValue, deepMerge, getTsConfigDetails, IGruntWrapperOptions, GruntWrapper, resolveValueAsync, ITsOption } from "@nevware21/grunt-plugins-shared-utils";
1212
import { ESLintRunner } from "./ESLintRunner";
1313
import { IEslintTsPluginTaskOptions } from "./interfaces/IEslintTsPluginOptions";
1414
import { Linter } from "eslint";
@@ -35,39 +35,70 @@ function _registerTask(inst: IGrunt, taskName: string) {
3535
grunt.logVerbose((" Options: [" + dumpObj(options) + "]").cyan);
3636
grunt.logVerbose((" Config : [" + dumpObj(this.data) + "]").cyan);
3737
}
38-
39-
let tsconfig = resolveValue(taskOptions.tsconfig, options.tsconfig);
40-
// eslint-disable-next-line security/detect-non-literal-fs-filename
41-
if (!tsconfig || !grunt.file.exists(tsconfig)) {
42-
grunt.logError("The TSConfig project file [" + tsconfig + "] does not exist");
43-
return false;
44-
}
4538

46-
const eslintOptions: IESLintRunnerOptions = {
47-
format: resolveValue(taskOptions.format, options.format, "codeframe"),
48-
logOutput: resolveValue(taskOptions.logOutput, options.logOutput),
49-
fix: resolveValue(taskOptions.fix, options.fix),
50-
suppressWarnings: resolveValue(taskOptions.suppressWarnings, options.suppressWarnings),
51-
quiet: resolveValue(taskOptions.quiet, options.quiet),
52-
outputFile: resolveValue(taskOptions.outputFile, options.outputFile),
53-
disableOutputFixes: resolveValue(taskOptions.disableOutputFixes, options.disableOutputFixes)
54-
};
55-
56-
const maxWarnings = resolveValue(taskOptions.maxWarnings, options.maxWarnings);
57-
grunt.logDebug("grunt-eslint-typescript options: " + dumpObj(eslintOptions, true));
58-
59-
let tsDetails = getTsConfigDetails(grunt, tsconfig, !eslintOptions.suppressWarnings);
60-
arrForEach(tsDetails, (tsDetail) => {
61-
if (tsDetail) {
62-
tsDetail.addFiles(options.src);
63-
tsDetail.addFiles(taskOptions.src);
39+
done = this.async();
40+
(async function runEslint() {
41+
let tsDefs: Array<string | ITsOption> = [];
42+
let tsconfig = await resolveValueAsync(taskOptions.tsconfig, options.tsconfig);
43+
44+
if (!tsconfig) {
45+
if (isString(tsconfig)) {
46+
tsDefs.push(tsconfig);
47+
} else if (Array.isArray(tsconfig)) {
48+
tsDefs = tsconfig;
49+
} else if (isIterable(tsconfig) || isIterator(tsconfig)) {
50+
iterForOf(tsconfig, (value) => {
51+
tsDefs.push(value);
52+
});
53+
} else {
54+
grunt.logError("The TSConfig project file [" + tsconfig + "] does not exist");
55+
return false;
56+
}
6457
}
65-
});
58+
59+
for (let lp = 0; lp < tsDefs.length; lp++) {
60+
// eslint-disable-next-line security/detect-non-literal-fs-filename, security/detect-object-injection
61+
let tsDef = tsDefs[lp];
6662

67-
let results: IESLintRunnerResponse = null;
63+
if (isString(tsDef)) {
64+
if (!grunt.file.exists(tsDef)) {
65+
// eslint-disable-next-line security/detect-object-injection
66+
grunt.logError("The TSConfig project file [" + tsDefs[lp] + "] does not exist");
67+
return false;
68+
}
69+
} else if (tsDef.name) {
70+
if (!grunt.file.exists(tsDef.name)) {
71+
grunt.logError("The TSConfig project file [" + tsDef.name + "] does not exist");
72+
return false;
73+
}
74+
}
75+
}
76+
77+
const eslintOptions: IESLintRunnerOptions = {
78+
format: resolveValue(taskOptions.format, options.format, "codeframe"),
79+
logOutput: resolveValue(taskOptions.logOutput, options.logOutput),
80+
fix: resolveValue(taskOptions.fix, options.fix),
81+
suppressWarnings: resolveValue(taskOptions.suppressWarnings, options.suppressWarnings),
82+
quiet: resolveValue(taskOptions.quiet, options.quiet),
83+
outputFile: resolveValue(taskOptions.outputFile, options.outputFile),
84+
disableOutputFixes: resolveValue(taskOptions.disableOutputFixes, options.disableOutputFixes)
85+
};
86+
87+
const maxWarnings = resolveValue(taskOptions.maxWarnings, options.maxWarnings);
88+
grunt.logDebug("grunt-eslint-typescript options: " + dumpObj(eslintOptions, true));
6889

69-
done = this.async();
70-
(async function runEslint() {
90+
let tsDetails = getTsConfigDetails(grunt, tsDefs, !eslintOptions.suppressWarnings);
91+
arrForEach(tsDetails, (tsDetail) => {
92+
if (tsDetail) {
93+
tsDetail.addFiles(options.src);
94+
tsDetail.addFiles(taskOptions.src);
95+
}
96+
});
97+
98+
let results: IESLintRunnerResponse = null;
99+
100+
101+
71102
const eslint = new ESLintRunner(grunt, eslintOptions);
72103

73104
// Merge all of the additional Config into the linter
@@ -140,7 +171,7 @@ function _registerTask(inst: IGrunt, taskName: string) {
140171
});
141172

142173
} catch (e) {
143-
inst.log.error("EsLint catch: " + e);
174+
inst.log.error("EsLint catch:: " + e + "\n" + dumpObj(e));
144175
if (done) {
145176
done(false);
146177
}

eslint-ts-plugin/src/interfaces/IEslintTsPluginOptions.ts

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* Licensed under the MIT license.
77
*/
88

9+
import { TsConfigDefinitions } from "@nevware21/grunt-plugins-shared-utils";
10+
import { IPromise } from "@nevware21/ts-async";
911
import { Linter } from "eslint";
1012

1113
export interface ITsCommonOptions {
@@ -70,44 +72,60 @@ export interface IEslintTsPluginOptions extends IEsLintOptions {
7072
/**
7173
* Log additional debug messages as verbose grunt messages
7274
*/
73-
debug?: boolean;
75+
debug?: boolean;
7476

75-
/**
76-
* The path to the tsConfig file to use
77-
*/
78-
tsconfig?: string;
77+
/**
78+
* The path to the tsConfig file to use, may be
79+
* - a single string
80+
* - an array of strings
81+
* - an iterable of strings
82+
* - an iterator of strings
83+
* - a single ITsOption object identifying the tsConfig
84+
* - an array of ITsOption objects identifying the tsConfigs
85+
* - an iterable of ITsOption objects identifying the tsConfigs
86+
* - an iterator of ITsOption objects identifying the tsConfigs
87+
* - a promise that resolves to any of the above
88+
* - a function that returns any of the above including a promise that resolves to any of the above
89+
*/
90+
tsconfig?: TsConfigDefinitions | IPromise<TsConfigDefinitions> | (() => TsConfigDefinitions | IPromise<TsConfigDefinitions>);
7991

8092
/**
8193
* If more than this number of warnings are reported failed the task
8294
*/
83-
maxWarnings?: number;
95+
maxWarnings?: number;
8496

8597
/**
8698
* An array of source files to be "added" to all tasks as either files or include for each task tsconfig
8799
*/
88-
src?: string | string[];
100+
src?: string | string[];
89101
}
90102

91103
export interface IEslintTsPluginTaskOptions extends IEsLintOptions {
92104
/**
93105
* Log additional debug messages as verbose grunt messages
94106
*/
95-
debug?: boolean;
96-
97-
/**
98-
* The path to the tsConfig file to use
99-
*/
100-
tsconfig?: string;
107+
debug?: boolean;
101108

109+
/**
110+
* The path to the tsConfig file to use, may be
111+
* - a single string
112+
* - an array of strings
113+
* - an iterable of strings
114+
* - an iterator of strings
115+
* - a promise that resolves to any of the above
116+
* - a function that returns any of the above including a promise that resolves to any of the above
117+
*/
118+
tsconfig?: TsConfigDefinitions | IPromise<TsConfigDefinitions> | (() => TsConfigDefinitions | IPromise<TsConfigDefinitions>);
119+
102120
/**
103121
* If more than this number of warnings are reported failed the task
104122
*/
105-
maxWarnings?: number;
123+
maxWarnings?: number;
106124

107125
/**
108126
* An array of source files to be "added" to all tasks as either files or include for each task tsconfig
109127
*/
110-
src?: string | string[];
128+
src?: string | string[];
111129

112130
/**
113131
* Ignore failures and continue

eslint-ts-plugin/test/src/ESLintRunner.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
*/
99

1010
import * as assert from "assert";
11-
import * as sinon from 'sinon';
1211
import { IGruntWrapper } from '@nevware21/grunt-plugins-shared-utils';
1312
import { ESLintRunner } from '../../src/ESLintRunner';
1413
import { IESLintRunnerOptions } from '../../src/interfaces/IESLintRunnerOptions';

gruntfile.js

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,31 @@
66
* Licensed under the MIT license.
77
*/
88

9-
'use strict';
9+
"use strict";
1010

1111
module.exports = function (grunt) {
1212

1313
// Project configuration.
1414
grunt.initConfig({
1515
jshint: {
1616
all: [
17-
'Gruntfile.js',
18-
'tasks/*.js',
19-
'<%= nodeunit.tests %>'
17+
"Gruntfile.js",
18+
"tasks/*.js",
19+
"<%= nodeunit.tests %>"
2020
],
2121
options: {
22-
jshintrc: '.jshintrc'
22+
jshintrc: ".jshintrc"
2323
}
2424
},
2525

2626
// Before generating any new files, remove any previously-created files.
2727
clean: {
28-
tests: ['tmp']
28+
tests: ["tmp"]
2929
},
3030

3131
// Unit tests.
3232
nodeunit: {
33-
tests: ['test/*_test.js']
33+
tests: ["test/*_test.js"]
3434
},
3535
ts: {
3636
options: {
@@ -41,13 +41,13 @@ module.exports = function (grunt) {
4141
"shared": {
4242
tsconfig: "./shared/tsconfig.json",
4343
src: [
44-
'./shared/src/**/*.ts'
45-
],
44+
"./shared/src/**/*.ts"
45+
]
4646
},
4747
"shared-test": {
4848
tsconfig: "./shared/test/tsconfig.test.json",
4949
src: [
50-
'./shared/test/src/**/*.ts'
50+
"./shared/test/src/**/*.ts"
5151
],
5252
},
5353
"ts_plugin": {
@@ -57,7 +57,7 @@ module.exports = function (grunt) {
5757
"ts_plugin-test": {
5858
tsconfig: "./ts-plugin/test/tsconfig.test.json",
5959
src: [
60-
'./ts-plugin/test/src/**/*.ts'
60+
"./ts-plugin/test/src/**/*.ts"
6161
],
6262
},
6363
"eslint_ts_plugin": {
@@ -70,7 +70,7 @@ module.exports = function (grunt) {
7070
"eslint_ts_plugin-test": {
7171
tsconfig: "./eslint-ts-plugin/test/tsconfig.test.json",
7272
src: [
73-
'./eslint-ts-plugin/test/src/**/*.ts'
73+
"./eslint-ts-plugin/test/src/**/*.ts"
7474
],
7575
},
7676
},
@@ -83,7 +83,7 @@ module.exports = function (grunt) {
8383
tsconfig: "./shared/tsconfig.json",
8484
ignoreFailures: true,
8585
src: [
86-
'./shared/src/**/*.ts'
86+
"./shared/src/**/*.ts"
8787
]
8888
},
8989
"shared-test": {
@@ -109,7 +109,7 @@ module.exports = function (grunt) {
109109
tsconfig: "./shared/tsconfig.json",
110110
fix: true,
111111
src: [
112-
'./shared/src/**/*.ts'
112+
"./shared/src/**/*.ts"
113113
]
114114
}
115115
},
@@ -140,10 +140,10 @@ module.exports = function (grunt) {
140140

141141
// Whenever the "test" task is run, first clean the "tmp" dir, then run this
142142
// plugin's task(s), then test the result.
143-
grunt.registerTask('shared_utils-test', [ "lint:shared-test-fix", "ts:shared-test" ]);
144-
grunt.registerTask('ts_plugin_test', ["lint:ts_plugin-fix", "ts:ts_plugin-test"]);
145-
grunt.registerTask('eslint_ts_plugin_test', ["lint:eslint_ts-fix", "ts:eslint_ts_plugin-test"]);
143+
grunt.registerTask("shared_utils-test", [ "lint:shared-test-fix", "ts:shared-test" ]);
144+
grunt.registerTask("ts_plugin_test", ["lint:ts_plugin-fix", "ts:ts_plugin-test"]);
145+
grunt.registerTask("eslint_ts_plugin_test", ["lint:eslint_ts-fix", "ts:eslint_ts_plugin-test"]);
146146

147147
// By default, lint and run all tests.
148-
grunt.registerTask('default', ['jshint', 'test']);
148+
grunt.registerTask("default", ["jshint", "test"]);
149149
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"scripts": {
2323
"postinstall": "node common/scripts/install-run-rush.js update --full",
2424
"build": "node common/scripts/install-run-rush.js rebuild --verbose",
25+
"rebuild": "node common/scripts/install-run-rush.js rebuild --verbose",
2526
"test": "node common/scripts/install-run-rush.js test --verbose",
2627
"lint": "node common/scripts/install-run-rush.js dolint --verbose",
2728
"check": "node common/scripts/install-run-rush.js check",

0 commit comments

Comments
 (0)