From e8cca36e22c842be563047575c898f414dfe01f9 Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Fri, 1 Jun 2018 22:47:35 +0200 Subject: [PATCH] feat: ability to use user provided tslint config (#159) This change adds the ability to use tslint.conf provided by the user. If the user doesn't have a config file, we fall back to the default gts config file. --- README.md | 5 ++++- src/lint.ts | 9 ++++++--- test/test-lint.ts | 28 +++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 40f536d7..3ad942ea 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ - **No configuration**. The easiest way to enforce consistent style in your project. Just drop it in. - **Automatically format code**. Just run `gts fix` and say goodbye to messy or inconsistent code. -- **Catch style issues & programmer errors early.** Save precious code review time by eliminating back-and-forth between reviewer & contributor. +- **Catch style issues & programmer errors early**. Save precious code review time by eliminating back-and-forth between reviewer & contributor. +- **Opinionated, but not to a fault**. We recommend you use the default configuration, but if you *need* to customize compiler or linter config, you can. Under the covers, we use [tslint][tslint-url] to enforce the style guide and provide automated fixes, and [clang-format][clang-format-url] to re-format code. @@ -42,6 +43,8 @@ When you run the `npx gts init` command, it's going to do a few things for you: - `compile`: Compiles the source code using TypeScript compiler. - `pretest`, `posttest` and `prepare`: convenience integrations. +We strongly recommend you use the default style config, but if you must tweak, you can edit the generated `tsconfig.json`. For linter, we use the default `tslint.json` unless we find that file in your project directory. + ## Individual files The commands above will all run in the scope of the current folder. Some commands can be run on individual files: diff --git a/src/lint.ts b/src/lint.ts index 5c68e503..554446bf 100644 --- a/src/lint.ts +++ b/src/lint.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as fs from 'fs'; import * as path from 'path'; import {Configuration, Linter} from 'tslint'; import * as ts from 'typescript'; @@ -27,11 +28,13 @@ import {Options} from './cli'; */ export function lint( options: Options, files: string[] = [], fix = false): boolean { - const tslintConfigPath = path.join(options.gtsRootDir, 'tslint.json'); + const configPath = + fs.existsSync(path.join(options.targetRootDir, 'tslint.json')) ? + path.join(options.targetRootDir, 'tslint.json') : + path.join(options.gtsRootDir, 'tslint.json'); const program = createProgram(options); - const configuration = - Configuration.findConfiguration(tslintConfigPath, '').results; + const configuration = Configuration.findConfiguration(configPath, '').results; const linter = new Linter({fix, formatter: 'codeFrame'}, program); const srcFiles = files.length > 0 ? files : Linter.getFileNames(program); srcFiles.forEach(file => { diff --git a/test/test-lint.ts b/test/test-lint.ts index 06cfe0a2..0bca9c50 100644 --- a/test/test-lint.ts +++ b/test/test-lint.ts @@ -42,7 +42,6 @@ test.serial('createProgram should return an object', async t => { }); }); - test.serial('lint should return true on good code', async t => { await withFixtures( { @@ -148,4 +147,31 @@ test.serial('lint should not throw for unrecognized files', async t => { }); }); +test.serial('lint should prefer user config file over default', async t => { + const CUSTOM_LINT_CODE = 'const t: Object;'; + + // By defualt the above should fail lint. + await withFixtures( + { + 'tsconfig.json': JSON.stringify({files: ['a.ts']}), + 'a.ts': CUSTOM_LINT_CODE + }, + async () => { + const okay = lint.lint(OPTIONS); + t.is(okay, false); + }); + + // User should be able to override the default config. + await withFixtures( + { + 'tsconfig.json': JSON.stringify({files: ['a.ts']}), + 'tslint.json': JSON.stringify({}), + 'a.ts': CUSTOM_LINT_CODE + }, + async () => { + const okay = lint.lint(OPTIONS); + t.is(okay, true); + }); +}); + // TODO: test for when tsconfig.json is missing.