From a4f217ef2d41b8b2f16cb646897ea08313ba4524 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Mon, 13 Mar 2017 19:42:06 +0100 Subject: [PATCH] build: replace forbidden-identifiers with tslint * Replaces the big `forbidden-identifiers` script with TSLint rules. Closes #2175 --- scripts/ci/forbidden-identifiers.js | 202 ------------------ .../connected-position-strategy.spec.ts | 2 +- tools/gulp/tasks/ci.ts | 6 +- tslint.json | 9 +- 4 files changed, 10 insertions(+), 209 deletions(-) delete mode 100755 scripts/ci/forbidden-identifiers.js diff --git a/scripts/ci/forbidden-identifiers.js b/scripts/ci/forbidden-identifiers.js deleted file mode 100755 index 301f22246023..000000000000 --- a/scripts/ci/forbidden-identifiers.js +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env node - -'use strict'; - -/* - * The forbidden identifiers script will check for blocked statements and also detect invalid - * imports of other scope packages. - * - * When running against a PR, the script will only analyze the specific amount of commits inside - * of the Pull Request. - * - * By default it checks all source files and fail if any errors were found. - */ - -const child_process = require('child_process'); -const fs = require('fs'); -const path = require('path'); -const glob = require('glob').sync; - -const blocked_statements = [ - '\\bddescribe\\(', - '\\bfdescribe\\(', - '\\biit\\(', - '\\bfit\\(', - '\\bxdescribe\\(', - '\\bxit\\(', - '\\bdebugger;', - 'from \\\'rxjs/Rx\\\'', - '\\r' -]; - -const sourceFolders = ['./src', './e2e']; -const blockedRegex = new RegExp(blocked_statements.join('|'), 'g'); - -/* - * Verify that the current PR is not adding any forbidden identifiers. - * Run the forbidden identifiers check against all sources when not verifying a PR. - */ - -findTestFiles() - - /* Only match .js or .ts, and remove .d.ts files. */ - .then(files => files.filter(name => /\.(js|ts)$/.test(name) && !/\.d\.ts$/.test(name))) - - /* Read content of the filtered files */ - .then(files => files.map(name => ({ name, content: fs.readFileSync(name, 'utf-8') }))) - - /* Run checks against content of the filtered files. */ - .then(diffList => findErrors(diffList)) - - /* Groups similar errors to simplify console output */ - .then(errors => groupErrors(errors)) - - /* Print the resolved errors to the console */ - .then(errors => printErrors(errors)) - - .catch(err => { - // An error occurred in this script. Output the error and the stack. - console.error(err.stack || err); - process.exit(2); - }); - -/** - * Finds errors inside of changed files by running them against the blocked statements. - * @param {{name: string, content: string}[]} diffList - */ -function findErrors(diffList) { - return diffList.reduce((errors, diffFile) => { - let fileName = diffFile.name; - let content = diffFile.content.split('\n'); - let lineNumber = 0; - - content.forEach(line => { - lineNumber++; - - let matches = line.match(blockedRegex); - - if (matches) { - - errors.push({ - fileName, - lineNumber, - statement: matches[0] - }); - - } - }); - - return errors; - - }, []); -} - -/** - * Groups similar errors in the same file which are present over a range of lines. - * @param {{fileName: string, lineNumber: number, statement: string}[]} errors - */ -function groupErrors(errors) { - - let initialError, initialLine, previousLine; - - return errors.filter(error => { - - if (initialError && isSimilarError(error)) { - previousLine = error.lineNumber; - - // Overwrite the lineNumber with a string, which indicates the range of lines. - initialError.lineNumber = `${initialLine}-${previousLine}`; - - return false; - } - - initialLine = previousLine = error.lineNumber; - initialError = error; - - return true; - }); - - /** Checks whether the given error is similar to the previous one. */ - function isSimilarError(error) { - return initialError.fileName === error.fileName && - initialError.statement === error.statement && - previousLine === (error.lineNumber - 1); - } -} - -/** - * Prints all errors to the console and terminates the process if errors were present. - * @param {{fileName: string, lineNumber: number, statement: string}[]} errors - */ -function printErrors(errors) { - if (errors.length > 0) { - - console.error('Error: You are using one or more blocked statements:\n'); - - errors.forEach(entry => { - - // Stringify the statement to represent line-endings or other unescaped characters. - let statement = JSON.stringify(entry.statement); - - console.error(` ${entry.fileName}@${entry.lineNumber}, Statement: ${statement}.\n`); - }); - - // Exit the process with an error exit code to notify the CI. - process.exit(1); - } -} - -/** - * Resolves all files, which should run against the forbidden identifiers check. - * @return {Promise.>} Files to be checked. - */ -function findTestFiles() { - if (process.env['TRAVIS_PULL_REQUEST']) { - return findChangedFiles(); - } - - let files = sourceFolders.map(folder => { - return glob(`${folder}/**/*`); - }).reduce((files, fileSet) => files.concat(fileSet), []); - - return Promise.resolve(files); -} - -/** - * List all the files that have been changed or added in the last commit range. - * @returns {Promise.>} Resolves with a list of files that are added or changed. - */ -function findChangedFiles() { - let commitRange = process.env['TRAVIS_COMMIT_RANGE']; - - return exec(`git diff --name-status ${commitRange} ${sourceFolders.join(' ')}`) - .then(rawDiff => { - return rawDiff - .split('\n') - .filter(line => { - // Status: C## => Copied (##% confident) - // R## => Renamed (##% confident) - // D => Deleted - // M => Modified - // A => Added - return line.match(/([CR][0-9]*|[AM])\s+/); - }) - .map(line => line.split(/\s+/, 2)[1]); - }); -} - -/** - * Executes a process command and wraps it inside of a promise. - * @returns {Promise.} - */ -function exec(cmd) { - return new Promise(function(resolve, reject) { - child_process.exec(cmd, function(err, stdout /*, stderr */) { - if (err) { - reject(err); - } else { - resolve(stdout); - } - }); - }); -} diff --git a/src/lib/core/overlay/position/connected-position-strategy.spec.ts b/src/lib/core/overlay/position/connected-position-strategy.spec.ts index 067a87c64939..2606d163fbb6 100644 --- a/src/lib/core/overlay/position/connected-position-strategy.spec.ts +++ b/src/lib/core/overlay/position/connected-position-strategy.spec.ts @@ -4,7 +4,7 @@ import {ViewportRuler, VIEWPORT_RULER_PROVIDER} from './viewport-ruler'; import {OverlayPositionBuilder} from './overlay-position-builder'; import {ConnectedOverlayPositionChange} from './connected-position'; import {Scrollable} from '../scroll/scrollable'; -import {Subscription} from 'rxjs'; +import {Subscription} from 'rxjs/Subscription'; import {TestBed, inject} from '@angular/core/testing'; import Spy = jasmine.Spy; import {SCROLL_DISPATCHER_PROVIDER} from '../scroll/scroll-dispatcher'; diff --git a/tools/gulp/tasks/ci.ts b/tools/gulp/tasks/ci.ts index 51fc8e7204b7..2eaeb98059f8 100644 --- a/tools/gulp/tasks/ci.ts +++ b/tools/gulp/tasks/ci.ts @@ -1,11 +1,7 @@ import {task} from 'gulp'; -task('ci:lint', ['ci:forbidden-identifiers', 'lint']); - -task('ci:forbidden-identifiers', function() { - require('../../../scripts/ci/forbidden-identifiers.js'); -}); +task('ci:lint', ['lint']); // Travis sometimes does not exit the process and times out. This is to prevent that. task('ci:test', ['test:single-run'], () => process.exit(0)); diff --git a/tslint.json b/tslint.json index 355f0a244748..476332448cce 100644 --- a/tslint.json +++ b/tslint.json @@ -25,6 +25,7 @@ "no-shadowed-variable": true, "no-unused-expression": true, "no-unused-var": [true, {"ignore-pattern": "^(_.*)$"}], + "no-debugger": true, "one-line": [ true, "check-catch", @@ -62,6 +63,12 @@ "check-operator", "check-separator", "check-type" - ] + ], + // Bans jasmine helper functions that will prevent the CI from properly running tests. + "ban": [true, ["fit"], ["fdescribe"], ["xit"], ["xdescribe"]], + // Disallows importing the whole RxJS library. Submodules can be still imported. + "import-blacklist": [true, "rxjs"], + // Avoids inconsistent linebreak styles in source files. Forces developers to use LF linebreaks. + "linebreak-style": [true, "LF"] } }