update-tslint.js 4.97 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const dependencies_1 = require("../../utility/dependencies");
const json_utils_1 = require("../../utility/json-utils");
const utils_1 = require("../update-9/utils");
exports.TSLINT_VERSION = '~6.1.0';
const TSLINT_CONFIG_PATH = '/tslint.json';
const RULES_TO_DELETE = [
    'no-use-before-declare',
    'no-unused-variable',
];
const RULES_TO_ADD = {
    align: {
        options: ['parameters', 'statements'],
    },
    'arrow-return-shorthand': true,
    curly: true,
    eofline: true,
    'import-spacing': true,
    indent: {
        options: ['spaces'],
    },
    'variable-name': {
        options: ['ban-keywords', 'check-format', 'allow-pascal-case'],
    },
    semicolon: { options: ['always'] },
    'space-before-function-paren': {
        options: {
            anonymous: 'never',
            asyncArrow: 'always',
            constructor: 'never',
            method: 'never',
            named: 'never',
        },
    },
    'typedef-whitespace': {
        options: [
            {
                'call-signature': 'nospace',
                'index-signature': 'nospace',
                parameter: 'nospace',
                'property-declaration': 'nospace',
                'variable-declaration': 'nospace',
            },
            {
                'call-signature': 'onespace',
                'index-signature': 'onespace',
                parameter: 'onespace',
                'property-declaration': 'onespace',
                'variable-declaration': 'onespace',
            },
        ],
    },
    whitespace: {
        options: [
            'check-branch',
            'check-decl',
            'check-operator',
            'check-separator',
            'check-type',
            'check-typecast',
        ],
    },
};
function default_1() {
    return (tree, context) => {
        const logger = context.logger;
        // Update tslint dependency
        const current = dependencies_1.getPackageJsonDependency(tree, 'tslint');
        if (!current) {
            logger.info('"tslint" in not a dependency of this workspace.');
            return;
        }
        if (current.version !== exports.TSLINT_VERSION) {
            dependencies_1.addPackageJsonDependency(tree, {
                type: current.type,
                name: 'tslint',
                version: exports.TSLINT_VERSION,
                overwrite: true,
            });
        }
        // Update tslint config.
        const tslintJsonAst = utils_1.readJsonFileAsAstObject(tree, TSLINT_CONFIG_PATH);
        if (!tslintJsonAst) {
            const config = ['tslint.js', 'tslint.yaml'].find(c => tree.exists(c));
            if (config) {
                logger.warn(`Expected a JSON configuration file but found "${config}".`);
            }
            else {
                logger.warn('Cannot find "tslint.json" configuration file.');
            }
            return;
        }
        // Remove old/deprecated rules.
        for (const rule of RULES_TO_DELETE) {
            const tslintJsonAst = utils_1.readJsonFileAsAstObject(tree, TSLINT_CONFIG_PATH);
            const rulesAst = json_utils_1.findPropertyInAstObject(tslintJsonAst, 'rules');
            if ((rulesAst === null || rulesAst === void 0 ? void 0 : rulesAst.kind) !== 'object') {
                break;
            }
            const recorder = tree.beginUpdate(TSLINT_CONFIG_PATH);
            json_utils_1.removePropertyInAstObject(recorder, rulesAst, rule);
            tree.commitUpdate(recorder);
        }
        // Add new rules only iif the configuration extends 'tslint:recommended'.
        // This is because some rules conflict with prettier or other tools.
        const extendsAst = json_utils_1.findPropertyInAstObject(tslintJsonAst, 'extends');
        if (!extendsAst ||
            (extendsAst.kind === 'string' && extendsAst.value !== 'tslint:recommended') ||
            (extendsAst.kind === 'array' && extendsAst.elements.some(e => e.value !== 'tslint:recommended'))) {
            logger.warn(`tslint configuration does not extend "tslint:recommended" or it extends multiple configurations.`
                + '\nSkipping rule changes as some rules might conflict.');
            return;
        }
        for (const [name, value] of Object.entries(RULES_TO_ADD)) {
            const tslintJsonAst = utils_1.readJsonFileAsAstObject(tree, TSLINT_CONFIG_PATH);
            const rulesAst = json_utils_1.findPropertyInAstObject(tslintJsonAst, 'rules');
            if ((rulesAst === null || rulesAst === void 0 ? void 0 : rulesAst.kind) !== 'object') {
                break;
            }
            if (json_utils_1.findPropertyInAstObject(rulesAst, name)) {
                // Skip as rule already exists.
                continue;
            }
            const recorder = tree.beginUpdate(TSLINT_CONFIG_PATH);
            json_utils_1.insertPropertyInAstObjectInOrder(recorder, rulesAst, name, value, 4);
            tree.commitUpdate(recorder);
        }
    };
}
exports.default = default_1;