Skip to content
This repository has been archived by the owner on May 2, 2023. It is now read-only.

Commit

Permalink
feat: replace codelyzer and ng-tslint with @angular-eslint (#160)
Browse files Browse the repository at this point in the history
  • Loading branch information
JounQin committed May 14, 2021
1 parent f40fed7 commit 5029b81
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/tame-paws-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tslint-config-eslint": minor
---

feat: replace codelyzer and ng-tslint with @angular-eslint
72 changes: 68 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# tslint-config-eslint

> Yet another TSLint Configuration which disables all rules which has been handled by [`eslint`](https://github.com/eslint/eslint), [`@typescript-eslint/eslint-plugin`](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin), [`eslint-plugin-sonarjs`](https://github.com/SonarSource/eslint-plugin-sonarjs) or [`eslint-plugin-sonar`](https://github.com/rx-ts/eslint-plugin-sonar).
[![GitHub Workflow Status](https://github.com/rx-ts/tslint-config-eslint/workflows/CI/badge.svg)](https://github.com/rx-ts/tslint-config-eslint/actions/workflows/ci.yml)
[![Codacy Grade](https://img.shields.io/codacy/grade/5c70cd4efc864eb3b344e32be9aecce8)](https://www.codacy.com/app/JounQin/tslint-config-eslint)
[![type-coverage](https://img.shields.io/badge/dynamic/json.svg?label=type-coverage&prefix=%E2%89%A5&suffix=%&query=$.typeCoverage.atLeast&uri=https%3A%2F%2Fraw.githubusercontent.com%2Frx-ts%2Ftslint-config-eslint%2Fmaster%2Fpackage.json)](https://github.com/plantain-00/type-coverage)
Expand All @@ -17,7 +15,11 @@
[![Code Style: Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![changesets](https://img.shields.io/badge/maintained%20with-changesets-176de3.svg)](https://github.com/atlassian/changesets)

[TSLint][] will be [deprecated](https://github.com/palantir/tslint/issues/4534) some time in 2019, but it has not been finished. So maybe you're using [ESLint][] with it together, then it would be terrible to lint codes twice, especially for those rules which has equivalent rules from [`eslint`](https://github.com/eslint/eslint), [`@typescript-eslint/eslint-plugin`](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin), [`eslint-plugin-sonarjs`](https://github.com/SonarSource/eslint-plugin-sonarjs) or [`eslint-plugin-sonar`](https://github.com/rx-ts/eslint-plugin-sonar).
> Yet another TSLint Configuration which disables all rules which has been handled by [`eslint`](https://github.com/eslint/eslint), [`@typescript-eslint/eslint-plugin`](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin), [`eslint-plugin-sonarjs`](https://github.com/SonarSource/eslint-plugin-sonarjs) or [`eslint-plugin-sonar`](https://github.com/rx-ts/eslint-plugin-sonar).
[TSLint][] will be [deprecated](https://github.com/palantir/tslint/issues/4534) some time in 2019, but it has not been finished. So maybe you're using [ESLint][] with it together, then it would be terrible to lint codes twice, especially for those rules which has equivalent rules from [`eslint`](https://github.com/eslint/eslint), [`@typescript-eslint`](https://github.com/typescript-eslint/typescript-eslint), [`eslint-plugin-sonarjs`](https://github.com/SonarSource/eslint-plugin-sonarjs) or [`eslint-plugin-sonar`](https://github.com/rx-ts/eslint-plugin-sonar).

And also [`@angular-eslint`](https://github.com/angular-eslint/angular-eslint) for Angular.

You may tried something like [tslint-to-eslint-config](https://github.com/typescript-eslint/tslint-to-eslint-config) to help you to migrate, while this package/configuration will help you to use [ESLint][] quickly without remove or refactor your original `tslint.json` heavily.

Expand All @@ -32,6 +34,8 @@ You may tried something like [tslint-to-eslint-config](https://github.com/typesc
- [Rules List](#rules-list)
- [tslint core](#tslint-core)
- [tslint-sonarts](#tslint-sonarts)
- [codelyzer](#codelyzer)
- [ng-tslint](#ng-tslint)
- [Forthcoming](#forthcoming)
- [Changelog](#changelog)
- [License](#license)
Expand Down Expand Up @@ -283,13 +287,73 @@ const {
| `no-variable-usage-before-declaration` | `sonar/no-variable-usage-before-declaration` |
| `use-type-alias` | `sonar/use-type-alias` |

### codelyzer

| old rule | new rule |
| --------------------------------------------- | ------------------------------------------------------------- |
| `template-accessibility-alt-text` | `@angular-eslint/template/accessibility-alt-text` |
| `template-accessibility-elements-content` | `@angular-eslint/template/accessibility-elements-content` |
| `template-accessibility-label-for` | `@angular-eslint/template/accessibility-label-for` |
| `template-accessibility-tabindex-no-positive` | `@angular-eslint/template/accessibility-tabindex-no-positive` |
| `template-accessibility-table-scope` | `@angular-eslint/template/accessibility-table-scope` |
| `template-accessibility-valid-aria` | `@angular-eslint/template/accessibility-valid-aria` |
| `template-banana-in-box` | `@angular-eslint/template/banana-in-box` |
| `template-click-events-have-key-events` | `@angular-eslint/template/click-events-have-key-events` |
| `template-conditional-complexity` | `@angular-eslint/template/conditional-complexity` |
| `template-cyclomatic-complexity` | `@angular-eslint/template/cyclomatic-complexity` |
| `template-i18n` | `@angular-eslint/template/i18n` |
| `template-mouse-events-have-key-events` | `@angular-eslint/template/mouse-events-have-key-events` |
| `template-no-any` | `@angular-eslint/template/no-any` |
| `template-no-autofocus` | `@angular-eslint/template/no-autofocus` |
| `template-no-call-expression` | `@angular-eslint/template/no-call-expression` |
| `template-no-distracting-elements` | `@angular-eslint/template/no-distracting-elements` |
| `template-no-negated-async` | `@angular-eslint/template/no-negated-async` |
| `template-use-track-by-function` | `@angular-eslint/template/use-track-by-function` |
| `import-destructuring-spacing` | `object-curly-spacing` |
| `use-pipe-decorator` | `N/A` |
| `component-class-suffix` | `@angular-eslint/component-class-suffix` |
| `component-max-inline-declarations` | `@angular-eslint/component-max-inline-declarations` |
| `component-selector` | `@angular-eslint/component-selector` |
| `contextual-decorator` | `@angular-eslint/contextual-decorator` |
| `contextual-lifecycle` | `@angular-eslint/contextual-lifecycle` |
| `directive-class-suffix` | `@angular-eslint/directive-class-suffix` |
| `directive-selector` | `@angular-eslint/directive-selector` |
| `no-attribute-decorator` | `@angular-eslint/no-attribute-decorator` |
| `no-conflicting-lifecycle` | `@angular-eslint/no-conflicting-lifecycle` |
| `no-forward-ref` | `@angular-eslint/no-forward-ref` |
| `no-host-metadata-property` | `@angular-eslint/no-host-metadata-property` |
| `no-input-prefix` | `@angular-eslint/no-input-prefix` |
| `no-input-rename` | `@angular-eslint/no-input-rename` |
| `no-inputs-metadata-property` | `@angular-eslint/no-inputs-metadata-property` |
| `no-lifecycle-call` | `@angular-eslint/no-lifecycle-call` |
| `no-output-native` | `@angular-eslint/no-output-native` |
| `no-output-on-prefix` | `@angular-eslint/no-output-on-prefix` |
| `no-output-rename` | `@angular-eslint/no-output-rename` |
| `no-outputs-metadata-property` | `@angular-eslint/no-outputs-metadata-property` |
| `no-pipe-impure` | `@angular-eslint/no-pipe-impure` |
| `no-queries-metadata-property` | `@angular-eslint/no-queries-metadata-property` |
| `pipe-prefix` | `@angular-eslint/pipe-prefix` |
| `prefer-on-push-component-change-detection` | `@angular-eslint/prefer-on-push-component-change-detection` |
| `prefer-output-readonly` | `@angular-eslint/prefer-output-readonly` |
| `relative-url-prefix` | `@angular-eslint/relative-url-prefix` |
| `use-component-selector` | `@angular-eslint/use-component-selector` |
| `use-component-view-encapsulation` | `@angular-eslint/use-component-view-encapsulation` |
| `use-injectable-provided-in` | `@angular-eslint/use-injectable-provided-in` |
| `use-lifecycle-interface` | `@angular-eslint/use-lifecycle-interface` |
| `use-pipe-transform-interface` | `@angular-eslint/use-pipe-transform-interface` |

### ng-tslint

| old rule | new rule |
| --------------- | -------------------------------------- |
| `member-naming` | `@typescript-eslint/naming-convention` |

<!-- suffix placeholder -->

## Forthcoming

Forthcoming configs include:

- [ ] Angular, disable replaceable [tslint-angular](https://github.com/mgechev/tslint-angular#readme) rules in favor of [angular-eslint](https://github.com/angular-eslint/angular-eslint)
- [ ] React, disable replaceable [tslint-react](https://github.com/palantir/tslint-react) rules in favor of [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react)

## Changelog
Expand Down
55 changes: 55 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"rules": {
"template-accessibility-alt-text": false,
"template-accessibility-elements-content": false,
"template-accessibility-label-for": false,
"template-accessibility-tabindex-no-positive": false,
"template-accessibility-table-scope": false,
"template-accessibility-valid-aria": false,
"template-banana-in-box": false,
"template-click-events-have-key-events": false,
"template-conditional-complexity": false,
"template-cyclomatic-complexity": false,
"template-i18n": false,
"template-mouse-events-have-key-events": false,
"template-no-any": false,
"template-no-autofocus": false,
"template-no-call-expression": false,
"template-no-distracting-elements": false,
"template-no-negated-async": false,
"template-use-track-by-function": false,
"import-destructuring-spacing": false,
"use-pipe-decorator": false,
"component-class-suffix": false,
"component-max-inline-declarations": false,
"component-selector": false,
"contextual-decorator": false,
"contextual-lifecycle": false,
"directive-class-suffix": false,
"directive-selector": false,
"no-attribute-decorator": false,
"no-conflicting-lifecycle": false,
"no-forward-ref": false,
"no-host-metadata-property": false,
"no-input-prefix": false,
"no-input-rename": false,
"no-inputs-metadata-property": false,
"no-lifecycle-call": false,
"no-output-native": false,
"no-output-on-prefix": false,
"no-output-rename": false,
"no-outputs-metadata-property": false,
"no-pipe-impure": false,
"no-queries-metadata-property": false,
"pipe-prefix": false,
"prefer-on-push-component-change-detection": false,
"prefer-output-readonly": false,
"relative-url-prefix": false,
"use-component-selector": false,
"use-component-view-encapsulation": false,
"use-injectable-provided-in": false,
"use-lifecycle-interface": false,
"use-pipe-transform-interface": false,
"member-naming": false
}
}
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,23 @@
"lint:es": "eslint . --cache -f friendly",
"lint:ts": "tslint -p . -t stylish",
"lint:tsc": "tsc --noEmit",
"prebuild": "rimraf rules.{d.ts,js}",
"prepare": "simple-git-hooks && yarn-deduplicate --strategy fewer || exit 0",
"release": "clean-publish && changeset publish",
"typecov": "type-coverage"
},
"peerDependencies": {
"@angular-eslint/eslint-plugin": "^12.0.0",
"@typescript-eslint/eslint-plugin": ">=3.0.0",
"eslint-plugin-sonar": ">=0.5.0",
"eslint-plugin-sonarjs": ">=0.7.0",
"tslint": ">=5.0.0",
"typescript": ">=3.0.0"
},
"peerDependenciesMeta": {
"@angular-eslint/eslint-plugin": {
"optional": true
},
"eslint-plugin-sonar": {
"optional": true
},
Expand All @@ -51,6 +56,7 @@
"@types/node": "^15.0.3",
"@types/prettier": "^2.2.3",
"clean-publish": "^2.2.0",
"rimraf": "^3.0.2",
"ts-node": "^9.1.1",
"tslint": "^6.1.3",
"type-coverage": "^2.17.5",
Expand Down
5 changes: 4 additions & 1 deletion prettier.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
"$schema": "http://json.schemastore.org/tslint",
"extends": "./base.json",
"rules": {
"prettier": false
"prettier": false,
"angular-whitespace": false,
"no-import-export-spacing": false,
"prefer-inline-decorator": false
}
}
97 changes: 93 additions & 4 deletions rules.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface RuleReplacements {
[rule: string]: string | string[]
[rule: string]: string | string[] | null
}

export interface DisabledRules {
Expand All @@ -23,7 +23,7 @@ export const addRulesPrefix = (rules: RuleReplacements, prefix: string) =>
Object.assign(acc, {
[oldRule]: Array.isArray(newRule)
? newRule.map(rule => addRulePrefix(rule, prefix))
: addRulePrefix(newRule, prefix),
: newRule && addRulePrefix(newRule, prefix),
}),
{},
)
Expand Down Expand Up @@ -103,9 +103,9 @@ export const CORE_REPLACEMENTS =
},
)

// from `@typescript-eslint/eslint-plugin`
export const TS_ESLINT = '@typescript-eslint'

// from `@typescript-eslint/eslint-plugin`
export const TS_AS_IS_REPLACEMENTS = [
'adjacent-overload-signatures',
'array-type',
Expand Down Expand Up @@ -174,6 +174,7 @@ export const TS_REPLACEMENTS = TS_AS_IS_REPLACEMENTS.reduce<RuleReplacements>(
},
)

// from `eslint-plugin-sonarjs`
export const SONARJS_AS_IS_REPLACEMENTS = [
'no-all-duplicated-branches',
'cognitive-complexity',
Expand Down Expand Up @@ -233,7 +234,7 @@ export const SONARJS_REPLACEMENTS =
},
)

// form `eslint-plugin-sonar`
// from `eslint-plugin-sonar`
const SONAR_AS_IS_REPLACEMENTS = [
'arguments-order',
'bool-param-default',
Expand Down Expand Up @@ -282,3 +283,91 @@ export const SONAR_REPLACEMENTS = addRulesPrefix(
),
'sonar',
)

// from `@angular-eslint/eslint-plugin`
export const NG_ESLINT = '@angular-eslint'

export const NG_AS_IS_REPLACEMENTS = [
'component-class-suffix',
'component-max-inline-declarations',
'component-selector',
'contextual-decorator',
'contextual-lifecycle',
'directive-class-suffix',
'directive-selector',
'no-attribute-decorator',
'no-conflicting-lifecycle',
'no-forward-ref',
'no-host-metadata-property',
'no-input-prefix',
'no-input-rename',
'no-inputs-metadata-property',
'no-lifecycle-call',
'no-output-native',
'no-output-on-prefix',
'no-output-rename',
'no-outputs-metadata-property',
'no-pipe-impure',
'no-queries-metadata-property',
'pipe-prefix',
'prefer-on-push-component-change-detection',
'prefer-output-readonly',
'relative-url-prefix',
'use-component-selector',
'use-component-view-encapsulation',
'use-injectable-provided-in',
'use-lifecycle-interface',
'use-pipe-transform-interface',
]

export const NG_TEMPLATE_REPLACEMENTS = [
'accessibility-alt-text',
'accessibility-elements-content',
'accessibility-label-for',
'accessibility-tabindex-no-positive',
'accessibility-table-scope',
'accessibility-valid-aria',
'banana-in-box',
'click-events-have-key-events',
'conditional-complexity',
'cyclomatic-complexity',
'i18n',
'mouse-events-have-key-events',
'no-any',
'no-autofocus',
'no-call-expression',
'no-distracting-elements',
'no-negated-async',
'use-track-by-function',
].reduce<RuleReplacements>(
(rules, name) =>
Object.assign(rules, {
[`template-${name}`]: addRulePrefix(name, '@angular-eslint/template'),
}),
{},
)

export const CODELYZER_REPLACEMENTS =
NG_AS_IS_REPLACEMENTS.reduce<RuleReplacements>(
(rules, rule) =>
Object.assign(rules, {
[rule]: addRulePrefix(rule, NG_ESLINT),
}),
{
...NG_TEMPLATE_REPLACEMENTS,

// core
'import-destructuring-spacing': 'object-curly-spacing',

// unnecessary
// https://github.com/angular-eslint/angular-eslint/issues/241
'use-pipe-decorator': null,
},
)

export const NG_TSLINT_REPLACEMENTS = addRulesPrefix(
{
'member-naming': 'naming-convention',
},
TS_ESLINT,
)
12 changes: 11 additions & 1 deletion scripts/readme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import fs from 'fs'
import prettier from 'prettier'

import {
CODELYZER_REPLACEMENTS,
CORE_REPLACEMENTS,
NG_TSLINT_REPLACEMENTS,
RuleReplacements,
SONARJS_REPLACEMENTS,
SONAR_REPLACEMENTS,
Expand Down Expand Up @@ -35,7 +37,7 @@ ${Object.entries(replacements)
oldRule +
'` | ' +
arrayify(newRule)
.map(rule => '`' + rule + '`')
.map(rule => '`' + (rule || 'N/A') + '`')
.join('<br>'),
)
.join('\n')}|
Expand All @@ -54,6 +56,14 @@ ${printReplacements({ ...CORE_REPLACEMENTS, ...TS_REPLACEMENTS })}
${printReplacements({ ...SONARJS_REPLACEMENTS, ...SONAR_REPLACEMENTS })}
### codelyzer
${printReplacements(CODELYZER_REPLACEMENTS)}
### ng-tslint
${printReplacements(NG_TSLINT_REPLACEMENTS)}
${suffix}`,
{
...prettier.resolveConfig.sync(readmePath),
Expand Down
Loading

0 comments on commit 5029b81

Please sign in to comment.