From 9ae1f10bc4ea4e5d05415fd87954ac1f19c3bc0c Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 2 Feb 2019 18:53:57 -0500 Subject: [PATCH 1/7] Revamped configs into 'core', 'latest', and (legacy) 'recommended' Those three config files now exist as `.json` under `/configs`; they're copied to `dist/build/configs`. `recommended.json` becomes `tslint.json` as well. --- .gitignore | 21 +- .prettierignore | 6 +- README.md | 52 +++- build-tasks/common/files.js | 10 + build-tasks/common/meta.js | 4 +- build-tasks/copy-config-json.js | 23 ++ build-tasks/generate-default-tslint-json.js | 11 - build-tasks/generate-recommendations.js | 54 ---- build-tasks/generate-stable-config.js | 54 ++++ .../templates/recommended_ruleset.template.js | 49 --- build-tasks/templates/stable.json.template.js | 6 + build-tasks/validate-config.js | 57 ---- configs/latest.json | 6 + configs/recommended.json | 286 ++++++++++++++++++ configs/stable.json | 82 +++++ package-lock.json | 14 +- package.json | 10 +- recommended_ruleset.js | 280 ----------------- src/utils/ExtendedMetadata.ts | 2 +- 19 files changed, 529 insertions(+), 498 deletions(-) create mode 100644 build-tasks/copy-config-json.js delete mode 100644 build-tasks/generate-default-tslint-json.js delete mode 100644 build-tasks/generate-recommendations.js create mode 100644 build-tasks/generate-stable-config.js delete mode 100644 build-tasks/templates/recommended_ruleset.template.js create mode 100644 build-tasks/templates/stable.json.template.js delete mode 100644 build-tasks/validate-config.js create mode 100644 configs/latest.json create mode 100644 configs/recommended.json create mode 100644 configs/stable.json delete mode 100644 recommended_ruleset.js diff --git a/.gitignore b/.gitignore index 1f274d955..af901ca55 100644 --- a/.gitignore +++ b/.gitignore @@ -1,24 +1,7 @@ +.npm_cache node_modules npm-debug.log -# TypeScrit temporary/cache files -**/.baseDir.ts -**/.tscache/ -tscommand-*.tmp.txt - +# Generated for builds **/dist/ - -# IDEA -.idea -tslint-microsoft-contrib.iml - -# vim swap files -*.sw* - -**/tags - -# local npm cache -.npm_cache - -out.html rule-metadata.json diff --git a/.prettierignore b/.prettierignore index bbdf00961..b121f7793 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,9 @@ # Build directory dist/ +# Configuration settings +configs/ + # Definition files *.d.ts @@ -10,6 +13,3 @@ package-lock.json # Test files test-data/NoUnnecessarySemicolonsTestInput.ts - -# Generated files -recommended_ruleset.js diff --git a/README.md b/README.md index 99980dad4..73d448c80 100644 --- a/README.md +++ b/README.md @@ -40,23 +40,57 @@ Add `"node_modules/tslint-microsoft-contrib"` under your `"rulesDirectory"` conf ### Which Rules Should I Turn On? There certainly are a lot of options! -To start, you can enable our recommended defaults ([recommended_ruleset.js](recommended_ruleset.js)) by adding `"tslint-microsoft-contrib"` under `"extends"` in your `tslint.json`: + +If you extend from one of the following configurations, `rulesDirectory` will have `node_modules/tslint-microsoft-contrib` included for you. + +> Please note, some of the default ruleset rules require the `--project` TSLint option. + +#### Stable + +To start, you can enable our "stable" defaults that come with tslint-microsoft-contrib ([configs/stable.json](./configs/stable.json)) by adding `"tslint-microsoft-contrib/configs/stable"` under `"extends"` in your `tslint.json`: ```json { - "extends": ["tslint-microsoft-contrib"], - "rulesDirectory": ["node_modules/tslint-microsoft-contrib"], - "rules": { - // ... - } + "extends": ["tslint-microsoft-contrib/configs/stable.json"] + // ... +} +``` + +These rules will not be added to in minor or patch releases, but will be in major releases. + +#### Latest + +To run with the latest and greatest rules ([configs/latest.json](./configs/latest.json)), extend from `tslint-microsoft-contrib/configs/latest`: + +```json +{ + "extends": ["tslint-microsoft-contrib/configs/latest.json"] + // ... } ``` -You can then disable rules you don't find useful. +These rules will not be added to in patch releases, but will be in minor releases. + +#### Recommended + +The "recommended" ruleset that ships by extending `tslint-microsoft-contrib` itself contains a list of rules that includes core TSLint rules. + +To start, you can enable our recommended defaults ([configs/recommended.json](./configs/recommended.json)) by adding just `"tslint-microsoft-contrib"` under `"extends"` in your `tslint.json`: + +```json +{ + "extends": ["tslint-microsoft-contrib"] + // ... +} +``` + +**The "recommended" ruleset is considered legacy**; it is generally preferable to extend from the stable or latest rulesets. +We recommend you instead explicitly include `tslint:recommended`, `tslint:latest`, or `tslint:all` in your `tslint.json` rather than enable core rules through this configuration. + +### Overriding Configurations -Please note, some of the default rules require the `--project` TSLint option. +You can [disable rules](https://palantir.github.io/tslint/usage/rule-flags) you don't find useful. -Also, please note that adding a rule to the recommended ruleset is considered backwards compatible. If you rely on version ranges in your dependencies then you may find that new rules being added to the product create violations and fail your build. We recommend you specify exact versions of lint libraries, including `tslint-microsoft-contrib`, in your `package.json`. diff --git a/build-tasks/common/files.js b/build-tasks/common/files.js index 5ead290e0..d07b11e66 100644 --- a/build-tasks/common/files.js +++ b/build-tasks/common/files.js @@ -2,6 +2,15 @@ const { red } = require('chalk'); const fs = require('fs'); const stripJsonComments = require('strip-json-comments'); +function readDirectory(directoryName) { + try { + return fs.readdirSync(directoryName); + } catch (e) { + console.log(red(`Unable to read directory: ${directoryName}. Error code: ${e.code}`)); + process.exit(1); + } +} + function readFile(fileName) { try { return fs.readFileSync(fileName, { encoding: 'utf8' }); @@ -39,6 +48,7 @@ function readJSONWithComments(fileName) { } module.exports = { + readDirectory, readFile, readJSON, readJSONWithComments, diff --git a/build-tasks/common/meta.js b/build-tasks/common/meta.js index 57be173b5..6e6f2494c 100644 --- a/build-tasks/common/meta.js +++ b/build-tasks/common/meta.js @@ -2,9 +2,9 @@ const path = require('path'); const glob = require('glob'); const { readJSON } = require('./files'); -function getAllRules() { +function getAllRules({ ignoreTslintRules = false } = {}) { const contribRules = glob.sync('dist/build/*Rule.js'); - const baseRules = glob.sync('node_modules/tslint/lib/rules/*Rule.js'); + const baseRules = ignoreTslintRules ? [] : glob.sync('node_modules/tslint/lib/rules/*Rule.js'); return contribRules.concat(baseRules); } diff --git a/build-tasks/copy-config-json.js b/build-tasks/copy-config-json.js new file mode 100644 index 000000000..f02b5f72f --- /dev/null +++ b/build-tasks/copy-config-json.js @@ -0,0 +1,23 @@ +/** + * Converts configs/ to ./dist/build/configs/ and configs/recommended.json to ./dist/build/recommended.json. + */ + +const mkdirp = require('mkdirp'); +const path = require('path'); + +const { readDirectory, readFile, writeFile } = require('./common/files'); + +const copyConfigFile = (configFileName, destinationFileName, newRulesDirectory) => { + const resolvedDestination = path.resolve(destinationFileName); + const data = readFile(path.resolve(configFileName)); + + writeFile(resolvedDestination, data.replace(/"rulesDirectory": \[(.*)\]/, `"rulesDirectory": ["${newRulesDirectory}"]`)); +}; + +mkdirp.sync('./dist/build/configs'); + +for (const configFileName of readDirectory('./configs')) { + copyConfigFile(`./configs/${configFileName}`, `./dist/build/configs/${configFileName}`, '../'); +} + +copyConfigFile('./configs/recommended.json', './dist/build/tslint.json', './'); diff --git a/build-tasks/generate-default-tslint-json.js b/build-tasks/generate-default-tslint-json.js deleted file mode 100644 index b9982fc4d..000000000 --- a/build-tasks/generate-default-tslint-json.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Converts recommended_ruleset.js to ./dist/build/tslint.json. - */ - -const path = require('path'); -const { writeFile } = require('./common/files'); - -const data = require(path.resolve('recommended_ruleset.js')); -data.rulesDirectory = './'; - -writeFile('dist/build/tslint.json', JSON.stringify(data, undefined, 4)); diff --git a/build-tasks/generate-recommendations.js b/build-tasks/generate-recommendations.js deleted file mode 100644 index d90845e93..000000000 --- a/build-tasks/generate-recommendations.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Generates the recommended_ruleset.js file. - */ - -const { red } = require('chalk'); -const { writeFile } = require('./common/files'); -const { getAllRules, getMetadataFromFile, getMetadataValue } = require('./common/meta'); -const groupedRows = {}; -const warnings = []; - -/** - * @see https://github.com/Microsoft/tslint-microsoft-contrib/issues/694 - */ -const ignoredRulesNotYetAdded = new Set(['ban-ts-ignore', 'comment-type', 'no-default-import', 'unnecessary-constructor']); - -getAllRules().forEach(ruleFile => { - const metadata = getMetadataFromFile(ruleFile); - - const ruleName = getMetadataValue(metadata, 'ruleName'); - if (ignoredRulesNotYetAdded.has(ruleName)) { - return; - } - - const groupName = getMetadataValue(metadata, 'group'); - if (groupName === 'Ignored') { - return; - } - if (groupName === '') { - warnings.push('Could not generate recommendation for rule file: ' + ruleFile); - } - if (groupedRows[groupName] === undefined) { - groupedRows[groupName] = []; - } - - let recommendation = getMetadataValue(metadata, 'recommendation', true, true); - if (recommendation === '') { - recommendation = 'true,'; - } - // Replace double quotes with single quote - recommendation = recommendation.replace(/"/g, "'"); - - groupedRows[groupName].push(` '${ruleName}': ${recommendation}`); -}); - -if (warnings.length > 0) { - console.log('\n' + red(warnings.join('\n'))); - process.exit(1); -} -Object.keys(groupedRows).forEach(groupName => groupedRows[groupName].sort()); - -const recommendedTemplate = require('./templates/recommended_ruleset.template'); -const data = recommendedTemplate(groupedRows); - -writeFile('recommended_ruleset.js', data); diff --git a/build-tasks/generate-stable-config.js b/build-tasks/generate-stable-config.js new file mode 100644 index 000000000..e3ab023c4 --- /dev/null +++ b/build-tasks/generate-stable-config.js @@ -0,0 +1,54 @@ +/** + * Generates config/stable.json. + * The `recommended` metadata for each rule is added there, except if... + * - ...the rule's `metadata.group` is `'Ignored'` + * - ...the rule is also mentioned in config/latest.json (which would be a breaking change) + * - ...the recommended setting is `false` (the rule is likely deprecated) + */ + +const { red } = require('chalk'); +const { writeFile } = require('./common/files'); +const { getAllRules, getMetadataFromFile, getMetadataValue } = require('./common/meta'); + +const recommendations = []; +const warnings = []; + +const latestRules = new Set(Object.keys(require('../configs/latest.json').rules)); + +getAllRules({ + ignoreTslintRules: true +}).forEach(ruleFile => { + const metadata = getMetadataFromFile(ruleFile); + const ruleName = getMetadataValue(metadata, 'ruleName'); + + const groupName = getMetadataValue(metadata, 'group'); + if (groupName === 'Ignored') { + return; + } + + let recommendation = getMetadataValue(metadata, 'recommendation', true, true); + if (recommendation === '') { + recommendation = 'true,'; + } + + // Don't mention rules recommended as disabled + if (recommendation.startsWith('false')) { + return; + } + + // Don't mention rules added to the 'latest' preset, as adding them to stable.json would be a breaking change + if (latestRules.has(ruleName)) { + return; + } + + recommendations.push(` "${ruleName}": ${recommendation}`); +}); + +if (warnings.length > 0) { + console.log('\n' + red(warnings.join('\n'))); + process.exit(1); +} + +const stableTemplate = require('./templates/stable.json.template'); + +writeFile('configs/stable.json', stableTemplate(recommendations)); diff --git a/build-tasks/templates/recommended_ruleset.template.js b/build-tasks/templates/recommended_ruleset.template.js deleted file mode 100644 index ae230aa94..000000000 --- a/build-tasks/templates/recommended_ruleset.template.js +++ /dev/null @@ -1,49 +0,0 @@ -module.exports = rows => - `/** - * These rule settings are a broad, general recommendation for a good default configuration. - * This file is exported in the npm/nuget package as ./tslint.json. - */ -module.exports = { - 'rules': { - /** - * Security Rules. The following rules should be turned on because they find security issues - * or are recommended in the Microsoft Secure Development Lifecycle (SDL) - */ -${rows.Security.join('\n')} - - /** - * Common Bugs and Correctness. The following rules should be turned on because they find - * common bug patterns in the code or enforce type safety. - */ -${rows.Correctness.join('\n')} - - /** - * Code Clarity. The following rules should be turned on because they make the code - * generally more clear to the reader. - */ -${rows.Clarity.join('\n')} - - /** - * Accessibility. The following rules should be turned on to guarantee the best user - * experience for keyboard and screen reader users. - */ -${rows.Accessibility.join('\n')} - - /** - * Whitespace related rules. The only recommended whitespace strategy is to pick a single format and - * be consistent. - */ -${rows.Whitespace.join('\n')} - - /** - * Controversial/Configurable rules. - */ -${rows.Configurable.join('\n')} - - /** - * Deprecated rules. The following rules are deprecated for various reasons. - */ -${rows.Deprecated.join('\n')} - } -}; -`; diff --git a/build-tasks/templates/stable.json.template.js b/build-tasks/templates/stable.json.template.js new file mode 100644 index 000000000..e40d99ef1 --- /dev/null +++ b/build-tasks/templates/stable.json.template.js @@ -0,0 +1,6 @@ +module.exports = recommendations => `{ + "rulesDirectory": ["../"], + "rules": { +${[...recommendations].sort().join('\n')} + } +}`; diff --git a/build-tasks/validate-config.js b/build-tasks/validate-config.js deleted file mode 100644 index 7cdadfc0d..000000000 --- a/build-tasks/validate-config.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Makes sure all the rules in the project are defined to run during the build. - */ - -const { yellow, yellowBright } = require('chalk'); -const { readJSONWithComments } = require('./common/files'); -const { getContribRuleNames } = require('./common/meta'); - -const tslintConfig = readJSONWithComments('tslint.json'); - -function ruleIsEnabled(value) { - if (value === undefined) { - return false; - } - - if (typeof value === 'boolean') { - return value; - } - - return value[0]; -} - -const disabledRules = new Set([ - 'missing-jsdoc', - 'no-duplicate-case', - 'no-empty-interfaces', - 'no-empty-line-after-opening-brace', - 'no-function-constructor-with-string-args', - 'no-increment-decrement', - 'no-multiline-string', - 'no-reserved-keywords', - 'no-relative-imports', - 'no-stateless-class', - 'no-unexternalized-strings', - 'no-unnecessary-bind', - 'no-unnecessary-semicolons', - 'no-var-self', - 'react-tsx-curly-spacing', - 'valid-typeof' -]); - -const errors = []; -getContribRuleNames().forEach(ruleName => { - if (disabledRules.has(ruleName)) { - return; - } - - if (!ruleIsEnabled(tslintConfig.rules[ruleName])) { - errors.push('A tslint-microsoft-contrib rule was found that is not enabled on the project: ' + ruleName); - } -}); - -if (errors.length > 0) { - console.log(yellow(errors.join('\n'))); - console.log(yellowBright(`Add the missing rule${errors.length === 1 ? '' : 's'} to tslint.json.`)); - process.exit(1); -} diff --git a/configs/latest.json b/configs/latest.json new file mode 100644 index 000000000..b7522008d --- /dev/null +++ b/configs/latest.json @@ -0,0 +1,6 @@ +{ + "extends": ["./stable.json"], + "rules": { + "react-a11y-iframes": true + } +} diff --git a/configs/recommended.json b/configs/recommended.json new file mode 100644 index 000000000..8ed00778a --- /dev/null +++ b/configs/recommended.json @@ -0,0 +1,286 @@ +/** + * This "recommended" ruleset is considered legacy; + * it is generally preferable to extend from the stable or latest rulesets. + * We recommend you instead explicitly include `tslint:recommended`, `tslint:latest`, or `tslint:all` + * in your `tslint.json` rather than enable core rules through this configuration. + * + * These rule settings are a broad, general recommendation for a good default configuration. + * This file is exported in the npm/nuget package as ./tslint.json. + */ +{ + "rulesDirectory": [], + "rules": { + /** + * Security Rules. The following rules should be turned on because they find security issues + * or are recommended in the Microsoft Secure Development Lifecycle (SDL) + */ + "function-constructor": true, + "insecure-random": true, + "no-banned-terms": true, + "no-cookies": true, + "no-delete-expression": true, + "no-disable-auto-sanitization": true, + "no-document-domain": true, + "no-document-write": true, + "no-eval": true, + "no-exec-script": true, + "no-function-constructor-with-string-args": false, // use tslint function-constructor rule intsead + "no-http-string": [true, "http://www.example.com/?.*", "http://localhost:?.*"], + "no-inner-html": true, + "no-octal-literal": true, + "no-string-based-set-immediate": true, + "no-string-based-set-interval": true, + "no-string-based-set-timeout": true, + "non-literal-fs-path": true, + "non-literal-require": true, + "possible-timing-attack": true, + "react-anchor-blank-noopener": true, + "react-iframe-missing-sandbox": true, + "react-no-dangerous-html": true, + + /** + * Common Bugs and Correctness. The following rules should be turned on because they find + * common bug patterns in the code or enforce type safety. + */ + "await-promise": true, + "forin": true, + "increment-decrement": true, + "jquery-deferred-must-complete": true, + "label-position": true, + "match-default-export-name": true, + "mocha-avoid-only": true, + "mocha-no-side-effect-code": true, + "no-any": true, + "no-arg": true, + "no-backbone-get-set-outside-model": true, + "no-bitwise": true, + "no-conditional-assignment": true, + "no-console": [true, "debug", "info", "error", "log", "time", "timeEnd", "trace"], + "no-constant-condition": true, + "no-control-regex": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-duplicate-switch-case": true, + "no-duplicate-variable": true, + "no-empty": true, + "no-floating-promises": true, + "no-for-in-array": true, + "no-implicit-dependencies": true, + "no-import-side-effect": true, + "no-increment-decrement": false, // use tslint increment-decrement rule instead + "no-invalid-regexp": true, + "no-invalid-template-strings": true, + "no-invalid-this": true, + "no-jquery-raw-elements": true, + "no-misused-new": true, + "no-non-null-assertion": true, + "no-object-literal-type-assertion": true, + "no-parameter-reassignment": true, + "no-reference-import": true, + "no-regex-spaces": true, + "no-sparse-arrays": true, + "no-string-literal": true, + "no-string-throw": true, + "no-submodule-imports": true, + "no-unnecessary-bind": false, // use tslint unnecessary-bind rule instead + "no-unnecessary-callback-wrapper": true, + "no-unnecessary-initializer": true, + "no-unnecessary-override": true, + "no-unsafe-any": true, + "no-unsafe-finally": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-with-statement": true, + "promise-function-async": true, + "promise-must-complete": true, + "radix": true, + "react-this-binding-issue": true, + "react-unused-props-and-state": true, + "restrict-plus-operands": true, // the plus operand should really only be used for strings and numbers + "strict-boolean-expressions": true, + "switch-default": true, + "switch-final-break": true, + "triple-equals": [true, "allow-null-check"], + "unnecessary-bind": true, + "use-isnan": true, + "use-named-parameter": true, + "use-simple-attributes": true, + + /** + * Code Clarity. The following rules should be turned on because they make the code + * generally more clear to the reader. + */ + "adjacent-overload-signatures": true, + "array-type": [true, "array"], + "arrow-parens": false, // for simple functions the parens on arrow functions are not needed + "ban-comma-operator": true, // possibly controversial + "binary-expression-operand-order": true, + "callable-types": true, + "chai-prefer-contains-to-index-of": true, + "chai-vague-errors": true, + "class-name": true, + "comment-format": true, + "completed-docs": [true, "classes"], + "export-name": true, + "file-name-casing": true, + "function-name": true, + "import-name": true, + "informative-docs": true, + "interface-name": true, + "jsdoc-format": true, + "max-classes-per-file": [true, 3], // we generally recommend making one public class per file + "max-file-line-count": true, + "max-func-body-length": [true, 100, { "ignore-parameters-to-function-regex": "^describe$" }], + "max-line-length": [true, 140], + "member-access": true, + "member-ordering": [true, { "order": "fields-first" }], + "mocha-unneeded-done": true, + "new-parens": true, + "newline-per-chained-call": true, + "no-construct": true, + "no-default-export": true, + "no-duplicate-imports": true, + "no-dynamic-delete": true, + "no-empty-interface": true, + "no-for-in": true, + "no-function-expression": true, + "no-inferrable-types": false, // turn no-inferrable-types off in order to make the code consistent in its use of type decorations + "no-multiline-string": false, + "no-null-keyword": true, + "no-parameter-properties": true, + "no-redundant-jsdoc": true, + "no-relative-imports": true, + "no-require-imports": true, + "no-return-await": true, + "no-shadowed-variable": true, + "no-suspicious-comment": true, + "no-this-assignment": true, + "no-typeof-undefined": true, + "no-unnecessary-field-initialization": true, + "no-unnecessary-local-variable": true, + "no-unnecessary-qualifier": true, + "no-unnecessary-type-assertion": true, + "no-unsupported-browser-code": true, + "no-useless-files": true, + "no-var-keyword": true, + "no-var-requires": true, + "no-void-expression": true, + "number-literal-format": true, + "object-literal-sort-keys": false, // turn object-literal-sort-keys off and sort keys in a meaningful manner + "one-variable-per-declaration": true, + "only-arrow-functions": false, // there are many valid reasons to declare a function + "ordered-imports": true, + "prefer-array-literal": true, + "prefer-const": true, + "prefer-for-of": true, + "prefer-method-signature": true, + "prefer-object-spread": true, + "prefer-readonly": true, + "prefer-template": true, + "prefer-while": true, + "type-literal-delimiter": true, + "typedef": [true, "call-signature", "arrow-call-signature", "parameter", "arrow-parameter", "property-declaration", "variable-declaration", "member-variable-declaration"], + "underscore-consistent-invocation": true, + "unified-signatures": true, + "use-default-type-parameter": true, + "variable-name": true, + "void-zero": true, + + /** + * Accessibility. The following rules should be turned on to guarantee the best user + * experience for keyboard and screen reader users. + */ + "react-a11y-accessible-headings": true, + "react-a11y-anchors": true, + "react-a11y-aria-unsupported-elements": true, + "react-a11y-event-has-role": true, + "react-a11y-image-button-has-alt": true, + "react-a11y-img-has-alt": true, + "react-a11y-input-elements": true, + "react-a11y-lang": true, + "react-a11y-meta": true, + "react-a11y-no-onchange": true, + "react-a11y-props": true, + "react-a11y-proptypes": true, + "react-a11y-required": true, + "react-a11y-role": true, + "react-a11y-role-has-required-aria-props": true, + "react-a11y-role-supports-aria-props": true, + "react-a11y-tabindex-no-positive": true, + "react-a11y-titles": true, + + /** + * Whitespace related rules. The only recommended whitespace strategy is to pick a single format and + * be consistent. + */ + "align": [true, "parameters", "arguments", "statements"], + "curly": true, + "encoding": true, + "eofline": true, + "import-spacing": true, + "indent": [true, "spaces"], + "linebreak-style": true, + "newline-before-return": true, + "no-consecutive-blank-lines": true, + "no-empty-line-after-opening-brace": false, + "no-irregular-whitespace": true, + "no-single-line-block-comment": true, + "no-trailing-whitespace": true, + "no-unnecessary-semicolons": true, + "object-literal-key-quotes": [true, "as-needed"], + "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"], + "quotemark": [true, "single"], + "semicolon": [true, "always"], + "space-within-parens": true, + "trailing-comma": [true, { "singleline": "never", "multiline": "never" }], // forcing trailing commas for multi-line + // lists results in lists that are easier to reorder and version control diffs that are more clear. + // Many teams like to have multiline be "always". There is no clear consensus on this rule but the + // internal MS JavaScript coding standard does discourage it. + "typedef-whitespace": false, + "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"], + + /** + * Controversial/Configurable rules. + */ + "ban": false, // only enable this if you have some code pattern that you want to ban + "ban-types": true, + "cyclomatic-complexity": true, + "deprecation": false, // deprecated APIs are sometimes unavoidable + "file-header": false, // enable this rule only if you are legally required to add a file header + "import-blacklist": false, // enable and configure this as you desire + "interface-over-type-literal": false, // there are plenty of reasons to prefer interfaces + "no-angle-bracket-type-assertion": false, // pick either type-cast format and use it consistently + "no-inferred-empty-object-type": false, // if the compiler is satisfied then this is probably not an issue + "no-internal-module": false, // only enable this if you are not using internal modules + "no-magic-numbers": false, // by default it will find too many false positives + "no-mergeable-namespace": false, // your project may require mergeable namespaces + "no-namespace": false, // only enable this if you are not using modules/namespaces + "no-reference": true, // in general you should use a module system and not /// reference imports + "no-unexternalized-strings": false, // the VS Code team has a specific localization process that this rule enforces + "object-literal-shorthand": false, // object-literal-shorthand offers an abbreviation not an abstraction + "prefer-conditional-expression": false, // unnecessarily strict + "prefer-switch": false, // more of a style preference + "prefer-type-cast": true, // pick either type-cast format and use it consistently + "return-undefined": false, // this actually affects the readability of the code + "space-before-function-paren": false, // turn this on if this is really your coding standard + + /** + * Deprecated rules. The following rules are deprecated for various reasons. + */ + "missing-jsdoc": false, + "missing-optional-annotation": false, // now supported by TypeScript compiler + "no-duplicate-case": false, + "no-duplicate-parameter-names": false, // now supported by TypeScript compiler + "no-empty-interfaces": false, // use tslint no-empty-interface rule instead + "no-missing-visibility-modifiers": false, // use tslint member-access rule instead + "no-multiple-var-decl": false, // use tslint one-variable-per-declaration rule instead + "no-reserved-keywords": false, + "no-stateless-class": false, + "no-switch-case-fall-through": false, // now supported by TypeScript compiler + "no-unnecessary-class": true, + "no-var-self": false, + "react-tsx-curly-spacing": false, + "typeof-compare": false, // the valid-typeof rule is currently superior to this version + "valid-typeof": false, + } +}; diff --git a/configs/stable.json b/configs/stable.json new file mode 100644 index 000000000..2dfd18f0f --- /dev/null +++ b/configs/stable.json @@ -0,0 +1,82 @@ +{ + "rulesDirectory": ["../"], + "rules": { + "chai-prefer-contains-to-index-of": true, + "chai-vague-errors": true, + "export-name": true, + "function-name": true, + "import-name": true, + "informative-docs": true, + "insecure-random": true, + "jquery-deferred-must-complete": true, + "max-func-body-length": [true, 100, { "ignore-parameters-to-function-regex": "^describe$" }], + "mocha-avoid-only": true, + "mocha-no-side-effect-code": true, + "mocha-unneeded-done": true, + "no-backbone-get-set-outside-model": true, + "no-banned-terms": true, + "no-constant-condition": true, + "no-control-regex": true, + "no-cookies": true, + "no-delete-expression": true, + "no-disable-auto-sanitization": true, + "no-document-domain": true, + "no-document-write": true, + "no-exec-script": true, + "no-for-in": true, + "no-function-expression": true, + "no-http-string": [true, "http://www.example.com/?.*", "http://localhost:?.*"], + "no-inner-html": true, + "no-invalid-regexp": true, + "no-jquery-raw-elements": true, + "no-octal-literal": true, + "no-regex-spaces": true, + "no-relative-imports": true, + "no-single-line-block-comment": true, + "no-string-based-set-immediate": true, + "no-string-based-set-interval": true, + "no-string-based-set-timeout": true, + "no-suspicious-comment": true, + "no-typeof-undefined": true, + "no-unnecessary-field-initialization": true, + "no-unnecessary-local-variable": true, + "no-unnecessary-override": true, + "no-unnecessary-semicolons": true, + "no-unsupported-browser-code": true, + "no-useless-files": true, + "no-with-statement": true, + "non-literal-fs-path": true, + "non-literal-require": true, + "possible-timing-attack": true, + "prefer-array-literal": true, + "prefer-type-cast": true, // pick either type-cast format and use it consistently + "promise-must-complete": true, + "react-a11y-accessible-headings": true, + "react-a11y-anchors": true, + "react-a11y-aria-unsupported-elements": true, + "react-a11y-event-has-role": true, + "react-a11y-image-button-has-alt": true, + "react-a11y-img-has-alt": true, + "react-a11y-input-elements": true, + "react-a11y-lang": true, + "react-a11y-meta": true, + "react-a11y-no-onchange": true, + "react-a11y-props": true, + "react-a11y-proptypes": true, + "react-a11y-required": true, + "react-a11y-role": true, + "react-a11y-role-has-required-aria-props": true, + "react-a11y-role-supports-aria-props": true, + "react-a11y-tabindex-no-positive": true, + "react-a11y-titles": true, + "react-anchor-blank-noopener": true, + "react-iframe-missing-sandbox": true, + "react-no-dangerous-html": true, + "react-this-binding-issue": true, + "react-unused-props-and-state": true, + "underscore-consistent-invocation": true, + "use-named-parameter": true, + "use-simple-attributes": true, + "void-zero": true + } +} diff --git a/package-lock.json b/package-lock.json index dec380380..cc37d684f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2987,6 +2987,12 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, "minimist-options": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", @@ -3025,14 +3031,6 @@ "dev": true, "requires": { "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } } }, "mocha": { diff --git a/package.json b/package.json index 103a2c6d7..a42d5aa30 100644 --- a/package.json +++ b/package.json @@ -49,12 +49,12 @@ }, "scripts": { "clean": "rimraf dist", + "copy:config-json": "node build-tasks/copy-config-json.js", "copy:json": "cpy \"src/**/*.json\" dist --parents", - "copy:meta": "cpy README.md recommended_ruleset.js dist/build --parents", + "copy:meta": "cpy README.md dist/build --parents", "copy:package": "cpy \"**/*.js\" \"**/*.json\" \"!tests/**\" \"!references.js\" \"tests/TestHelper.js\" \"tests/TestHelper.d.ts\" ../build --cwd=\"dist/src\" --parents", "create-rule": "node build-tasks/create-rule.js", - "generate:recommendations": "node build-tasks/generate-recommendations.js", - "generate:default-tslint-json": "node build-tasks/generate-default-tslint-json.js", + "generate:stable-config": "node build-tasks/generate-stable-config.js", "generate:sdl-report": "node build-tasks/generate-sdl-report.js", "generate:rule-metadata": "node build-tasks/generate-rule-metadata.js", "generate:package-json-for-npm": "node build-tasks/generate-package-json-for-npm.js", @@ -64,10 +64,9 @@ "start": "npm-run-all clean copy:json watch:src", "test:mocha": "mocha \"dist/src/tests/**/*.js\" --timeout 5000", "test:rules": "tslint -r dist/src --test \"tests/**\"", - "test": "npm-run-all clean copy:json tsc:src test:* tslint:check lint:* validate:* copy:package copy:meta generate:*", + "test": "npm-run-all clean copy:json tsc:src test:* tslint:check lint:* validate:* copy:package generate:* copy:meta copy:config-json", "tsc:src": "tsc", "tslint:check": "tslint-config-prettier-check ./tslint.json", - "validate:config": "node build-tasks/validate-config.js", "validate:documentation": "node build-tasks/validate-documentation.js", "watch:run-tests": "node build-tasks/watch-run-tests.js", "watch:src": "tsc --watch" @@ -87,6 +86,7 @@ "husky": "^1.1.3", "inquirer": "^6.2.1", "lint-staged": "^8.0.4", + "mkdirp": "^0.5.1", "mocha": "5.2.0", "npm-run-all": "^4.1.5", "prettier": "1.15.0", diff --git a/recommended_ruleset.js b/recommended_ruleset.js deleted file mode 100644 index 2f88ebc8a..000000000 --- a/recommended_ruleset.js +++ /dev/null @@ -1,280 +0,0 @@ -/** - * These rule settings are a broad, general recommendation for a good default configuration. - * This file is exported in the npm/nuget package as ./tslint.json. - */ -module.exports = { - 'rules': { - /** - * Security Rules. The following rules should be turned on because they find security issues - * or are recommended in the Microsoft Secure Development Lifecycle (SDL) - */ - 'function-constructor': true, - 'insecure-random': true, - 'no-banned-terms': true, - 'no-cookies': true, - 'no-delete-expression': true, - 'no-disable-auto-sanitization': true, - 'no-document-domain': true, - 'no-document-write': true, - 'no-eval': true, - 'no-exec-script': true, - 'no-function-constructor-with-string-args': false, // use tslint function-constructor rule intsead - 'no-http-string': [true, 'http://www.example.com/?.*', 'http://localhost:?.*'], - 'no-inner-html': true, - 'no-octal-literal': true, - 'no-string-based-set-immediate': true, - 'no-string-based-set-interval': true, - 'no-string-based-set-timeout': true, - 'non-literal-fs-path': true, - 'non-literal-require': true, - 'possible-timing-attack': true, - 'react-anchor-blank-noopener': true, - 'react-iframe-missing-sandbox': true, - 'react-no-dangerous-html': true, - - /** - * Common Bugs and Correctness. The following rules should be turned on because they find - * common bug patterns in the code or enforce type safety. - */ - 'await-promise': true, - 'forin': true, - 'increment-decrement': true, - 'jquery-deferred-must-complete': true, - 'label-position': true, - 'match-default-export-name': true, - 'mocha-avoid-only': true, - 'mocha-no-side-effect-code': true, - 'no-any': true, - 'no-arg': true, - 'no-backbone-get-set-outside-model': true, - 'no-bitwise': true, - 'no-conditional-assignment': true, - 'no-console': [true, 'debug', 'info', 'error', 'log', 'time', 'timeEnd', 'trace'], - 'no-constant-condition': true, - 'no-control-regex': true, - 'no-debugger': true, - 'no-duplicate-super': true, - 'no-duplicate-switch-case': true, - 'no-duplicate-variable': true, - 'no-empty': true, - 'no-floating-promises': true, - 'no-for-in-array': true, - 'no-implicit-dependencies': true, - 'no-import-side-effect': true, - 'no-increment-decrement': false, // use tslint increment-decrement rule instead - 'no-invalid-regexp': true, - 'no-invalid-template-strings': true, - 'no-invalid-this': true, - 'no-jquery-raw-elements': true, - 'no-misused-new': true, - 'no-non-null-assertion': true, - 'no-object-literal-type-assertion': true, - 'no-parameter-reassignment': true, - 'no-reference-import': true, - 'no-regex-spaces': true, - 'no-sparse-arrays': true, - 'no-string-literal': true, - 'no-string-throw': true, - 'no-submodule-imports': true, - 'no-unnecessary-bind': false, // use tslint unnecessary-bind rule instead - 'no-unnecessary-callback-wrapper': true, - 'no-unnecessary-initializer': true, - 'no-unnecessary-override': true, - 'no-unsafe-any': true, - 'no-unsafe-finally': true, - 'no-unused-expression': true, - 'no-use-before-declare': true, - 'no-with-statement': true, - 'promise-function-async': true, - 'promise-must-complete': true, - 'radix': true, - 'react-this-binding-issue': true, - 'react-unused-props-and-state': true, - 'restrict-plus-operands': true, // the plus operand should really only be used for strings and numbers - 'strict-boolean-expressions': true, - 'switch-default': true, - 'switch-final-break': true, - 'triple-equals': [true, 'allow-null-check'], - 'unnecessary-bind': true, - 'use-isnan': true, - 'use-named-parameter': true, - 'use-simple-attributes': true, - - /** - * Code Clarity. The following rules should be turned on because they make the code - * generally more clear to the reader. - */ - 'adjacent-overload-signatures': true, - 'array-type': [true, 'array'], - 'arrow-parens': false, // for simple functions the parens on arrow functions are not needed - 'ban-comma-operator': true, // possibly controversial - 'binary-expression-operand-order': true, - 'callable-types': true, - 'chai-prefer-contains-to-index-of': true, - 'chai-vague-errors': true, - 'class-name': true, - 'comment-format': true, - 'completed-docs': [true, 'classes'], - 'export-name': true, - 'file-name-casing': true, - 'function-name': true, - 'import-name': true, - 'informative-docs': true, - 'interface-name': true, - 'jsdoc-format': true, - 'max-classes-per-file': [true, 3], // we generally recommend making one public class per file - 'max-file-line-count': true, - 'max-func-body-length': [true, 100, { 'ignore-parameters-to-function-regex': '^describe$' }], - 'max-line-length': [true, 140], - 'member-access': true, - 'member-ordering': [true, { 'order': 'fields-first' }], - 'mocha-unneeded-done': true, - 'new-parens': true, - 'newline-per-chained-call': true, - 'no-construct': true, - 'no-default-export': true, - 'no-duplicate-imports': true, - 'no-dynamic-delete': true, - 'no-empty-interface': true, - 'no-for-in': true, - 'no-function-expression': true, - 'no-inferrable-types': false, // turn no-inferrable-types off in order to make the code consistent in its use of type decorations - 'no-multiline-string': false, - 'no-null-keyword': true, - 'no-parameter-properties': true, - 'no-redundant-jsdoc': true, - 'no-relative-imports': true, - 'no-require-imports': true, - 'no-return-await': true, - 'no-shadowed-variable': true, - 'no-suspicious-comment': true, - 'no-this-assignment': true, - 'no-typeof-undefined': true, - 'no-unnecessary-field-initialization': true, - 'no-unnecessary-local-variable': true, - 'no-unnecessary-qualifier': true, - 'no-unnecessary-type-assertion': true, - 'no-unsupported-browser-code': true, - 'no-useless-files': true, - 'no-var-keyword': true, - 'no-var-requires': true, - 'no-void-expression': true, - 'number-literal-format': true, - 'object-literal-sort-keys': false, // turn object-literal-sort-keys off and sort keys in a meaningful manner - 'one-variable-per-declaration': true, - 'only-arrow-functions': false, // there are many valid reasons to declare a function - 'ordered-imports': true, - 'prefer-array-literal': true, - 'prefer-const': true, - 'prefer-for-of': true, - 'prefer-method-signature': true, - 'prefer-object-spread': true, - 'prefer-readonly': true, - 'prefer-template': true, - 'prefer-while': true, - 'type-literal-delimiter': true, - 'typedef': [true, 'call-signature', 'arrow-call-signature', 'parameter', 'arrow-parameter', 'property-declaration', 'variable-declaration', 'member-variable-declaration'], - 'underscore-consistent-invocation': true, - 'unified-signatures': true, - 'use-default-type-parameter': true, - 'variable-name': true, - 'void-zero': true, - - /** - * Accessibility. The following rules should be turned on to guarantee the best user - * experience for keyboard and screen reader users. - */ - 'react-a11y-accessible-headings': true, - 'react-a11y-anchors': true, - 'react-a11y-aria-unsupported-elements': true, - 'react-a11y-event-has-role': true, - 'react-a11y-image-button-has-alt': true, - 'react-a11y-img-has-alt': true, - 'react-a11y-input-elements': true, - 'react-a11y-lang': true, - 'react-a11y-meta': true, - 'react-a11y-no-onchange': true, - 'react-a11y-props': true, - 'react-a11y-proptypes': true, - 'react-a11y-required': true, - 'react-a11y-role': true, - 'react-a11y-role-has-required-aria-props': true, - 'react-a11y-role-supports-aria-props': true, - 'react-a11y-tabindex-no-positive': true, - 'react-a11y-titles': true, - - /** - * Whitespace related rules. The only recommended whitespace strategy is to pick a single format and - * be consistent. - */ - 'align': [true, 'parameters', 'arguments', 'statements'], - 'curly': true, - 'encoding': true, - 'eofline': true, - 'import-spacing': true, - 'indent': [true, 'spaces'], - 'linebreak-style': true, - 'newline-before-return': true, - 'no-consecutive-blank-lines': true, - 'no-empty-line-after-opening-brace': false, - 'no-irregular-whitespace': true, - 'no-single-line-block-comment': true, - 'no-trailing-whitespace': true, - 'no-unnecessary-semicolons': true, - 'object-literal-key-quotes': [true, 'as-needed'], - 'one-line': [true, 'check-open-brace', 'check-catch', 'check-else', 'check-whitespace'], - 'quotemark': [true, 'single'], - 'semicolon': [true, 'always'], - 'space-within-parens': true, - 'trailing-comma': [true, { 'singleline': 'never', 'multiline': 'never' }], // forcing trailing commas for multi-line - // lists results in lists that are easier to reorder and version control diffs that are more clear. - // Many teams like to have multiline be 'always'. There is no clear consensus on this rule but the - // internal MS JavaScript coding standard does discourage it. - 'typedef-whitespace': false, - 'whitespace': [true, 'check-branch', 'check-decl', 'check-operator', 'check-separator', 'check-type'], - - /** - * Controversial/Configurable rules. - */ - 'ban': false, // only enable this if you have some code pattern that you want to ban - 'ban-types': true, - 'cyclomatic-complexity': true, - 'deprecation': false, // deprecated APIs are sometimes unavoidable - 'file-header': false, // enable this rule only if you are legally required to add a file header - 'import-blacklist': false, // enable and configure this as you desire - 'interface-over-type-literal': false, // there are plenty of reasons to prefer interfaces - 'no-angle-bracket-type-assertion': false, // pick either type-cast format and use it consistently - 'no-inferred-empty-object-type': false, // if the compiler is satisfied then this is probably not an issue - 'no-internal-module': false, // only enable this if you are not using internal modules - 'no-magic-numbers': false, // by default it will find too many false positives - 'no-mergeable-namespace': false, // your project may require mergeable namespaces - 'no-namespace': false, // only enable this if you are not using modules/namespaces - 'no-reference': true, // in general you should use a module system and not /// reference imports - 'no-unexternalized-strings': false, // the VS Code team has a specific localization process that this rule enforces - 'object-literal-shorthand': false, // object-literal-shorthand offers an abbreviation not an abstraction - 'prefer-conditional-expression': false, // unnecessarily strict - 'prefer-switch': false, // more of a style preference - 'prefer-type-cast': true, // pick either type-cast format and use it consistently - 'return-undefined': false, // this actually affects the readability of the code - 'space-before-function-paren': false, // turn this on if this is really your coding standard - - /** - * Deprecated rules. The following rules are deprecated for various reasons. - */ - 'missing-jsdoc': false, - 'missing-optional-annotation': false, // now supported by TypeScript compiler - 'no-duplicate-case': false, - 'no-duplicate-parameter-names': false, // now supported by TypeScript compiler - 'no-empty-interfaces': false, // use tslint no-empty-interface rule instead - 'no-missing-visibility-modifiers': false, // use tslint member-access rule instead - 'no-multiple-var-decl': false, // use tslint one-variable-per-declaration rule instead - 'no-reserved-keywords': false, - 'no-stateless-class': false, - 'no-switch-case-fall-through': false, // now supported by TypeScript compiler - 'no-unnecessary-class': true, - 'no-var-self': false, - 'react-tsx-curly-spacing': false, - 'typeof-compare': false, // the valid-typeof rule is currently superior to this version - 'valid-typeof': false, - } -}; diff --git a/src/utils/ExtendedMetadata.ts b/src/utils/ExtendedMetadata.ts index b1a955b34..f6bbab2f0 100644 --- a/src/utils/ExtendedMetadata.ts +++ b/src/utils/ExtendedMetadata.ts @@ -30,6 +30,6 @@ export type Severity = 'Critical' | 'Important' | 'Moderate' | 'Low'; export type Level = 'Mandatory' | 'Opportunity for Excellence'; /** - * Ignored - Use this value to exclude the rule from recommended_ruleset.js and the deployed tslint.json file. + * Ignored - Use this value to exclude the rule from configs/recommended.json and the deployed tslint.json file. */ export type Group = 'Ignored' | 'Security' | 'Correctness' | 'Accessibility' | 'Clarity' | 'Whitespace' | 'Configurable' | 'Deprecated'; From d96cd9cca1c0aff087efa4ae9cc20be970e9464e Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 17 Feb 2019 20:32:54 -0500 Subject: [PATCH 2/7] Normalized trailing commas; added back .gitignore fields --- .gitignore | 7 +++++++ build-tasks/generate-stable-config.js | 11 ++--------- build-tasks/templates/stable.json.template.js | 5 +++-- configs/recommended.json | 4 ++-- configs/stable.json | 2 +- src/informativeDocsRule.ts | 2 +- src/maxFuncBodyLengthRule.ts | 2 +- src/missingJsdocRule.ts | 2 +- src/missingOptionalAnnotationRule.ts | 2 +- src/noDuplicateCaseRule.ts | 2 +- src/noDuplicateParameterNamesRule.ts | 2 +- src/noEmptyInterfacesRule.ts | 2 +- src/noEmptyLineAfterOpeningBraceRule.ts | 2 +- src/noFunctionConstructorWithStringArgsRule.ts | 2 +- src/noHttpStringRule.ts | 2 +- src/noIncrementDecrementRule.ts | 2 +- src/noMissingVisibilityModifiersRule.ts | 2 +- src/noMultilineStringRule.ts | 2 +- src/noMultipleVarDeclRule.ts | 2 +- src/noReservedKeywordsRule.ts | 2 +- src/noStatelessClassRule.ts | 2 +- src/noUnexternalizedStringsRule.ts | 2 +- src/noUnnecessaryBindRule.ts | 2 +- src/noVarSelfRule.ts | 2 +- src/preferTypeCastRule.ts | 2 +- src/reactTsxCurlySpacingRule.ts | 2 +- src/validTypeofRule.ts | 2 +- 27 files changed, 37 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index af901ca55..5314662bf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,13 @@ node_modules npm-debug.log +# IDEA +.idea +tslint-microsoft-contrib.iml + +# vim swap files +*.sw* + # Generated for builds **/dist/ rule-metadata.json diff --git a/build-tasks/generate-stable-config.js b/build-tasks/generate-stable-config.js index e3ab023c4..40c0a31f2 100644 --- a/build-tasks/generate-stable-config.js +++ b/build-tasks/generate-stable-config.js @@ -3,15 +3,13 @@ * The `recommended` metadata for each rule is added there, except if... * - ...the rule's `metadata.group` is `'Ignored'` * - ...the rule is also mentioned in config/latest.json (which would be a breaking change) - * - ...the recommended setting is `false` (the rule is likely deprecated) + * - ...the recommended setting starts with `false` (the rule is likely deprecated) */ -const { red } = require('chalk'); const { writeFile } = require('./common/files'); const { getAllRules, getMetadataFromFile, getMetadataValue } = require('./common/meta'); const recommendations = []; -const warnings = []; const latestRules = new Set(Object.keys(require('../configs/latest.json').rules)); @@ -28,7 +26,7 @@ getAllRules({ let recommendation = getMetadataValue(metadata, 'recommendation', true, true); if (recommendation === '') { - recommendation = 'true,'; + recommendation = 'true'; } // Don't mention rules recommended as disabled @@ -44,11 +42,6 @@ getAllRules({ recommendations.push(` "${ruleName}": ${recommendation}`); }); -if (warnings.length > 0) { - console.log('\n' + red(warnings.join('\n'))); - process.exit(1); -} - const stableTemplate = require('./templates/stable.json.template'); writeFile('configs/stable.json', stableTemplate(recommendations)); diff --git a/build-tasks/templates/stable.json.template.js b/build-tasks/templates/stable.json.template.js index e40d99ef1..8d8469a87 100644 --- a/build-tasks/templates/stable.json.template.js +++ b/build-tasks/templates/stable.json.template.js @@ -1,6 +1,7 @@ module.exports = recommendations => `{ "rulesDirectory": ["../"], "rules": { -${[...recommendations].sort().join('\n')} +${[...recommendations].sort().join(',\n')} } -}`; +} +`; diff --git a/configs/recommended.json b/configs/recommended.json index 8ed00778a..e7bd7aae8 100644 --- a/configs/recommended.json +++ b/configs/recommended.json @@ -281,6 +281,6 @@ "no-var-self": false, "react-tsx-curly-spacing": false, "typeof-compare": false, // the valid-typeof rule is currently superior to this version - "valid-typeof": false, + "valid-typeof": false } -}; +} diff --git a/configs/stable.json b/configs/stable.json index 2dfd18f0f..54ada7a5d 100644 --- a/configs/stable.json +++ b/configs/stable.json @@ -49,7 +49,7 @@ "non-literal-require": true, "possible-timing-attack": true, "prefer-array-literal": true, - "prefer-type-cast": true, // pick either type-cast format and use it consistently + "prefer-type-cast": true, "promise-must-complete": true, "react-a11y-accessible-headings": true, "react-a11y-anchors": true, diff --git a/src/informativeDocsRule.ts b/src/informativeDocsRule.ts index 14d3b538f..5d75298b8 100644 --- a/src/informativeDocsRule.ts +++ b/src/informativeDocsRule.ts @@ -57,7 +57,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Moderate', level: 'Opportunity for Excellence', group: 'Clarity', - recommendation: 'true,', + recommendation: 'true', ruleName: 'informative-docs', type: 'maintainability', typescriptOnly: false diff --git a/src/maxFuncBodyLengthRule.ts b/src/maxFuncBodyLengthRule.ts index 1e4b6ff02..2fe5abff0 100644 --- a/src/maxFuncBodyLengthRule.ts +++ b/src/maxFuncBodyLengthRule.ts @@ -31,7 +31,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Moderate', level: 'Opportunity for Excellence', group: 'Clarity', - recommendation: '[true, 100, { "ignore-parameters-to-function-regex": "^describe$" }],', + recommendation: '[true, 100, { "ignore-parameters-to-function-regex": "^describe$" }]', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/missingJsdocRule.ts b/src/missingJsdocRule.ts index 7b4b559fd..9e826eb4e 100644 --- a/src/missingJsdocRule.ts +++ b/src/missingJsdocRule.ts @@ -16,7 +16,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false,' + recommendation: 'false' }; public static FAILURE_STRING: string = 'File missing JSDoc comment at the top-level.'; diff --git a/src/missingOptionalAnnotationRule.ts b/src/missingOptionalAnnotationRule.ts index 9e024c685..00cbce4f4 100644 --- a/src/missingOptionalAnnotationRule.ts +++ b/src/missingOptionalAnnotationRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false, // now supported by TypeScript compiler' + recommendation: 'false' }; public static FAILURE_STRING: string = 'Argument following optional argument missing optional annotation: '; diff --git a/src/noDuplicateCaseRule.ts b/src/noDuplicateCaseRule.ts index 2b42a1cfc..62c35c6af 100644 --- a/src/noDuplicateCaseRule.ts +++ b/src/noDuplicateCaseRule.ts @@ -16,7 +16,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Error', severity: 'Critical', level: 'Opportunity for Excellence', - recommendation: 'false,', + recommendation: 'false', group: 'Deprecated', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noDuplicateParameterNamesRule.ts b/src/noDuplicateParameterNamesRule.ts index 24298c706..216c71dd5 100644 --- a/src/noDuplicateParameterNamesRule.ts +++ b/src/noDuplicateParameterNamesRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false, // now supported by TypeScript compiler' + recommendation: 'false' }; public static FAILURE_STRING: string = 'Duplicate parameter name: '; diff --git a/src/noEmptyInterfacesRule.ts b/src/noEmptyInterfacesRule.ts index 8772844cd..02c2cfd90 100644 --- a/src/noEmptyInterfacesRule.ts +++ b/src/noEmptyInterfacesRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Moderate', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false, // use tslint no-empty-interface rule instead', + recommendation: 'false', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noEmptyLineAfterOpeningBraceRule.ts b/src/noEmptyLineAfterOpeningBraceRule.ts index f9c89df7b..65b68398c 100644 --- a/src/noEmptyLineAfterOpeningBraceRule.ts +++ b/src/noEmptyLineAfterOpeningBraceRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Whitespace', - recommendation: 'false,', + recommendation: 'false', commonWeaknessEnumeration: '710' }; diff --git a/src/noFunctionConstructorWithStringArgsRule.ts b/src/noFunctionConstructorWithStringArgsRule.ts index 3a0f8ee43..4865ea6e7 100644 --- a/src/noFunctionConstructorWithStringArgsRule.ts +++ b/src/noFunctionConstructorWithStringArgsRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Error', severity: 'Critical', level: 'Mandatory', - recommendation: 'false, // use tslint function-constructor rule intsead', + recommendation: 'false', group: 'Security', commonWeaknessEnumeration: '95, 676, 242, 116' }; diff --git a/src/noHttpStringRule.ts b/src/noHttpStringRule.ts index 161c89152..d9bbcfdb0 100644 --- a/src/noHttpStringRule.ts +++ b/src/noHttpStringRule.ts @@ -24,7 +24,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Critical', level: 'Mandatory', group: 'Security', - recommendation: '[true, "http://www.example.com/?.*", "http://localhost:?.*"],', + recommendation: '[true, "http://www.example.com/?.*", "http://localhost:?.*"]', commonWeaknessEnumeration: '319' }; diff --git a/src/noIncrementDecrementRule.ts b/src/noIncrementDecrementRule.ts index 603569a72..216727eed 100644 --- a/src/noIncrementDecrementRule.ts +++ b/src/noIncrementDecrementRule.ts @@ -34,7 +34,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Warning', severity: 'Low', level: 'Opportunity for Excellence', - recommendation: 'false, // use tslint increment-decrement rule instead', + recommendation: 'false', group: 'Correctness', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noMissingVisibilityModifiersRule.ts b/src/noMissingVisibilityModifiersRule.ts index 658226961..b264ef9b2 100644 --- a/src/noMissingVisibilityModifiersRule.ts +++ b/src/noMissingVisibilityModifiersRule.ts @@ -18,7 +18,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false, // use tslint member-access rule instead', + recommendation: 'false', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noMultilineStringRule.ts b/src/noMultilineStringRule.ts index 1d1434c3e..a0ec822b5 100644 --- a/src/noMultilineStringRule.ts +++ b/src/noMultilineStringRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Clarity', - recommendation: 'false,', + recommendation: 'false', commonWeaknessEnumeration: '710' }; diff --git a/src/noMultipleVarDeclRule.ts b/src/noMultipleVarDeclRule.ts index 176fd1fb6..1f66f1710 100644 --- a/src/noMultipleVarDeclRule.ts +++ b/src/noMultipleVarDeclRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false, // use tslint one-variable-per-declaration rule instead', + recommendation: 'false', commonWeaknessEnumeration: '710' }; diff --git a/src/noReservedKeywordsRule.ts b/src/noReservedKeywordsRule.ts index cf1ca4fd7..7ba9c18d6 100644 --- a/src/noReservedKeywordsRule.ts +++ b/src/noReservedKeywordsRule.ts @@ -16,7 +16,7 @@ export class Rule extends Lint.Rules.AbstractRule { typescriptOnly: true, issueClass: 'SDL', issueType: 'Error', - recommendation: 'false,', + recommendation: 'false', severity: 'Critical', level: 'Mandatory', group: 'Deprecated', diff --git a/src/noStatelessClassRule.ts b/src/noStatelessClassRule.ts index f730ac30b..0b83da1a6 100644 --- a/src/noStatelessClassRule.ts +++ b/src/noStatelessClassRule.ts @@ -20,7 +20,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Warning', severity: 'Important', level: 'Opportunity for Excellence', - recommendation: 'false,', + recommendation: 'false', group: 'Deprecated', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noUnexternalizedStringsRule.ts b/src/noUnexternalizedStringsRule.ts index 45584ba7e..7053349df 100644 --- a/src/noUnexternalizedStringsRule.ts +++ b/src/noUnexternalizedStringsRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Configurable', - recommendation: 'false, // the VS Code team has a specific localization process that this rule enforces' + recommendation: 'false' }; public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { diff --git a/src/noUnnecessaryBindRule.ts b/src/noUnnecessaryBindRule.ts index 3225045a6..262c7bedc 100644 --- a/src/noUnnecessaryBindRule.ts +++ b/src/noUnnecessaryBindRule.ts @@ -17,7 +17,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Warning', severity: 'Important', level: 'Opportunity for Excellence', - recommendation: 'false, // use tslint unnecessary-bind rule instead', + recommendation: 'false', group: 'Correctness', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/noVarSelfRule.ts b/src/noVarSelfRule.ts index 95431251d..c1b1f5350 100644 --- a/src/noVarSelfRule.ts +++ b/src/noVarSelfRule.ts @@ -23,7 +23,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Important', level: 'Opportunity for Excellence', group: 'Deprecated', - recommendation: 'false,', + recommendation: 'false', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/preferTypeCastRule.ts b/src/preferTypeCastRule.ts index 37d979e5c..474aa4a30 100644 --- a/src/preferTypeCastRule.ts +++ b/src/preferTypeCastRule.ts @@ -19,7 +19,7 @@ export class Rule extends Lint.Rules.AbstractRule { severity: 'Low', level: 'Opportunity for Excellence', group: 'Configurable', - recommendation: 'true, // pick either type-cast format and use it consistently', + recommendation: 'true', commonWeaknessEnumeration: '398, 710' }; diff --git a/src/reactTsxCurlySpacingRule.ts b/src/reactTsxCurlySpacingRule.ts index 5ebf5f299..09a1b9d15 100644 --- a/src/reactTsxCurlySpacingRule.ts +++ b/src/reactTsxCurlySpacingRule.ts @@ -31,7 +31,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Warning', severity: 'Low', level: 'Opportunity for Excellence', - recommendation: 'false,', + recommendation: 'false', group: 'Deprecated' }; diff --git a/src/validTypeofRule.ts b/src/validTypeofRule.ts index b917ce040..1ab7c7e12 100644 --- a/src/validTypeofRule.ts +++ b/src/validTypeofRule.ts @@ -16,7 +16,7 @@ export class Rule extends Lint.Rules.AbstractRule { issueType: 'Error', severity: 'Critical', level: 'Opportunity for Excellence', - recommendation: 'false,', + recommendation: 'false', group: 'Deprecated' }; From 223abd960793d53078b427efd7fbf673c7b11973 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 17 Feb 2019 20:38:23 -0500 Subject: [PATCH 3/7] Moved void-zero to latest.json --- configs/latest.json | 3 ++- configs/stable.json | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/latest.json b/configs/latest.json index b7522008d..9496f84cc 100644 --- a/configs/latest.json +++ b/configs/latest.json @@ -1,6 +1,7 @@ { "extends": ["./stable.json"], "rules": { - "react-a11y-iframes": true + "react-a11y-iframes": true, + "void-zero": true } } diff --git a/configs/stable.json b/configs/stable.json index 54ada7a5d..93e0b5651 100644 --- a/configs/stable.json +++ b/configs/stable.json @@ -76,7 +76,6 @@ "react-unused-props-and-state": true, "underscore-consistent-invocation": true, "use-named-parameter": true, - "use-simple-attributes": true, - "void-zero": true + "use-simple-attributes": true } } From eab84aee83ba244d1f58ec2b6e922608cf9f6ba7 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 17 Feb 2019 21:03:23 -0500 Subject: [PATCH 4/7] Moved to exporting root-level configs --- .prettierignore | 8 ++------ README.md | 10 +++++----- build-tasks/copy-config-json.js | 12 +++++------- src/utils/ExtendedMetadata.ts | 2 +- 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/.prettierignore b/.prettierignore index b121f7793..c98aab7fe 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,15 +1,11 @@ # Build directory dist/ -# Configuration settings -configs/ +# Configuration and npm settings +*.json # Definition files *.d.ts -# NPM files -package.json -package-lock.json - # Test files test-data/NoUnnecessarySemicolonsTestInput.ts diff --git a/README.md b/README.md index 73d448c80..61b003773 100644 --- a/README.md +++ b/README.md @@ -47,11 +47,11 @@ If you extend from one of the following configurations, `rulesDirectory` will ha #### Stable -To start, you can enable our "stable" defaults that come with tslint-microsoft-contrib ([configs/stable.json](./configs/stable.json)) by adding `"tslint-microsoft-contrib/configs/stable"` under `"extends"` in your `tslint.json`: +To start, you can enable our "stable" defaults that come with tslint-microsoft-contrib ([stable.json](./stable.json)) by adding `"tslint-microsoft-contrib/stable"` under `"extends"` in your `tslint.json`: ```json { - "extends": ["tslint-microsoft-contrib/configs/stable.json"] + "extends": ["tslint-microsoft-contrib/stable"] // ... } ``` @@ -60,11 +60,11 @@ These rules will not be added to in minor or patch releases, but will be in majo #### Latest -To run with the latest and greatest rules ([configs/latest.json](./configs/latest.json)), extend from `tslint-microsoft-contrib/configs/latest`: +To run with the latest and greatest rules ([latest.json](./latest.json)), extend from `tslint-microsoft-contrib/latest`: ```json { - "extends": ["tslint-microsoft-contrib/configs/latest.json"] + "extends": ["tslint-microsoft-contrib/latest"] // ... } ``` @@ -75,7 +75,7 @@ These rules will not be added to in patch releases, but will be in minor release The "recommended" ruleset that ships by extending `tslint-microsoft-contrib` itself contains a list of rules that includes core TSLint rules. -To start, you can enable our recommended defaults ([configs/recommended.json](./configs/recommended.json)) by adding just `"tslint-microsoft-contrib"` under `"extends"` in your `tslint.json`: +To start, you can enable our recommended defaults ([recommended.json](./recommended.json)) by adding just `"tslint-microsoft-contrib"` under `"extends"` in your `tslint.json`: ```json { diff --git a/build-tasks/copy-config-json.js b/build-tasks/copy-config-json.js index f02b5f72f..c476f567f 100644 --- a/build-tasks/copy-config-json.js +++ b/build-tasks/copy-config-json.js @@ -1,5 +1,5 @@ /** - * Converts configs/ to ./dist/build/configs/ and configs/recommended.json to ./dist/build/recommended.json. + * Converts configs/*.json to ./dist/build/*.json. */ const mkdirp = require('mkdirp'); @@ -7,17 +7,15 @@ const path = require('path'); const { readDirectory, readFile, writeFile } = require('./common/files'); -const copyConfigFile = (configFileName, destinationFileName, newRulesDirectory) => { +const copyConfigFile = (configFileName, destinationFileName) => { const resolvedDestination = path.resolve(destinationFileName); const data = readFile(path.resolve(configFileName)); - writeFile(resolvedDestination, data.replace(/"rulesDirectory": \[(.*)\]/, `"rulesDirectory": ["${newRulesDirectory}"]`)); + writeFile(resolvedDestination, data.replace(/"rulesDirectory": \[(.*)\]/, `"rulesDirectory": ["./"]`)); }; -mkdirp.sync('./dist/build/configs'); +mkdirp.sync('./dist/build'); for (const configFileName of readDirectory('./configs')) { - copyConfigFile(`./configs/${configFileName}`, `./dist/build/configs/${configFileName}`, '../'); + copyConfigFile(`./configs/${configFileName}`, `./dist/build/${configFileName}`); } - -copyConfigFile('./configs/recommended.json', './dist/build/tslint.json', './'); diff --git a/src/utils/ExtendedMetadata.ts b/src/utils/ExtendedMetadata.ts index f6bbab2f0..a40a96611 100644 --- a/src/utils/ExtendedMetadata.ts +++ b/src/utils/ExtendedMetadata.ts @@ -30,6 +30,6 @@ export type Severity = 'Critical' | 'Important' | 'Moderate' | 'Low'; export type Level = 'Mandatory' | 'Opportunity for Excellence'; /** - * Ignored - Use this value to exclude the rule from configs/recommended.json and the deployed tslint.json file. + * Ignored - Use this value to exclude the rule from recommended.json. */ export type Group = 'Ignored' | 'Security' | 'Correctness' | 'Accessibility' | 'Clarity' | 'Whitespace' | 'Configurable' | 'Deprecated'; From 6c3b411451b52be153c90b3d706d2ac587974b9b Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 17 Feb 2019 21:11:30 -0500 Subject: [PATCH 5/7] Switched to auto-generating latest.json --- ...-stable-config.js => generate-latest-config.js} | 14 +++++++------- ...le.json.template.js => latest.json.template.js} | 1 + configs/latest.json | 1 + package.json | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) rename build-tasks/{generate-stable-config.js => generate-latest-config.js} (68%) rename build-tasks/templates/{stable.json.template.js => latest.json.template.js} (80%) diff --git a/build-tasks/generate-stable-config.js b/build-tasks/generate-latest-config.js similarity index 68% rename from build-tasks/generate-stable-config.js rename to build-tasks/generate-latest-config.js index 40c0a31f2..2d2b46eee 100644 --- a/build-tasks/generate-stable-config.js +++ b/build-tasks/generate-latest-config.js @@ -1,8 +1,8 @@ /** - * Generates config/stable.json. + * Generates config/latest.json. * The `recommended` metadata for each rule is added there, except if... * - ...the rule's `metadata.group` is `'Ignored'` - * - ...the rule is also mentioned in config/latest.json (which would be a breaking change) + * - ...the rule is also mentioned in config/stable.json * - ...the recommended setting starts with `false` (the rule is likely deprecated) */ @@ -11,7 +11,7 @@ const { getAllRules, getMetadataFromFile, getMetadataValue } = require('./common const recommendations = []; -const latestRules = new Set(Object.keys(require('../configs/latest.json').rules)); +const stableRules = new Set(Object.keys(require('../configs/stable.json').rules)); getAllRules({ ignoreTslintRules: true @@ -34,14 +34,14 @@ getAllRules({ return; } - // Don't mention rules added to the 'latest' preset, as adding them to stable.json would be a breaking change - if (latestRules.has(ruleName)) { + // Don't redundantly mention rules added to the 'stable' preset + if (stableRules.has(ruleName)) { return; } recommendations.push(` "${ruleName}": ${recommendation}`); }); -const stableTemplate = require('./templates/stable.json.template'); +const stableTemplate = require('./templates/latest.json.template'); -writeFile('configs/stable.json', stableTemplate(recommendations)); +writeFile('configs/latest.json', stableTemplate(recommendations)); diff --git a/build-tasks/templates/stable.json.template.js b/build-tasks/templates/latest.json.template.js similarity index 80% rename from build-tasks/templates/stable.json.template.js rename to build-tasks/templates/latest.json.template.js index 8d8469a87..8b277db4b 100644 --- a/build-tasks/templates/stable.json.template.js +++ b/build-tasks/templates/latest.json.template.js @@ -1,4 +1,5 @@ module.exports = recommendations => `{ + "extends": ["./stable.json"], "rulesDirectory": ["../"], "rules": { ${[...recommendations].sort().join(',\n')} diff --git a/configs/latest.json b/configs/latest.json index 9496f84cc..2154d05c1 100644 --- a/configs/latest.json +++ b/configs/latest.json @@ -1,5 +1,6 @@ { "extends": ["./stable.json"], + "rulesDirectory": ["../"], "rules": { "react-a11y-iframes": true, "void-zero": true diff --git a/package.json b/package.json index a42d5aa30..27bbb6bae 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "copy:meta": "cpy README.md dist/build --parents", "copy:package": "cpy \"**/*.js\" \"**/*.json\" \"!tests/**\" \"!references.js\" \"tests/TestHelper.js\" \"tests/TestHelper.d.ts\" ../build --cwd=\"dist/src\" --parents", "create-rule": "node build-tasks/create-rule.js", - "generate:stable-config": "node build-tasks/generate-stable-config.js", + "generate:latest-config": "node build-tasks/generate-latest-config.js", "generate:sdl-report": "node build-tasks/generate-sdl-report.js", "generate:rule-metadata": "node build-tasks/generate-rule-metadata.js", "generate:package-json-for-npm": "node build-tasks/generate-package-json-for-npm.js", From 1bdb61f15ddfbccb6058ceac797caf08596930bd Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sun, 17 Feb 2019 21:22:15 -0500 Subject: [PATCH 6/7] Aligned naming with TSLint's recommended -> latest --- README.md | 14 +- build-tasks/generate-latest-config.js | 12 +- build-tasks/templates/latest.json.template.js | 2 +- configs/latest.json | 2 +- configs/legacy.json | 286 ++++++++++++++++++ configs/recommended.json | 281 +++-------------- configs/stable.json | 81 ----- 7 files changed, 340 insertions(+), 338 deletions(-) create mode 100644 configs/legacy.json delete mode 100644 configs/stable.json diff --git a/README.md b/README.md index 61b003773..b1a113a99 100644 --- a/README.md +++ b/README.md @@ -45,13 +45,13 @@ If you extend from one of the following configurations, `rulesDirectory` will ha > Please note, some of the default ruleset rules require the `--project` TSLint option. -#### Stable +#### Recommended -To start, you can enable our "stable" defaults that come with tslint-microsoft-contrib ([stable.json](./stable.json)) by adding `"tslint-microsoft-contrib/stable"` under `"extends"` in your `tslint.json`: +To start, you can enable our stable "recommended" defaults that come with tslint-microsoft-contrib ([recommended.json](./recommended.json)) by adding `"tslint-microsoft-contrib/recommended"` under `"extends"` in your `tslint.json`: ```json { - "extends": ["tslint-microsoft-contrib/stable"] + "extends": ["tslint-microsoft-contrib/recommended"] // ... } ``` @@ -71,9 +71,9 @@ To run with the latest and greatest rules ([latest.json](./latest.json)), extend These rules will not be added to in patch releases, but will be in minor releases. -#### Recommended +#### Legacy -The "recommended" ruleset that ships by extending `tslint-microsoft-contrib` itself contains a list of rules that includes core TSLint rules. +The old "recommended" ruleset that ships by extending `tslint-microsoft-contrib` itself contains a list of rules that includes core TSLint rules. To start, you can enable our recommended defaults ([recommended.json](./recommended.json)) by adding just `"tslint-microsoft-contrib"` under `"extends"` in your `tslint.json`: @@ -84,9 +84,11 @@ To start, you can enable our recommended defaults ([recommended.json](./recommen } ``` -**The "recommended" ruleset is considered legacy**; it is generally preferable to extend from the stable or latest rulesets. +**This ruleset is considered legacy**; it is generally preferable to extend from the 'recommended' or 'latest' rulesets. We recommend you instead explicitly include `tslint:recommended`, `tslint:latest`, or `tslint:all` in your `tslint.json` rather than enable core rules through this configuration. +In the next major version of TSLint, this will instead be an alis for `"tslint-microsoft-contrib/recommended"`. + ### Overriding Configurations You can [disable rules](https://palantir.github.io/tslint/usage/rule-flags) you don't find useful. diff --git a/build-tasks/generate-latest-config.js b/build-tasks/generate-latest-config.js index 2d2b46eee..cb59ad46e 100644 --- a/build-tasks/generate-latest-config.js +++ b/build-tasks/generate-latest-config.js @@ -2,7 +2,7 @@ * Generates config/latest.json. * The `recommended` metadata for each rule is added there, except if... * - ...the rule's `metadata.group` is `'Ignored'` - * - ...the rule is also mentioned in config/stable.json + * - ...the rule is also mentioned in config/recommended.json * - ...the recommended setting starts with `false` (the rule is likely deprecated) */ @@ -11,7 +11,7 @@ const { getAllRules, getMetadataFromFile, getMetadataValue } = require('./common const recommendations = []; -const stableRules = new Set(Object.keys(require('../configs/stable.json').rules)); +const recommendedRules = new Set(Object.keys(require('../configs/recommended.json').rules)); getAllRules({ ignoreTslintRules: true @@ -34,14 +34,14 @@ getAllRules({ return; } - // Don't redundantly mention rules added to the 'stable' preset - if (stableRules.has(ruleName)) { + // Don't redundantly mention rules added to the 'recommended' preset + if (recommendedRules.has(ruleName)) { return; } recommendations.push(` "${ruleName}": ${recommendation}`); }); -const stableTemplate = require('./templates/latest.json.template'); +const latestTemplate = require('./templates/latest.json.template'); -writeFile('configs/latest.json', stableTemplate(recommendations)); +writeFile('configs/latest.json', latestTemplate(recommendations)); diff --git a/build-tasks/templates/latest.json.template.js b/build-tasks/templates/latest.json.template.js index 8b277db4b..bd480177f 100644 --- a/build-tasks/templates/latest.json.template.js +++ b/build-tasks/templates/latest.json.template.js @@ -1,5 +1,5 @@ module.exports = recommendations => `{ - "extends": ["./stable.json"], + "extends": ["./recommended.json"], "rulesDirectory": ["../"], "rules": { ${[...recommendations].sort().join(',\n')} diff --git a/configs/latest.json b/configs/latest.json index 2154d05c1..8e9892034 100644 --- a/configs/latest.json +++ b/configs/latest.json @@ -1,5 +1,5 @@ { - "extends": ["./stable.json"], + "extends": ["./recommended.json"], "rulesDirectory": ["../"], "rules": { "react-a11y-iframes": true, diff --git a/configs/legacy.json b/configs/legacy.json new file mode 100644 index 000000000..2cc617570 --- /dev/null +++ b/configs/legacy.json @@ -0,0 +1,286 @@ +/** + * This "recommended" ruleset is considered legacy; + * it is generally preferable to extend from the 'recommended' or 'latest' rulesets. + * We recommend you instead explicitly include `tslint:recommended`, `tslint:latest`, or `tslint:all` + * in your `tslint.json` rather than enable core rules through this configuration. + * + * These rule settings are a broad, general recommendation for a good default configuration. + * This file is exported in the npm/nuget package as ./tslint.json. + */ +{ + "rulesDirectory": [], + "rules": { + /** + * Security Rules. The following rules should be turned on because they find security issues + * or are recommended in the Microsoft Secure Development Lifecycle (SDL) + */ + "function-constructor": true, + "insecure-random": true, + "no-banned-terms": true, + "no-cookies": true, + "no-delete-expression": true, + "no-disable-auto-sanitization": true, + "no-document-domain": true, + "no-document-write": true, + "no-eval": true, + "no-exec-script": true, + "no-function-constructor-with-string-args": false, // use tslint function-constructor rule intsead + "no-http-string": [true, "http://www.example.com/?.*", "http://localhost:?.*"], + "no-inner-html": true, + "no-octal-literal": true, + "no-string-based-set-immediate": true, + "no-string-based-set-interval": true, + "no-string-based-set-timeout": true, + "non-literal-fs-path": true, + "non-literal-require": true, + "possible-timing-attack": true, + "react-anchor-blank-noopener": true, + "react-iframe-missing-sandbox": true, + "react-no-dangerous-html": true, + + /** + * Common Bugs and Correctness. The following rules should be turned on because they find + * common bug patterns in the code or enforce type safety. + */ + "await-promise": true, + "forin": true, + "increment-decrement": true, + "jquery-deferred-must-complete": true, + "label-position": true, + "match-default-export-name": true, + "mocha-avoid-only": true, + "mocha-no-side-effect-code": true, + "no-any": true, + "no-arg": true, + "no-backbone-get-set-outside-model": true, + "no-bitwise": true, + "no-conditional-assignment": true, + "no-console": [true, "debug", "info", "error", "log", "time", "timeEnd", "trace"], + "no-constant-condition": true, + "no-control-regex": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-duplicate-switch-case": true, + "no-duplicate-variable": true, + "no-empty": true, + "no-floating-promises": true, + "no-for-in-array": true, + "no-implicit-dependencies": true, + "no-import-side-effect": true, + "no-increment-decrement": false, // use tslint increment-decrement rule instead + "no-invalid-regexp": true, + "no-invalid-template-strings": true, + "no-invalid-this": true, + "no-jquery-raw-elements": true, + "no-misused-new": true, + "no-non-null-assertion": true, + "no-object-literal-type-assertion": true, + "no-parameter-reassignment": true, + "no-reference-import": true, + "no-regex-spaces": true, + "no-sparse-arrays": true, + "no-string-literal": true, + "no-string-throw": true, + "no-submodule-imports": true, + "no-unnecessary-bind": false, // use tslint unnecessary-bind rule instead + "no-unnecessary-callback-wrapper": true, + "no-unnecessary-initializer": true, + "no-unnecessary-override": true, + "no-unsafe-any": true, + "no-unsafe-finally": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-with-statement": true, + "promise-function-async": true, + "promise-must-complete": true, + "radix": true, + "react-this-binding-issue": true, + "react-unused-props-and-state": true, + "restrict-plus-operands": true, // the plus operand should really only be used for strings and numbers + "strict-boolean-expressions": true, + "switch-default": true, + "switch-final-break": true, + "triple-equals": [true, "allow-null-check"], + "unnecessary-bind": true, + "use-isnan": true, + "use-named-parameter": true, + "use-simple-attributes": true, + + /** + * Code Clarity. The following rules should be turned on because they make the code + * generally more clear to the reader. + */ + "adjacent-overload-signatures": true, + "array-type": [true, "array"], + "arrow-parens": false, // for simple functions the parens on arrow functions are not needed + "ban-comma-operator": true, // possibly controversial + "binary-expression-operand-order": true, + "callable-types": true, + "chai-prefer-contains-to-index-of": true, + "chai-vague-errors": true, + "class-name": true, + "comment-format": true, + "completed-docs": [true, "classes"], + "export-name": true, + "file-name-casing": true, + "function-name": true, + "import-name": true, + "informative-docs": true, + "interface-name": true, + "jsdoc-format": true, + "max-classes-per-file": [true, 3], // we generally recommend making one public class per file + "max-file-line-count": true, + "max-func-body-length": [true, 100, { "ignore-parameters-to-function-regex": "^describe$" }], + "max-line-length": [true, 140], + "member-access": true, + "member-ordering": [true, { "order": "fields-first" }], + "mocha-unneeded-done": true, + "new-parens": true, + "newline-per-chained-call": true, + "no-construct": true, + "no-default-export": true, + "no-duplicate-imports": true, + "no-dynamic-delete": true, + "no-empty-interface": true, + "no-for-in": true, + "no-function-expression": true, + "no-inferrable-types": false, // turn no-inferrable-types off in order to make the code consistent in its use of type decorations + "no-multiline-string": false, + "no-null-keyword": true, + "no-parameter-properties": true, + "no-redundant-jsdoc": true, + "no-relative-imports": true, + "no-require-imports": true, + "no-return-await": true, + "no-shadowed-variable": true, + "no-suspicious-comment": true, + "no-this-assignment": true, + "no-typeof-undefined": true, + "no-unnecessary-field-initialization": true, + "no-unnecessary-local-variable": true, + "no-unnecessary-qualifier": true, + "no-unnecessary-type-assertion": true, + "no-unsupported-browser-code": true, + "no-useless-files": true, + "no-var-keyword": true, + "no-var-requires": true, + "no-void-expression": true, + "number-literal-format": true, + "object-literal-sort-keys": false, // turn object-literal-sort-keys off and sort keys in a meaningful manner + "one-variable-per-declaration": true, + "only-arrow-functions": false, // there are many valid reasons to declare a function + "ordered-imports": true, + "prefer-array-literal": true, + "prefer-const": true, + "prefer-for-of": true, + "prefer-method-signature": true, + "prefer-object-spread": true, + "prefer-readonly": true, + "prefer-template": true, + "prefer-while": true, + "type-literal-delimiter": true, + "typedef": [true, "call-signature", "arrow-call-signature", "parameter", "arrow-parameter", "property-declaration", "variable-declaration", "member-variable-declaration"], + "underscore-consistent-invocation": true, + "unified-signatures": true, + "use-default-type-parameter": true, + "variable-name": true, + "void-zero": true, + + /** + * Accessibility. The following rules should be turned on to guarantee the best user + * experience for keyboard and screen reader users. + */ + "react-a11y-accessible-headings": true, + "react-a11y-anchors": true, + "react-a11y-aria-unsupported-elements": true, + "react-a11y-event-has-role": true, + "react-a11y-image-button-has-alt": true, + "react-a11y-img-has-alt": true, + "react-a11y-input-elements": true, + "react-a11y-lang": true, + "react-a11y-meta": true, + "react-a11y-no-onchange": true, + "react-a11y-props": true, + "react-a11y-proptypes": true, + "react-a11y-required": true, + "react-a11y-role": true, + "react-a11y-role-has-required-aria-props": true, + "react-a11y-role-supports-aria-props": true, + "react-a11y-tabindex-no-positive": true, + "react-a11y-titles": true, + + /** + * Whitespace related rules. The only recommended whitespace strategy is to pick a single format and + * be consistent. + */ + "align": [true, "parameters", "arguments", "statements"], + "curly": true, + "encoding": true, + "eofline": true, + "import-spacing": true, + "indent": [true, "spaces"], + "linebreak-style": true, + "newline-before-return": true, + "no-consecutive-blank-lines": true, + "no-empty-line-after-opening-brace": false, + "no-irregular-whitespace": true, + "no-single-line-block-comment": true, + "no-trailing-whitespace": true, + "no-unnecessary-semicolons": true, + "object-literal-key-quotes": [true, "as-needed"], + "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"], + "quotemark": [true, "single"], + "semicolon": [true, "always"], + "space-within-parens": true, + "trailing-comma": [true, { "singleline": "never", "multiline": "never" }], // forcing trailing commas for multi-line + // lists results in lists that are easier to reorder and version control diffs that are more clear. + // Many teams like to have multiline be "always". There is no clear consensus on this rule but the + // internal MS JavaScript coding standard does discourage it. + "typedef-whitespace": false, + "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"], + + /** + * Controversial/Configurable rules. + */ + "ban": false, // only enable this if you have some code pattern that you want to ban + "ban-types": true, + "cyclomatic-complexity": true, + "deprecation": false, // deprecated APIs are sometimes unavoidable + "file-header": false, // enable this rule only if you are legally required to add a file header + "import-blacklist": false, // enable and configure this as you desire + "interface-over-type-literal": false, // there are plenty of reasons to prefer interfaces + "no-angle-bracket-type-assertion": false, // pick either type-cast format and use it consistently + "no-inferred-empty-object-type": false, // if the compiler is satisfied then this is probably not an issue + "no-internal-module": false, // only enable this if you are not using internal modules + "no-magic-numbers": false, // by default it will find too many false positives + "no-mergeable-namespace": false, // your project may require mergeable namespaces + "no-namespace": false, // only enable this if you are not using modules/namespaces + "no-reference": true, // in general you should use a module system and not /// reference imports + "no-unexternalized-strings": false, // the VS Code team has a specific localization process that this rule enforces + "object-literal-shorthand": false, // object-literal-shorthand offers an abbreviation not an abstraction + "prefer-conditional-expression": false, // unnecessarily strict + "prefer-switch": false, // more of a style preference + "prefer-type-cast": true, // pick either type-cast format and use it consistently + "return-undefined": false, // this actually affects the readability of the code + "space-before-function-paren": false, // turn this on if this is really your coding standard + + /** + * Deprecated rules. The following rules are deprecated for various reasons. + */ + "missing-jsdoc": false, + "missing-optional-annotation": false, // now supported by TypeScript compiler + "no-duplicate-case": false, + "no-duplicate-parameter-names": false, // now supported by TypeScript compiler + "no-empty-interfaces": false, // use tslint no-empty-interface rule instead + "no-missing-visibility-modifiers": false, // use tslint member-access rule instead + "no-multiple-var-decl": false, // use tslint one-variable-per-declaration rule instead + "no-reserved-keywords": false, + "no-stateless-class": false, + "no-switch-case-fall-through": false, // now supported by TypeScript compiler + "no-unnecessary-class": true, + "no-var-self": false, + "react-tsx-curly-spacing": false, + "typeof-compare": false, // the valid-typeof rule is currently superior to this version + "valid-typeof": false + } +} diff --git a/configs/recommended.json b/configs/recommended.json index e7bd7aae8..93e0b5651 100644 --- a/configs/recommended.json +++ b/configs/recommended.json @@ -1,195 +1,56 @@ -/** - * This "recommended" ruleset is considered legacy; - * it is generally preferable to extend from the stable or latest rulesets. - * We recommend you instead explicitly include `tslint:recommended`, `tslint:latest`, or `tslint:all` - * in your `tslint.json` rather than enable core rules through this configuration. - * - * These rule settings are a broad, general recommendation for a good default configuration. - * This file is exported in the npm/nuget package as ./tslint.json. - */ { - "rulesDirectory": [], + "rulesDirectory": ["../"], "rules": { - /** - * Security Rules. The following rules should be turned on because they find security issues - * or are recommended in the Microsoft Secure Development Lifecycle (SDL) - */ - "function-constructor": true, + "chai-prefer-contains-to-index-of": true, + "chai-vague-errors": true, + "export-name": true, + "function-name": true, + "import-name": true, + "informative-docs": true, "insecure-random": true, + "jquery-deferred-must-complete": true, + "max-func-body-length": [true, 100, { "ignore-parameters-to-function-regex": "^describe$" }], + "mocha-avoid-only": true, + "mocha-no-side-effect-code": true, + "mocha-unneeded-done": true, + "no-backbone-get-set-outside-model": true, "no-banned-terms": true, + "no-constant-condition": true, + "no-control-regex": true, "no-cookies": true, "no-delete-expression": true, "no-disable-auto-sanitization": true, "no-document-domain": true, "no-document-write": true, - "no-eval": true, "no-exec-script": true, - "no-function-constructor-with-string-args": false, // use tslint function-constructor rule intsead + "no-for-in": true, + "no-function-expression": true, "no-http-string": [true, "http://www.example.com/?.*", "http://localhost:?.*"], "no-inner-html": true, - "no-octal-literal": true, - "no-string-based-set-immediate": true, - "no-string-based-set-interval": true, - "no-string-based-set-timeout": true, - "non-literal-fs-path": true, - "non-literal-require": true, - "possible-timing-attack": true, - "react-anchor-blank-noopener": true, - "react-iframe-missing-sandbox": true, - "react-no-dangerous-html": true, - - /** - * Common Bugs and Correctness. The following rules should be turned on because they find - * common bug patterns in the code or enforce type safety. - */ - "await-promise": true, - "forin": true, - "increment-decrement": true, - "jquery-deferred-must-complete": true, - "label-position": true, - "match-default-export-name": true, - "mocha-avoid-only": true, - "mocha-no-side-effect-code": true, - "no-any": true, - "no-arg": true, - "no-backbone-get-set-outside-model": true, - "no-bitwise": true, - "no-conditional-assignment": true, - "no-console": [true, "debug", "info", "error", "log", "time", "timeEnd", "trace"], - "no-constant-condition": true, - "no-control-regex": true, - "no-debugger": true, - "no-duplicate-super": true, - "no-duplicate-switch-case": true, - "no-duplicate-variable": true, - "no-empty": true, - "no-floating-promises": true, - "no-for-in-array": true, - "no-implicit-dependencies": true, - "no-import-side-effect": true, - "no-increment-decrement": false, // use tslint increment-decrement rule instead "no-invalid-regexp": true, - "no-invalid-template-strings": true, - "no-invalid-this": true, "no-jquery-raw-elements": true, - "no-misused-new": true, - "no-non-null-assertion": true, - "no-object-literal-type-assertion": true, - "no-parameter-reassignment": true, - "no-reference-import": true, + "no-octal-literal": true, "no-regex-spaces": true, - "no-sparse-arrays": true, - "no-string-literal": true, - "no-string-throw": true, - "no-submodule-imports": true, - "no-unnecessary-bind": false, // use tslint unnecessary-bind rule instead - "no-unnecessary-callback-wrapper": true, - "no-unnecessary-initializer": true, - "no-unnecessary-override": true, - "no-unsafe-any": true, - "no-unsafe-finally": true, - "no-unused-expression": true, - "no-use-before-declare": true, - "no-with-statement": true, - "promise-function-async": true, - "promise-must-complete": true, - "radix": true, - "react-this-binding-issue": true, - "react-unused-props-and-state": true, - "restrict-plus-operands": true, // the plus operand should really only be used for strings and numbers - "strict-boolean-expressions": true, - "switch-default": true, - "switch-final-break": true, - "triple-equals": [true, "allow-null-check"], - "unnecessary-bind": true, - "use-isnan": true, - "use-named-parameter": true, - "use-simple-attributes": true, - - /** - * Code Clarity. The following rules should be turned on because they make the code - * generally more clear to the reader. - */ - "adjacent-overload-signatures": true, - "array-type": [true, "array"], - "arrow-parens": false, // for simple functions the parens on arrow functions are not needed - "ban-comma-operator": true, // possibly controversial - "binary-expression-operand-order": true, - "callable-types": true, - "chai-prefer-contains-to-index-of": true, - "chai-vague-errors": true, - "class-name": true, - "comment-format": true, - "completed-docs": [true, "classes"], - "export-name": true, - "file-name-casing": true, - "function-name": true, - "import-name": true, - "informative-docs": true, - "interface-name": true, - "jsdoc-format": true, - "max-classes-per-file": [true, 3], // we generally recommend making one public class per file - "max-file-line-count": true, - "max-func-body-length": [true, 100, { "ignore-parameters-to-function-regex": "^describe$" }], - "max-line-length": [true, 140], - "member-access": true, - "member-ordering": [true, { "order": "fields-first" }], - "mocha-unneeded-done": true, - "new-parens": true, - "newline-per-chained-call": true, - "no-construct": true, - "no-default-export": true, - "no-duplicate-imports": true, - "no-dynamic-delete": true, - "no-empty-interface": true, - "no-for-in": true, - "no-function-expression": true, - "no-inferrable-types": false, // turn no-inferrable-types off in order to make the code consistent in its use of type decorations - "no-multiline-string": false, - "no-null-keyword": true, - "no-parameter-properties": true, - "no-redundant-jsdoc": true, "no-relative-imports": true, - "no-require-imports": true, - "no-return-await": true, - "no-shadowed-variable": true, + "no-single-line-block-comment": true, + "no-string-based-set-immediate": true, + "no-string-based-set-interval": true, + "no-string-based-set-timeout": true, "no-suspicious-comment": true, - "no-this-assignment": true, "no-typeof-undefined": true, "no-unnecessary-field-initialization": true, "no-unnecessary-local-variable": true, - "no-unnecessary-qualifier": true, - "no-unnecessary-type-assertion": true, + "no-unnecessary-override": true, + "no-unnecessary-semicolons": true, "no-unsupported-browser-code": true, "no-useless-files": true, - "no-var-keyword": true, - "no-var-requires": true, - "no-void-expression": true, - "number-literal-format": true, - "object-literal-sort-keys": false, // turn object-literal-sort-keys off and sort keys in a meaningful manner - "one-variable-per-declaration": true, - "only-arrow-functions": false, // there are many valid reasons to declare a function - "ordered-imports": true, + "no-with-statement": true, + "non-literal-fs-path": true, + "non-literal-require": true, + "possible-timing-attack": true, "prefer-array-literal": true, - "prefer-const": true, - "prefer-for-of": true, - "prefer-method-signature": true, - "prefer-object-spread": true, - "prefer-readonly": true, - "prefer-template": true, - "prefer-while": true, - "type-literal-delimiter": true, - "typedef": [true, "call-signature", "arrow-call-signature", "parameter", "arrow-parameter", "property-declaration", "variable-declaration", "member-variable-declaration"], - "underscore-consistent-invocation": true, - "unified-signatures": true, - "use-default-type-parameter": true, - "variable-name": true, - "void-zero": true, - - /** - * Accessibility. The following rules should be turned on to guarantee the best user - * experience for keyboard and screen reader users. - */ + "prefer-type-cast": true, + "promise-must-complete": true, "react-a11y-accessible-headings": true, "react-a11y-anchors": true, "react-a11y-aria-unsupported-elements": true, @@ -208,79 +69,13 @@ "react-a11y-role-supports-aria-props": true, "react-a11y-tabindex-no-positive": true, "react-a11y-titles": true, - - /** - * Whitespace related rules. The only recommended whitespace strategy is to pick a single format and - * be consistent. - */ - "align": [true, "parameters", "arguments", "statements"], - "curly": true, - "encoding": true, - "eofline": true, - "import-spacing": true, - "indent": [true, "spaces"], - "linebreak-style": true, - "newline-before-return": true, - "no-consecutive-blank-lines": true, - "no-empty-line-after-opening-brace": false, - "no-irregular-whitespace": true, - "no-single-line-block-comment": true, - "no-trailing-whitespace": true, - "no-unnecessary-semicolons": true, - "object-literal-key-quotes": [true, "as-needed"], - "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"], - "quotemark": [true, "single"], - "semicolon": [true, "always"], - "space-within-parens": true, - "trailing-comma": [true, { "singleline": "never", "multiline": "never" }], // forcing trailing commas for multi-line - // lists results in lists that are easier to reorder and version control diffs that are more clear. - // Many teams like to have multiline be "always". There is no clear consensus on this rule but the - // internal MS JavaScript coding standard does discourage it. - "typedef-whitespace": false, - "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"], - - /** - * Controversial/Configurable rules. - */ - "ban": false, // only enable this if you have some code pattern that you want to ban - "ban-types": true, - "cyclomatic-complexity": true, - "deprecation": false, // deprecated APIs are sometimes unavoidable - "file-header": false, // enable this rule only if you are legally required to add a file header - "import-blacklist": false, // enable and configure this as you desire - "interface-over-type-literal": false, // there are plenty of reasons to prefer interfaces - "no-angle-bracket-type-assertion": false, // pick either type-cast format and use it consistently - "no-inferred-empty-object-type": false, // if the compiler is satisfied then this is probably not an issue - "no-internal-module": false, // only enable this if you are not using internal modules - "no-magic-numbers": false, // by default it will find too many false positives - "no-mergeable-namespace": false, // your project may require mergeable namespaces - "no-namespace": false, // only enable this if you are not using modules/namespaces - "no-reference": true, // in general you should use a module system and not /// reference imports - "no-unexternalized-strings": false, // the VS Code team has a specific localization process that this rule enforces - "object-literal-shorthand": false, // object-literal-shorthand offers an abbreviation not an abstraction - "prefer-conditional-expression": false, // unnecessarily strict - "prefer-switch": false, // more of a style preference - "prefer-type-cast": true, // pick either type-cast format and use it consistently - "return-undefined": false, // this actually affects the readability of the code - "space-before-function-paren": false, // turn this on if this is really your coding standard - - /** - * Deprecated rules. The following rules are deprecated for various reasons. - */ - "missing-jsdoc": false, - "missing-optional-annotation": false, // now supported by TypeScript compiler - "no-duplicate-case": false, - "no-duplicate-parameter-names": false, // now supported by TypeScript compiler - "no-empty-interfaces": false, // use tslint no-empty-interface rule instead - "no-missing-visibility-modifiers": false, // use tslint member-access rule instead - "no-multiple-var-decl": false, // use tslint one-variable-per-declaration rule instead - "no-reserved-keywords": false, - "no-stateless-class": false, - "no-switch-case-fall-through": false, // now supported by TypeScript compiler - "no-unnecessary-class": true, - "no-var-self": false, - "react-tsx-curly-spacing": false, - "typeof-compare": false, // the valid-typeof rule is currently superior to this version - "valid-typeof": false + "react-anchor-blank-noopener": true, + "react-iframe-missing-sandbox": true, + "react-no-dangerous-html": true, + "react-this-binding-issue": true, + "react-unused-props-and-state": true, + "underscore-consistent-invocation": true, + "use-named-parameter": true, + "use-simple-attributes": true } } diff --git a/configs/stable.json b/configs/stable.json deleted file mode 100644 index 93e0b5651..000000000 --- a/configs/stable.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "rulesDirectory": ["../"], - "rules": { - "chai-prefer-contains-to-index-of": true, - "chai-vague-errors": true, - "export-name": true, - "function-name": true, - "import-name": true, - "informative-docs": true, - "insecure-random": true, - "jquery-deferred-must-complete": true, - "max-func-body-length": [true, 100, { "ignore-parameters-to-function-regex": "^describe$" }], - "mocha-avoid-only": true, - "mocha-no-side-effect-code": true, - "mocha-unneeded-done": true, - "no-backbone-get-set-outside-model": true, - "no-banned-terms": true, - "no-constant-condition": true, - "no-control-regex": true, - "no-cookies": true, - "no-delete-expression": true, - "no-disable-auto-sanitization": true, - "no-document-domain": true, - "no-document-write": true, - "no-exec-script": true, - "no-for-in": true, - "no-function-expression": true, - "no-http-string": [true, "http://www.example.com/?.*", "http://localhost:?.*"], - "no-inner-html": true, - "no-invalid-regexp": true, - "no-jquery-raw-elements": true, - "no-octal-literal": true, - "no-regex-spaces": true, - "no-relative-imports": true, - "no-single-line-block-comment": true, - "no-string-based-set-immediate": true, - "no-string-based-set-interval": true, - "no-string-based-set-timeout": true, - "no-suspicious-comment": true, - "no-typeof-undefined": true, - "no-unnecessary-field-initialization": true, - "no-unnecessary-local-variable": true, - "no-unnecessary-override": true, - "no-unnecessary-semicolons": true, - "no-unsupported-browser-code": true, - "no-useless-files": true, - "no-with-statement": true, - "non-literal-fs-path": true, - "non-literal-require": true, - "possible-timing-attack": true, - "prefer-array-literal": true, - "prefer-type-cast": true, - "promise-must-complete": true, - "react-a11y-accessible-headings": true, - "react-a11y-anchors": true, - "react-a11y-aria-unsupported-elements": true, - "react-a11y-event-has-role": true, - "react-a11y-image-button-has-alt": true, - "react-a11y-img-has-alt": true, - "react-a11y-input-elements": true, - "react-a11y-lang": true, - "react-a11y-meta": true, - "react-a11y-no-onchange": true, - "react-a11y-props": true, - "react-a11y-proptypes": true, - "react-a11y-required": true, - "react-a11y-role": true, - "react-a11y-role-has-required-aria-props": true, - "react-a11y-role-supports-aria-props": true, - "react-a11y-tabindex-no-positive": true, - "react-a11y-titles": true, - "react-anchor-blank-noopener": true, - "react-iframe-missing-sandbox": true, - "react-no-dangerous-html": true, - "react-this-binding-issue": true, - "react-unused-props-and-state": true, - "underscore-consistent-invocation": true, - "use-named-parameter": true, - "use-simple-attributes": true - } -} From acddf467a7af6542a95adc5fcb8e83dcfdc6803a Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 19 Feb 2019 07:55:21 -0500 Subject: [PATCH 7/7] Update ExtendedMetadata.ts --- src/utils/ExtendedMetadata.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/ExtendedMetadata.ts b/src/utils/ExtendedMetadata.ts index a40a96611..d1f381fd5 100644 --- a/src/utils/ExtendedMetadata.ts +++ b/src/utils/ExtendedMetadata.ts @@ -30,6 +30,6 @@ export type Severity = 'Critical' | 'Important' | 'Moderate' | 'Low'; export type Level = 'Mandatory' | 'Opportunity for Excellence'; /** - * Ignored - Use this value to exclude the rule from recommended.json. + * Ignored - Use this value to exclude the rule from configuration files. */ export type Group = 'Ignored' | 'Security' | 'Correctness' | 'Accessibility' | 'Clarity' | 'Whitespace' | 'Configurable' | 'Deprecated';